lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Mon, 17 Oct 2022 19:08:13 -0700 From: Kees Cook <keescook@...omium.org> To: Ard Biesheuvel <ardb@...nel.org> Cc: Kees Cook <keescook@...omium.org>, Tony Luck <tony.luck@...el.com>, "Guilherme G. Piccoli" <gpiccoli@...lia.com>, Nick Terrell <terrelln@...com>, linux-hardening@...r.kernel.org, linux-kernel@...r.kernel.org Subject: [PATCH 5/5] pstore: Use zstd directly by default for compression If compression is desired, use zstd directly to avoid Crypto API overhead. Cc: Tony Luck <tony.luck@...el.com> Cc: "Guilherme G. Piccoli" <gpiccoli@...lia.com> Cc: Nick Terrell <terrelln@...com> Cc: linux-hardening@...r.kernel.org Signed-off-by: Kees Cook <keescook@...omium.org> --- fs/pstore/Kconfig | 11 +++++- fs/pstore/platform.c | 93 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 97 insertions(+), 7 deletions(-) diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig index a95b3981cb0e..1f05312c7479 100644 --- a/fs/pstore/Kconfig +++ b/fs/pstore/Kconfig @@ -25,7 +25,7 @@ config PSTORE_DEFAULT_KMSG_BYTES choice prompt "Panic dump compression" depends on PSTORE - default PSTORE_COMPRESS_CRYPTO + default PSTORE_COMPRESS help Choose whether and how to compress the panic dump output. This is usually only needed for very storage-constrained backends. @@ -38,6 +38,15 @@ choice available to from the Crypto API. Note that this may reserve non-trivial amounts of per-CPU memory. + config PSTORE_COMPRESS + bool "Use recommended best compression algorithm" + select CRYPTO_ZSTD + help + Use the compression routines currently deemed best suited + for panic dump compression. Currently, this is "zstd". + As this compression is used directly through its library + interface, no per-CPU memory is allocated by the Crypto API. + config PSTORE_COMPRESS_NONE bool "Do not compress panic dumps" help diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 4d883dc2e8a7..51d2801fc880 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -23,6 +23,7 @@ #include <linux/uaccess.h> #include <linux/jiffies.h> #include <linux/workqueue.h> +#include <linux/zstd.h> #include "internal.h" @@ -72,13 +73,17 @@ module_param(backend, charp, 0444); MODULE_PARM_DESC(backend, "specific backend to use"); static char *compress __ro_after_init = -#ifdef CONFIG_PSTORE_COMPRESS_CRYPTO_DEFAULT - CONFIG_PSTORE_COMPRESS_CRYPTO_DEFAULT; +#ifdef CONFIG_PSTORE_COMPRESS + "zstd"; #else - NULL; -#endif +# ifdef CONFIG_PSTORE_COMPRESS_CRYPTO_DEFAULT + CONFIG_PSTORE_COMPRESS_CRYPTO_DEFAULT; module_param(compress, charp, 0444); MODULE_PARM_DESC(compress, "compression to use"); +# else + NULL; +# endif +#endif /* How much of the kernel log to snapshot */ unsigned long kmsg_bytes = CONFIG_PSTORE_DEFAULT_KMSG_BYTES; @@ -88,6 +93,12 @@ MODULE_PARM_DESC(kmsg_bytes, "amount of kernel log to snapshot (in bytes)"); /* Compression parameters */ static struct crypto_comp *tfm; +static zstd_cctx *cctx; +static zstd_dctx *dctx; +static void *cwksp; +static void *dwksp; +zstd_parameters zparams; + static char *big_oops_buf; static size_t big_oops_buf_sz; @@ -175,6 +186,14 @@ static int pstore_compress(const void *in, void *out, return 0; } + if (IS_ENABLED(CONFIG_PSTORE_COMPRESS)) { + *outlen = zstd_compress_cctx(cctx, out, *outlen, in, inlen, + &zparams); + if (zstd_is_error(*outlen)) + return -EINVAL; + return 0; + } + return -EINVAL; } @@ -203,12 +222,56 @@ static int allocate_crypto_buf(void) return 0; } +static int allocate_zstd_buf(void) +{ + size_t csize, dsize; + + /* Skip if compression init already done. */ + if (cctx) + return 0; + + zparams = zstd_get_params(3, 0); + csize = zstd_cctx_workspace_bound(&zparams.cParams); + dsize = zstd_dctx_workspace_bound(); + +#define init_ctx(dir, name) do { \ + dir##wksp = kzalloc(dir##size, GFP_KERNEL); \ + if (!dir##wksp) { \ + pr_err("Failed %zu byte %s " #name " allocation\n", \ + dir##size, compress); \ + return -ENOMEM; \ + } \ + dir##ctx = zstd_init_##dir##ctx(dir##wksp, dir##size); \ + if (!dir##ctx) { \ + pr_err("Failed %s " #name " context init\n", compress); \ + return -EINVAL; \ + } \ +} while (0) + + init_ctx(c, compress); + init_ctx(d, decompress); + +#undef init_wksp + + pr_info("Using crash dump compression: built-in %s\n", compress); + return 0; +} + static void free_buf_for_compression(void) { if (IS_ENABLED(CONFIG_PSTORE_COMPRESS_CRYPTO) && tfm) { crypto_free_comp(tfm); tfm = NULL; } + if (IS_ENABLED(CONFIG_PSTORE_COMPRESS) && cctx) { + cctx = NULL; + dctx = NULL; + kfree(cwksp); + cwksp = NULL; + kfree(dwksp); + dwksp = NULL; + + } kfree(big_oops_buf); big_oops_buf = NULL; big_oops_buf_sz = 0; @@ -228,7 +291,10 @@ static void allocate_buf_for_compression(void) return; /* Initialize compression routines. */ - rc = allocate_crypto_buf(); + if (IS_ENABLED(CONFIG_PSTORE_COMPRESS_CRYPTO)) + rc = allocate_crypto_buf(); + else + rc = allocate_zstd_buf(); if (rc) goto fail; @@ -598,6 +664,16 @@ static int pstore_decompress_crypto(struct pstore_record *record, char *workspac return 0; } +static int pstore_decompress_zstd(struct pstore_record *record, + char *workspace, size_t *outlen) +{ + *outlen = zstd_decompress_dctx(dctx, workspace, *outlen, + record->buf, record->size); + if (zstd_is_error(*outlen)) + return -EINVAL; + return 0; +} + static void decompress_record(struct pstore_record *record) { size_t unzipped_len; @@ -626,7 +702,12 @@ static void decompress_record(struct pstore_record *record) if (!workspace) return; - rc = pstore_decompress_crypto(record, workspace, &unzipped_len); + if (IS_ENABLED(CONFIG_PSTORE_COMPRESS_CRYPTO)) + rc = pstore_decompress_crypto(record, workspace, + &unzipped_len); + else + rc = pstore_decompress_zstd(record, workspace, + &unzipped_len); if (rc) { kfree(workspace); return; -- 2.34.1
Powered by blists - more mailing lists