Commit a2f31df0 authored by John Johansen's avatar John Johansen

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: default avatarJohn Johansen <john.johansen@canonical.com>
Acked-by: default avatarJon Tourville <jon.tourville@canonical.com>
parent 70f24a9f
...@@ -1315,7 +1315,7 @@ SEQ_RAWDATA_FOPS(compressed_size); ...@@ -1315,7 +1315,7 @@ SEQ_RAWDATA_FOPS(compressed_size);
static int decompress_zstd(char *src, size_t slen, char *dst, size_t dlen) static int decompress_zstd(char *src, size_t slen, char *dst, size_t dlen)
{ {
#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY #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(); const size_t wksp_len = zstd_dctx_workspace_bound();
zstd_dctx *ctx; zstd_dctx *ctx;
void *wksp; void *wksp;
......
...@@ -1294,7 +1294,7 @@ static int compress_zstd(const char *src, size_t slen, char **dst, size_t *dlen) ...@@ -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); 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; ret = -EINVAL;
goto cleanup; goto cleanup;
} }
...@@ -1348,9 +1348,10 @@ static int compress_loaddata(struct aa_loaddata *data) ...@@ -1348,9 +1348,10 @@ static int compress_loaddata(struct aa_loaddata *data)
void *udata = data->data; void *udata = data->data;
int error = compress_zstd(udata, data->size, &data->data, int error = compress_zstd(udata, data->size, &data->data,
&data->compressed_size); &data->compressed_size);
if (error) if (error) {
data->compressed_size = data->size;
return error; return error;
}
if (udata != data->data) if (udata != data->data)
kvfree(udata); kvfree(udata);
} else } else
......
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