aboutsummaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-21 13:25:04 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-21 13:25:04 -0700
commit3556485f1595e3964ba539e39ea682acbb835cee (patch)
tree7f5ee254f425b1427ac0059b5f347a307f8538a1 /security
parentb8716614a7cc2fc15ea2a518edd04755fb08d922 (diff)
parent09f61cdbb32a9d812c618d3922db533542736bb0 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates for 3.4 from James Morris: "The main addition here is the new Yama security module from Kees Cook, which was discussed at the Linux Security Summit last year. Its purpose is to collect miscellaneous DAC security enhancements in one place. This also marks a departure in policy for LSM modules, which were previously limited to being standalone access control systems. Chromium OS is using Yama, and I believe there are plans for Ubuntu, at least. This patchset also includes maintenance updates for AppArmor, TOMOYO and others." Fix trivial conflict in <net/sock.h> due to the jumo_label->static_key rename. * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (38 commits) AppArmor: Fix location of const qualifier on generated string tables TOMOYO: Return error if fails to delete a domain AppArmor: add const qualifiers to string arrays AppArmor: Add ability to load extended policy TOMOYO: Return appropriate value to poll(). AppArmor: Move path failure information into aa_get_name and rename AppArmor: Update dfa matching routines. AppArmor: Minor cleanup of d_namespace_path to consolidate error handling AppArmor: Retrieve the dentry_path for error reporting when path lookup fails AppArmor: Add const qualifiers to generated string tables AppArmor: Fix oops in policy unpack auditing AppArmor: Fix error returned when a path lookup is disconnected KEYS: testing wrong bit for KEY_FLAG_REVOKED TOMOYO: Fix mount flags checking order. security: fix ima kconfig warning AppArmor: Fix the error case for chroot relative path name lookup AppArmor: fix mapping of META_READ to audit and quiet flags AppArmor: Fix underflow in xindex calculation AppArmor: Fix dropping of allowed operations that are force audited AppArmor: Add mising end of structure test to caps unpacking ...
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig6
-rw-r--r--security/Makefile2
-rw-r--r--security/apparmor/Makefile27
-rw-r--r--security/apparmor/apparmorfs.c195
-rw-r--r--security/apparmor/audit.c7
-rw-r--r--security/apparmor/domain.c5
-rw-r--r--security/apparmor/file.c21
-rw-r--r--security/apparmor/include/apparmor.h15
-rw-r--r--security/apparmor/include/apparmorfs.h44
-rw-r--r--security/apparmor/include/audit.h9
-rw-r--r--security/apparmor/include/file.h2
-rw-r--r--security/apparmor/include/match.h3
-rw-r--r--security/apparmor/include/path.h3
-rw-r--r--security/apparmor/include/policy.h15
-rw-r--r--security/apparmor/include/resource.h4
-rw-r--r--security/apparmor/match.c80
-rw-r--r--security/apparmor/path.c56
-rw-r--r--security/apparmor/policy.c3
-rw-r--r--security/apparmor/policy_unpack.c31
-rw-r--r--security/apparmor/resource.c5
-rw-r--r--security/capability.c5
-rw-r--r--security/commoncap.c1
-rw-r--r--security/integrity/ima/Kconfig4
-rw-r--r--security/integrity/ima/ima_audit.c2
-rw-r--r--security/integrity/ima/ima_policy.c3
-rw-r--r--security/keys/keyctl.c15
-rw-r--r--security/keys/process_keys.c3
-rw-r--r--security/security.c21
-rw-r--r--security/selinux/hooks.c2
-rw-r--r--security/smack/smack_lsm.c3
-rw-r--r--security/tomoyo/audit.c4
-rw-r--r--security/tomoyo/common.c63
-rw-r--r--security/tomoyo/common.h6
-rw-r--r--security/tomoyo/mount.c38
-rw-r--r--security/tomoyo/securityfs_if.c5
-rw-r--r--security/yama/Kconfig13
-rw-r--r--security/yama/Makefile3
-rw-r--r--security/yama/yama_lsm.c323
38 files changed, 856 insertions, 191 deletions
diff --git a/security/Kconfig b/security/Kconfig
index 51bd5a0b69a..ccc61f8006b 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -187,6 +187,7 @@ source security/selinux/Kconfig
source security/smack/Kconfig
source security/tomoyo/Kconfig
source security/apparmor/Kconfig
+source security/yama/Kconfig
source security/integrity/Kconfig
@@ -196,6 +197,7 @@ choice
default DEFAULT_SECURITY_SMACK if SECURITY_SMACK
default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO
default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR
+ default DEFAULT_SECURITY_YAMA if SECURITY_YAMA
default DEFAULT_SECURITY_DAC
help
@@ -214,6 +216,9 @@ choice
config DEFAULT_SECURITY_APPARMOR
bool "AppArmor" if SECURITY_APPARMOR=y
+ config DEFAULT_SECURITY_YAMA
+ bool "Yama" if SECURITY_YAMA=y
+
config DEFAULT_SECURITY_DAC
bool "Unix Discretionary Access Controls"
@@ -225,6 +230,7 @@ config DEFAULT_SECURITY
default "smack" if DEFAULT_SECURITY_SMACK
default "tomoyo" if DEFAULT_SECURITY_TOMOYO
default "apparmor" if DEFAULT_SECURITY_APPARMOR
+ default "yama" if DEFAULT_SECURITY_YAMA
default "" if DEFAULT_SECURITY_DAC
endmenu
diff --git a/security/Makefile b/security/Makefile
index a5e502f8a05..c26c81e9257 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -7,6 +7,7 @@ subdir-$(CONFIG_SECURITY_SELINUX) += selinux
subdir-$(CONFIG_SECURITY_SMACK) += smack
subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo
subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
+subdir-$(CONFIG_SECURITY_YAMA) += yama
# always enable default capabilities
obj-y += commoncap.o
@@ -21,6 +22,7 @@ obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
obj-$(CONFIG_AUDIT) += lsm_audit.o
obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o
obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o
+obj-$(CONFIG_SECURITY_YAMA) += yama/built-in.o
obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
# Object integrity file lists
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index 2dafe50a2e2..806bd19af7f 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -15,7 +15,7 @@ clean-files := capability_names.h rlim_names.h
# to
# [1] = "dac_override",
quiet_cmd_make-caps = GEN $@
-cmd_make-caps = echo "static const char *capability_names[] = {" > $@ ;\
+cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\
sed $< >>$@ -r -n -e '/CAP_FS_MASK/d' \
-e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\
echo "};" >> $@
@@ -28,25 +28,38 @@ cmd_make-caps = echo "static const char *capability_names[] = {" > $@ ;\
# [RLIMIT_STACK] = "stack",
#
# and build a second integer table (with the second sed cmd), that maps
-# RLIMIT defines to the order defined in asm-generic/resource.h Thi is
+# RLIMIT defines to the order defined in asm-generic/resource.h This is
# required by policy load to map policy ordering of RLIMITs to internal
# ordering for architectures that redefine an RLIMIT.
# Transforms lines from
# #define RLIMIT_STACK 3 /* max stack size */
# to
# RLIMIT_STACK,
+#
+# and build the securityfs entries for the mapping.
+# Transforms lines from
+# #define RLIMIT_FSIZE 1 /* Maximum filesize */
+# #define RLIMIT_STACK 3 /* max stack size */
+# to
+# #define AA_FS_RLIMIT_MASK "fsize stack"
quiet_cmd_make-rlim = GEN $@
-cmd_make-rlim = echo "static const char *rlim_names[] = {" > $@ ;\
+cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
+ > $@ ;\
sed $< >> $@ -r -n \
-e 's/^\# ?define[ \t]+(RLIMIT_([A-Z0-9_]+)).*/[\1] = "\L\2",/p';\
echo "};" >> $@ ;\
- echo "static const int rlim_map[] = {" >> $@ ;\
+ echo "static const int rlim_map[RLIM_NLIMITS] = {" >> $@ ;\
sed -r -n "s/^\# ?define[ \t]+(RLIMIT_[A-Z0-9_]+).*/\1,/p" $< >> $@ ;\
- echo "};" >> $@
+ echo "};" >> $@ ; \
+ echo -n '\#define AA_FS_RLIMIT_MASK "' >> $@ ;\
+ sed -r -n 's/^\# ?define[ \t]+RLIMIT_([A-Z0-9_]+).*/\L\1/p' $< | \
+ tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
$(obj)/capability.o : $(obj)/capability_names.h
$(obj)/resource.o : $(obj)/rlim_names.h
-$(obj)/capability_names.h : $(srctree)/include/linux/capability.h
+$(obj)/capability_names.h : $(srctree)/include/linux/capability.h \
+ $(src)/Makefile
$(call cmd,make-caps)
-$(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h
+$(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h \
+ $(src)/Makefile
$(call cmd,make-rlim)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index e39df6d4377..16c15ec6f67 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -18,12 +18,14 @@
#include <linux/seq_file.h>
#include <linux/uaccess.h>
#include <linux/namei.h>
+#include <linux/capability.h>
#include "include/apparmor.h"
#include "include/apparmorfs.h"
#include "include/audit.h"
#include "include/context.h"
#include "include/policy.h"
+#include "include/resource.h"
/**
* aa_simple_write_to_buffer - common routine for getting policy from user
@@ -142,38 +144,166 @@ static const struct file_operations aa_fs_profile_remove = {
.llseek = default_llseek,
};
-/** Base file system setup **/
+static int aa_fs_seq_show(struct seq_file *seq, void *v)
+{
+ struct aa_fs_entry *fs_file = seq->private;
+
+ if (!fs_file)
+ return 0;
-static struct dentry *aa_fs_dentry __initdata;
+ switch (fs_file->v_type) {
+ case AA_FS_TYPE_BOOLEAN:
+ seq_printf(seq, "%s\n", fs_file->v.boolean ? "yes" : "no");
+ break;
+ case AA_FS_TYPE_STRING:
+ seq_printf(seq, "%s\n", fs_file->v.string);
+ break;
+ case AA_FS_TYPE_U64:
+ seq_printf(seq, "%#08lx\n", fs_file->v.u64);
+ break;
+ default:
+ /* Ignore unpritable entry types. */
+ break;
+ }
+
+ return 0;
+}
-static void __init aafs_remove(const char *name)
+static int aa_fs_seq_open(struct inode *inode, struct file *file)
{
- struct dentry *dentry;
+ return single_open(file, aa_fs_seq_show, inode->i_private);
+}
+
+const struct file_operations aa_fs_seq_file_ops = {
+ .owner = THIS_MODULE,
+ .open = aa_fs_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/** Base file system setup **/
+
+static struct aa_fs_entry aa_fs_entry_file[] = {
+ AA_FS_FILE_STRING("mask", "create read write exec append mmap_exec " \
+ "link lock"),
+ { }
+};
- dentry = lookup_one_len(name, aa_fs_dentry, strlen(name));
- if (!IS_ERR(dentry)) {
- securityfs_remove(dentry);
- dput(dentry);
+static struct aa_fs_entry aa_fs_entry_domain[] = {
+ AA_FS_FILE_BOOLEAN("change_hat", 1),
+ AA_FS_FILE_BOOLEAN("change_hatv", 1),
+ AA_FS_FILE_BOOLEAN("change_onexec", 1),
+ AA_FS_FILE_BOOLEAN("change_profile", 1),
+ { }
+};
+
+static struct aa_fs_entry aa_fs_entry_features[] = {
+ AA_FS_DIR("domain", aa_fs_entry_domain),
+ AA_FS_DIR("file", aa_fs_entry_file),
+ AA_FS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
+ AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
+ { }
+};
+
+static struct aa_fs_entry aa_fs_entry_apparmor[] = {
+ AA_FS_FILE_FOPS(".load", 0640, &aa_fs_profile_load),
+ AA_FS_FILE_FOPS(".replace", 0640, &aa_fs_profile_replace),
+ AA_FS_FILE_FOPS(".remove", 0640, &aa_fs_profile_remove),
+ AA_FS_DIR("features", aa_fs_entry_features),
+ { }
+};
+
+static struct aa_fs_entry aa_fs_entry =
+ AA_FS_DIR("apparmor", aa_fs_entry_apparmor);
+
+/**
+ * aafs_create_file - create a file entry in the apparmor securityfs
+ * @fs_file: aa_fs_entry to build an entry for (NOT NULL)
+ * @parent: the parent dentry in the securityfs
+ *
+ * Use aafs_remove_file to remove entries created with this fn.
+ */
+static int __init aafs_create_file(struct aa_fs_entry *fs_file,
+ struct dentry *parent)
+{
+ int error = 0;
+
+ fs_file->dentry = securityfs_create_file(fs_file->name,
+ S_IFREG | fs_file->mode,
+ parent, fs_file,
+ fs_file->file_ops);
+ if (IS_ERR(fs_file->dentry)) {
+ error = PTR_ERR(fs_file->dentry);
+ fs_file->dentry = NULL;
}
+ return error;
}
/**
- * aafs_create - create an entry in the apparmor filesystem
- * @name: name of the entry (NOT NULL)
- * @mask: file permission mask of the file
- * @fops: file operations for the file (NOT NULL)
+ * aafs_create_dir - recursively create a directory entry in the securityfs
+ * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL)
+ * @parent: the parent dentry in the securityfs
*
- * Used aafs_remove to remove entries created with this fn.
+ * Use aafs_remove_dir to remove entries created with this fn.
*/
-static int __init aafs_create(const char *name, umode_t mask,
- const struct file_operations *fops)
+static int __init aafs_create_dir(struct aa_fs_entry *fs_dir,
+ struct dentry *parent)
{
- struct dentry *dentry;
+ int error;
+ struct aa_fs_entry *fs_file;
- dentry = securityfs_create_file(name, S_IFREG | mask, aa_fs_dentry,
- NULL, fops);
+ fs_dir->dentry = securityfs_create_dir(fs_dir->name, parent);
+ if (IS_ERR(fs_dir->dentry)) {
+ error = PTR_ERR(fs_dir->dentry);
+ fs_dir->dentry = NULL;
+ goto failed;
+ }
- return IS_ERR(dentry) ? PTR_ERR(dentry) : 0;
+ for (fs_file = fs_dir->v.files; fs_file->name; ++fs_file) {
+ if (fs_file->v_type == AA_FS_TYPE_DIR)
+ error = aafs_create_dir(fs_file, fs_dir->dentry);
+ else
+ error = aafs_create_file(fs_file, fs_dir->dentry);
+ if (error)
+ goto failed;
+ }
+
+ return 0;
+
+failed:
+ return error;
+}
+
+/**
+ * aafs_remove_file - drop a single file entry in the apparmor securityfs
+ * @fs_file: aa_fs_entry to detach from the securityfs (NOT NULL)
+ */
+static void __init aafs_remove_file(struct aa_fs_entry *fs_file)
+{
+ if (!fs_file->dentry)
+ return;
+
+ securityfs_remove(fs_file->dentry);
+ fs_file->dentry = NULL;
+}
+
+/**
+ * aafs_remove_dir - recursively drop a directory entry from the securityfs
+ * @fs_dir: aa_fs_entry (and all child entries) to detach (NOT NULL)
+ */
+static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir)
+{
+ struct aa_fs_entry *fs_file;
+
+ for (fs_file = fs_dir->v.files; fs_file->name; ++fs_file) {
+ if (fs_file->v_type == AA_FS_TYPE_DIR)
+ aafs_remove_dir(fs_file);
+ else
+ aafs_remove_file(fs_file);
+ }
+
+ aafs_remove_file(fs_dir);
}
/**
@@ -183,14 +313,7 @@ static int __init aafs_create(const char *name, umode_t mask,
*/
void __init aa_destroy_aafs(void)
{
- if (aa_fs_dentry) {
- aafs_remove(".remove");
- aafs_remove(".replace");
- aafs_remove(".load");
-
- securityfs_remove(aa_fs_dentry);
- aa_fs_dentry = NULL;
- }
+ aafs_remove_dir(&aa_fs_entry);
}
/**
@@ -207,25 +330,13 @@ static int __init aa_create_aafs(void)
if (!apparmor_initialized)
return 0;
- if (aa_fs_dentry) {
+ if (aa_fs_entry.dentry) {
AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
return -EEXIST;
}
- aa_fs_dentry = securityfs_create_dir("apparmor", NULL);
- if (IS_ERR(aa_fs_dentry)) {
- error = PTR_ERR(aa_fs_dentry);
- aa_fs_dentry = NULL;
- goto error;
- }
-
- error = aafs_create(".load", 0640, &aa_fs_profile_load);
- if (error)
- goto error;
- error = aafs_create(".replace", 0640, &aa_fs_profile_replace);
- if (error)
- goto error;
- error = aafs_create(".remove", 0640, &aa_fs_profile_remove);
+ /* Populate fs tree. */
+ error = aafs_create_dir(&aa_fs_entry, NULL);
if (error)
goto error;
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index f3fafedd798..5ff67776a5a 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -19,7 +19,7 @@
#include "include/audit.h"
#include "include/policy.h"
-const char *op_table[] = {
+const char *const op_table[] = {
"null",
"sysctl",
@@ -73,7 +73,7 @@ const char *op_table[] = {
"profile_remove"
};
-const char *audit_mode_names[] = {
+const char *const audit_mode_names[] = {
"normal",
"quiet_denied",
"quiet",
@@ -81,7 +81,7 @@ const char *audit_mode_names[] = {
"all"
};
-static char *aa_audit_type[] = {
+static const char *const aa_audit_type[] = {
"AUDIT",
"ALLOWED",
"DENIED",
@@ -89,6 +89,7 @@ static char *aa_audit_type[] = {
"STATUS",
"ERROR",
"KILLED"
+ "AUTO"
};
/*
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index c1e18ba5bdc..7c69599a69e 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -372,13 +372,12 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
state = profile->file.start;
/* buffer freed below, name is pointer into buffer */
- error = aa_get_name(&bprm->file->f_path, profile->path_flags, &buffer,
- &name);
+ error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer,
+ &name, &info);
if (error) {
if (profile->flags &
(PFLAG_IX_ON_NAME_ERROR | PFLAG_UNCONFINED))
error = 0;
- info = "Exec failed name resolution";
name = bprm->filename;
goto audit;
}
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 7312db74121..3022c0f4f0d 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -173,8 +173,6 @@ static u32 map_old_perms(u32 old)
if (old & 0x40) /* AA_EXEC_MMAP */
new |= AA_EXEC_MMAP;
- new |= AA_MAY_META_READ;
-
return new;
}
@@ -212,6 +210,7 @@ static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state,
perms.quiet = map_old_perms(dfa_other_quiet(dfa, state));
perms.xindex = dfa_other_xindex(dfa, state);
}
+ perms.allow |= AA_MAY_META_READ;
/* change_profile wasn't determined by ownership in old mapping */
if (ACCEPT_TABLE(dfa)[state] & 0x80000000)
@@ -279,22 +278,16 @@ int aa_path_perm(int op, struct aa_profile *profile, struct path *path,
int error;
flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
- error = aa_get_name(path, flags, &buffer, &name);
+ error = aa_path_name(path, flags, &buffer, &name, &info);
if (error) {
if (error == -ENOENT && is_deleted(path->dentry)) {
/* Access to open files that are deleted are
* give a pass (implicit delegation)
*/
error = 0;
+ info = NULL;
perms.allow = request;
- } else if (error == -ENOENT)
- info = "Failed name lookup - deleted entry";
- else if (error == -ESTALE)
- info = "Failed name lookup - disconnected path";
- else if (error == -ENAMETOOLONG)
- info = "Failed name lookup - name too long";
- else
- info = "Failed name lookup";
+ }
} else {
aa_str_perms(profile->file.dfa, profile->file.start, name, cond,
&perms);
@@ -365,12 +358,14 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
lperms = nullperms;
/* buffer freed below, lname is pointer in buffer */
- error = aa_get_name(&link, profile->path_flags, &buffer, &lname);
+ error = aa_path_name(&link, profile->path_flags, &buffer, &lname,
+ &info);
if (error)
goto audit;
/* buffer2 freed below, tname is pointer in buffer2 */
- error = aa_get_name(&target, profile->path_flags, &buffer2, &tname);
+ error = aa_path_name(&target, profile->path_flags, &buffer2, &tname,
+ &info);
if (error)
goto audit;
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
index df364956081..40aedd9f73e 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -19,6 +19,19 @@
#include "match.h"
+/*
+ * Class of mediation types in the AppArmor policy db
+ */
+#define AA_CLASS_ENTRY 0
+#define AA_CLASS_UNKNOWN 1
+#define AA_CLASS_FILE 2
+#define AA_CLASS_CAP 3
+#define AA_CLASS_NET 4
+#define AA_CLASS_RLIMITS 5
+#define AA_CLASS_DOMAIN 6
+
+#define AA_CLASS_LAST AA_CLASS_DOMAIN
+
/* Control parameters settable through module/boot flags */
extern enum audit_mode aa_g_audit;
extern bool aa_g_audit_header;
@@ -81,7 +94,7 @@ static inline unsigned int aa_dfa_null_transition(struct aa_dfa *dfa,
unsigned int start)
{
/* the null transition only needs the string's null terminator byte */
- return aa_dfa_match_len(dfa, start, "", 1);
+ return aa_dfa_next(dfa, start, 0);
}
static inline bool mediated_filesystem(struct inode *inode)
diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
index cb1e93a114d..7ea4769fab3 100644
--- a/security/apparmor/include/apparmorfs.h
+++ b/security/apparmor/include/apparmorfs.h
@@ -15,6 +15,50 @@
#ifndef __AA_APPARMORFS_H
#define __AA_APPARMORFS_H
+enum aa_fs_type {
+ AA_FS_TYPE_BOOLEAN,
+ AA_FS_TYPE_STRING,
+ AA_FS_TYPE_U64,
+ AA_FS_TYPE_FOPS,
+ AA_FS_TYPE_DIR,
+};
+
+struct aa_fs_entry;
+
+struct aa_fs_entry {
+ const char *name;
+ struct dentry *dentry;
+ umode_t mode;
+ enum aa_fs_type v_type;
+ union {
+ bool boolean;
+ char *string;
+ unsigned long u64;
+ struct aa_fs_entry *files;
+ } v;
+ const struct file_operations *file_ops;
+};
+
+extern const struct file_operations aa_fs_seq_file_ops;
+
+#define AA_FS_FILE_BOOLEAN(_name, _value) \
+ { .name = (_name), .mode = 0444, \
+ .v_type = AA_FS_TYPE_BOOLEAN, .v.boolean = (_value), \
+ .file_ops = &aa_fs_seq_file_ops }
+#define AA_FS_FILE_STRING(_name, _value) \
+ { .name = (_name), .mode = 0444, \
+ .v_type = AA_FS_TYPE_STRING, .v.string = (_value), \
+ .file_ops = &aa_fs_seq_file_ops }
+#define AA_FS_FILE_U64(_name, _value) \
+ { .name = (_name), .mode = 0444, \
+ .v_type = AA_FS_TYPE_U64, .v.u64 = (_value), \
+ .file_ops = &aa_fs_seq_file_ops }
+#define AA_FS_FILE_FOPS(_name, _mode, _fops) \
+ { .name = (_name), .v_type = AA_FS_TYPE_FOPS, \
+ .mode = (_mode), .file_ops = (_fops) }
+#define AA_FS_DIR(_name, _value) \
+ { .name = (_name), .v_type = AA_FS_TYPE_DIR, .v.files = (_value) }
+
extern void __init aa_destroy_aafs(void);
#endif /* __AA_APPARMORFS_H */
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index 1951786d32e..4ba78c203af 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -25,11 +25,9 @@
struct aa_profile;
-extern const char *audit_mode_names[];
+extern const char *const audit_mode_names[];
#define AUDIT_MAX_INDEX 5
-#define AUDIT_APPARMOR_AUTO 0 /* auto choose audit message type */
-
enum audit_mode {
AUDIT_NORMAL, /* follow normal auditing of accesses */
AUDIT_QUIET_DENIED, /* quiet all denied access messages */
@@ -45,10 +43,11 @@ enum audit_type {
AUDIT_APPARMOR_HINT,
AUDIT_APPARMOR_STATUS,
AUDIT_APPARMOR_ERROR,
- AUDIT_APPARMOR_KILL
+ AUDIT_APPARMOR_KILL,
+ AUDIT_APPARMOR_AUTO
};
-extern const char *op_table[];
+extern const char *const op_table[];
enum aa_ops {
OP_NULL,
diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
index ab8c6d87f75..f98fd4701d8 100644
--- a/security/apparmor/include/file.h
+++ b/security/apparmor/include/file.h
@@ -117,7 +117,7 @@ static inline u16 dfa_map_xindex(u16 mask)
index |= AA_X_NAME;
} else if (old_index == 3) {
index |= AA_X_NAME | AA_X_CHILD;
- } else {
+ } else if (old_index) {
index |= AA_X_TABLE;
index |= old_index - 4;
}
diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
index a4a863997bd..775843e7f98 100644
--- a/security/apparmor/include/match.h
+++ b/security/apparmor/include/match.h
@@ -116,6 +116,9 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
const char *str, int len);
unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
const char *str);
+unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
+ const char c);
+
void aa_dfa_free_kref(struct kref *kref);
/**
diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
index 27b327a7fae..286ac75dc88 100644
--- a/security/apparmor/include/path.h
+++ b/security/apparmor/include/path.h
@@ -26,6 +26,7 @@ enum path_flags {
PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */
};
-int aa_get_name(struct path *path, int flags, char **buffer, const char **name);
+int aa_path_name(struct path *path, int flags, char **buffer,
+ const char **name, const char **info);
#endif /* __AA_PATH_H */
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index aeda5cf5690..bda4569fdd8 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -29,7 +29,7 @@
#include "file.h"
#include "resource.h"
-extern const char *profile_mode_names[];
+extern const char *const profile_mode_names[];
#define APPARMOR_NAMES_MAX_INDEX 3
#define COMPLAIN_MODE(_profile) \
@@ -129,6 +129,17 @@ struct aa_namespace {
struct list_head sub_ns;
};
+/* struct aa_policydb - match engine for a policy
+ * dfa: dfa pattern match
+ * start: set of start states for the different classes of data
+ */
+struct aa_policydb {
+ /* Generic policy DFA specific rule types will be subsections of it */
+ struct aa_dfa *dfa;
+ unsigned int start[AA_CLASS_LAST + 1];
+
+};
+
/* struct aa_profile - basic confinement data
* @base - base components of the profile (name, refcount, lists, lock ...)
* @parent: parent of profile
@@ -143,6 +154,7 @@ struct aa_namespace {
* @flags: flags controlling profile behavior
* @path_flags: flags controlling path generation behavior
* @size: the memory consumed by this profiles rules
+ * @policy: general match rules governing policy
* @file: The set of rules governing basic file access and domain transitions
* @caps: capabilities for the profile
* @rlimits: rlimits for the profile
@@ -179,6 +191,7 @@ struct aa_profile {
u32 path_flags;
int size;
+ struct aa_policydb policy;
struct aa_file_rules file;
struct aa_caps caps;
struct aa_rlimit rlimits;
diff --git a/security/apparmor/include/resource.h b/security/apparmor/include/resource.h
index 02baec732bb..d3f4cf02795 100644
--- a/security/apparmor/include/resource.h
+++ b/security/apparmor/include/resource.h
@@ -18,6 +18,8 @@
#include <linux/resource.h>
#include <linux/sched.h>
+#include "apparmorfs.h"
+
struct aa_profile;
/* struct aa_rlimit - rlimit settings for the profile
@@ -32,6 +34,8 @@ struct aa_rlimit {
struct rlimit limits[RLIM_NLIMITS];
};
+extern struct aa_fs_entry aa_fs_entry_rlimit[];
+
int aa_map_resource(int resource);
int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *,