Commit 00aa9d0b authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'apparmor-pr-2022-08-08' of...

Merge tag 'apparmor-pr-2022-08-08' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor

Pull AppArmor updates from John Johansen:
 "This is mostly cleanups and bug fixes with the one bigger change being
  Mathew Wilcox's patch to use XArrays instead of the IDR from the
  thread around the locking weirdness.

  Features:
   - Convert secid mapping to XArrays instead of IDR
   - Add a kernel label to use on kernel objects
   - Extend policydb permission set by making use of the xbits
   - Make export of raw binary profile to userspace optional
   - Enable tuning of policy paranoid load for embedded systems
   - Don't create raw_sha1 symlink if sha1 hashing is disabled
   - Allow labels to carry debug flags

  Cleanups:
   - Update MAINTAINERS file
   - Use struct_size() helper in kmalloc()
   - Move ptrace mediation to more logical task.{h,c}
   - Resolve uninitialized symbol warnings
   - Remove redundant ret variable
   - Mark alloc_unconfined() as static
   - Update help description of policy hash for introspection
   - Remove some casts which are no-longer required

  Bug Fixes:
   - Fix aa_label_asxprint return check
   - Fix reference count leak in aa_pivotroot()
   - Fix memleak in aa_simple_write_to_buffer()
   - Fix kernel doc comments
   - Fix absroot causing audited secids to begin with =
   - Fix quiet_denied for file rules
   - Fix failed mount permission check error message
   - Disable showing the mode as part of a secid to secctx
   - Fix setting unconfined mode on a loaded profile
   - Fix overlapping attachment computation
   - Fix undefined reference to `zlib_deflate_workspacesize'"

* tag 'apparmor-pr-2022-08-08' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor: (34 commits)
  apparmor: Update MAINTAINERS file with new email address
  apparmor: correct config reference to intended one
  apparmor: move ptrace mediation to more logical task.{h,c}
  apparmor: extend policydb permission set by making use of the xbits
  apparmor: allow label to carry debug flags
  apparmor: fix overlapping attachment computation
  apparmor: fix setting unconfined mode on a loaded profile
  apparmor: Fix some kernel-doc comments
  apparmor: Mark alloc_unconfined() as static
  apparmor: disable showing the mode as part of a secid to secctx
  apparmor: Convert secid mapping to XArrays instead of IDR
  apparmor: add a kernel label to use on kernel objects
  apparmor: test: Remove some casts which are no-longer required
  apparmor: Fix memleak in aa_simple_write_to_buffer()
  apparmor: fix reference count leak in aa_pivotroot()
  apparmor: Fix some kernel-doc comments
  apparmor: Fix undefined reference to `zlib_deflate_workspacesize'
  apparmor: fix aa_label_asxprint return check
  apparmor: Fix some kernel-doc comments
  apparmor: Fix some kernel-doc comments
  ...
parents 0af5cb34 c269fca7
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -1390,10 +1390,14 @@ F: include/uapi/linux/apm_bios.h
APPARMOR SECURITY MODULE
M:	John Johansen <john.johansen@canonical.com>
L:	apparmor@lists.ubuntu.com (subscribers-only, general discussion)
M:	John Johansen <john@apparmor.net>
L:	apparmor@lists.ubuntu.com (moderated for non-subscribers)
S:	Supported
W:	wiki.apparmor.net
W:	apparmor.net
B:	https://gitlab.com/apparmor/apparmor-kernel
C:	irc://irc.oftc.net/apparmor
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor
T:	https://gitlab.com/apparmor/apparmor-kernel.git
F:	Documentation/admin-guide/LSM/apparmor.rst
F:	security/apparmor/
+61 −25
Original line number Diff line number Diff line
@@ -6,8 +6,6 @@ config SECURITY_APPARMOR
	select SECURITY_PATH
	select SECURITYFS
	select SECURITY_NETWORK
	select ZLIB_INFLATE
	select ZLIB_DEFLATE
	default n
	help
	  This enables the AppArmor security module.
@@ -17,29 +15,6 @@ config SECURITY_APPARMOR

	  If you are unsure how to answer this question, answer N.

config SECURITY_APPARMOR_HASH
	bool "Enable introspection of sha1 hashes for loaded profiles"
	depends on SECURITY_APPARMOR
	select CRYPTO
	select CRYPTO_SHA1
	default y
	help
	  This option selects whether introspection of loaded policy
	  is available to userspace via the apparmor filesystem.

config SECURITY_APPARMOR_HASH_DEFAULT
       bool "Enable policy hash introspection by default"
       depends on SECURITY_APPARMOR_HASH
       default y
       help
         This option selects whether sha1 hashing of loaded policy
	 is enabled by default. The generation of sha1 hashes for
	 loaded policy provide system administrators a quick way
	 to verify that policy in the kernel matches what is expected,
	 however it can slow down policy load on some devices. In
	 these cases policy hashing can be disabled by default and
	 enabled only if needed.

config SECURITY_APPARMOR_DEBUG
	bool "Build AppArmor with debug code"
	depends on SECURITY_APPARMOR
