[4/5] pstore: Refactor compression initialization

Message ID 20221018020815.2872331-4-keescook@chromium.org
State New
Headers
Series pstore: Use zstd directly by default for compression |

Commit Message

Kees Cook Oct. 18, 2022, 2:08 a.m. UTC
  In preparation for calling zstd library compression routines, split the
crypto-specific initialization into a separate init routine.

Cc: Tony Luck <tony.luck@intel.com>
Cc: "Guilherme G. Piccoli" <gpiccoli@igalia.com>
Cc: linux-hardening@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/pstore/platform.c | 71 +++++++++++++++++++++++++++-----------------
 1 file changed, 43 insertions(+), 28 deletions(-)
  

Patch

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 210a4224edb4..4d883dc2e8a7 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -178,48 +178,29 @@  static int pstore_compress(const void *in, void *out,
 	return -EINVAL;
 }
 
-static void allocate_buf_for_compression(void)
+static int allocate_crypto_buf(void)
 {
 	struct crypto_comp *ctx;
-	int size;
-	char *buf;
 
-	/* Skip if not built-in or compression backend not selected yet. */
-	if (IS_ENABLED(CONFIG_PSTORE_COMPRESS_NONE) || !compress)
-		return;
-
-	/* Skip if no pstore backend yet or compression init already done. */
-	if (!psinfo || tfm)
-		return;
+	/* Skip if compression init already done. */
+	if (tfm)
+		return 0;
 
 	if (!crypto_has_comp(compress, 0, 0)) {
 		pr_err("Unknown compression: %s\n", compress);
-		return;
-	}
-
-	/* Worst-case compression should never be more than uncompressed. */
-	size = psinfo->bufsize;
-	buf = kmalloc(size, GFP_KERNEL);
-	if (!buf) {
-		pr_err("Failed %d byte compression buffer allocation for: %s\n",
-		       size, compress);
-		return;
+		return -EINVAL;
 	}
 
 	ctx = crypto_alloc_comp(compress, 0, 0);
 	if (IS_ERR_OR_NULL(ctx)) {
-		kfree(buf);
 		pr_err("crypto_alloc_comp('%s') failed: %ld\n", compress,
 		       PTR_ERR(ctx));
-		return;
+		return -ENOMEM;
 	}
-
-	/* A non-NULL big_oops_buf indicates compression is available. */
 	tfm = ctx;
-	big_oops_buf_sz = size;
-	big_oops_buf = buf;
 
-	pr_info("Using crash dump compression: %s\n", compress);
+	pr_info("Using crash dump compression: crypto API %s\n", compress);
+	return 0;
 }
 
 static void free_buf_for_compression(void)
@@ -233,6 +214,38 @@  static void free_buf_for_compression(void)
 	big_oops_buf_sz = 0;
 }
 
+static void allocate_buf_for_compression(void)
+{
+	char *buf;
+	int rc;
+
+	/* Skip if not built-in or compression backend not selected yet. */
+	if (IS_ENABLED(CONFIG_PSTORE_COMPRESS_NONE) || !compress)
+		return;
+
+	/* Skip if no pstore backend yet. */
+	if (!psinfo)
+		return;
+
+	/* Initialize compression routines. */
+	rc = allocate_crypto_buf();
+	if (rc)
+		goto fail;
+
+	/* Create common buffer for compression work. */
+	buf = kmalloc(psinfo->bufsize, GFP_KERNEL);
+	if (!buf)
+		goto fail;
+
+	/* A non-NULL big_oops_buf indicates compression is available. */
+	big_oops_buf_sz = psinfo->bufsize;
+	big_oops_buf = buf;
+	return;
+
+fail:
+	free_buf_for_compression();
+}
+
 /*
  * Called when compression fails, since the printk buffer
  * would be fetched for compression calling it again when
@@ -589,6 +602,7 @@  static void decompress_record(struct pstore_record *record)
 {
 	size_t unzipped_len;
 	char *unzipped, *workspace;
+	int rc;
 
 	if (IS_ENABLED(CONFIG_PSTORE_COMPRESS_NONE) || !record->compressed)
 		return;
@@ -612,7 +626,8 @@  static void decompress_record(struct pstore_record *record)
 	if (!workspace)
 		return;
 
-	if (pstore_decompress_crypto(record, workspace, &unzipped_len) != 0) {
+	rc = pstore_decompress_crypto(record, workspace, &unzipped_len);
+	if (rc) {
 		kfree(workspace);
 		return;
 	}