Commit 40158dbf authored by Guilherme G. Piccoli's avatar Guilherme G. Piccoli Committed by Kees Cook

Revert "pstore: migrate to crypto acomp interface"

This reverts commit e4f0a7ec.

When using this new interface, both efi_pstore and ramoops
backends are unable to properly decompress dmesg if using
zstd, lz4 and lzo algorithms (and maybe more). It does succeed
with deflate though.

The message observed in the kernel log is:

[2.328828] pstore: crypto_acomp_decompress failed, ret = -22!

The pstore infrastructure is able to collect the dmesg with
both backends tested, but since decompression fails it's
unreadable. With this revert everything is back to normal.

Fixes: e4f0a7ec ("pstore: migrate to crypto acomp interface")
Cc: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: default avatarGuilherme G. Piccoli <gpiccoli@igalia.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20220929215515.276486-1-gpiccoli@igalia.com
parent 568035b0
...@@ -28,14 +28,11 @@ ...@@ -28,14 +28,11 @@
#include <linux/crypto.h> #include <linux/crypto.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/scatterlist.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <crypto/acompress.h>
#include "internal.h" #include "internal.h"
/* /*
...@@ -93,8 +90,7 @@ module_param(compress, charp, 0444); ...@@ -93,8 +90,7 @@ module_param(compress, charp, 0444);
MODULE_PARM_DESC(compress, "compression to use"); MODULE_PARM_DESC(compress, "compression to use");
/* Compression parameters */ /* Compression parameters */
static struct crypto_acomp *tfm; static struct crypto_comp *tfm;
static struct acomp_req *creq;
struct pstore_zbackend { struct pstore_zbackend {
int (*zbufsize)(size_t size); int (*zbufsize)(size_t size);
...@@ -272,21 +268,12 @@ static const struct pstore_zbackend zbackends[] = { ...@@ -272,21 +268,12 @@ static const struct pstore_zbackend zbackends[] = {
static int pstore_compress(const void *in, void *out, static int pstore_compress(const void *in, void *out,
unsigned int inlen, unsigned int outlen) unsigned int inlen, unsigned int outlen)
{ {
struct scatterlist src, dst;
int ret; int ret;
if (!IS_ENABLED(CONFIG_PSTORE_COMPRESS)) if (!IS_ENABLED(CONFIG_PSTORE_COMPRESS))
return -EINVAL; return -EINVAL;
sg_init_table(&src, 1); ret = crypto_comp_compress(tfm, in, inlen, out, &outlen);
sg_set_buf(&src, in, inlen);
sg_init_table(&dst, 1);
sg_set_buf(&dst, out, outlen);
acomp_request_set_params(creq, &src, &dst, inlen, outlen);
ret = crypto_acomp_compress(creq);
if (ret) { if (ret) {
pr_err("crypto_comp_compress failed, ret = %d!\n", ret); pr_err("crypto_comp_compress failed, ret = %d!\n", ret);
return ret; return ret;
...@@ -297,7 +284,7 @@ static int pstore_compress(const void *in, void *out, ...@@ -297,7 +284,7 @@ static int pstore_compress(const void *in, void *out,
static void allocate_buf_for_compression(void) static void allocate_buf_for_compression(void)
{ {
struct crypto_acomp *acomp; struct crypto_comp *ctx;
int size; int size;
char *buf; char *buf;
...@@ -309,7 +296,7 @@ static void allocate_buf_for_compression(void) ...@@ -309,7 +296,7 @@ static void allocate_buf_for_compression(void)
if (!psinfo || tfm) if (!psinfo || tfm)
return; return;
if (!crypto_has_acomp(zbackend->name, 0, CRYPTO_ALG_ASYNC)) { if (!crypto_has_comp(zbackend->name, 0, 0)) {
pr_err("Unknown compression: %s\n", zbackend->name); pr_err("Unknown compression: %s\n", zbackend->name);
return; return;
} }
...@@ -328,24 +315,16 @@ static void allocate_buf_for_compression(void) ...@@ -328,24 +315,16 @@ static void allocate_buf_for_compression(void)
return; return;
} }
acomp = crypto_alloc_acomp(zbackend->name, 0, CRYPTO_ALG_ASYNC); ctx = crypto_alloc_comp(zbackend->name, 0, 0);
if (IS_ERR_OR_NULL(acomp)) { if (IS_ERR_OR_NULL(ctx)) {
kfree(buf); kfree(buf);
pr_err("crypto_alloc_comp('%s') failed: %ld\n", zbackend->name, pr_err("crypto_alloc_comp('%s') failed: %ld\n", zbackend->name,
PTR_ERR(acomp)); PTR_ERR(ctx));
return;
}
creq = acomp_request_alloc(acomp);
if (!creq) {
crypto_free_acomp(acomp);
kfree(buf);
pr_err("acomp_request_alloc('%s') failed\n", zbackend->name);
return; return;
} }
/* A non-NULL big_oops_buf indicates compression is available. */ /* A non-NULL big_oops_buf indicates compression is available. */
tfm = acomp; tfm = ctx;
big_oops_buf_sz = size; big_oops_buf_sz = size;
big_oops_buf = buf; big_oops_buf = buf;
...@@ -355,8 +334,7 @@ static void allocate_buf_for_compression(void) ...@@ -355,8 +334,7 @@ static void allocate_buf_for_compression(void)
static void free_buf_for_compression(void) static void free_buf_for_compression(void)
{ {
if (IS_ENABLED(CONFIG_PSTORE_COMPRESS) && tfm) { if (IS_ENABLED(CONFIG_PSTORE_COMPRESS) && tfm) {
acomp_request_free(creq); crypto_free_comp(tfm);
crypto_free_acomp(tfm);
tfm = NULL; tfm = NULL;
} }
kfree(big_oops_buf); kfree(big_oops_buf);
...@@ -693,8 +671,6 @@ static void decompress_record(struct pstore_record *record) ...@@ -693,8 +671,6 @@ static void decompress_record(struct pstore_record *record)
int ret; int ret;
int unzipped_len; int unzipped_len;
char *unzipped, *workspace; char *unzipped, *workspace;
struct acomp_req *dreq;
struct scatterlist src, dst;
if (!IS_ENABLED(CONFIG_PSTORE_COMPRESS) || !record->compressed) if (!IS_ENABLED(CONFIG_PSTORE_COMPRESS) || !record->compressed)
return; return;
...@@ -718,30 +694,16 @@ static void decompress_record(struct pstore_record *record) ...@@ -718,30 +694,16 @@ static void decompress_record(struct pstore_record *record)
if (!workspace) if (!workspace)
return; return;
dreq = acomp_request_alloc(tfm);
if (!dreq) {
kfree(workspace);
return;
}
sg_init_table(&src, 1);
sg_set_buf(&src, record->buf, record->size);
sg_init_table(&dst, 1);
sg_set_buf(&dst, workspace, unzipped_len);
acomp_request_set_params(dreq, &src, &dst, record->size, unzipped_len);
/* After decompression "unzipped_len" is almost certainly smaller. */ /* After decompression "unzipped_len" is almost certainly smaller. */
ret = crypto_acomp_decompress(dreq); ret = crypto_comp_decompress(tfm, record->buf, record->size,
workspace, &unzipped_len);
if (ret) { if (ret) {
pr_err("crypto_acomp_decompress failed, ret = %d!\n", ret); pr_err("crypto_comp_decompress failed, ret = %d!\n", ret);
kfree(workspace); kfree(workspace);
return; return;
} }
/* Append ECC notice to decompressed buffer. */ /* Append ECC notice to decompressed buffer. */
unzipped_len = dreq->dlen;
memcpy(workspace + unzipped_len, record->buf + record->size, memcpy(workspace + unzipped_len, record->buf + record->size,
record->ecc_notice_size); record->ecc_notice_size);
...@@ -749,7 +711,6 @@ static void decompress_record(struct pstore_record *record) ...@@ -749,7 +711,6 @@ static void decompress_record(struct pstore_record *record)
unzipped = kmemdup(workspace, unzipped_len + record->ecc_notice_size, unzipped = kmemdup(workspace, unzipped_len + record->ecc_notice_size,
GFP_KERNEL); GFP_KERNEL);
kfree(workspace); kfree(workspace);
acomp_request_free(dreq);
if (!unzipped) if (!unzipped)
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment