summaryrefslogtreecommitdiff
path: root/security/apparmor/apparmorfs.c
diff options
context:
space:
mode:
authorJon Tourville <jon.tourville@canonical.com>2022-07-11 11:36:08 -0500
committerJohn Johansen <john.johansen@canonical.com>2022-10-03 14:49:02 -0700
commitf4d6b94b40c966ddd9eeb0d451e8a02c595ec7e3 (patch)
tree918cf11a9d4d6ccc6f362f4ee149586bff23c1fc /security/apparmor/apparmorfs.c
parentf47acc4b7c43d566bf42816335830c4c17f9c200 (diff)
apparmor: use zstd compression for profile data
Change the algorithm used by apparmor to compress profile data from zlib to zstd, using the new zstd API introduced in 5.16. Zstd provides a larger range of compression levels than zlib and significantly better performance at the default level (for a relatively small increase in compressed size). The apparmor module parameter raw_data_compression_level is now clamped to the minimum and maximum compression levels reported by the zstd library. A compression level of 0 retains the previous behavior of disabling policy compression instead of using zstd's behavior, which is to use the default compression level. Signed-off-by: Jon Tourville <jon.tourville@canonical.com> Signed-off-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security/apparmor/apparmorfs.c')
-rw-r--r--security/apparmor/apparmorfs.c60
1 files changed, 24 insertions, 36 deletions
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 7160e7aa58b9..d98bbf267fc7 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -21,7 +21,7 @@
#include <linux/fs.h>
#include <linux/fs_context.h>
#include <linux/poll.h>
-#include <linux/zlib.h>
+#include <linux/zstd.h>
#include <uapi/linux/major.h>
#include <uapi/linux/magic.h>
@@ -1297,42 +1297,30 @@ SEQ_RAWDATA_FOPS(revision);
SEQ_RAWDATA_FOPS(hash);
SEQ_RAWDATA_FOPS(compressed_size);
-static int deflate_decompress(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
- if (aa_g_rawdata_compression_level != 0) {
- int error = 0;
- struct z_stream_s strm;
-
- memset(&strm, 0, sizeof(strm));
-
- strm.workspace = kvzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
- if (!strm.workspace)
- return -ENOMEM;
-
- strm.next_in = src;
- strm.avail_in = slen;
-
- error = zlib_inflateInit(&strm);
- if (error != Z_OK) {
- error = -ENOMEM;
- goto fail_inflate_init;
+ if (aa_g_rawdata_compression_level == 0) {
+ const size_t wksp_len = zstd_dctx_workspace_bound();
+ zstd_dctx *ctx;
+ void *wksp;
+ size_t out_len;
+ int ret = 0;
+
+ wksp = kvzalloc(wksp_len, GFP_KERNEL);
+ if (!wksp) {
+ ret = -ENOMEM;
+ goto cleanup;
}
- strm.next_out = dst;
- strm.avail_out = dlen;
-
- error = zlib_inflate(&strm, Z_FINISH);
- if (error != Z_STREAM_END)
- error = -EINVAL;
- else
- error = 0;
-
- zlib_inflateEnd(&strm);
-fail_inflate_init:
- kvfree(strm.workspace);
-
- return error;
+ out_len = zstd_decompress_dctx(ctx, dst, dlen, src, slen);
+ if (zstd_is_error(out_len)) {
+ ret = -EINVAL;
+ goto cleanup;
+ }
+cleanup:
+ kvfree(wksp);
+ return ret;
}
#endif
@@ -1381,9 +1369,9 @@ static int rawdata_open(struct inode *inode, struct file *file)
private->loaddata = loaddata;
- error = deflate_decompress(loaddata->data, loaddata->compressed_size,
- RAWDATA_F_DATA_BUF(private),
- loaddata->size);
+ error = decompress_zstd(loaddata->data, loaddata->compressed_size,
+ RAWDATA_F_DATA_BUF(private),
+ loaddata->size);
if (error)
goto fail_decompress;