summaryrefslogtreecommitdiff
path: root/security/apparmor
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2022-09-29 16:48:10 +0300
committerJohn Johansen <john.johansen@canonical.com>2022-10-04 00:49:04 +0300
commita2f31df06b7aa1769f12ec6f9ae7f18e78582cad (patch)
tree64e36b139b1621471e8a958ae813e8a6ccb4acf5 /security/apparmor
parent70f24a9f9084b7fffd95daa707cce8e339b189dd (diff)
downloadlinux-a2f31df06b7aa1769f12ec6f9ae7f18e78582cad.tar.xz
apparmor: Fix decompression of rawdata for read back to userspace
The rawdata readback has a few of problems. First if compression is enabled when the data is read then the compressed data is read out instead decompressing the data. Second if compression of the data fails, the code does not handle holding onto the raw_data in uncompressed form. Third if the compression is enabled/disabled after the rawdata was loaded, the check against the global control of whether to use compression does not reflect what was already done to the data. Fix these by always storing the compressed size, along with the original data size even if compression fails or is not used. And use this to detect whether the rawdata is actually compressed. Fixes: 52ccc20c652b ("apparmor: use zstd compression for profile data") Signed-off-by: John Johansen <john.johansen@canonical.com> Acked-by: Jon Tourville <jon.tourville@canonical.com>
Diffstat (limited to 'security/apparmor')
-rw-r--r--security/apparmor/apparmorfs.c2
-rw-r--r--security/apparmor/policy_unpack.c7
2 files changed, 5 insertions, 4 deletions
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 2c138309ad66..424b2c1e586d 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -1315,7 +1315,7 @@ SEQ_RAWDATA_FOPS(compressed_size);
static int decompress_zstd(char *src, size_t slen, char *dst, size_t dlen)
{
#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
- if (aa_g_rawdata_compression_level == 0) {
+ if (slen < dlen) {
const size_t wksp_len = zstd_dctx_workspace_bound();
zstd_dctx *ctx;
void *wksp;
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 6deaeecb76fe..45c9dfdc8e0d 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -1294,7 +1294,7 @@ static int compress_zstd(const char *src, size_t slen, char **dst, size_t *dlen)
}
out_len = zstd_compress_cctx(ctx, out, out_len, src, slen, &params);
- if (zstd_is_error(out_len)) {
+ if (zstd_is_error(out_len) || out_len >= slen) {
ret = -EINVAL;
goto cleanup;
}
@@ -1348,9 +1348,10 @@ static int compress_loaddata(struct aa_loaddata *data)
void *udata = data->data;
int error = compress_zstd(udata, data->size, &data->data,
&data->compressed_size);
- if (error)
+ if (error) {
+ data->compressed_size = data->size;
return error;
-
+ }
if (udata != data->data)
kvfree(udata);
} else