@@ -69,6 +44,67 @@ config SECURITY_APPARMOR_DEBUG_MESSAGES
	  When enabled, various debug messages will be logged to
	  the kernel message buffer.

config SECURITY_APPARMOR_INTROSPECT_POLICY
	bool "Allow loaded policy to be introspected"
	depends on SECURITY_APPARMOR
	default y
	help
	  This option selects whether introspection of loaded policy
	  is available to userspace via the apparmor filesystem. This
	  adds to kernel memory usage. It is required for introspection
	  of loaded policy, and check point and restore support. It
	  can be disabled for embedded systems where reducing memory and
	  cpu is paramount.

config SECURITY_APPARMOR_HASH
	bool "Enable introspection of sha1 hashes for loaded profiles"
	depends on SECURITY_APPARMOR_INTROSPECT_POLICY
	select CRYPTO
	select CRYPTO_SHA1
	default y
	help
	  This option selects whether introspection of loaded policy
	  hashes is available to userspace via the apparmor
	  filesystem. This option provides a light weight means of
	  checking loaded policy.  This option adds to policy load
	  time and can be disabled for small embedded systems.

config SECURITY_APPARMOR_HASH_DEFAULT
       bool "Enable policy hash introspection by default"
       depends on SECURITY_APPARMOR_HASH
       default y
       help
         This option selects whether sha1 hashing of loaded policy
	 is enabled by default. The generation of sha1 hashes for
	 loaded policy provide system administrators a quick way
	 to verify that policy in the kernel matches what is expected,
	 however it can slow down policy load on some devices. In
	 these cases policy hashing can be disabled by default and
	 enabled only if needed.

config SECURITY_APPARMOR_EXPORT_BINARY
	bool "Allow exporting the raw binary policy"
	depends on SECURITY_APPARMOR_INTROSPECT_POLICY
	select ZLIB_INFLATE
	select ZLIB_DEFLATE
	default y
	help
	  This option allows reading back binary policy as it was loaded.
	  It increases the amount of kernel memory needed by policy and
	  also increases policy load time. This option is required for
	  checkpoint and restore support, and debugging of loaded policy.

config SECURITY_APPARMOR_PARANOID_LOAD
	bool "Perform full verification of loaded policy"
	depends on SECURITY_APPARMOR
	default y
	help
	  This options allows controlling whether apparmor does a full
	  verification of loaded policy. This should not be disabled
	  except for embedded systems where the image is read only,
	  includes policy, and has some form of integrity check.
	  Disabling the check will speed up policy loads.

config SECURITY_APPARMOR_KUNIT_TEST
	bool "Build KUnit tests for policy_unpack.c" if !KUNIT_ALL_TESTS
	depends on KUNIT=y && SECURITY_APPARMOR
+58 −45
Original line number Diff line number Diff line
@@ -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,16 +1297,11 @@ SEQ_RAWDATA_FOPS(compressed_size);

static int deflate_decompress(char *src, size_t slen, char *dst, size_t dlen)
{
	int error;
#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));

		strm.workspace = kvzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
@@ -1331,8 +1329,16 @@ static int deflate_decompress(char *src, size_t slen, char *dst, size_t dlen)
		zlib_inflateEnd(&strm);
fail_inflate_init:
		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,
			    loff_t *ppos)
@@ -1492,10 +1498,12 @@ int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata)

	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,7 +1738,9 @@ 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) {
		if (aa_g_hash_policy) {
			dent = aafs_create("raw_sha1", S_IFLNK | 0444, dir,
					   profile->label.proxy, NULL, NULL,
					   &rawdata_link_sha1_iops);
@@ -1737,7 +1748,7 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
				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),
	{ }
};

+1 −1
Original line number Diff line number Diff line
@@ -137,7 +137,7 @@ int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
	}
	if (AUDIT_MODE(profile) == AUDIT_QUIET ||
	    (type == AUDIT_APPARMOR_DENIED &&
	     AUDIT_MODE(profile) == AUDIT_QUIET))
	     AUDIT_MODE(profile) == AUDIT_QUIET_DENIED))
		return aad(sa)->error;

	if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
+2 −3
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ static inline unsigned int match_component(struct aa_profile *profile,
 * @profile: profile to find perms for
 * @label: label to check access permissions for
 * @stack: whether this is a stacking request
 * @start: state to start match in
 * @state: state to start match in
 * @subns: whether to do permission checks on components in a subns
 * @request: permissions to request
 * @perms: perms struct to set
@@ -466,7 +466,7 @@ static struct aa_label *find_attach(const struct linux_binprm *bprm,
				 * xattrs, or a longer match
				 */
				candidate = profile;
				candidate_len = profile->xmatch_len;
				candidate_len = max(count, profile->xmatch_len);
				candidate_xattrs = ret;
				conflict = false;
			}
@@ -1279,7 +1279,6 @@ static int change_profile_perms_wrapper(const char *op, const char *name,
/**
 * aa_change_profile - perform a one-way profile transition
 * @fqname: name of profile may include namespace (NOT NULL)
 * @onexec: whether this transition is to take place immediately or at exec
 * @flags: flags affecting change behavior
 *
 * Change to new profile @name.  Unlike with hats, there is no way
Loading