Commit d61c57fd authored by John Johansen's avatar John Johansen
Browse files

apparmor: make export of raw binary profile to userspace optional



Embedded systems have limited space and don't need the introspection
or checkpoint restore capability provided by exporting the raw
profile binary data so make it so make it a config option.

This will reduce run time memory use and also speed up policy loads.

Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
parent 65cc9c39
Loading
Loading
Loading
Loading
+50 −28
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,32 +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
	  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_DEBUG
	bool "Build AppArmor with debug code"
	depends on SECURITY_APPARMOR
@@ -72,6 +44,56 @@ 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_KUNIT_TEST
	bool "Build KUnit tests for policy_unpack.c" if !KUNIT_ALL_TESTS
	depends on KUNIT=y && SECURITY_APPARMOR
+9 −2
Original line number Diff line number Diff line
@@ -70,6 +70,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,6 +95,7 @@ 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
@@ -1201,7 +1203,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)\
{									      \
@@ -1492,6 +1494,8 @@ 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 **/

@@ -1557,6 +1561,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 +1663,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,6 +1734,7 @@ 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,
@@ -1754,6 +1760,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));
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ extern enum audit_mode aa_g_audit;
extern bool aa_g_audit_header;
extern bool aa_g_debug;
extern bool aa_g_hash_policy;
extern bool aa_g_export_binary;
extern int aa_g_rawdata_compression_level;
extern bool aa_g_lock_policy;
extern bool aa_g_logsyscall;
+14 −0
Original line number Diff line number Diff line
@@ -114,7 +114,21 @@ int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name,
		     struct dentry *dent);

struct aa_loaddata;

#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
void __aa_fs_remove_rawdata(struct aa_loaddata *rawdata);
int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata);
#else
static inline void __aa_fs_remove_rawdata(struct aa_loaddata *rawdata)
{
	/* empty stub */
}

static inline int __aa_fs_create_rawdata(struct aa_ns *ns,
					 struct aa_loaddata *rawdata)
{
	return 0;
}
#endif /* CONFIG_SECURITY_APPARMOR_EXPORT_BINARY */

#endif /* __AA_APPARMORFS_H */
+6 −0
Original line number Diff line number Diff line
@@ -1357,6 +1357,12 @@ bool aa_g_hash_policy = IS_ENABLED(CONFIG_SECURITY_APPARMOR_HASH_DEFAULT);
module_param_named(hash_policy, aa_g_hash_policy, aabool, S_IRUSR | S_IWUSR);
#endif

/* whether policy exactly as loaded is retained for debug and checkpointing */
bool aa_g_export_binary = IS_ENABLED(CONFIG_SECURITY_APPARMOR_EXPORT_BINARY);
#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
module_param_named(export_binary, aa_g_export_binary, aabool, 0600);
#endif

/* policy loaddata compression level */
int aa_g_rawdata_compression_level = Z_DEFAULT_COMPRESSION;
module_param_named(rawdata_compression_level, aa_g_rawdata_compression_level,
Loading