[3/5] pstore: Use size_t for compress/decompression type widths

Message ID 20221018020815.2872331-3-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 adding direct library calls for zstd, refactor
routines to use normalized compress/decompression type widths of size_t.

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 | 47 ++++++++++++++++++++++++++++++--------------
 1 file changed, 32 insertions(+), 15 deletions(-)
  

Patch

diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 1f01c4b904fc..210a4224edb4 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -155,17 +155,24 @@  static bool pstore_cannot_block_path(enum kmsg_dump_reason reason)
 }
 
 static int pstore_compress(const void *in, void *out,
-			   unsigned int inlen, unsigned int outlen)
+			   size_t inlen, size_t *outlen)
 {
 	if (IS_ENABLED(CONFIG_PSTORE_COMPRESS_CRYPTO)) {
+		unsigned int crypto_outlen;
 		int ret;
 
-		ret = crypto_comp_compress(tfm, in, inlen, out, &outlen);
+		if (inlen > UINT_MAX || *outlen > UINT_MAX)
+			return -EINVAL;
+
+		crypto_outlen = *outlen;
+		ret = crypto_comp_compress(tfm, in, inlen, out, &crypto_outlen);
 		if (ret) {
 			pr_err("crypto_comp_compress failed, ret = %d!\n", ret);
 			return ret;
 		}
-		return outlen;
+
+		*outlen = crypto_outlen;
+		return 0;
 	}
 
 	return -EINVAL;
@@ -297,7 +304,6 @@  static void pstore_dump(struct kmsg_dumper *dumper,
 		char *dst;
 		size_t dst_size;
 		int header_size;
-		int zipped_len = -1;
 		size_t dump_size;
 		struct pstore_record record;
 
@@ -327,11 +333,11 @@  static void pstore_dump(struct kmsg_dumper *dumper,
 			break;
 
 		if (big_oops_buf) {
-			zipped_len = pstore_compress(dst, psinfo->buf,
-						header_size + dump_size,
-						psinfo->bufsize);
+			size_t zipped_len = psinfo->bufsize;
 
-			if (zipped_len > 0) {
+			if (pstore_compress(dst, psinfo->buf,
+					    header_size + dump_size,
+					    &zipped_len) == 0) {
 				record.compressed = true;
 				record.size = zipped_len;
 			} else {
@@ -563,10 +569,25 @@  void pstore_unregister(struct pstore_info *psi)
 }
 EXPORT_SYMBOL_GPL(pstore_unregister);
 
-static void decompress_record(struct pstore_record *record)
+static int pstore_decompress_crypto(struct pstore_record *record, char *workspace, size_t *outlen)
 {
+	unsigned int crypto_outlen = *outlen;
 	int ret;
-	int unzipped_len;
+
+	ret = crypto_comp_decompress(tfm, record->buf, record->size,
+				     workspace, &crypto_outlen);
+	if (ret) {
+		pr_err("crypto_comp_decompress failed, ret = %d!\n", ret);
+		return 0;
+	}
+
+	*outlen = crypto_outlen;
+	return 0;
+}
+
+static void decompress_record(struct pstore_record *record)
+{
+	size_t unzipped_len;
 	char *unzipped, *workspace;
 
 	if (IS_ENABLED(CONFIG_PSTORE_COMPRESS_NONE) || !record->compressed)
@@ -591,11 +612,7 @@  static void decompress_record(struct pstore_record *record)
 	if (!workspace)
 		return;
 
-	/* After decompression "unzipped_len" is almost certainly smaller. */
-	ret = crypto_comp_decompress(tfm, record->buf, record->size,
-					  workspace, &unzipped_len);
-	if (ret) {
-		pr_err("crypto_comp_decompress failed, ret = %d!\n", ret);
+	if (pstore_decompress_crypto(record, workspace, &unzipped_len) != 0) {
 		kfree(workspace);
 		return;
 	}