Merge tag 'apparmor-pr-2022-08-08' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / security / apparmor / apparmorfs.c
index 0797edb2fb3dc6c4e16921c7e3c3dad91ae98792..d066ccc219e2d9df4fe1887d4660ad491f80ef02 100644 (file)
@@ -36,6 +36,7 @@
 #include "include/policy_ns.h"
 #include "include/resource.h"
 #include "include/policy_unpack.h"
+#include "include/task.h"
 
 /*
  * The apparmor filesystem interface used for policy load and introspection
@@ -70,6 +71,7 @@ struct rawdata_f_data {
        struct aa_loaddata *loaddata;
 };
 
+#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
 #define RAWDATA_F_DATA_BUF(p) (char *)(p + 1)
 
 static void rawdata_f_data_free(struct rawdata_f_data *private)
@@ -94,9 +96,10 @@ static struct rawdata_f_data *rawdata_f_data_alloc(size_t size)
 
        return ret;
 }
+#endif
 
 /**
- * aa_mangle_name - mangle a profile name to std profile layout form
+ * mangle_name - mangle a profile name to std profile layout form
  * @name: profile name to mangle  (NOT NULL)
  * @target: buffer to store mangled name, same length as @name (MAYBE NULL)
  *
@@ -401,7 +404,7 @@ static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf,
 
        data->size = copy_size;
        if (copy_from_user(data->data, userbuf, copy_size)) {
-               kvfree(data);
+               aa_put_loaddata(data);
                return ERR_PTR(-EFAULT);
        }
 
@@ -1201,7 +1204,7 @@ SEQ_NS_FOPS(name);
 
 
 /* policy/raw_data/ * file ops */
-
+#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
 #define SEQ_RAWDATA_FOPS(NAME)                                               \
 static int seq_rawdata_ ##NAME ##_open(struct inode *inode, struct file *file)\
 {                                                                            \
@@ -1294,44 +1297,47 @@ SEQ_RAWDATA_FOPS(compressed_size);
 
 static int deflate_decompress(char *src, size_t slen, char *dst, size_t dlen)
 {
-       int error;
-       struct z_stream_s strm;
+#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
+       if (aa_g_rawdata_compression_level != 0) {
+               int error = 0;
+               struct z_stream_s strm;
 
-       if (aa_g_rawdata_compression_level == 0) {
-               if (dlen < slen)
-                       return -EINVAL;
-               memcpy(dst, src, slen);
-               return 0;
-       }
+               memset(&strm, 0, sizeof(strm));
 
-       memset(&strm, 0, sizeof(strm));
+               strm.workspace = kvzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
+               if (!strm.workspace)
+                       return -ENOMEM;
 
-       strm.workspace = kvzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
-       if (!strm.workspace)
-               return -ENOMEM;
-
-       strm.next_in = src;
-       strm.avail_in = slen;
+               strm.next_in = src;
+               strm.avail_in = slen;
 
-       error = zlib_inflateInit(&strm);
-       if (error != Z_OK) {
-               error = -ENOMEM;
-               goto fail_inflate_init;
-       }
+               error = zlib_inflateInit(&strm);
+               if (error != Z_OK) {
+                       error = -ENOMEM;
+                       goto fail_inflate_init;
+               }
 
-       strm.next_out = dst;
-       strm.avail_out = dlen;
+               strm.next_out = dst;
+               strm.avail_out = dlen;
 
-       error = zlib_inflate(&strm, Z_FINISH);
-       if (error != Z_STREAM_END)
-               error = -EINVAL;
-       else
-               error = 0;
+               error = zlib_inflate(&strm, Z_FINISH);
+               if (error != Z_STREAM_END)
+                       error = -EINVAL;
+               else
+                       error = 0;
 
-       zlib_inflateEnd(&strm);
+               zlib_inflateEnd(&strm);
 fail_inflate_init:
-       kvfree(strm.workspace);
-       return error;
+               kvfree(strm.workspace);
+
+               return error;
+       }
+#endif
+
+       if (dlen < slen)
+               return -EINVAL;
+       memcpy(dst, src, slen);
+       return 0;
 }
 
 static ssize_t rawdata_read(struct file *file, char __user *buf, size_t size,
@@ -1492,10 +1498,12 @@ fail:
 
        return PTR_ERR(dent);
 }
+#endif /* CONFIG_SECURITY_APPARMOR_EXPORT_BINARY */
+
 
 /** fns to setup dynamic per profile/namespace files **/
 
-/**
+/*
  *
  * Requires: @profile->ns->lock held
  */
@@ -1522,7 +1530,7 @@ void __aafs_profile_rmdir(struct aa_profile *profile)
        }
 }
 
-/**
+/*
  *
  * Requires: @old->ns->lock held
  */
@@ -1557,6 +1565,7 @@ static struct dentry *create_profile_file(struct dentry *dir, const char *name,
        return dent;
 }
 
+#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
 static int profile_depth(struct aa_profile *profile)
 {
        int depth = 0;
@@ -1658,7 +1667,7 @@ static const struct inode_operations rawdata_link_abi_iops = {
 static const struct inode_operations rawdata_link_data_iops = {
        .get_link       = rawdata_get_link_data,
 };
-
+#endif /* CONFIG_SECURITY_APPARMOR_EXPORT_BINARY */
 
 /*
  * Requires: @profile->ns->lock held
@@ -1729,15 +1738,17 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
                profile->dents[AAFS_PROF_HASH] = dent;
        }
 
+#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
        if (profile->rawdata) {
-               dent = aafs_create("raw_sha1", S_IFLNK | 0444, dir,
-                                  profile->label.proxy, NULL, NULL,
-                                  &rawdata_link_sha1_iops);
-               if (IS_ERR(dent))
-                       goto fail;
-               aa_get_proxy(profile->label.proxy);
-               profile->dents[AAFS_PROF_RAW_HASH] = dent;
-
+               if (aa_g_hash_policy) {
+                       dent = aafs_create("raw_sha1", S_IFLNK | 0444, dir,
+                                          profile->label.proxy, NULL, NULL,
+                                          &rawdata_link_sha1_iops);
+                       if (IS_ERR(dent))
+                               goto fail;
+                       aa_get_proxy(profile->label.proxy);
+                       profile->dents[AAFS_PROF_RAW_HASH] = dent;
+               }
                dent = aafs_create("raw_abi", S_IFLNK | 0444, dir,
                                   profile->label.proxy, NULL, NULL,
                                   &rawdata_link_abi_iops);
@@ -1754,6 +1765,7 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
                aa_get_proxy(profile->label.proxy);
                profile->dents[AAFS_PROF_RAW_DATA] = dent;
        }
+#endif /*CONFIG_SECURITY_APPARMOR_EXPORT_BINARY */
 
        list_for_each_entry(child, &profile->base.profiles, base.list) {
                error = __aafs_profile_mkdir(child, prof_child_dir(profile));
@@ -1880,7 +1892,7 @@ static void __aa_fs_list_remove_rawdata(struct aa_ns *ns)
                __aa_fs_remove_rawdata(ent);
 }
 
-/**
+/*
  *
  * Requires: @ns->lock held
  */
@@ -2323,6 +2335,7 @@ static struct aa_sfs_entry aa_sfs_entry_versions[] = {
        AA_SFS_FILE_BOOLEAN("v6",       1),
        AA_SFS_FILE_BOOLEAN("v7",       1),
        AA_SFS_FILE_BOOLEAN("v8",       1),
+       AA_SFS_FILE_BOOLEAN("v9",       1),
        { }
 };