summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/.gitignore1
-rw-r--r--security/apparmor/Makefile43
-rw-r--r--security/apparmor/apparmorfs.c45
-rw-r--r--security/apparmor/domain.c4
-rw-r--r--security/apparmor/file.c30
-rw-r--r--security/apparmor/include/apparmor.h2
-rw-r--r--security/apparmor/include/audit.h39
-rw-r--r--security/apparmor/include/domain.h5
-rw-r--r--security/apparmor/include/ipc.h6
-rw-r--r--security/apparmor/include/label.h1
-rw-r--r--security/apparmor/include/mount.h54
-rw-r--r--security/apparmor/include/net.h114
-rw-r--r--security/apparmor/include/perms.h5
-rw-r--r--security/apparmor/include/policy.h13
-rw-r--r--security/apparmor/include/sig_names.h98
-rw-r--r--security/apparmor/ipc.c99
-rw-r--r--security/apparmor/label.c36
-rw-r--r--security/apparmor/lib.c5
-rw-r--r--security/apparmor/lsm.c472
-rw-r--r--security/apparmor/mount.c696
-rw-r--r--security/apparmor/net.c184
-rw-r--r--security/apparmor/policy.c166
-rw-r--r--security/apparmor/policy_ns.c2
-rw-r--r--security/apparmor/policy_unpack.c105
-rw-r--r--security/commoncap.c6
-rw-r--r--security/keys/Kconfig4
-rw-r--r--security/keys/big_key.c139
-rw-r--r--security/keys/internal.h2
-rw-r--r--security/keys/key.c6
-rw-r--r--security/keys/keyctl.c13
-rw-r--r--security/keys/keyring.c37
-rw-r--r--security/keys/proc.c8
-rw-r--r--security/keys/process_keys.c6
-rw-r--r--security/keys/request_key_auth.c74
-rw-r--r--security/smack/smack_lsm.c55
35 files changed, 2253 insertions, 322 deletions
diff --git a/security/apparmor/.gitignore b/security/apparmor/.gitignore
index 9cdec70d72b8..d5b291e94264 100644
--- a/security/apparmor/.gitignore
+++ b/security/apparmor/.gitignore
@@ -1,5 +1,6 @@
1# 1#
2# Generated include files 2# Generated include files
3# 3#
4net_names.h
4capability_names.h 5capability_names.h
5rlim_names.h 6rlim_names.h
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index a16b195274de..dafdd387d42b 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -4,11 +4,44 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
4 4
5apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \ 5apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
6 path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \ 6 path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
7 resource.o secid.o file.o policy_ns.o label.o 7 resource.o secid.o file.o policy_ns.o label.o mount.o net.o
8apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o 8apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
9 9
10clean-files := capability_names.h rlim_names.h 10clean-files := capability_names.h rlim_names.h net_names.h
11 11
12# Build a lower case string table of address family names
13# Transform lines from
14# #define AF_LOCAL 1 /* POSIX name for AF_UNIX */
15# #define AF_INET 2 /* Internet IP Protocol */
16# to
17# [1] = "local",
18# [2] = "inet",
19#
20# and build the securityfs entries for the mapping.
21# Transforms lines from
22# #define AF_INET 2 /* Internet IP Protocol */
23# to
24# #define AA_SFS_AF_MASK "local inet"
25quiet_cmd_make-af = GEN $@
26cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ;\
27 sed $< >>$@ -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "/AF_ROUTE/d" -e \
28 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
29 echo "};" >> $@ ;\
30 printf '%s' '\#define AA_SFS_AF_MASK "' >> $@ ;\
31 sed -r -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "/AF_ROUTE/d" -e \
32 's/^\#define[ \t]+AF_([A-Z0-9_]+)[ \t]+([0-9]+)(.*)/\L\1/p'\
33 $< | tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
34
35# Build a lower case string table of sock type names
36# Transform lines from
37# SOCK_STREAM = 1,
38# to
39# [1] = "stream",
40quiet_cmd_make-sock = GEN $@
41cmd_make-sock = echo "static const char *sock_type_names[] = {" >> $@ ;\
42 sed $^ >>$@ -r -n \
43 -e 's/^\tSOCK_([A-Z0-9_]+)[\t]+=[ \t]+([0-9]+)(.*)/[\2] = "\L\1",/p';\
44 echo "};" >> $@
12 45
13# Build a lower case string table of capability names 46# Build a lower case string table of capability names
14# Transforms lines from 47# Transforms lines from
@@ -61,6 +94,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
61 tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@ 94 tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
62 95
63$(obj)/capability.o : $(obj)/capability_names.h 96$(obj)/capability.o : $(obj)/capability_names.h
97$(obj)/net.o : $(obj)/net_names.h
64$(obj)/resource.o : $(obj)/rlim_names.h 98$(obj)/resource.o : $(obj)/rlim_names.h
65$(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \ 99$(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
66 $(src)/Makefile 100 $(src)/Makefile
@@ -68,3 +102,8 @@ $(obj)/capability_names.h : $(srctree)/include/uapi/linux/capability.h \
68$(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \ 102$(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \
69 $(src)/Makefile 103 $(src)/Makefile
70 $(call cmd,make-rlim) 104 $(call cmd,make-rlim)
105$(obj)/net_names.h : $(srctree)/include/linux/socket.h \
106 $(srctree)/include/linux/net.h \
107 $(src)/Makefile
108 $(call cmd,make-af)
109 $(call cmd,make-sock)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 853c2ec8e0c9..518d5928661b 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -32,6 +32,7 @@
32#include "include/audit.h" 32#include "include/audit.h"
33#include "include/context.h" 33#include "include/context.h"
34#include "include/crypto.h" 34#include "include/crypto.h"
35#include "include/ipc.h"
35#include "include/policy_ns.h" 36#include "include/policy_ns.h"
36#include "include/label.h" 37#include "include/label.h"
37#include "include/policy.h" 38#include "include/policy.h"
@@ -248,8 +249,10 @@ static struct dentry *aafs_create(const char *name, umode_t mode,
248 249
249 inode_lock(dir); 250 inode_lock(dir);
250 dentry = lookup_one_len(name, parent, strlen(name)); 251 dentry = lookup_one_len(name, parent, strlen(name));
251 if (IS_ERR(dentry)) 252 if (IS_ERR(dentry)) {
253 error = PTR_ERR(dentry);
252 goto fail_lock; 254 goto fail_lock;
255 }
253 256
254 if (d_really_is_positive(dentry)) { 257 if (d_really_is_positive(dentry)) {
255 error = -EEXIST; 258 error = -EEXIST;
@@ -1443,6 +1446,10 @@ void __aafs_profile_migrate_dents(struct aa_profile *old,
1443{ 1446{
1444 int i; 1447 int i;
1445 1448
1449 AA_BUG(!old);
1450 AA_BUG(!new);
1451 AA_BUG(!mutex_is_locked(&profiles_ns(old)->lock));
1452
1446 for (i = 0; i < AAFS_PROF_SIZEOF; i++) { 1453 for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
1447 new->dents[i] = old->dents[i]; 1454 new->dents[i] = old->dents[i];
1448 if (new->dents[i]) 1455 if (new->dents[i])
@@ -1506,6 +1513,9 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
1506 struct dentry *dent = NULL, *dir; 1513 struct dentry *dent = NULL, *dir;
1507 int error; 1514 int error;
1508 1515
1516 AA_BUG(!profile);
1517 AA_BUG(!mutex_is_locked(&profiles_ns(profile)->lock));
1518
1509 if (!parent) { 1519 if (!parent) {
1510 struct aa_profile *p; 1520 struct aa_profile *p;
1511 p = aa_deref_parent(profile); 1521 p = aa_deref_parent(profile);
@@ -1731,6 +1741,7 @@ void __aafs_ns_rmdir(struct aa_ns *ns)
1731 1741
1732 if (!ns) 1742 if (!ns)
1733 return; 1743 return;
1744 AA_BUG(!mutex_is_locked(&ns->lock));
1734 1745
1735 list_for_each_entry(child, &ns->base.profiles, base.list) 1746 list_for_each_entry(child, &ns->base.profiles, base.list)
1736 __aafs_profile_rmdir(child); 1747 __aafs_profile_rmdir(child);
@@ -1903,6 +1914,10 @@ static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
1903{ 1914{
1904 struct aa_ns *parent, *next; 1915 struct aa_ns *parent, *next;
1905 1916
1917 AA_BUG(!root);
1918 AA_BUG(!ns);
1919 AA_BUG(ns != root && !mutex_is_locked(&ns->parent->lock));
1920
1906 /* is next namespace a child */ 1921 /* is next namespace a child */
1907 if (!list_empty(&ns->sub_ns)) { 1922 if (!list_empty(&ns->sub_ns)) {
1908 next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list); 1923 next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
@@ -1937,6 +1952,9 @@ static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
1937static struct aa_profile *__first_profile(struct aa_ns *root, 1952static struct aa_profile *__first_profile(struct aa_ns *root,
1938 struct aa_ns *ns) 1953 struct aa_ns *ns)
1939{ 1954{
1955 AA_BUG(!root);
1956 AA_BUG(ns && !mutex_is_locked(&ns->lock));
1957
1940 for (; ns; ns = __next_ns(root, ns)) { 1958 for (; ns; ns = __next_ns(root, ns)) {
1941 if (!list_empty(&ns->base.profiles)) 1959 if (!list_empty(&ns->base.profiles))
1942 return list_first_entry(&ns->base.profiles, 1960 return list_first_entry(&ns->base.profiles,
@@ -1959,6 +1977,8 @@ static struct aa_profile *__next_profile(struct aa_profile *p)
1959 struct aa_profile *parent; 1977 struct aa_profile *parent;
1960 struct aa_ns *ns = p->ns; 1978 struct aa_ns *ns = p->ns;
1961 1979
1980 AA_BUG(!mutex_is_locked(&profiles_ns(p)->lock));
1981
1962 /* is next profile a child */ 1982 /* is next profile a child */
1963 if (!list_empty(&p->base.profiles)) 1983 if (!list_empty(&p->base.profiles))
1964 return list_first_entry(&p->base.profiles, typeof(*p), 1984 return list_first_entry(&p->base.profiles, typeof(*p),
@@ -2127,6 +2147,11 @@ static struct aa_sfs_entry aa_sfs_entry_ptrace[] = {
2127 { } 2147 { }
2128}; 2148};
2129 2149
2150static struct aa_sfs_entry aa_sfs_entry_signal[] = {
2151 AA_SFS_FILE_STRING("mask", AA_SFS_SIG_MASK),
2152 { }
2153};
2154
2130static struct aa_sfs_entry aa_sfs_entry_domain[] = { 2155static struct aa_sfs_entry aa_sfs_entry_domain[] = {
2131 AA_SFS_FILE_BOOLEAN("change_hat", 1), 2156 AA_SFS_FILE_BOOLEAN("change_hat", 1),
2132 AA_SFS_FILE_BOOLEAN("change_hatv", 1), 2157 AA_SFS_FILE_BOOLEAN("change_hatv", 1),
@@ -2151,9 +2176,14 @@ static struct aa_sfs_entry aa_sfs_entry_policy[] = {
2151 { } 2176 { }
2152}; 2177};
2153 2178
2179static struct aa_sfs_entry aa_sfs_entry_mount[] = {
2180 AA_SFS_FILE_STRING("mask", "mount umount pivot_root"),
2181 { }
2182};
2183
2154static struct aa_sfs_entry aa_sfs_entry_ns[] = { 2184static struct aa_sfs_entry aa_sfs_entry_ns[] = {
2155 AA_SFS_FILE_BOOLEAN("profile", 1), 2185 AA_SFS_FILE_BOOLEAN("profile", 1),
2156 AA_SFS_FILE_BOOLEAN("pivot_root", 1), 2186 AA_SFS_FILE_BOOLEAN("pivot_root", 0),
2157 { } 2187 { }
2158}; 2188};
2159 2189
@@ -2172,22 +2202,25 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
2172 AA_SFS_DIR("policy", aa_sfs_entry_policy), 2202 AA_SFS_DIR("policy", aa_sfs_entry_policy),
2173 AA_SFS_DIR("domain", aa_sfs_entry_domain), 2203 AA_SFS_DIR("domain", aa_sfs_entry_domain),
2174 AA_SFS_DIR("file", aa_sfs_entry_file), 2204 AA_SFS_DIR("file", aa_sfs_entry_file),
2205 AA_SFS_DIR("network", aa_sfs_entry_network),
2206 AA_SFS_DIR("mount", aa_sfs_entry_mount),
2175 AA_SFS_DIR("namespaces", aa_sfs_entry_ns), 2207 AA_SFS_DIR("namespaces", aa_sfs_entry_ns),
2176 AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK), 2208 AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
2177 AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit), 2209 AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit),
2178 AA_SFS_DIR("caps", aa_sfs_entry_caps), 2210 AA_SFS_DIR("caps", aa_sfs_entry_caps),
2179 AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace), 2211 AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace),
2212 AA_SFS_DIR("signal", aa_sfs_entry_signal),
2180 AA_SFS_DIR("query", aa_sfs_entry_query), 2213 AA_SFS_DIR("query", aa_sfs_entry_query),
2181 { } 2214 { }
2182}; 2215};
2183 2216
2184static struct aa_sfs_entry aa_sfs_entry_apparmor[] = { 2217static struct aa_sfs_entry aa_sfs_entry_apparmor[] = {
2185 AA_SFS_FILE_FOPS(".access", 0640, &aa_sfs_access), 2218 AA_SFS_FILE_FOPS(".access", 0666, &aa_sfs_access),
2186 AA_SFS_FILE_FOPS(".stacked", 0444, &seq_ns_stacked_fops), 2219 AA_SFS_FILE_FOPS(".stacked", 0444, &seq_ns_stacked_fops),
2187 AA_SFS_FILE_FOPS(".ns_stacked", 0444, &seq_ns_nsstacked_fops), 2220 AA_SFS_FILE_FOPS(".ns_stacked", 0444, &seq_ns_nsstacked_fops),
2188 AA_SFS_FILE_FOPS(".ns_level", 0666, &seq_ns_level_fops), 2221 AA_SFS_FILE_FOPS(".ns_level", 0444, &seq_ns_level_fops),
2189 AA_SFS_FILE_FOPS(".ns_name", 0640, &seq_ns_name_fops), 2222 AA_SFS_FILE_FOPS(".ns_name", 0444, &seq_ns_name_fops),
2190 AA_SFS_FILE_FOPS("profiles", 0440, &aa_sfs_profiles_fops), 2223 AA_SFS_FILE_FOPS("profiles", 0444, &aa_sfs_profiles_fops),
2191 AA_SFS_DIR("features", aa_sfs_entry_features), 2224 AA_SFS_DIR("features", aa_sfs_entry_features),
2192 { } 2225 { }
2193}; 2226};
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 17a601c67b62..dd754b7850a8 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -374,8 +374,8 @@ static const char *next_name(int xtype, const char *name)
374 * 374 *
375 * Returns: refcounted label, or NULL on failure (MAYBE NULL) 375 * Returns: refcounted label, or NULL on failure (MAYBE NULL)
376 */ 376 */
377static struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex, 377struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
378 const char **name) 378 const char **name)
379{ 379{
380 struct aa_label *label = NULL; 380 struct aa_label *label = NULL;
381 u32 xtype = xindex & AA_X_TYPE_MASK; 381 u32 xtype = xindex & AA_X_TYPE_MASK;
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 3382518b87fa..db80221891c6 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -21,6 +21,7 @@
21#include "include/context.h" 21#include "include/context.h"
22#include "include/file.h" 22#include "include/file.h"
23#include "include/match.h" 23#include "include/match.h"
24#include "include/net.h"
24#include "include/path.h" 25#include "include/path.h"
25#include "include/policy.h" 26#include "include/policy.h"
26#include "include/label.h" 27#include "include/label.h"
@@ -566,6 +567,32 @@ static int __file_path_perm(const char *op, struct aa_label *label,
566 return error; 567 return error;
567} 568}
568 569
570static int __file_sock_perm(const char *op, struct aa_label *label,
571 struct aa_label *flabel, struct file *file,
572 u32 request, u32 denied)
573{
574 struct socket *sock = (struct socket *) file->private_data;
575 int error;
576
577 AA_BUG(!sock);
578
579 /* revalidation due to label out of date. No revocation at this time */
580 if (!denied && aa_label_is_subset(flabel, label))
581 return 0;
582
583 /* TODO: improve to skip profiles cached in flabel */
584 error = aa_sock_file_perm(label, op, request, sock);
585 if (denied) {
586 /* TODO: improve to skip profiles checked above */
587 /* check every profile in file label to is cached */
588 last_error(error, aa_sock_file_perm(flabel, op, request, sock));
589 }
590 if (!error)
591 update_file_ctx(file_ctx(file), label, request);
592
593 return error;
594}
595
569/** 596/**
570 * aa_file_perm - do permission revalidation check & audit for @file 597 * aa_file_perm - do permission revalidation check & audit for @file
571 * @op: operation being checked 598 * @op: operation being checked
@@ -610,6 +637,9 @@ int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
610 error = __file_path_perm(op, label, flabel, file, request, 637 error = __file_path_perm(op, label, flabel, file, request,
611 denied); 638 denied);
612 639
640 else if (S_ISSOCK(file_inode(file)->i_mode))
641 error = __file_sock_perm(op, label, flabel, file, request,
642 denied);
613done: 643done:
614 rcu_read_unlock(); 644 rcu_read_unlock();
615 645
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
index aaf893f4e4f5..829082c35faa 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -27,7 +27,9 @@
27#define AA_CLASS_NET 4 27#define AA_CLASS_NET 4
28#define AA_CLASS_RLIMITS 5 28#define AA_CLASS_RLIMITS 5
29#define AA_CLASS_DOMAIN 6 29#define AA_CLASS_DOMAIN 6
30#define AA_CLASS_MOUNT 7
30#define AA_CLASS_PTRACE 9 31#define AA_CLASS_PTRACE 9
32#define AA_CLASS_SIGNAL 10
31#define AA_CLASS_LABEL 16 33#define AA_CLASS_LABEL 16
32 34
33#define AA_CLASS_LAST AA_CLASS_LABEL 35#define AA_CLASS_LAST AA_CLASS_LABEL
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index c68839a44351..ff4316e1068d 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -71,6 +71,10 @@ enum audit_type {
71#define OP_FMPROT "file_mprotect" 71#define OP_FMPROT "file_mprotect"
72#define OP_INHERIT "file_inherit" 72#define OP_INHERIT "file_inherit"
73 73
74#define OP_PIVOTROOT "pivotroot"
75#define OP_MOUNT "mount"
76#define OP_UMOUNT "umount"
77
74#define OP_CREATE "create" 78#define OP_CREATE "create"
75#define OP_POST_CREATE "post_create" 79#define OP_POST_CREATE "post_create"
76#define OP_BIND "bind" 80#define OP_BIND "bind"
@@ -86,6 +90,7 @@ enum audit_type {
86#define OP_SHUTDOWN "socket_shutdown" 90#define OP_SHUTDOWN "socket_shutdown"
87 91
88#define OP_PTRACE "ptrace" 92#define OP_PTRACE "ptrace"
93#define OP_SIGNAL "signal"
89 94
90#define OP_EXEC "exec" 95#define OP_EXEC "exec"
91 96
@@ -116,20 +121,36 @@ struct apparmor_audit_data {
116 /* these entries require a custom callback fn */ 121 /* these entries require a custom callback fn */
117 struct { 122 struct {
118 struct aa_label *peer; 123 struct aa_label *peer;
119 struct { 124 union {
120 const char *target; 125 struct {
121 kuid_t ouid; 126 kuid_t ouid;
122 } fs; 127 const char *target;
128 } fs;
129 struct {
130 int type, protocol;
131 struct sock *peer_sk;
132 void *addr;
133 int addrlen;
134 } net;
135 int signal;
136 struct {
137 int rlim;
138 unsigned long max;
139 } rlim;
140 };
123 }; 141 };
124 struct { 142 struct {
125 const char *name; 143 struct aa_profile *profile;
126 long pos;
127 const char *ns; 144 const char *ns;
145 long pos;
128 } iface; 146 } iface;
129 struct { 147 struct {
130 int rlim; 148 const char *src_name;
131 unsigned long max; 149 const char *type;
132 } rlim; 150 const char *trans;
151 const char *data;
152 unsigned long flags;
153 } mnt;
133 }; 154 };
134}; 155};
135 156
diff --git a/security/apparmor/include/domain.h b/security/apparmor/include/domain.h
index 24c5976d6143..ac9862ff7cdf 100644
--- a/security/apparmor/include/domain.h
+++ b/security/apparmor/include/domain.h
@@ -15,6 +15,8 @@
15#include <linux/binfmts.h> 15#include <linux/binfmts.h>
16#include <linux/types.h> 16#include <linux/types.h>
17 17
18#include "label.h"
19
18#ifndef __AA_DOMAIN_H 20#ifndef __AA_DOMAIN_H
19#define __AA_DOMAIN_H 21#define __AA_DOMAIN_H
20 22
@@ -29,6 +31,9 @@ struct aa_domain {
29#define AA_CHANGE_ONEXEC 4 31#define AA_CHANGE_ONEXEC 4
30#define AA_CHANGE_STACK 8 32#define AA_CHANGE_STACK 8
31 33
34struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
35 const char **name);
36
32int apparmor_bprm_set_creds(struct linux_binprm *bprm); 37int apparmor_bprm_set_creds(struct linux_binprm *bprm);
33 38
34void aa_free_domain_entries(struct aa_domain *domain); 39void aa_free_domain_entries(struct aa_domain *domain);
diff --git a/security/apparmor/include/ipc.h b/security/apparmor/include/ipc.h
index 656fdb81c8a0..5ffc218d1e74 100644
--- a/security/apparmor/include/ipc.h
+++ b/security/apparmor/include/ipc.h
@@ -27,8 +27,14 @@ struct aa_profile;
27 27
28#define AA_PTRACE_PERM_MASK (AA_PTRACE_READ | AA_PTRACE_TRACE | \ 28#define AA_PTRACE_PERM_MASK (AA_PTRACE_READ | AA_PTRACE_TRACE | \
29 AA_MAY_BE_READ | AA_MAY_BE_TRACED) 29 AA_MAY_BE_READ | AA_MAY_BE_TRACED)
30#define AA_SIGNAL_PERM_MASK (MAY_READ | MAY_WRITE)
31
32#define AA_SFS_SIG_MASK "hup int quit ill trap abrt bus fpe kill usr1 " \
33 "segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg " \
34 "xcpu xfsz vtalrm prof winch io pwr sys emt lost"
30 35
31int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee, 36int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
32 u32 request); 37 u32 request);
38int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig);
33 39
34#endif /* __AA_IPC_H */ 40#endif /* __AA_IPC_H */
diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h
index 9a283b722755..af22dcbbcb8a 100644
--- a/security/apparmor/include/label.h
+++ b/security/apparmor/include/label.h
@@ -310,6 +310,7 @@ bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp);
310#define FLAG_SHOW_MODE 1 310#define FLAG_SHOW_MODE 1
311#define FLAG_VIEW_SUBNS 2 311#define FLAG_VIEW_SUBNS 2
312#define FLAG_HIDDEN_UNCONFINED 4 312#define FLAG_HIDDEN_UNCONFINED 4
313#define FLAG_ABS_ROOT 8
313int aa_label_snxprint(char *str, size_t size, struct aa_ns *view, 314int aa_label_snxprint(char *str, size_t size, struct aa_ns *view,
314 struct aa_label *label, int flags); 315 struct aa_label *label, int flags);
315int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label, 316int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label,
diff --git a/security/apparmor/include/mount.h b/security/apparmor/include/mount.h
new file mode 100644
index 000000000000..25d6067fa6ef
--- /dev/null
+++ b/security/apparmor/include/mount.h
@@ -0,0 +1,54 @@
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor file mediation function definitions.
5 *
6 * Copyright 2017 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation, version 2 of the
11 * License.
12 */
13
14#ifndef __AA_MOUNT_H
15#define __AA_MOUNT_H
16
17#include <linux/fs.h>
18#include <linux/path.h>
19
20#include "domain.h"
21#include "policy.h"
22
23/* mount perms */
24#define AA_MAY_PIVOTROOT 0x01
25#define AA_MAY_MOUNT 0x02
26#define AA_MAY_UMOUNT 0x04
27#define AA_AUDIT_DATA 0x40
28#define AA_MNT_CONT_MATCH 0x40
29
30#define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN)
31
32int aa_remount(struct aa_label *label, const struct path *path,
33 unsigned long flags, void *data);
34
35int aa_bind_mount(struct aa_label *label, const struct path *path,
36 const char *old_name, unsigned long flags);
37
38
39int aa_mount_change_type(struct aa_label *label, const struct path *path,
40 unsigned long flags);
41
42int aa_move_mount(struct aa_label *label, const struct path *path,
43 const char *old_name);
44
45int aa_new_mount(struct aa_label *label, const char *dev_name,
46 const struct path *path, const char *type, unsigned long flags,
47 void *data);
48
49int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags);
50
51int aa_pivotroot(struct aa_label *label, const struct path *old_path,
52 const struct path *new_path);
53
54#endif /* __AA_MOUNT_H */
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
new file mode 100644
index 000000000000..140c8efcf364
--- /dev/null
+++ b/security/apparmor/include/net.h
@@ -0,0 +1,114 @@
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor network mediation definitions.
5 *
6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2017 Canonical Ltd.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2 of the
12 * License.
13 */
14
15#ifndef __AA_NET_H
16#define __AA_NET_H
17
18#include <net/sock.h>
19#include <linux/path.h>
20
21#include "apparmorfs.h"
22#include "label.h"
23#include "perms.h"
24#include "policy.h"
25
26#define AA_MAY_SEND AA_MAY_WRITE
27#define AA_MAY_RECEIVE AA_MAY_READ
28
29#define AA_MAY_SHUTDOWN AA_MAY_DELETE
30
31#define AA_MAY_CONNECT AA_MAY_OPEN
32#define AA_MAY_ACCEPT 0x00100000
33
34#define AA_MAY_BIND 0x00200000
35#define AA_MAY_LISTEN 0x00400000
36
37#define AA_MAY_SETOPT 0x01000000
38#define AA_MAY_GETOPT 0x02000000
39
40#define NET_PERMS_MASK (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CREATE | \
41 AA_MAY_SHUTDOWN | AA_MAY_BIND | AA_MAY_LISTEN | \
42 AA_MAY_CONNECT | AA_MAY_ACCEPT | AA_MAY_SETATTR | \
43 AA_MAY_GETATTR | AA_MAY_SETOPT | AA_MAY_GETOPT)
44
45#define NET_FS_PERMS (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CREATE | \
46 AA_MAY_SHUTDOWN | AA_MAY_CONNECT | AA_MAY_RENAME |\
47 AA_MAY_SETATTR | AA_MAY_GETATTR | AA_MAY_CHMOD | \
48 AA_MAY_CHOWN | AA_MAY_CHGRP | AA_MAY_LOCK | \
49 AA_MAY_MPROT)
50
51#define NET_PEER_MASK (AA_MAY_SEND | AA_MAY_RECEIVE | AA_MAY_CONNECT | \
52 AA_MAY_ACCEPT)
53struct aa_sk_ctx {
54 struct aa_label *label;
55 struct aa_label *peer;
56 struct path path;
57};
58
59#define SK_CTX(X) ((X)->sk_security)
60#define SOCK_ctx(X) SOCK_INODE(X)->i_security
61#define DEFINE_AUDIT_NET(NAME, OP, SK, F, T, P) \
62 struct lsm_network_audit NAME ## _net = { .sk = (SK), \
63 .family = (F)}; \
64 DEFINE_AUDIT_DATA(NAME, \
65 ((SK) && (F) != AF_UNIX) ? LSM_AUDIT_DATA_NET : \
66 LSM_AUDIT_DATA_NONE, \
67 OP); \
68 NAME.u.net = &(NAME ## _net); \
69 aad(&NAME)->net.type = (T); \
70 aad(&NAME)->net.protocol = (P)
71
72#define DEFINE_AUDIT_SK(NAME, OP, SK) \
73 DEFINE_AUDIT_NET(NAME, OP, SK, (SK)->sk_family, (SK)->sk_type, \
74 (SK)->sk_protocol)
75
76/* struct aa_net - network confinement data
77 * @allow: basic network families permissions
78 * @audit: which network permissions to force audit
79 * @quiet: which network permissions to quiet rejects
80 */
81struct aa_net {
82 u16 allow[AF_MAX];
83 u16 audit[AF_MAX];
84 u16 quiet[AF_MAX];
85};
86
87
88extern struct aa_sfs_entry aa_sfs_entry_network[];
89
90void audit_net_cb(struct audit_buffer *ab, void *va);
91int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
92 u32 request, u16 family, int type);
93int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
94 int type, int protocol);
95static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
96 struct common_audit_data *sa,
97 u32 request,
98 struct sock *sk)
99{
100 return aa_profile_af_perm(profile, sa, request, sk->sk_family,
101 sk->sk_type);
102}
103int aa_sk_perm(const char *op, u32 request, struct sock *sk);
104
105int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
106 struct socket *sock);
107
108
109static inline void aa_free_net_rules(struct aa_net *new)
110{
111 /* NOP */
112}
113
114#endif /* __AA_NET_H */
diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
index 2b27bb79aec4..af04d5a7d73d 100644
--- a/security/apparmor/include/perms.h
+++ b/security/apparmor/include/perms.h
@@ -135,9 +135,10 @@ extern struct aa_perms allperms;
135 135
136 136
137void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask); 137void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask);
138void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask); 138void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names,
139 u32 mask);
139void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, 140void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
140 u32 chrsmask, const char **names, u32 namesmask); 141 u32 chrsmask, const char * const *names, u32 namesmask);
141void aa_apply_modes_to_perms(struct aa_profile *profile, 142void aa_apply_modes_to_perms(struct aa_profile *profile,
142 struct aa_perms *perms); 143 struct aa_perms *perms);
143void aa_compute_perms(struct aa_dfa *dfa, unsigned int state, 144void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index 17fe41a9cac3..4364088a0b9e 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -30,6 +30,7 @@
30#include "file.h" 30#include "file.h"
31#include "lib.h" 31#include "lib.h"
32#include "label.h" 32#include "label.h"
33#include "net.h"
33#include "perms.h" 34#include "perms.h"
34#include "resource.h" 35#include "resource.h"
35 36
@@ -111,6 +112,7 @@ struct aa_data {
111 * @policy: general match rules governing policy 112 * @policy: general match rules governing policy
112 * @file: The set of rules governing basic file access and domain transitions 113 * @file: The set of rules governing basic file access and domain transitions
113 * @caps: capabilities for the profile 114 * @caps: capabilities for the profile
115 * @net: network controls for the profile
114 * @rlimits: rlimits for the profile 116 * @rlimits: rlimits for the profile
115 * 117 *
116 * @dents: dentries for the profiles file entries in apparmorfs 118 * @dents: dentries for the profiles file entries in apparmorfs
@@ -148,6 +150,7 @@ struct aa_profile {
148 struct aa_policydb policy; 150 struct aa_policydb policy;
149 struct aa_file_rules file; 151 struct aa_file_rules file;
150 struct aa_caps caps; 152 struct aa_caps caps;
153 struct aa_net net;
151 struct aa_rlimit rlimits; 154 struct aa_rlimit rlimits;
152 155
153 struct aa_loaddata *rawdata; 156 struct aa_loaddata *rawdata;
@@ -220,6 +223,16 @@ static inline unsigned int PROFILE_MEDIATES_SAFE(struct aa_profile *profile,
220 return 0; 223 return 0;
221} 224}
222 225
226static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile,
227 u16 AF) {
228 unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
229 u16 be_af = cpu_to_be16(AF);
230
231 if (!state)
232 return 0;
233 return aa_dfa_match_len(profile->policy.dfa, state, (char *) &be_af, 2);
234}
235
223/** 236/**
224 * aa_get_profile - increment refcount on profile @p 237 * aa_get_profile - increment refcount on profile @p
225 * @p: profile (MAYBE NULL) 238 * @p: profile (MAYBE NULL)
diff --git a/security/apparmor/include/sig_names.h b/security/apparmor/include/sig_names.h
new file mode 100644
index 000000000000..92e62fe95292
--- /dev/null
+++ b/security/apparmor/include/sig_names.h
@@ -0,0 +1,98 @@
1#include <linux/signal.h>
2
3#define SIGUNKNOWN 0
4#define MAXMAPPED_SIG 35
5/* provide a mapping of arch signal to internal signal # for mediation
6 * those that are always an alias SIGCLD for SIGCLHD and SIGPOLL for SIGIO
7 * map to the same entry those that may/or may not get a separate entry
8 */
9static const int sig_map[MAXMAPPED_SIG] = {
10 [0] = MAXMAPPED_SIG, /* existence test */
11 [SIGHUP] = 1,
12 [SIGINT] = 2,
13 [SIGQUIT] = 3,
14 [SIGILL] = 4,
15 [SIGTRAP] = 5, /* -, 5, - */
16 [SIGABRT] = 6, /* SIGIOT: -, 6, - */
17 [SIGBUS] = 7, /* 10, 7, 10 */
18 [SIGFPE] = 8,
19 [SIGKILL] = 9,
20 [SIGUSR1] = 10, /* 30, 10, 16 */
21 [SIGSEGV] = 11,
22 [SIGUSR2] = 12, /* 31, 12, 17 */
23 [SIGPIPE] = 13,
24 [SIGALRM] = 14,
25 [SIGTERM] = 15,
26#ifdef SIGSTKFLT
27 [SIGSTKFLT] = 16, /* -, 16, - */
28#endif
29 [SIGCHLD] = 17, /* 20, 17, 18. SIGCHLD -, -, 18 */
30 [SIGCONT] = 18, /* 19, 18, 25 */
31 [SIGSTOP] = 19, /* 17, 19, 23 */
32 [SIGTSTP] = 20, /* 18, 20, 24 */
33 [SIGTTIN] = 21, /* 21, 21, 26 */
34 [SIGTTOU] = 22, /* 22, 22, 27 */
35 [SIGURG] = 23, /* 16, 23, 21 */
36 [SIGXCPU] = 24, /* 24, 24, 30 */
37 [SIGXFSZ] = 25, /* 25, 25, 31 */
38 [SIGVTALRM] = 26, /* 26, 26, 28 */
39 [SIGPROF] = 27, /* 27, 27, 29 */
40 [SIGWINCH] = 28, /* 28, 28, 20 */
41 [SIGIO] = 29, /* SIGPOLL: 23, 29, 22 */
42 [SIGPWR] = 30, /* 29, 30, 19. SIGINFO 29, -, - */
43#ifdef SIGSYS
44 [SIGSYS] = 31, /* 12, 31, 12. often SIG LOST/UNUSED */
45#endif
46#ifdef SIGEMT
47 [SIGEMT] = 32, /* 7, - , 7 */
48#endif
49#if defined(SIGLOST) && SIGPWR != SIGLOST /* sparc */
50 [SIGLOST] = 33, /* unused on Linux */
51#endif
52#if defined(SIGUNUSED) && \
53 defined(SIGLOST) && defined(SIGSYS) && SIGLOST != SIGSYS
54 [SIGUNUSED] = 34, /* -, 31, - */
55#endif
56};
57
58/* this table is ordered post sig_map[sig] mapping */
59static const char *const sig_names[MAXMAPPED_SIG + 1] = {
60 "unknown",
61 "hup",
62 "int",
63 "quit",
64 "ill",
65 "trap",
66 "abrt",
67 "bus",
68 "fpe",
69 "kill",
70 "usr1",
71 "segv",
72 "usr2",
73 "pipe",
74 "alrm",
75 "term",
76 "stkflt",
77 "chld",
78 "cont",
79 "stop",
80 "stp",
81 "ttin",
82 "ttou",
83 "urg",
84 "xcpu",
85 "xfsz",
86 "vtalrm",
87 "prof",
88 "winch",
89 "io",
90 "pwr",
91 "sys",
92 "emt",
93 "lost",
94 "unused",
95
96 "exists", /* always last existence test mapped to MAXMAPPED_SIG */
97};
98
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
index 11e66b5bbc42..66fb9ede9447 100644
--- a/security/apparmor/ipc.c
+++ b/security/apparmor/ipc.c
@@ -20,6 +20,7 @@
20#include "include/context.h" 20#include "include/context.h"
21#include "include/policy.h" 21#include "include/policy.h"
22#include "include/ipc.h" 22#include "include/ipc.h"
23#include "include/sig_names.h"
23 24
24/** 25/**
25 * audit_ptrace_mask - convert mask to permission string 26 * audit_ptrace_mask - convert mask to permission string
@@ -121,3 +122,101 @@ int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
121} 122}
122 123
123 124
125static inline int map_signal_num(int sig)
126{
127 if (sig > SIGRTMAX)
128 return SIGUNKNOWN;
129 else if (sig >= SIGRTMIN)
130 return sig - SIGRTMIN + 128; /* rt sigs mapped to 128 */
131 else if (sig <= MAXMAPPED_SIG)
132 return sig_map[sig];
133 return SIGUNKNOWN;
134}
135
136/**
137 * audit_file_mask - convert mask to permission string
138 * @buffer: buffer to write string to (NOT NULL)
139 * @mask: permission mask to convert
140 */
141static void audit_signal_mask(struct audit_buffer *ab, u32 mask)
142{
143 if (mask & MAY_READ)
144 audit_log_string(ab, "receive");
145 if (mask & MAY_WRITE)
146 audit_log_string(ab, "send");
147}
148
149/**
150 * audit_cb - call back for signal specific audit fields
151 * @ab: audit_buffer (NOT NULL)
152 * @va: audit struct to audit values of (NOT NULL)
153 */
154static void audit_signal_cb(struct audit_buffer *ab, void *va)
155{
156 struct common_audit_data *sa = va;
157
158 if (aad(sa)->request & AA_SIGNAL_PERM_MASK) {
159 audit_log_format(ab, " requested_mask=");
160 audit_signal_mask(ab, aad(sa)->request);
161 if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) {
162 audit_log_format(ab, " denied_mask=");
163 audit_signal_mask(ab, aad(sa)->denied);
164 }
165 }
166 if (aad(sa)->signal <= MAXMAPPED_SIG)
167 audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]);
168 else
169 audit_log_format(ab, " signal=rtmin+%d",
170 aad(sa)->signal - 128);
171 audit_log_format(ab, " peer=");
172 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
173 FLAGS_NONE, GFP_ATOMIC);
174}
175
176/* TODO: update to handle compound name&name2, conditionals */
177static void profile_match_signal(struct aa_profile *profile, const char *label,
178 int signal, struct aa_perms *perms)
179{
180 unsigned int state;
181
182 /* TODO: secondary cache check <profile, profile, perm> */
183 state = aa_dfa_next(profile->policy.dfa,
184 profile->policy.start[AA_CLASS_SIGNAL],
185 signal);
186 state = aa_dfa_match(profile->policy.dfa, state, label);
187 aa_compute_perms(profile->policy.dfa, state, perms);
188}
189
190static int profile_signal_perm(struct aa_profile *profile,
191 struct aa_profile *peer, u32 request,
192 struct common_audit_data *sa)
193{
194 struct aa_perms perms;
195
196 if (profile_unconfined(profile) ||
197 !PROFILE_MEDIATES(profile, AA_CLASS_SIGNAL))
198 return 0;
199
200 aad(sa)->peer = &peer->label;
201 profile_match_signal(profile, peer->base.hname, aad(sa)->signal,
202 &perms);
203 aa_apply_modes_to_perms(profile, &perms);
204 return aa_check_perms(profile, &perms, request, sa, audit_signal_cb);
205}
206
207static int aa_signal_cross_perm(struct aa_profile *sender,
208 struct aa_profile *target,
209 struct common_audit_data *sa)
210{
211 return xcheck(profile_signal_perm(sender, target, MAY_WRITE, sa),
212 profile_signal_perm(target, sender, MAY_READ, sa));
213}
214
215int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig)
216{
217 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SIGNAL);
218
219 aad(&sa)->signal = map_signal_num(sig);
220 return xcheck_labels_profiles(sender, target, aa_signal_cross_perm,
221 &sa);
222}
diff --git a/security/apparmor/label.c b/security/apparmor/label.c
index e052eaba1cf6..c5b99b954580 100644
--- a/security/apparmor/label.c
+++ b/security/apparmor/label.c
@@ -49,7 +49,7 @@ static void free_proxy(struct aa_proxy *proxy)
49 /* p->label will not updated any more as p is dead */ 49 /* p->label will not updated any more as p is dead */
50 aa_put_label(rcu_dereference_protected(proxy->label, true)); 50 aa_put_label(rcu_dereference_protected(proxy->label, true));
51 memset(proxy, 0, sizeof(*proxy)); 51 memset(proxy, 0, sizeof(*proxy));
52 proxy->label = (struct aa_label *) PROXY_POISON; 52 RCU_INIT_POINTER(proxy->label, (struct aa_label *)PROXY_POISON);
53 kfree(proxy); 53 kfree(proxy);
54 } 54 }
55} 55}
@@ -1450,9 +1450,11 @@ bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp)
1450 * cached label name is present and visible 1450 * cached label name is present and visible
1451 * @label->hname only exists if label is namespace hierachical 1451 * @label->hname only exists if label is namespace hierachical
1452 */ 1452 */
1453static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label) 1453static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label,
1454 int flags)
1454{ 1455{
1455 if (label->hname && labels_ns(label) == ns) 1456 if (label->hname && (!ns || labels_ns(label) == ns) &&
1457 !(flags & ~FLAG_SHOW_MODE))
1456 return true; 1458 return true;
1457 1459
1458 return false; 1460 return false;
@@ -1495,7 +1497,7 @@ static int aa_profile_snxprint(char *str, size_t size, struct aa_ns *view,
1495 view = profiles_ns(profile); 1497 view = profiles_ns(profile);
1496 1498
1497 if (view != profile->ns && 1499 if (view != profile->ns &&
1498 (!prev_ns || (prev_ns && *prev_ns != profile->ns))) { 1500 (!prev_ns || (*prev_ns != profile->ns))) {
1499 if (prev_ns) 1501 if (prev_ns)
1500 *prev_ns = profile->ns; 1502 *prev_ns = profile->ns;
1501 ns_name = aa_ns_name(view, profile->ns, 1503 ns_name = aa_ns_name(view, profile->ns,
@@ -1605,8 +1607,13 @@ int aa_label_snxprint(char *str, size_t size, struct aa_ns *ns,
1605 AA_BUG(!str && size != 0); 1607 AA_BUG(!str && size != 0);
1606 AA_BUG(!label); 1608 AA_BUG(!label);
1607 1609
1608 if (!ns) 1610 if (flags & FLAG_ABS_ROOT) {
1611 ns = root_ns;
1612 len = snprintf(str, size, "=");
1613 update_for_len(total, len, size, str);
1614 } else if (!ns) {
1609 ns = labels_ns(label); 1615 ns = labels_ns(label);
1616 }
1610 1617
1611 label_for_each(i, label, profile) { 1618 label_for_each(i, label, profile) {
1612 if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) { 1619 if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) {
@@ -1710,10 +1717,8 @@ void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns,
1710 AA_BUG(!ab); 1717 AA_BUG(!ab);
1711 AA_BUG(!label); 1718 AA_BUG(!label);
1712 1719
1713 if (!ns) 1720 if (!use_label_hname(ns, label, flags) ||
1714 ns = labels_ns(label); 1721 display_mode(ns, label, flags)) {
1715
1716 if (!use_label_hname(ns, label) || display_mode(ns, label, flags)) {
1717 len = aa_label_asxprint(&name, ns, label, flags, gfp); 1722 len = aa_label_asxprint(&name, ns, label, flags, gfp);
1718 if (len == -1) { 1723 if (len == -1) {
1719 AA_DEBUG("label print error"); 1724 AA_DEBUG("label print error");
@@ -1738,10 +1743,7 @@ void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns,
1738 AA_BUG(!f); 1743 AA_BUG(!f);
1739 AA_BUG(!label); 1744 AA_BUG(!label);
1740 1745
1741 if (!ns) 1746 if (!use_label_hname(ns, label, flags)) {
1742 ns = labels_ns(label);
1743
1744 if (!use_label_hname(ns, label)) {
1745 char *str; 1747 char *str;
1746 int len; 1748 int len;
1747 1749
@@ -1764,10 +1766,7 @@ void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags,
1764{ 1766{
1765 AA_BUG(!label); 1767 AA_BUG(!label);
1766 1768
1767 if (!ns) 1769 if (!use_label_hname(ns, label, flags)) {
1768 ns = labels_ns(label);
1769
1770 if (!use_label_hname(ns, label)) {
1771 char *str; 1770 char *str;
1772 int len; 1771 int len;
1773 1772
@@ -1874,6 +1873,9 @@ struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
1874 if (*str == '&') 1873 if (*str == '&')
1875 str++; 1874 str++;
1876 } 1875 }
1876 if (*str == '=')
1877 base = &root_ns->unconfined->label;
1878
1877 error = vec_setup(profile, vec, len, gfp); 1879 error = vec_setup(profile, vec, len, gfp);
1878 if (error) 1880 if (error)
1879 return ERR_PTR(error); 1881 return ERR_PTR(error);
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index 08ca26bcca77..8818621b5d95 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -211,7 +211,8 @@ void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask)
211 *str = '\0'; 211 *str = '\0';
212} 212}
213 213
214void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask) 214void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names,
215 u32 mask)
215{ 216{
216 const char *fmt = "%s"; 217 const char *fmt = "%s";
217 unsigned int i, perm = 1; 218 unsigned int i, perm = 1;
@@ -229,7 +230,7 @@ void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask)
229} 230}
230 231
231void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, 232void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
232 u32 chrsmask, const char **names, u32 namesmask) 233 u32 chrsmask, const char * const *names, u32 namesmask)
233{ 234{
234 char str[33]; 235 char str[33];
235 236
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 7a82c0f61452..72b915dfcaf7 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -33,11 +33,13 @@
33#include "include/context.h" 33#include "include/context.h"
34#include "include/file.h" 34#include "include/file.h"
35#include "include/ipc.h" 35#include "include/ipc.h"
36#include "include/net.h"
36#include "include/path.h" 37#include "include/path.h"
37#include "include/label.h" 38#include "include/label.h"
38#include "include/policy.h" 39#include "include/policy.h"
39#include "include/policy_ns.h" 40#include "include/policy_ns.h"
40#include "include/procattr.h" 41#include "include/procattr.h"
42#include "include/mount.h"
41 43
42/* Flag indicating whether initialization completed */ 44/* Flag indicating whether initialization completed */
43int apparmor_initialized; 45int apparmor_initialized;
@@ -511,6 +513,65 @@ static int apparmor_file_mprotect(struct vm_area_struct *vma,
511 !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0); 513 !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
512} 514}
513 515
516static int apparmor_sb_mount(const char *dev_name, const struct path *path,
517 const char *type, unsigned long flags, void *data)
518{
519 struct aa_label *label;
520 int error = 0;
521
522 /* Discard magic */
523 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
524 flags &= ~MS_MGC_MSK;
525
526 flags &= ~AA_MS_IGNORE_MASK;
527
528 label = __begin_current_label_crit_section();
529 if (!unconfined(label)) {
530 if (flags & MS_REMOUNT)
531 error = aa_remount(label, path, flags, data);
532 else if (flags & MS_BIND)
533 error = aa_bind_mount(label, path, dev_name, flags);
534 else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE |
535 MS_UNBINDABLE))
536 error = aa_mount_change_type(label, path, flags);
537 else if (flags & MS_MOVE)
538 error = aa_move_mount(label, path, dev_name);
539 else
540 error = aa_new_mount(label, dev_name, path, type,
541 flags, data);
542 }
543 __end_current_label_crit_section(label);
544
545 return error;
546}
547
548static int apparmor_sb_umount(struct vfsmount *mnt, int flags)
549{
550 struct aa_label *label;
551 int error = 0;
552
553 label = __begin_current_label_crit_section();
554 if (!unconfined(label))
555 error = aa_umount(label, mnt, flags);
556 __end_current_label_crit_section(label);
557
558 return error;
559}
560
561static int apparmor_sb_pivotroot(const struct path *old_path,
562 const struct path *new_path)
563{
564 struct aa_label *label;
565 int error = 0;
566
567 label = aa_get_current_label();
568 if (!unconfined(label))
569 error = aa_pivotroot(label, old_path, new_path);
570 aa_put_label(label);
571
572 return error;
573}
574
514static int apparmor_getprocattr(struct task_struct *task, char *name, 575static int apparmor_getprocattr(struct task_struct *task, char *name,
515 char **value) 576 char **value)
516{ 577{
@@ -656,12 +717,398 @@ static int apparmor_task_setrlimit(struct task_struct *task,
656 return error; 717 return error;
657} 718}
658 719
720static int apparmor_task_kill(struct task_struct *target, struct siginfo *info,
721 int sig, u32 secid)
722{
723 struct aa_label *cl, *tl;
724 int error;
725
726 if (secid)
727 /* TODO: after secid to label mapping is done.
728 * Dealing with USB IO specific behavior
729 */
730 return 0;
731 cl = __begin_current_label_crit_section();
732 tl = aa_get_task_label(target);
733 error = aa_may_signal(cl, tl, sig);
734 aa_put_label(tl);
735 __end_current_label_crit_section(cl);
736
737 return error;
738}
739
740/**
741 * apparmor_sk_alloc_security - allocate and attach the sk_security field
742 */
743static int apparmor_sk_alloc_security(struct sock *sk, int family, gfp_t flags)
744{
745 struct aa_sk_ctx *ctx;
746
747 ctx = kzalloc(sizeof(*ctx), flags);
748 if (!ctx)
749 return -ENOMEM;
750
751 SK_CTX(sk) = ctx;
752
753 return 0;
754}
755
756/**
757 * apparmor_sk_free_security - free the sk_security field
758 */
759static void apparmor_sk_free_security(struct sock *sk)
760{
761 struct aa_sk_ctx *ctx = SK_CTX(sk);
762
763 SK_CTX(sk) = NULL;
764 aa_put_label(ctx->label);
765 aa_put_label(ctx->peer);
766 path_put(&ctx->path);
767 kfree(ctx);
768}
769
770/**
771 * apparmor_clone_security - clone the sk_security field
772 */
773static void apparmor_sk_clone_security(const struct sock *sk,
774 struct sock *newsk)
775{
776 struct aa_sk_ctx *ctx = SK_CTX(sk);
777 struct aa_sk_ctx *new = SK_CTX(newsk);
778
779 new->label = aa_get_label(ctx->label);
780 new->peer = aa_get_label(ctx->peer);
781 new->path = ctx->path;
782 path_get(&new->path);
783}
784
785static int aa_sock_create_perm(struct aa_label *label, int family, int type,
786 int protocol)
787{
788 AA_BUG(!label);
789 AA_BUG(in_interrupt());
790
791 return aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family, type,
792 protocol);
793}
794
795
796/**
797 * apparmor_socket_create - check perms before creating a new socket
798 */
799static int apparmor_socket_create(int family, int type, int protocol, int kern)
800{
801 struct aa_label *label;
802 int error = 0;
803
804 label = begin_current_label_crit_section();
805 if (!(kern || unconfined(label)))
806 error = aa_sock_create_perm(label, family, type, protocol);
807 end_current_label_crit_section(label);
808
809 return error;
810}
811
812/**
813 * apparmor_socket_post_create - setup the per-socket security struct
814 *
815 * Note:
816 * - kernel sockets currently labeled unconfined but we may want to
817 * move to a special kernel label
818 * - socket may not have sk here if created with sock_create_lite or
819 * sock_alloc. These should be accept cases which will be handled in
820 * sock_graft.
821 */
822static int apparmor_socket_post_create(struct socket *sock, int family,
823 int type, int protocol, int kern)
824{
825 struct aa_label *label;
826
827 if (kern) {
828 struct aa_ns *ns = aa_get_current_ns();
829
830 label = aa_get_label(ns_unconfined(ns));
831 aa_put_ns(ns);
832 } else
833 label = aa_get_current_label();
834
835 if (sock->sk) {
836 struct aa_sk_ctx *ctx = SK_CTX(sock->sk);
837
838 aa_put_label(ctx->label);
839 ctx->label = aa_get_label(label);
840 }
841 aa_put_label(label);
842
843 return 0;
844}
845
846/**
847 * apparmor_socket_bind - check perms before bind addr to socket
848 */
849static int apparmor_socket_bind(struct socket *sock,
850 struct sockaddr *address, int addrlen)
851{
852 AA_BUG(!sock);
853 AA_BUG(!sock->sk);
854 AA_BUG(!address);
855 AA_BUG(in_interrupt());
856
857 return aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk);
858}
859
860/**
861 * apparmor_socket_connect - check perms before connecting @sock to @address
862 */
863static int apparmor_socket_connect(struct socket *sock,
864 struct sockaddr *address, int addrlen)
865{
866 AA_BUG(!sock);
867 AA_BUG(!sock->sk);
868 AA_BUG(!address);
869 AA_BUG(in_interrupt());
870
871 return aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk);
872}
873
874/**
875 * apparmor_socket_list - check perms before allowing listen
876 */
877static int apparmor_socket_listen(struct socket *sock, int backlog)
878{
879 AA_BUG(!sock);
880 AA_BUG(!sock->sk);
881 AA_BUG(in_interrupt());
882
883 return aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk);
884}
885
886/**
887 * apparmor_socket_accept - check perms before accepting a new connection.
888 *
889 * Note: while @newsock is created and has some information, the accept
890 * has not been done.
891 */
892static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
893{
894 AA_BUG(!sock);
895 AA_BUG(!sock->sk);
896 AA_BUG(!newsock);
897 AA_BUG(in_interrupt());
898
899 return aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk);
900}
901
902static int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
903 struct msghdr *msg, int size)
904{
905 AA_BUG(!sock);
906 AA_BUG(!sock->sk);
907 AA_BUG(!msg);
908 AA_BUG(in_interrupt());
909
910 return aa_sk_perm(op, request, sock->sk);
911}
912
913/**
914 * apparmor_socket_sendmsg - check perms before sending msg to another socket
915 */
916static int apparmor_socket_sendmsg(struct socket *sock,
917 struct msghdr *msg, int size)
918{
919 return aa_sock_msg_perm(OP_SENDMSG, AA_MAY_SEND, sock, msg, size);
920}
921
922/**
923 * apparmor_socket_recvmsg - check perms before receiving a message
924 */
925static int apparmor_socket_recvmsg(struct socket *sock,
926 struct msghdr *msg, int size, int flags)
927{
928 return aa_sock_msg_perm(OP_RECVMSG, AA_MAY_RECEIVE, sock, msg, size);
929}
930
931/* revaliation, get/set attr, shutdown */
932static int aa_sock_perm(const char *op, u32 request, struct socket *sock)
933{
934 AA_BUG(!sock);
935 AA_BUG(!sock->sk);
936 AA_BUG(in_interrupt());
937
938 return aa_sk_perm(op, request, sock->sk);
939}
940
941/**
942 * apparmor_socket_getsockname - check perms before getting the local address
943 */
944static int apparmor_socket_getsockname(struct socket *sock)
945{
946 return aa_sock_perm(OP_GETSOCKNAME, AA_MAY_GETATTR, sock);
947}
948
949/**
950 * apparmor_socket_getpeername - check perms before getting remote address
951 */
952static int apparmor_socket_getpeername(struct socket *sock)
953{
954 return aa_sock_perm(OP_GETPEERNAME, AA_MAY_GETATTR, sock);
955}
956
957/* revaliation, get/set attr, opt */
958static int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock,
959 int level, int optname)
960{
961 AA_BUG(!sock);
962 AA_BUG(!sock->sk);
963 AA_BUG(in_interrupt());
964
965 return aa_sk_perm(op, request, sock->sk);
966}
967
968/**
969 * apparmor_getsockopt - check perms before getting socket options
970 */
971static int apparmor_socket_getsockopt(struct socket *sock, int level,
972 int optname)
973{
974 return aa_sock_opt_perm(OP_GETSOCKOPT, AA_MAY_GETOPT, sock,
975 level, optname);
976}
977
978/**
979 * apparmor_setsockopt - check perms before setting socket options
980 */
981static int apparmor_socket_setsockopt(struct socket *sock, int level,
982 int optname)
983{
984 return aa_sock_opt_perm(OP_SETSOCKOPT, AA_MAY_SETOPT, sock,
985 level, optname);
986}
987
988/**
989 * apparmor_socket_shutdown - check perms before shutting down @sock conn
990 */
991static int apparmor_socket_shutdown(struct socket *sock, int how)
992{
993 return aa_sock_perm(OP_SHUTDOWN, AA_MAY_SHUTDOWN, sock);
994}
995
996/**
997 * apparmor_socket_sock_recv_skb - check perms before associating skb to sk
998 *
999 * Note: can not sleep may be called with locks held
1000 *
1001 * dont want protocol specific in __skb_recv_datagram()
1002 * to deny an incoming connection socket_sock_rcv_skb()
1003 */
1004static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
1005{
1006 return 0;
1007}
1008
1009
1010static struct aa_label *sk_peer_label(struct sock *sk)
1011{
1012 struct aa_sk_ctx *ctx = SK_CTX(sk);
1013
1014 if (ctx->peer)
1015 return ctx->peer;
1016
1017 return ERR_PTR(-ENOPROTOOPT);
1018}
1019
1020/**
1021 * apparmor_socket_getpeersec_stream - get security context of peer
1022 *
1023 * Note: for tcp only valid if using ipsec or cipso on lan
1024 */
1025static int apparmor_socket_getpeersec_stream(struct socket *sock,
1026 char __user *optval,
1027 int __user *optlen,
1028 unsigned int len)
1029{
1030 char *name;
1031 int slen, error = 0;
1032 struct aa_label *label;
1033 struct aa_label *peer;
1034
1035 label = begin_current_label_crit_section();
1036 peer = sk_peer_label(sock->sk);
1037 if (IS_ERR(peer)) {
1038 error = PTR_ERR(peer);
1039 goto done;
1040 }
1041 slen = aa_label_asxprint(&name, labels_ns(label), peer,
1042 FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
1043 FLAG_HIDDEN_UNCONFINED, GFP_KERNEL);
1044 /* don't include terminating \0 in slen, it breaks some apps */
1045 if (slen < 0) {
1046 error = -ENOMEM;
1047 } else {
1048 if (slen > len) {
1049 error = -ERANGE;
1050 } else if (copy_to_user(optval, name, slen)) {
1051 error = -EFAULT;
1052 goto out;
1053 }
1054 if (put_user(slen, optlen))
1055 error = -EFAULT;
1056out:
1057 kfree(name);
1058
1059 }
1060
1061done:
1062 end_current_label_crit_section(label);
1063
1064 return error;
1065}
1066
1067/**
1068 * apparmor_socket_getpeersec_dgram - get security label of packet
1069 * @sock: the peer socket
1070 * @skb: packet data
1071 * @secid: pointer to where to put the secid of the packet
1072 *
1073 * Sets the netlabel socket state on sk from parent
1074 */
1075static int apparmor_socket_getpeersec_dgram(struct socket *sock,
1076 struct sk_buff *skb, u32 *secid)
1077
1078{
1079 /* TODO: requires secid support */
1080 return -ENOPROTOOPT;
1081}
1082
1083/**
1084 * apparmor_sock_graft - Initialize newly created socket
1085 * @sk: child sock
1086 * @parent: parent socket
1087 *
1088 * Note: could set off of SOCK_CTX(parent) but need to track inode and we can
1089 * just set sk security information off of current creating process label
1090 * Labeling of sk for accept case - probably should be sock based
1091 * instead of task, because of the case where an implicitly labeled
1092 * socket is shared by different tasks.
1093 */
1094static void apparmor_sock_graft(struct sock *sk, struct socket *parent)
1095{
1096 struct aa_sk_ctx *ctx = SK_CTX(sk);
1097
1098 if (!ctx->label)
1099 ctx->label = aa_get_current_label();
1100}
1101
659static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { 1102static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
660 LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), 1103 LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
661 LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), 1104 LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
662 LSM_HOOK_INIT(capget, apparmor_capget), 1105 LSM_HOOK_INIT(capget, apparmor_capget),
663 LSM_HOOK_INIT(capable, apparmor_capable), 1106 LSM_HOOK_INIT(capable, apparmor_capable),
664 1107
1108 LSM_HOOK_INIT(sb_mount, apparmor_sb_mount),
1109 LSM_HOOK_INIT(sb_umount, apparmor_sb_umount),
1110 LSM_HOOK_INIT(sb_pivotroot, apparmor_sb_pivotroot),
1111
665 LSM_HOOK_INIT(path_link, apparmor_path_link), 1112 LSM_HOOK_INIT(path_link, apparmor_path_link),
666 LSM_HOOK_INIT(path_unlink, apparmor_path_unlink), 1113 LSM_HOOK_INIT(path_unlink, apparmor_path_unlink),
667 LSM_HOOK_INIT(path_symlink, apparmor_path_symlink), 1114 LSM_HOOK_INIT(path_symlink, apparmor_path_symlink),
@@ -686,6 +1133,30 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
686 LSM_HOOK_INIT(getprocattr, apparmor_getprocattr), 1133 LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
687 LSM_HOOK_INIT(setprocattr, apparmor_setprocattr), 1134 LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
688 1135
1136 LSM_HOOK_INIT(sk_alloc_security, apparmor_sk_alloc_security),
1137 LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security),
1138 LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security),
1139
1140 LSM_HOOK_INIT(socket_create, apparmor_socket_create),
1141 LSM_HOOK_INIT(socket_post_create, apparmor_socket_post_create),
1142 LSM_HOOK_INIT(socket_bind, apparmor_socket_bind),
1143 LSM_HOOK_INIT(socket_connect, apparmor_socket_connect),
1144 LSM_HOOK_INIT(socket_listen, apparmor_socket_listen),
1145 LSM_HOOK_INIT(socket_accept, apparmor_socket_accept),
1146 LSM_HOOK_INIT(socket_sendmsg, apparmor_socket_sendmsg),
1147 LSM_HOOK_INIT(socket_recvmsg, apparmor_socket_recvmsg),
1148 LSM_HOOK_INIT(socket_getsockname, apparmor_socket_getsockname),
1149 LSM_HOOK_INIT(socket_getpeername, apparmor_socket_getpeername),
1150 LSM_HOOK_INIT(socket_getsockopt, apparmor_socket_getsockopt),
1151 LSM_HOOK_INIT(socket_setsockopt, apparmor_socket_setsockopt),
1152 LSM_HOOK_INIT(socket_shutdown, apparmor_socket_shutdown),
1153 LSM_HOOK_INIT(socket_sock_rcv_skb, apparmor_socket_sock_rcv_skb),
1154 LSM_HOOK_INIT(socket_getpeersec_stream,
1155 apparmor_socket_getpeersec_stream),
1156 LSM_HOOK_INIT(socket_getpeersec_dgram,
1157 apparmor_socket_getpeersec_dgram),
1158 LSM_HOOK_INIT(sock_graft, apparmor_sock_graft),
1159
689 LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank), 1160 LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank),
690 LSM_HOOK_INIT(cred_free, apparmor_cred_free), 1161 LSM_HOOK_INIT(cred_free, apparmor_cred_free),
691 LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare), 1162 LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare),
@@ -696,6 +1167,7 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
696 LSM_HOOK_INIT(bprm_committed_creds, apparmor_bprm_committed_creds), 1167 LSM_HOOK_INIT(bprm_committed_creds, apparmor_bprm_committed_creds),
697 1168
698 LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit), 1169 LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit),
1170 LSM_HOOK_INIT(task_kill, apparmor_task_kill),
699}; 1171};
700 1172
701/* 1173/*
diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
new file mode 100644
index 000000000000..82a64b58041d
--- /dev/null
+++ b/security/apparmor/mount.c
@@ -0,0 +1,696 @@
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor mediation of files
5 *
6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2017 Canonical Ltd.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2 of the
12 * License.
13 */
14
15#include <linux/fs.h>
16#include <linux/mount.h>
17#include <linux/namei.h>
18
19#include "include/apparmor.h"
20#include "include/audit.h"
21#include "include/context.h"
22#include "include/domain.h"
23#include "include/file.h"
24#include "include/match.h"
25#include "include/mount.h"
26#include "include/path.h"
27#include "include/policy.h"
28
29
30static void audit_mnt_flags(struct audit_buffer *ab, unsigned long flags)
31{
32 if (flags & MS_RDONLY)
33 audit_log_format(ab, "ro");
34 else
35 audit_log_format(ab, "rw");
36 if (flags & MS_NOSUID)
37 audit_log_format(ab, ", nosuid");
38 if (flags & MS_NODEV)
39 audit_log_format(ab, ", nodev");
40 if (flags & MS_NOEXEC)
41 audit_log_format(ab, ", noexec");
42 if (flags & MS_SYNCHRONOUS)
43 audit_log_format(ab, ", sync");
44 if (flags & MS_REMOUNT)
45 audit_log_format(ab, ", remount");
46 if (flags & MS_MANDLOCK)
47 audit_log_format(ab, ", mand");
48 if (flags & MS_DIRSYNC)
49 audit_log_format(ab, ", dirsync");
50 if (flags & MS_NOATIME)
51 audit_log_format(ab, ", noatime");
52 if (flags & MS_NODIRATIME)
53 audit_log_format(ab, ", nodiratime");
54 if (flags & MS_BIND)
55 audit_log_format(ab, flags & MS_REC ? ", rbind" : ", bind");
56 if (flags & MS_MOVE)
57 audit_log_format(ab, ", move");
58 if (flags & MS_SILENT)
59 audit_log_format(ab, ", silent");
60 if (flags & MS_POSIXACL)
61 audit_log_format(ab, ", acl");
62 if (flags & MS_UNBINDABLE)
63 audit_log_format(ab, flags & MS_REC ? ", runbindable" :
64 ", unbindable");
65 if (flags & MS_PRIVATE)
66 audit_log_format(ab, flags & MS_REC ? ", rprivate" :
67 ", private");
68 if (flags & MS_SLAVE)
69 audit_log_format(ab, flags & MS_REC ? ", rslave" :
70 ", slave");
71 if (flags & MS_SHARED)
72 audit_log_format(ab, flags & MS_REC ? ", rshared" :
73 ", shared");
74 if (flags & MS_RELATIME)
75 audit_log_format(ab, ", relatime");
76 if (flags & MS_I_VERSION)
77 audit_log_format(ab, ", iversion");
78 if (flags & MS_STRICTATIME)
79 audit_log_format(ab, ", strictatime");
80 if (flags & MS_NOUSER)
81 audit_log_format(ab, ", nouser");
82}
83
84/**
85 * audit_cb - call back for mount specific audit fields
86 * @ab: audit_buffer (NOT NULL)
87 * @va: audit struct to audit values of (NOT NULL)
88 */
89static void audit_cb(struct audit_buffer *ab, void *va)
90{
91 struct common_audit_data *sa = va;
92
93 if (aad(sa)->mnt.type) {
94 audit_log_format(ab, " fstype=");
95 audit_log_untrustedstring(ab, aad(sa)->mnt.type);
96 }
97 if (aad(sa)->mnt.src_name) {
98 audit_log_format(ab, " srcname=");
99 audit_log_untrustedstring(ab, aad(sa)->mnt.src_name);
100 }
101 if (aad(sa)->mnt.trans) {
102 audit_log_format(ab, " trans=");
103 audit_log_untrustedstring(ab, aad(sa)->mnt.trans);
104 }
105 if (aad(sa)->mnt.flags) {
106 audit_log_format(ab, " flags=\"");
107 audit_mnt_flags(ab, aad(sa)->mnt.flags);
108 audit_log_format(ab, "\"");
109 }
110 if (aad(sa)->mnt.data) {
111 audit_log_format(ab, " options=");
112 audit_log_untrustedstring(ab, aad(sa)->mnt.data);
113 }
114}
115
116/**
117 * audit_mount - handle the auditing of mount operations
118 * @profile: the profile being enforced (NOT NULL)
119 * @op: operation being mediated (NOT NULL)
120 * @name: name of object being mediated (MAYBE NULL)
121 * @src_name: src_name of object being mediated (MAYBE_NULL)
122 * @type: type of filesystem (MAYBE_NULL)
123 * @trans: name of trans (MAYBE NULL)
124 * @flags: filesystem idependent mount flags
125 * @data: filesystem mount flags
126 * @request: permissions requested
127 * @perms: the permissions computed for the request (NOT NULL)
128 * @info: extra information message (MAYBE NULL)
129 * @error: 0 if operation allowed else failure error code
130 *
131 * Returns: %0 or error on failure
132 */
133static int audit_mount(struct aa_profile *profile, const char *op,
134 const char *name, const char *src_name,
135 const char *type, const char *trans,
136 unsigned long flags, const void *data, u32 request,
137 struct aa_perms *perms, const char *info, int error)
138{
139 int audit_type = AUDIT_APPARMOR_AUTO;
140 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, op);
141
142 if (likely(!error)) {
143 u32 mask = perms->audit;
144
145 if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
146 mask = 0xffff;
147
148 /* mask off perms that are not being force audited */
149 request &= mask;
150
151 if (likely(!request))
152 return 0;
153 audit_type = AUDIT_APPARMOR_AUDIT;
154 } else {
155 /* only report permissions that were denied */
156 request = request & ~perms->allow;
157
158 if (request & perms->kill)
159 audit_type = AUDIT_APPARMOR_KILL;
160
161 /* quiet known rejects, assumes quiet and kill do not overlap */
162 if ((request & perms->quiet) &&
163 AUDIT_MODE(profile) != AUDIT_NOQUIET &&
164 AUDIT_MODE(profile) != AUDIT_ALL)
165 request &= ~perms->quiet;
166
167 if (!request)
168 return error;
169 }
170
171 aad(&sa)->name = name;
172 aad(&sa)->mnt.src_name = src_name;
173 aad(&sa)->mnt.type = type;
174 aad(&sa)->mnt.trans = trans;
175 aad(&sa)->mnt.flags = flags;
176 if (data && (perms->audit & AA_AUDIT_DATA))
177 aad(&sa)->mnt.data = data;
178 aad(&sa)->info = info;
179 aad(&sa)->error = error;
180
181 return aa_audit(audit_type, profile, &sa, audit_cb);
182}
183
184/**
185 * match_mnt_flags - Do an ordered match on mount flags
186 * @dfa: dfa to match against
187 * @state: state to start in
188 * @flags: mount flags to match against
189 *
190 * Mount flags are encoded as an ordered match. This is done instead of
191 * checking against a simple bitmask, to allow for logical operations
192 * on the flags.
193 *
194 * Returns: next state after flags match
195 */
196static unsigned int match_mnt_flags(struct aa_dfa *dfa, unsigned int state,
197 unsigned long flags)
198{
199 unsigned int i;
200
201 for (i = 0; i <= 31 ; ++i) {
202 if ((1 << i) & flags)
203 state = aa_dfa_next(dfa, state, i + 1);
204 }
205
206 return state;
207}
208
209/**
210 * compute_mnt_perms - compute mount permission associated with @state
211 * @dfa: dfa to match against (NOT NULL)
212 * @state: state match finished in
213 *
214 * Returns: mount permissions
215 */
216static struct aa_perms compute_mnt_perms(struct aa_dfa *dfa,
217 unsigned int state)
218{
219 struct aa_perms perms;
220
221 perms.kill = 0;
222 perms.allow = dfa_user_allow(dfa, state);
223 perms.audit = dfa_user_audit(dfa, state);
224 perms.quiet = dfa_user_quiet(dfa, state);
225 perms.xindex = dfa_user_xindex(dfa, state);
226
227 return perms;
228}
229
230static const char * const mnt_info_table[] = {
231 "match succeeded",
232 "failed mntpnt match",
233 "failed srcname match",
234 "failed type match",
235 "failed flags match",
236 "failed data match"
237};
238
239/*
240 * Returns 0 on success else element that match failed in, this is the
241 * index into the mnt_info_table above
242 */
243static int do_match_mnt(struct aa_dfa *dfa, unsigned int start,
244 const char *mntpnt, const char *devname,
245 const char *type, unsigned long flags,
246 void *data, bool binary, struct aa_perms *perms)
247{
248 unsigned int state;
249
250 AA_BUG(!dfa);
251 AA_BUG(!perms);
252
253 state = aa_dfa_match(dfa, start, mntpnt);
254 state = aa_dfa_null_transition(dfa, state);
255 if (!state)
256 return 1;
257
258 if (devname)
259 state = aa_dfa_match(dfa, state, devname);
260 state = aa_dfa_null_transition(dfa, state);
261 if (!state)
262 return 2;
263
264 if (type)
265 state = aa_dfa_match(dfa, state, type);
266 state = aa_dfa_null_transition(dfa, state);
267 if (!state)
268 return 3;
269
270 state = match_mnt_flags(dfa, state, flags);
271 if (!state)
272 return 4;
273 *perms = compute_mnt_perms(dfa, state);
274 if (perms->allow & AA_MAY_MOUNT)
275 return 0;
276
277 /* only match data if not binary and the DFA flags data is expected */
278 if (data && !binary && (perms->allow & AA_MNT_CONT_MATCH)) {
279 state = aa_dfa_null_transition(dfa, state);
280 if (!state)
281 return 4;
282
283 state = aa_dfa_match(dfa, state, data);
284 if (!state)
285 return 5;
286 *perms = compute_mnt_perms(dfa, state);
287 if (perms->allow & AA_MAY_MOUNT)
288 return 0;
289 }
290
291 /* failed at end of flags match */
292 return 4;
293}
294
295
296static int path_flags(struct aa_profile *profile, const struct path *path)
297{
298 AA_BUG(!profile);
299 AA_BUG(!path);
300
301 return profile->path_flags |
302 (S_ISDIR(path->dentry->d_inode->i_mode) ? PATH_IS_DIR : 0);
303}
304
305/**
306 * match_mnt_path_str - handle path matching for mount
307 * @profile: the confining profile
308 * @mntpath: for the mntpnt (NOT NULL)
309 * @buffer: buffer to be used to lookup mntpath
310 * @devnme: string for the devname/src_name (MAY BE NULL OR ERRPTR)
311 * @type: string for the dev type (MAYBE NULL)
312 * @flags: mount flags to match
313 * @data: fs mount data (MAYBE NULL)
314 * @binary: whether @data is binary
315 * @devinfo: error str if (IS_ERR(@devname))
316 *
317 * Returns: 0 on success else error
318 */
319static int match_mnt_path_str(struct aa_profile *profile,
320 const struct path *mntpath, char *buffer,
321 const char *devname, const char *type,
322 unsigned long flags, void *data, bool binary,
323 const char *devinfo)
324{
325 struct aa_perms perms = { };
326 const char *mntpnt = NULL, *info = NULL;
327 int pos, error;
328
329 AA_BUG(!profile);
330 AA_BUG(!mntpath);
331 AA_BUG(!buffer);
332
333 error = aa_path_name(mntpath, path_flags(profile, mntpath), buffer,
334 &mntpnt, &info, profile->disconnected);
335 if (error)
336 goto audit;
337 if (IS_ERR(devname)) {
338 error = PTR_ERR(devname);
339 devname = NULL;
340 info = devinfo;
341 goto audit;
342 }
343
344 error = -EACCES;
345 pos = do_match_mnt(profile->policy.dfa,
346 profile->policy.start[AA_CLASS_MOUNT],
347 mntpnt, devname, type, flags, data, binary, &perms);
348 if (pos) {
349 info = mnt_info_table[pos];
350 goto audit;
351 }
352 error = 0;
353
354audit:
355 return audit_mount(profile, OP_MOUNT, mntpnt, devname, type, NULL,
356 flags, data, AA_MAY_MOUNT, &perms, info, error);
357}
358
359/**
360 * match_mnt - handle path matching for mount
361 * @profile: the confining profile
362 * @mntpath: for the mntpnt (NOT NULL)
363 * @buffer: buffer to be used to lookup mntpath
364 * @devpath: path devname/src_name (MAYBE NULL)
365 * @devbuffer: buffer to be used to lookup devname/src_name
366 * @type: string for the dev type (MAYBE NULL)
367 * @flags: mount flags to match
368 * @data: fs mount data (MAYBE NULL)
369 * @binary: whether @data is binary
370 *
371 * Returns: 0 on success else error
372 */
373static int match_mnt(struct aa_profile *profile, const struct path *path,
374 char *buffer, struct path *devpath, char *devbuffer,
375 const char *type, unsigned long flags, void *data,
376 bool binary)
377{
378 const char *devname = NULL, *info = NULL;
379 int error = -EACCES;
380
381 AA_BUG(!profile);
382 AA_BUG(devpath && !devbuffer);
383
384 if (devpath) {
385 error = aa_path_name(devpath, path_flags(profile, devpath),
386 devbuffer, &devname, &info,
387 profile->disconnected);
388 if (error)
389 devname = ERR_PTR(error);
390 }
391
392 return match_mnt_path_str(profile, path, buffer, devname, type, flags,
393 data, binary, info);
394}
395
396int aa_remount(struct aa_label *label, const struct path *path,
397 unsigned long flags, void *data)
398{
399 struct aa_profile *profile;
400 char *buffer = NULL;
401 bool binary;
402 int error;
403
404 AA_BUG(!label);
405 AA_BUG(!path);
406
407 binary = path->dentry->d_sb->s_type->fs_flags & FS_BINARY_MOUNTDATA;
408
409 get_buffers(buffer);
410 error = fn_for_each_confined(label, profile,
411 match_mnt(profile, path, buffer, NULL, NULL, NULL,
412 flags, data, binary));
413 put_buffers(buffer);
414
415 return error;
416}
417
418int aa_bind_mount(struct aa_label *label, const struct path *path,
419 const char *dev_name, unsigned long flags)
420{
421 struct aa_profile *profile;
422 char *buffer = NULL, *old_buffer = NULL;
423 struct path old_path;
424 int error;
425
426 AA_BUG(!label);
427 AA_BUG(!path);
428
429 if (!dev_name || !*dev_name)
430 return -EINVAL;
431
432 flags &= MS_REC | MS_BIND;
433
434 error = kern_path(dev_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
435 if (error)
436 return error;
437
438 get_buffers(buffer, old_buffer);
439 error = fn_for_each_confined(label, profile,
440 match_mnt(profile, path, buffer, &old_path, old_buffer,
441 NULL, flags, NULL, false));
442 put_buffers(buffer, old_buffer);
443 path_put(&old_path);
444
445 return error;
446}
447
448int aa_mount_change_type(struct aa_label *label, const struct path *path,
449 unsigned long flags)
450{
451 struct aa_profile *profile;
452 char *buffer = NULL;
453 int error;
454
455 AA_BUG(!label);
456 AA_BUG(!path);
457
458 /* These are the flags allowed by do_change_type() */
459 flags &= (MS_REC | MS_SILENT | MS_SHARED | MS_PRIVATE | MS_SLAVE |
460 MS_UNBINDABLE);
461
462 get_buffers(buffer);
463 error = fn_for_each_confined(label, profile,
464 match_mnt(profile, path, buffer, NULL, NULL, NULL,
465 flags, NULL, false));
466 put_buffers(buffer);
467
468 return error;
469}
470
471int aa_move_mount(struct aa_label *label, const struct path *path,
472 const char *orig_name)
473{
474 struct aa_profile *profile;
475 char *buffer = NULL, *old_buffer = NULL;
476 struct path old_path;
477 int error;
478
479 AA_BUG(!label);
480 AA_BUG(!path);
481
482 if (!orig_name || !*orig_name)
483 return -EINVAL;
484
485 error = kern_path(orig_name, LOOKUP_FOLLOW, &old_path);
486 if (error)
487 return error;
488
489 get_buffers(buffer, old_buffer);
490 error = fn_for_each_confined(label, profile,
491 match_mnt(profile, path, buffer, &old_path, old_buffer,
492 NULL, MS_MOVE, NULL, false));
493 put_buffers(buffer, old_buffer);
494 path_put(&old_path);
495
496 return error;
497}
498
499int aa_new_mount(struct aa_label *label, const char *dev_name,
500 const struct path *path, const char *type, unsigned long flags,
501 void *data)
502{
503 struct aa_profile *profile;
504 char *buffer = NULL, *dev_buffer = NULL;
505 bool binary = true;
506 int error;
507 int requires_dev = 0;
508 struct path tmp_path, *dev_path = NULL;
509
510 AA_BUG(!label);
511 AA_BUG(!path);
512
513 if (type) {
514 struct file_system_type *fstype;
515
516 fstype = get_fs_type(type);
517 if (!fstype)
518 return -ENODEV;
519 binary = fstype->fs_flags & FS_BINARY_MOUNTDATA;
520 requires_dev = fstype->fs_flags & FS_REQUIRES_DEV;
521 put_filesystem(fstype);
522
523 if (requires_dev) {
524 if (!dev_name || !*dev_name)
525 return -ENOENT;
526
527 error = kern_path(dev_name, LOOKUP_FOLLOW, &tmp_path);
528 if (error)
529 return error;
530 dev_path = &tmp_path;
531 }
532 }
533
534 get_buffers(buffer, dev_buffer);
535 if (dev_path) {
536 error = fn_for_each_confined(label, profile,
537 match_mnt(profile, path, buffer, dev_path, dev_buffer,
538 type, flags, data, binary));
539 } else {
540 error = fn_for_each_confined(label, profile,
541 match_mnt_path_str(profile, path, buffer, dev_name,
542 type, flags, data, binary, NULL));
543 }
544 put_buffers(buffer, dev_buffer);
545 if (dev_path)
546 path_put(dev_path);
547
548 return error;
549}
550
551static int profile_umount(struct aa_profile *profile, struct path *path,
552 char *buffer)
553{
554 struct aa_perms perms = { };
555 const char *name = NULL, *info = NULL;
556 unsigned int state;
557 int error;
558
559 AA_BUG(!profile);
560 AA_BUG(!path);
561
562 error = aa_path_name(path, path_flags(profile, path), buffer, &name,
563 &info, profile->disconnected);
564 if (error)
565 goto audit;
566
567 state = aa_dfa_match(profile->policy.dfa,
568 profile->policy.start[AA_CLASS_MOUNT],
569 name);
570 perms = compute_mnt_perms(profile->policy.dfa, state);
571 if (AA_MAY_UMOUNT & ~perms.allow)
572 error = -EACCES;
573
574audit:
575 return audit_mount(profile, OP_UMOUNT, name, NULL, NULL, NULL, 0, NULL,
576 AA_MAY_UMOUNT, &perms, info, error);
577}
578
579int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags)
580{
581 struct aa_profile *profile;
582 char *buffer = NULL;
583 int error;
584 struct path path = { .mnt = mnt, .dentry = mnt->mnt_root };
585
586 AA_BUG(!label);
587 AA_BUG(!mnt);
588
589 get_buffers(buffer);
590 error = fn_for_each_confined(label, profile,
591 profile_umount(profile, &path, buffer));
592 put_buffers(buffer);
593
594 return error;
595}
596
597/* helper fn for transition on pivotroot
598 *
599 * Returns: label for transition or ERR_PTR. Does not return NULL
600 */
601static struct aa_label *build_pivotroot(struct aa_profile *profile,
602 const struct path *new_path,
603 char *new_buffer,
604 const struct path *old_path,
605 char *old_buffer)
606{
607 const char *old_name, *new_name = NULL, *info = NULL;
608 const char *trans_name = NULL;
609 struct aa_perms perms = { };
610 unsigned int state;
611 int error;
612
613 AA_BUG(!profile);
614 AA_BUG(!new_path);
615 AA_BUG(!old_path);
616
617 if (profile_unconfined(profile))
618 return aa_get_newest_label(&profile->label);
619
620 error = aa_path_name(old_path, path_flags(profile, old_path),
621 old_buffer, &old_name, &info,
622 profile->disconnected);
623 if (error)
624 goto audit;
625 error = aa_path_name(new_path, path_flags(profile, new_path),
626 new_buffer, &new_name, &info,
627 profile->disconnected);
628 if (error)
629 goto audit;
630
631 error = -EACCES;
632 state = aa_dfa_match(profile->policy.dfa,
633 profile->policy.start[AA_CLASS_MOUNT],
634 new_name);
635 state = aa_dfa_null_transition(profile->policy.dfa, state);
636 state = aa_dfa_match(profile->policy.dfa, state, old_name);
637 perms = compute_mnt_perms(profile->policy.dfa, state);
638
639 if (AA_MAY_PIVOTROOT & perms.allow)
640 error = 0;
641
642audit:
643 error = audit_mount(profile, OP_PIVOTROOT, new_name, old_name,
644 NULL, trans_name, 0, NULL, AA_MAY_PIVOTROOT,
645 &perms, info, error);
646 if (error)
647 return ERR_PTR(error);
648
649 return aa_get_newest_label(&profile->label);
650}
651
652int aa_pivotroot(struct aa_label *label, const struct path *old_path,
653 const struct path *new_path)
654{
655 struct aa_profile *profile;
656 struct aa_label *target = NULL;
657 char *old_buffer = NULL, *new_buffer = NULL, *info = NULL;
658 int error;
659
660 AA_BUG(!label);
661 AA_BUG(!old_path);
662 AA_BUG(!new_path);
663
664 get_buffers(old_buffer, new_buffer);
665 target = fn_label_build(label, profile, GFP_ATOMIC,
666 build_pivotroot(profile, new_path, new_buffer,
667 old_path, old_buffer));
668 if (!target) {
669 info = "label build failed";
670 error = -ENOMEM;
671 goto fail;
672 } else if (!IS_ERR(target)) {
673 error = aa_replace_current_label(target);
674 if (error) {
675 /* TODO: audit target */
676 aa_put_label(target);
677 goto out;
678 }
679 } else
680 /* already audited error */
681 error = PTR_ERR(target);
682out:
683 put_buffers(old_buffer, new_buffer);
684
685 return error;
686
687fail:
688 /* TODO: add back in auditing of new_name and old_name */
689 error = fn_for_each(label, profile,
690 audit_mount(profile, OP_PIVOTROOT, NULL /*new_name */,
691 NULL /* old_name */,
692 NULL, NULL,
693 0, NULL, AA_MAY_PIVOTROOT, &nullperms, info,
694 error));
695 goto out;
696}
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
new file mode 100644
index 000000000000..33d54435f8d6
--- /dev/null
+++ b/security/apparmor/net.c
@@ -0,0 +1,184 @@
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor network mediation
5 *
6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2017 Canonical Ltd.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2 of the
12 * License.
13 */
14
15#include "include/apparmor.h"
16#include "include/audit.h"
17#include "include/context.h"
18#include "include/label.h"
19#include "include/net.h"
20#include "include/policy.h"
21
22#include "net_names.h"
23
24
25struct aa_sfs_entry aa_sfs_entry_network[] = {
26 AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK),
27 { }
28};
29
30static const char * const net_mask_names[] = {
31 "unknown",
32 "send",
33 "receive",
34 "unknown",
35
36 "create",
37 "shutdown",
38 "connect",
39 "unknown",
40
41 "setattr",
42 "getattr",
43 "setcred",
44 "getcred",
45
46 "chmod",
47 "chown",
48 "chgrp",
49 "lock",
50
51 "mmap",
52 "mprot",
53 "unknown",
54 "unknown",
55
56 "accept",
57 "bind",
58 "listen",
59 "unknown",
60
61 "setopt",
62 "getopt",
63 "unknown",
64 "unknown",
65
66 "unknown",
67 "unknown",
68 "unknown",
69 "unknown",
70};
71
72
73/* audit callback for net specific fields */
74void audit_net_cb(struct audit_buffer *ab, void *va)
75{
76 struct common_audit_data *sa = va;
77
78 audit_log_format(ab, " family=");
79 if (address_family_names[sa->u.net->family])
80 audit_log_string(ab, address_family_names[sa->u.net->family]);
81 else
82 audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
83 audit_log_format(ab, " sock_type=");
84 if (sock_type_names[aad(sa)->net.type])
85 audit_log_string(ab, sock_type_names[aad(sa)->net.type]);
86 else
87 audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type);
88 audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol);
89
90 if (aad(sa)->request & NET_PERMS_MASK) {
91 audit_log_format(ab, " requested_mask=");
92 aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0,
93 net_mask_names, NET_PERMS_MASK);
94
95 if (aad(sa)->denied & NET_PERMS_MASK) {
96 audit_log_format(ab, " denied_mask=");
97 aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0,
98 net_mask_names, NET_PERMS_MASK);
99 }
100 }
101 if (aad(sa)->peer) {
102 audit_log_format(ab, " peer=");
103 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
104 FLAGS_NONE, GFP_ATOMIC);
105 }
106}
107
108
109/* Generic af perm */
110int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
111 u32 request, u16 family, int type)
112{
113 struct aa_perms perms = { };
114
115 AA_BUG(family >= AF_MAX);
116 AA_BUG(type < 0 || type >= SOCK_MAX);
117
118 if (profile_unconfined(profile))
119 return 0;
120
121 perms.allow = (profile->net.allow[family] & (1 << type)) ?
122 ALL_PERMS_MASK : 0;
123 perms.audit = (profile->net.audit[family] & (1 << type)) ?
124 ALL_PERMS_MASK : 0;
125 perms.quiet = (profile->net.quiet[family] & (1 << type)) ?
126 ALL_PERMS_MASK : 0;
127 aa_apply_modes_to_perms(profile, &perms);
128
129 return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
130}
131
132int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
133 int type, int protocol)
134{
135 struct aa_profile *profile;
136 DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol);
137
138 return fn_for_each_confined(label, profile,
139 aa_profile_af_perm(profile, &sa, request, family,
140 type));
141}
142
143static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
144 struct sock *sk)
145{
146 struct aa_profile *profile;
147 DEFINE_AUDIT_SK(sa, op, sk);
148
149 AA_BUG(!label);
150 AA_BUG(!sk);
151
152 if (unconfined(label))
153 return 0;
154
155 return fn_for_each_confined(label, profile,
156 aa_profile_af_sk_perm(profile, &sa, request, sk));
157}
158
159int aa_sk_perm(const char *op, u32 request, struct sock *sk)
160{
161 struct aa_label *label;
162 int error;
163
164 AA_BUG(!sk);
165 AA_BUG(in_interrupt());
166
167 /* TODO: switch to begin_current_label ???? */
168 label = begin_current_label_crit_section();
169 error = aa_label_sk_perm(label, op, request, sk);
170 end_current_label_crit_section(label);
171
172 return error;
173}
174
175
176int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
177 struct socket *sock)
178{
179 AA_BUG(!label);
180 AA_BUG(!sock);
181 AA_BUG(!sock->sk);
182
183 return aa_label_sk_perm(label, op, request, sock->sk);
184}
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 244ea4a4a8f0..4243b0c3f0e4 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -289,85 +289,6 @@ fail:
289 return NULL; 289 return NULL;
290} 290}
291 291
292/**
293 * aa_new_null_profile - create or find a null-X learning profile
294 * @parent: profile that caused this profile to be created (NOT NULL)
295 * @hat: true if the null- learning profile is a hat
296 * @base: name to base the null profile off of
297 * @gfp: type of allocation
298 *
299 * Find/Create a null- complain mode profile used in learning mode. The
300 * name of the profile is unique and follows the format of parent//null-XXX.
301 * where XXX is based on the @name or if that fails or is not supplied
302 * a unique number
303 *
304 * null profiles are added to the profile list but the list does not
305 * hold a count on them so that they are automatically released when
306 * not in use.
307 *
308 * Returns: new refcounted profile else NULL on failure
309 */
310struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
311 const char *base, gfp_t gfp)
312{
313 struct aa_profile *profile;
314 char *name;
315
316 AA_BUG(!parent);
317
318 if (base) {
319 name = kmalloc(strlen(parent->base.hname) + 8 + strlen(base),
320 gfp);
321 if (name) {
322 sprintf(name, "%s//null-%s", parent->base.hname, base);
323 goto name;
324 }
325 /* fall through to try shorter uniq */
326 }
327
328 name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, gfp);
329 if (!name)
330 return NULL;
331 sprintf(name, "%s//null-%x", parent->base.hname,
332 atomic_inc_return(&parent->ns->uniq_null));
333
334name:
335 /* lookup to see if this is a dup creation */
336 profile = aa_find_child(parent, basename(name));
337 if (profile)
338 goto out;
339
340 profile = aa_alloc_profile(name, NULL, gfp);
341 if (!profile)
342 goto fail;
343
344 profile->mode = APPARMOR_COMPLAIN;
345 profile->label.flags |= FLAG_NULL;
346 if (hat)
347 profile->label.flags |= FLAG_HAT;
348 profile->path_flags = parent->path_flags;
349
350 /* released on free_profile */
351 rcu_assign_pointer(profile->parent, aa_get_profile(parent));
352 profile->ns = aa_get_ns(parent->ns);
353 profile->file.dfa = aa_get_dfa(nulldfa);
354 profile->policy.dfa = aa_get_dfa(nulldfa);
355
356 mutex_lock(&profile->ns->lock);
357 __add_profile(&parent->base.profiles, profile);
358 mutex_unlock(&profile->ns->lock);
359
360 /* refcount released by caller */
361out:
362 kfree(name);
363
364 return profile;
365
366fail:
367 aa_free_profile(profile);
368 return NULL;
369}
370
371/* TODO: profile accounting - setup in remove */ 292/* TODO: profile accounting - setup in remove */
372 293
373/** 294/**
@@ -559,6 +480,93 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
559} 480}
560 481
561/** 482/**
483 * aa_new_null_profile - create or find a null-X learning profile
484 * @parent: profile that caused this profile to be created (NOT NULL)
485 * @hat: true if the null- learning profile is a hat
486 * @base: name to base the null profile off of
487 * @gfp: type of allocation
488 *
489 * Find/Create a null- complain mode profile used in learning mode. The
490 * name of the profile is unique and follows the format of parent//null-XXX.
491 * where XXX is based on the @name or if that fails or is not supplied
492 * a unique number
493 *
494 * null profiles are added to the profile list but the list does not
495 * hold a count on them so that they are automatically released when
496 * not in use.
497 *
498 * Returns: new refcounted profile else NULL on failure
499 */
500struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
501 const char *base, gfp_t gfp)
502{
503 struct aa_profile *p, *profile;
504 const char *bname;
505 char *name;
506
507 AA_BUG(!parent);
508
509 if (base) {
510 name = kmalloc(strlen(parent->base.hname) + 8 + strlen(base),
511 gfp);
512 if (name) {
513 sprintf(name, "%s//null-%s", parent->base.hname, base);
514 goto name;
515 }
516 /* fall through to try shorter uniq */
517 }
518
519 name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, gfp);
520 if (!name)
521 return NULL;
522 sprintf(name, "%s//null-%x", parent->base.hname,
523 atomic_inc_return(&parent->ns->uniq_null));
524
525name:
526 /* lookup to see if this is a dup creation */
527 bname = basename(name);
528 profile = aa_find_child(parent, bname);
529 if (profile)
530 goto out;
531
532 profile = aa_alloc_profile(name, NULL, gfp);
533 if (!profile)
534 goto fail;
535
536 profile->mode = APPARMOR_COMPLAIN;
537 profile->label.flags |= FLAG_NULL;
538 if (hat)
539 profile->label.flags |= FLAG_HAT;
540 profile->path_flags = parent->path_flags;
541
542 /* released on free_profile */
543 rcu_assign_pointer(profile->parent, aa_get_profile(parent));
544 profile->ns = aa_get_ns(parent->ns);
545 profile->file.dfa = aa_get_dfa(nulldfa);
546 profile->policy.dfa = aa_get_dfa(nulldfa);
547
548 mutex_lock(&profile->ns->lock);
549 p = __find_child(&parent->base.profiles, bname);
550 if (p) {
551 aa_free_profile(profile);
552 profile = aa_get_profile(p);
553 } else {
554 __add_profile(&parent->base.profiles, profile);
555 }
556 mutex_unlock(&profile->ns->lock);
557
558 /* refcount released by caller */
559out:
560 kfree(name);
561
562 return profile;
563
564fail:
565 aa_free_profile(profile);
566 return NULL;
567}
568
569/**
562 * replacement_allowed - test to see if replacement is allowed 570 * replacement_allowed - test to see if replacement is allowed
563 * @profile: profile to test if it can be replaced (MAYBE NULL) 571 * @profile: profile to test if it can be replaced (MAYBE NULL)
564 * @noreplace: true if replacement shouldn't be allowed but addition is okay 572 * @noreplace: true if replacement shouldn't be allowed but addition is okay
diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
index 351d3bab3a3d..62a3589c62ab 100644
--- a/security/apparmor/policy_ns.c
+++ b/security/apparmor/policy_ns.c
@@ -112,6 +112,8 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
112 ns->unconfined->label.flags |= FLAG_IX_ON_NAME_ERROR | 112 ns->unconfined->label.flags |= FLAG_IX_ON_NAME_ERROR |
113 FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED; 113 FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED;
114 ns->unconfined->mode = APPARMOR_UNCONFINED; 114 ns->unconfined->mode = APPARMOR_UNCONFINED;
115 ns->unconfined->file.dfa = aa_get_dfa(nulldfa);
116 ns->unconfined->policy.dfa = aa_get_dfa(nulldfa);
115 117
116 /* ns and ns->unconfined share ns->unconfined refcount */ 118 /* ns and ns->unconfined share ns->unconfined refcount */
117 ns->unconfined->ns = ns; 119 ns->unconfined->ns = ns;
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index c600f4dd1783..5a2aec358322 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -85,9 +85,9 @@ static void audit_cb(struct audit_buffer *ab, void *va)
85 audit_log_format(ab, " ns="); 85 audit_log_format(ab, " ns=");
86 audit_log_untrustedstring(ab, aad(sa)->iface.ns); 86 audit_log_untrustedstring(ab, aad(sa)->iface.ns);
87 } 87 }
88 if (aad(sa)->iface.name) { 88 if (aad(sa)->name) {
89 audit_log_format(ab, " name="); 89 audit_log_format(ab, " name=");
90 audit_log_untrustedstring(ab, aad(sa)->iface.name); 90 audit_log_untrustedstring(ab, aad(sa)->name);
91 } 91 }
92 if (aad(sa)->iface.pos) 92 if (aad(sa)->iface.pos)
93 audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos); 93 audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos);
@@ -114,9 +114,9 @@ static int audit_iface(struct aa_profile *new, const char *ns_name,
114 aad(&sa)->iface.pos = e->pos - e->start; 114 aad(&sa)->iface.pos = e->pos - e->start;
115 aad(&sa)->iface.ns = ns_name; 115 aad(&sa)->iface.ns = ns_name;
116 if (new) 116 if (new)
117 aad(&sa)->iface.name = new->base.hname; 117 aad(&sa)->name = new->base.hname;
118 else 118 else
119 aad(&sa)->iface.name = name; 119 aad(&sa)->name = name;
120 aad(&sa)->info = info; 120 aad(&sa)->info = info;
121 aad(&sa)->error = error; 121 aad(&sa)->error = error;
122 122
@@ -275,6 +275,19 @@ fail:
275 return 0; 275 return 0;
276} 276}
277 277
278static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
279{
280 if (unpack_nameX(e, AA_U16, name)) {
281 if (!inbounds(e, sizeof(u16)))
282 return 0;
283 if (data)
284 *data = le16_to_cpu(get_unaligned((__le16 *) e->pos));
285 e->pos += sizeof(u16);
286 return 1;
287 }
288 return 0;
289}
290
278static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) 291static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
279{ 292{
280 if (unpack_nameX(e, AA_U32, name)) { 293 if (unpack_nameX(e, AA_U32, name)) {
@@ -448,7 +461,7 @@ fail:
448 */ 461 */
449static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile) 462static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
450{ 463{
451 void *pos = e->pos; 464 void *saved_pos = e->pos;
452 465
453 /* exec table is optional */ 466 /* exec table is optional */
454 if (unpack_nameX(e, AA_STRUCT, "xtable")) { 467 if (unpack_nameX(e, AA_STRUCT, "xtable")) {
@@ -511,7 +524,7 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
511 524
512fail: 525fail:
513 aa_free_domain_entries(&profile->file.trans); 526 aa_free_domain_entries(&profile->file.trans);
514 e->pos = pos; 527 e->pos = saved_pos;
515 return 0; 528 return 0;
516} 529}
517 530
@@ -583,7 +596,8 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
583{ 596{
584 struct aa_profile *profile = NULL; 597 struct aa_profile *profile = NULL;
585 const char *tmpname, *tmpns = NULL, *name = NULL; 598 const char *tmpname, *tmpns = NULL, *name = NULL;
586 size_t ns_len; 599 const char *info = "failed to unpack profile";
600 size_t size = 0, ns_len;
587 struct rhashtable_params params = { 0 }; 601 struct rhashtable_params params = { 0 };
588 char *key = NULL; 602 char *key = NULL;
589 struct aa_data *data; 603 struct aa_data *data;
@@ -604,8 +618,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
604 tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len); 618 tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len);
605 if (tmpns) { 619 if (tmpns) {
606 *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL); 620 *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL);
607 if (!*ns_name) 621 if (!*ns_name) {
622 info = "out of memory";
608 goto fail; 623 goto fail;
624 }
609 name = tmpname; 625 name = tmpname;
610 } 626 }
611 627
@@ -624,12 +640,15 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
624 if (IS_ERR(profile->xmatch)) { 640 if (IS_ERR(profile->xmatch)) {
625 error = PTR_ERR(profile->xmatch); 641 error = PTR_ERR(profile->xmatch);
626 profile->xmatch = NULL; 642 profile->xmatch = NULL;
643 info = "bad xmatch";
627 goto fail; 644 goto fail;
628 } 645 }
629 /* xmatch_len is not optional if xmatch is set */ 646 /* xmatch_len is not optional if xmatch is set */
630 if (profile->xmatch) { 647 if (profile->xmatch) {
631 if (!unpack_u32(e, &tmp, NULL)) 648 if (!unpack_u32(e, &tmp, NULL)) {
649 info = "missing xmatch len";
632 goto fail; 650 goto fail;
651 }
633 profile->xmatch_len = tmp; 652 profile->xmatch_len = tmp;
634 } 653 }
635 654
@@ -637,8 +656,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
637 (void) unpack_str(e, &profile->disconnected, "disconnected"); 656 (void) unpack_str(e, &profile->disconnected, "disconnected");
638 657
639 /* per profile debug flags (complain, audit) */ 658 /* per profile debug flags (complain, audit) */
640 if (!unpack_nameX(e, AA_STRUCT, "flags")) 659 if (!unpack_nameX(e, AA_STRUCT, "flags")) {
660 info = "profile missing flags";
641 goto fail; 661 goto fail;
662 }
663 info = "failed to unpack profile flags";
642 if (!unpack_u32(e, &tmp, NULL)) 664 if (!unpack_u32(e, &tmp, NULL))
643 goto fail; 665 goto fail;
644 if (tmp & PACKED_FLAG_HAT) 666 if (tmp & PACKED_FLAG_HAT)
@@ -667,6 +689,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
667 /* set a default value if path_flags field is not present */ 689 /* set a default value if path_flags field is not present */
668 profile->path_flags = PATH_MEDIATE_DELETED; 690 profile->path_flags = PATH_MEDIATE_DELETED;
669 691
692 info = "failed to unpack profile capabilities";
670 if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL)) 693 if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
671 goto fail; 694 goto fail;
672 if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL)) 695 if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL))
@@ -676,6 +699,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
676 if (!unpack_u32(e, &tmpcap.cap[0], NULL)) 699 if (!unpack_u32(e, &tmpcap.cap[0], NULL))
677 goto fail; 700 goto fail;
678 701
702 info = "failed to unpack upper profile capabilities";
679 if (unpack_nameX(e, AA_STRUCT, "caps64")) { 703 if (unpack_nameX(e, AA_STRUCT, "caps64")) {
680 /* optional upper half of 64 bit caps */ 704 /* optional upper half of 64 bit caps */
681 if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL)) 705 if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL))
@@ -690,6 +714,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
690 goto fail; 714 goto fail;
691 } 715 }
692 716
717 info = "failed to unpack extended profile capabilities";
693 if (unpack_nameX(e, AA_STRUCT, "capsx")) { 718 if (unpack_nameX(e, AA_STRUCT, "capsx")) {
694 /* optional extended caps mediation mask */ 719 /* optional extended caps mediation mask */
695 if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL)) 720 if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL))
@@ -700,11 +725,46 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
700 goto fail; 725 goto fail;
701 } 726 }
702 727
703 if (!unpack_rlimits(e, profile)) 728 if (!unpack_rlimits(e, profile)) {
729 info = "failed to unpack profile rlimits";
704 goto fail; 730 goto fail;
731 }
732
733 size = unpack_array(e, "net_allowed_af");
734 if (size) {
735
736 for (i = 0; i < size; i++) {
737 /* discard extraneous rules that this kernel will
738 * never request
739 */
740 if (i >= AF_MAX) {
741 u16 tmp;
742
743 if (!unpack_u16(e, &tmp, NULL) ||
744 !unpack_u16(e, &tmp, NULL) ||
745 !unpack_u16(e, &tmp, NULL))
746 goto fail;
747 continue;
748 }
749 if (!unpack_u16(e, &profile->net.allow[i], NULL))
750 goto fail;
751 if (!unpack_u16(e, &profile->net.audit[i], NULL))
752 goto fail;
753 if (!unpack_u16(e, &profile->net.quiet[i], NULL))
754 goto fail;
755 }
756 if (!unpack_nameX(e, AA_ARRAYEND, NULL))
757 goto fail;
758 }
759 if (VERSION_LT(e->version, v7)) {
760 /* pre v7 policy always allowed these */
761 profile->net.allow[AF_UNIX] = 0xffff;
762 profile->net.allow[AF_NETLINK] = 0xffff;
763 }
705 764
706 if (unpack_nameX(e, AA_STRUCT, "policydb")) { 765 if (unpack_nameX(e, AA_STRUCT, "policydb")) {
707 /* generic policy dfa - optional and may be NULL */ 766 /* generic policy dfa - optional and may be NULL */
767 info = "failed to unpack policydb";
708 profile->policy.dfa = unpack_dfa(e); 768 profile->policy.dfa = unpack_dfa(e);
709 if (IS_ERR(profile->policy.dfa)) { 769 if (IS_ERR(profile->policy.dfa)) {
710 error = PTR_ERR(profile->policy.dfa); 770 error = PTR_ERR(profile->policy.dfa);
@@ -734,6 +794,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
734 if (IS_ERR(profile->file.dfa)) { 794 if (IS_ERR(profile->file.dfa)) {
735 error = PTR_ERR(profile->file.dfa); 795 error = PTR_ERR(profile->file.dfa);
736 profile->file.dfa = NULL; 796 profile->file.dfa = NULL;
797 info = "failed to unpack profile file rules";
737 goto fail; 798 goto fail;
738 } else if (profile->file.dfa) { 799 } else if (profile->file.dfa) {
739 if (!unpack_u32(e, &profile->file.start, "dfa_start")) 800 if (!unpack_u32(e, &profile->file.start, "dfa_start"))
@@ -746,10 +807,13 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
746 } else 807 } else
747 profile->file.dfa = aa_get_dfa(nulldfa); 808 profile->file.dfa = aa_get_dfa(nulldfa);
748 809
749 if (!unpack_trans_table(e, profile)) 810 if (!unpack_trans_table(e, profile)) {
811 info = "failed to unpack profile transition table";
750 goto fail; 812 goto fail;
813 }
751 814
752 if (unpack_nameX(e, AA_STRUCT, "data")) { 815 if (unpack_nameX(e, AA_STRUCT, "data")) {
816 info = "out of memory";
753 profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL); 817 profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL);
754 if (!profile->data) 818 if (!profile->data)
755 goto fail; 819 goto fail;
@@ -761,8 +825,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
761 params.hashfn = strhash; 825 params.hashfn = strhash;
762 params.obj_cmpfn = datacmp; 826 params.obj_cmpfn = datacmp;
763 827
764 if (rhashtable_init(profile->data, &params)) 828 if (rhashtable_init(profile->data, &params)) {
829 info = "failed to init key, value hash table";
765 goto fail; 830 goto fail;
831 }
766 832
767 while (unpack_strdup(e, &key, NULL)) { 833 while (unpack_strdup(e, &key, NULL)) {
768 data = kzalloc(sizeof(*data), GFP_KERNEL); 834 data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -784,12 +850,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
784 profile->data->p); 850 profile->data->p);
785 } 851 }
786 852
787 if (!unpack_nameX(e, AA_STRUCTEND, NULL)) 853 if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
854 info = "failed to unpack end of key, value data table";
788 goto fail; 855 goto fail;
856 }
789 } 857 }
790 858
791 if (!unpack_nameX(e, AA_STRUCTEND, NULL)) 859 if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
860 info = "failed to unpack end of profile";
792 goto fail; 861 goto fail;
862 }
793 863
794 return profile; 864 return profile;
795 865
@@ -798,8 +868,7 @@ fail:
798 name = NULL; 868 name = NULL;
799 else if (!name) 869 else if (!name)
800 name = "unknown"; 870 name = "unknown";
801 audit_iface(profile, NULL, name, "failed to unpack profile", e, 871 audit_iface(profile, NULL, name, info, e, error);
802 error);
803 aa_free_profile(profile); 872 aa_free_profile(profile);
804 873
805 return ERR_PTR(error); 874 return ERR_PTR(error);
@@ -832,7 +901,7 @@ static int verify_header(struct aa_ext *e, int required, const char **ns)
832 * if not specified use previous version 901 * if not specified use previous version
833 * Mask off everything that is not kernel abi version 902 * Mask off everything that is not kernel abi version
834 */ 903 */
835 if (VERSION_LT(e->version, v5) && VERSION_GT(e->version, v7)) { 904 if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) {
836 audit_iface(NULL, NULL, NULL, "unsupported interface version", 905 audit_iface(NULL, NULL, NULL, "unsupported interface version",
837 e, error); 906 e, error);
838 return error; 907 return error;
diff --git a/security/commoncap.c b/security/commoncap.c
index 6bf72b175b49..c25e0d27537f 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -294,10 +294,10 @@ int cap_capset(struct cred *new,
294 * 294 *
295 * Determine if an inode having a change applied that's marked ATTR_KILL_PRIV 295 * Determine if an inode having a change applied that's marked ATTR_KILL_PRIV
296 * affects the security markings on that inode, and if it is, should 296 * affects the security markings on that inode, and if it is, should
297 * inode_killpriv() be invoked or the change rejected? 297 * inode_killpriv() be invoked or the change rejected.
298 * 298 *
299 * Returns 0 if granted; +ve if granted, but inode_killpriv() is required; and 299 * Returns 1 if security.capability has a value, meaning inode_killpriv()
300 * -ve to deny the change. 300 * is required, 0 otherwise, meaning inode_killpriv() is not required.
301 */ 301 */
302int cap_inode_need_killpriv(struct dentry *dentry) 302int cap_inode_need_killpriv(struct dentry *dentry)
303{ 303{
diff --git a/security/keys/Kconfig b/security/keys/Kconfig
index a7a23b5541f8..91eafada3164 100644
--- a/security/keys/Kconfig
+++ b/security/keys/Kconfig
@@ -45,10 +45,8 @@ config BIG_KEYS
45 bool "Large payload keys" 45 bool "Large payload keys"
46 depends on KEYS 46 depends on KEYS
47 depends on TMPFS 47 depends on TMPFS
48 depends on (CRYPTO_ANSI_CPRNG = y || CRYPTO_DRBG = y)
49 select CRYPTO_AES 48 select CRYPTO_AES
50 select CRYPTO_ECB 49 select CRYPTO_GCM
51 select CRYPTO_RNG
52 help 50 help
53 This option provides support for holding large keys within the kernel 51 This option provides support for holding large keys within the kernel
54 (for example Kerberos ticket caches). The data may be stored out to 52 (for example Kerberos ticket caches). The data may be stored out to
diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index 6acb00f6f22c..e607830b6154 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -1,5 +1,6 @@
1/* Large capacity key type 1/* Large capacity key type
2 * 2 *
3 * Copyright (C) 2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
3 * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved. 4 * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 5 * Written by David Howells (dhowells@redhat.com)
5 * 6 *
@@ -16,10 +17,10 @@
16#include <linux/shmem_fs.h> 17#include <linux/shmem_fs.h>
17#include <linux/err.h> 18#include <linux/err.h>
18#include <linux/scatterlist.h> 19#include <linux/scatterlist.h>
20#include <linux/random.h>
19#include <keys/user-type.h> 21#include <keys/user-type.h>
20#include <keys/big_key-type.h> 22#include <keys/big_key-type.h>
21#include <crypto/rng.h> 23#include <crypto/aead.h>
22#include <crypto/skcipher.h>
23 24
24/* 25/*
25 * Layout of key payload words. 26 * Layout of key payload words.
@@ -49,7 +50,12 @@ enum big_key_op {
49/* 50/*
50 * Key size for big_key data encryption 51 * Key size for big_key data encryption
51 */ 52 */
52#define ENC_KEY_SIZE 16 53#define ENC_KEY_SIZE 32
54
55/*
56 * Authentication tag length
57 */
58#define ENC_AUTHTAG_SIZE 16
53 59
54/* 60/*
55 * big_key defined keys take an arbitrary string as the description and an 61 * big_key defined keys take an arbitrary string as the description and an
@@ -64,57 +70,62 @@ struct key_type key_type_big_key = {
64 .destroy = big_key_destroy, 70 .destroy = big_key_destroy,
65 .describe = big_key_describe, 71 .describe = big_key_describe,
66 .read = big_key_read, 72 .read = big_key_read,
73 /* no ->update(); don't add it without changing big_key_crypt() nonce */
67}; 74};
68 75
69/* 76/*
70 * Crypto names for big_key data encryption 77 * Crypto names for big_key data authenticated encryption
71 */ 78 */
72static const char big_key_rng_name[] = "stdrng"; 79static const char big_key_alg_name[] = "gcm(aes)";
73static const char big_key_alg_name[] = "ecb(aes)";
74 80
75/* 81/*
76 * Crypto algorithms for big_key data encryption 82 * Crypto algorithms for big_key data authenticated encryption
77 */ 83 */
78static struct crypto_rng *big_key_rng; 84static struct crypto_aead *big_key_aead;
79static struct crypto_skcipher *big_key_skcipher;
80 85
81/* 86/*
82 * Generate random key to encrypt big_key data 87 * Since changing the key affects the entire object, we need a mutex.
83 */ 88 */
84static inline int big_key_gen_enckey(u8 *key) 89static DEFINE_MUTEX(big_key_aead_lock);
85{
86 return crypto_rng_get_bytes(big_key_rng, key, ENC_KEY_SIZE);
87}
88 90
89/* 91/*
90 * Encrypt/decrypt big_key data 92 * Encrypt/decrypt big_key data
91 */ 93 */
92static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key) 94static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key)
93{ 95{
94 int ret = -EINVAL; 96 int ret;
95 struct scatterlist sgio; 97 struct scatterlist sgio;
96 SKCIPHER_REQUEST_ON_STACK(req, big_key_skcipher); 98 struct aead_request *aead_req;
97 99 /* We always use a zero nonce. The reason we can get away with this is
98 if (crypto_skcipher_setkey(big_key_skcipher, key, ENC_KEY_SIZE)) { 100 * because we're using a different randomly generated key for every
101 * different encryption. Notably, too, key_type_big_key doesn't define
102 * an .update function, so there's no chance we'll wind up reusing the
103 * key to encrypt updated data. Simply put: one key, one encryption.
104 */
105 u8 zero_nonce[crypto_aead_ivsize(big_key_aead)];
106
107 aead_req = aead_request_alloc(big_key_aead, GFP_KERNEL);
108 if (!aead_req)
109 return -ENOMEM;
110
111 memset(zero_nonce, 0, sizeof(zero_nonce));
112 sg_init_one(&sgio, data, datalen + (op == BIG_KEY_ENC ? ENC_AUTHTAG_SIZE : 0));
113 aead_request_set_crypt(aead_req, &sgio, &sgio, datalen, zero_nonce);
114 aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
115 aead_request_set_ad(aead_req, 0);
116
117 mutex_lock(&big_key_aead_lock);
118 if (crypto_aead_setkey(big_key_aead, key, ENC_KEY_SIZE)) {
99 ret = -EAGAIN; 119 ret = -EAGAIN;
100 goto error; 120 goto error;
101 } 121 }
102
103 skcipher_request_set_tfm(req, big_key_skcipher);
104 skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP,
105 NULL, NULL);
106
107 sg_init_one(&sgio, data, datalen);
108 skcipher_request_set_crypt(req, &sgio, &sgio, datalen, NULL);
109
110 if (op == BIG_KEY_ENC) 122 if (op == BIG_KEY_ENC)
111 ret = crypto_skcipher_encrypt(req); 123 ret = crypto_aead_encrypt(aead_req);
112 else 124 else
113 ret = crypto_skcipher_decrypt(req); 125 ret = crypto_aead_decrypt(aead_req);
114
115 skcipher_request_zero(req);
116
117error: 126error:
127 mutex_unlock(&big_key_aead_lock);
128 aead_request_free(aead_req);
118 return ret; 129 return ret;
119} 130}
120 131
@@ -146,16 +157,13 @@ int big_key_preparse(struct key_preparsed_payload *prep)
146 * 157 *
147 * File content is stored encrypted with randomly generated key. 158 * File content is stored encrypted with randomly generated key.
148 */ 159 */
149 size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); 160 size_t enclen = datalen + ENC_AUTHTAG_SIZE;
150 loff_t pos = 0; 161 loff_t pos = 0;
151 162
152 /* prepare aligned data to encrypt */
153 data = kmalloc(enclen, GFP_KERNEL); 163 data = kmalloc(enclen, GFP_KERNEL);
154 if (!data) 164 if (!data)
155 return -ENOMEM; 165 return -ENOMEM;
156
157 memcpy(data, prep->data, datalen); 166 memcpy(data, prep->data, datalen);
158 memset(data + datalen, 0x00, enclen - datalen);
159 167
160 /* generate random key */ 168 /* generate random key */
161 enckey = kmalloc(ENC_KEY_SIZE, GFP_KERNEL); 169 enckey = kmalloc(ENC_KEY_SIZE, GFP_KERNEL);
@@ -163,13 +171,12 @@ int big_key_preparse(struct key_preparsed_payload *prep)
163 ret = -ENOMEM; 171 ret = -ENOMEM;
164 goto error; 172 goto error;
165 } 173 }
166 174 ret = get_random_bytes_wait(enckey, ENC_KEY_SIZE);
167 ret = big_key_gen_enckey(enckey); 175 if (unlikely(ret))
168 if (ret)
169 goto err_enckey; 176 goto err_enckey;
170 177
171 /* encrypt aligned data */ 178 /* encrypt aligned data */
172 ret = big_key_crypt(BIG_KEY_ENC, data, enclen, enckey); 179 ret = big_key_crypt(BIG_KEY_ENC, data, datalen, enckey);
173 if (ret) 180 if (ret)
174 goto err_enckey; 181 goto err_enckey;
175 182
@@ -195,7 +202,7 @@ int big_key_preparse(struct key_preparsed_payload *prep)
195 *path = file->f_path; 202 *path = file->f_path;
196 path_get(path); 203 path_get(path);
197 fput(file); 204 fput(file);
198 kfree(data); 205 kzfree(data);
199 } else { 206 } else {
200 /* Just store the data in a buffer */ 207 /* Just store the data in a buffer */
201 void *data = kmalloc(datalen, GFP_KERNEL); 208 void *data = kmalloc(datalen, GFP_KERNEL);
@@ -211,9 +218,9 @@ int big_key_preparse(struct key_preparsed_payload *prep)
211err_fput: 218err_fput:
212 fput(file); 219 fput(file);
213err_enckey: 220err_enckey:
214 kfree(enckey); 221 kzfree(enckey);
215error: 222error:
216 kfree(data); 223 kzfree(data);
217 return ret; 224 return ret;
218} 225}
219 226
@@ -227,7 +234,7 @@ void big_key_free_preparse(struct key_preparsed_payload *prep)
227 234
228 path_put(path); 235 path_put(path);
229 } 236 }
230 kfree(prep->payload.data[big_key_data]); 237 kzfree(prep->payload.data[big_key_data]);
231} 238}
232 239
233/* 240/*
@@ -259,7 +266,7 @@ void big_key_destroy(struct key *key)
259 path->mnt = NULL; 266 path->mnt = NULL;
260 path->dentry = NULL; 267 path->dentry = NULL;
261 } 268 }
262 kfree(key->payload.data[big_key_data]); 269 kzfree(key->payload.data[big_key_data]);
263 key->payload.data[big_key_data] = NULL; 270 key->payload.data[big_key_data] = NULL;
264} 271}
265 272
@@ -295,7 +302,7 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
295 struct file *file; 302 struct file *file;
296 u8 *data; 303 u8 *data;
297 u8 *enckey = (u8 *)key->payload.data[big_key_data]; 304 u8 *enckey = (u8 *)key->payload.data[big_key_data];
298 size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); 305 size_t enclen = datalen + ENC_AUTHTAG_SIZE;
299 loff_t pos = 0; 306 loff_t pos = 0;
300 307
301 data = kmalloc(enclen, GFP_KERNEL); 308 data = kmalloc(enclen, GFP_KERNEL);
@@ -328,7 +335,7 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
328err_fput: 335err_fput:
329 fput(file); 336 fput(file);
330error: 337error:
331 kfree(data); 338 kzfree(data);
332 } else { 339 } else {
333 ret = datalen; 340 ret = datalen;
334 if (copy_to_user(buffer, key->payload.data[big_key_data], 341 if (copy_to_user(buffer, key->payload.data[big_key_data],
@@ -344,47 +351,31 @@ error:
344 */ 351 */
345static int __init big_key_init(void) 352static int __init big_key_init(void)
346{ 353{
347 struct crypto_skcipher *cipher;
348 struct crypto_rng *rng;
349 int ret; 354 int ret;
350 355
351 rng = crypto_alloc_rng(big_key_rng_name, 0, 0);
352 if (IS_ERR(rng)) {
353 pr_err("Can't alloc rng: %ld\n", PTR_ERR(rng));
354 return PTR_ERR(rng);
355 }
356
357 big_key_rng = rng;
358
359 /* seed RNG */
360 ret = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng));
361 if (ret) {
362 pr_err("Can't reset rng: %d\n", ret);
363 goto error_rng;
364 }
365
366 /* init block cipher */ 356 /* init block cipher */
367 cipher = crypto_alloc_skcipher(big_key_alg_name, 0, CRYPTO_ALG_ASYNC); 357 big_key_aead = crypto_alloc_aead(big_key_alg_name, 0, CRYPTO_ALG_ASYNC);
368 if (IS_ERR(cipher)) { 358 if (IS_ERR(big_key_aead)) {
369 ret = PTR_ERR(cipher); 359 ret = PTR_ERR(big_key_aead);
370 pr_err("Can't alloc crypto: %d\n", ret); 360 pr_err("Can't alloc crypto: %d\n", ret);
371 goto error_rng; 361 return ret;
362 }
363 ret = crypto_aead_setauthsize(big_key_aead, ENC_AUTHTAG_SIZE);
364 if (ret < 0) {
365 pr_err("Can't set crypto auth tag len: %d\n", ret);
366 goto free_aead;
372 } 367 }
373
374 big_key_skcipher = cipher;
375 368
376 ret = register_key_type(&key_type_big_key); 369 ret = register_key_type(&key_type_big_key);
377 if (ret < 0) { 370 if (ret < 0) {
378 pr_err("Can't register type: %d\n", ret); 371 pr_err("Can't register type: %d\n", ret);
379 goto error_cipher; 372 goto free_aead;
380 } 373 }
381 374
382 return 0; 375 return 0;
383 376
384error_cipher: 377free_aead:
385 crypto_free_skcipher(big_key_skcipher); 378 crypto_free_aead(big_key_aead);
386error_rng:
387 crypto_free_rng(big_key_rng);
388 return ret; 379 return ret;
389} 380}
390 381
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 1c02c6547038..503adbae7b0d 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -141,7 +141,7 @@ extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
141extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx); 141extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx);
142extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx); 142extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx);
143 143
144extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check); 144extern struct key *find_keyring_by_name(const char *name, bool uid_keyring);
145 145
146extern int install_user_keyrings(void); 146extern int install_user_keyrings(void);
147extern int install_thread_keyring_to_cred(struct cred *); 147extern int install_thread_keyring_to_cred(struct cred *);
diff --git a/security/keys/key.c b/security/keys/key.c
index 83da68d98b40..eb914a838840 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -54,10 +54,10 @@ void __key_check(const struct key *key)
54struct key_user *key_user_lookup(kuid_t uid) 54struct key_user *key_user_lookup(kuid_t uid)
55{ 55{
56 struct key_user *candidate = NULL, *user; 56 struct key_user *candidate = NULL, *user;
57 struct rb_node *parent = NULL; 57 struct rb_node *parent, **p;
58 struct rb_node **p;
59 58
60try_again: 59try_again:
60 parent = NULL;
61 p = &key_user_tree.rb_node; 61 p = &key_user_tree.rb_node;
62 spin_lock(&key_user_lock); 62 spin_lock(&key_user_lock);
63 63
@@ -302,6 +302,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
302 key->flags |= 1 << KEY_FLAG_IN_QUOTA; 302 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
303 if (flags & KEY_ALLOC_BUILT_IN) 303 if (flags & KEY_ALLOC_BUILT_IN)
304 key->flags |= 1 << KEY_FLAG_BUILTIN; 304 key->flags |= 1 << KEY_FLAG_BUILTIN;
305 if (flags & KEY_ALLOC_UID_KEYRING)
306 key->flags |= 1 << KEY_FLAG_UID_KEYRING;
305 307
306#ifdef KEY_DEBUGGING 308#ifdef KEY_DEBUGGING
307 key->magic = KEY_DEBUG_MAGIC; 309 key->magic = KEY_DEBUG_MAGIC;
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index ab0b337c84b4..365ff85d7e27 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -766,12 +766,17 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
766 766
767 key = key_ref_to_ptr(key_ref); 767 key = key_ref_to_ptr(key_ref);
768 768
769 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
770 ret = -ENOKEY;
771 goto error2;
772 }
773
769 /* see if we can read it directly */ 774 /* see if we can read it directly */
770 ret = key_permission(key_ref, KEY_NEED_READ); 775 ret = key_permission(key_ref, KEY_NEED_READ);
771 if (ret == 0) 776 if (ret == 0)
772 goto can_read_key; 777 goto can_read_key;
773 if (ret != -EACCES) 778 if (ret != -EACCES)
774 goto error; 779 goto error2;
775 780
776 /* we can't; see if it's searchable from this process's keyrings 781 /* we can't; see if it's searchable from this process's keyrings
777 * - we automatically take account of the fact that it may be 782 * - we automatically take account of the fact that it may be
@@ -1406,11 +1411,9 @@ long keyctl_assume_authority(key_serial_t id)
1406 } 1411 }
1407 1412
1408 ret = keyctl_change_reqkey_auth(authkey); 1413 ret = keyctl_change_reqkey_auth(authkey);
1409 if (ret < 0) 1414 if (ret == 0)
1410 goto error; 1415 ret = authkey->serial;
1411 key_put(authkey); 1416 key_put(authkey);
1412
1413 ret = authkey->serial;
1414error: 1417error:
1415 return ret; 1418 return ret;
1416} 1419}
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index de81793f9920..4fa82a8a9c0e 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -423,7 +423,7 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m)
423} 423}
424 424
425struct keyring_read_iterator_context { 425struct keyring_read_iterator_context {
426 size_t qty; 426 size_t buflen;
427 size_t count; 427 size_t count;
428 key_serial_t __user *buffer; 428 key_serial_t __user *buffer;
429}; 429};
@@ -435,9 +435,9 @@ static int keyring_read_iterator(const void *object, void *data)
435 int ret; 435 int ret;
436 436
437 kenter("{%s,%d},,{%zu/%zu}", 437 kenter("{%s,%d},,{%zu/%zu}",
438 key->type->name, key->serial, ctx->count, ctx->qty); 438 key->type->name, key->serial, ctx->count, ctx->buflen);
439 439
440 if (ctx->count >= ctx->qty) 440 if (ctx->count >= ctx->buflen)
441 return 1; 441 return 1;
442 442
443 ret = put_user(key->serial, ctx->buffer); 443 ret = put_user(key->serial, ctx->buffer);
@@ -472,16 +472,12 @@ static long keyring_read(const struct key *keyring,
472 return 0; 472 return 0;
473 473
474 /* Calculate how much data we could return */ 474 /* Calculate how much data we could return */
475 ctx.qty = nr_keys * sizeof(key_serial_t);
476
477 if (!buffer || !buflen) 475 if (!buffer || !buflen)
478 return ctx.qty; 476 return nr_keys * sizeof(key_serial_t);
479
480 if (buflen > ctx.qty)
481 ctx.qty = buflen;
482 477
483 /* Copy the IDs of the subscribed keys into the buffer */ 478 /* Copy the IDs of the subscribed keys into the buffer */
484 ctx.buffer = (key_serial_t __user *)buffer; 479 ctx.buffer = (key_serial_t __user *)buffer;
480 ctx.buflen = buflen;
485 ctx.count = 0; 481 ctx.count = 0;
486 ret = assoc_array_iterate(&keyring->keys, keyring_read_iterator, &ctx); 482 ret = assoc_array_iterate(&keyring->keys, keyring_read_iterator, &ctx);
487 if (ret < 0) { 483 if (ret < 0) {
@@ -1101,15 +1097,15 @@ found:
1101/* 1097/*
1102 * Find a keyring with the specified name. 1098 * Find a keyring with the specified name.
1103 * 1099 *
1104 * All named keyrings in the current user namespace are searched, provided they 1100 * Only keyrings that have nonzero refcount, are not revoked, and are owned by a
1105 * grant Search permission directly to the caller (unless this check is 1101 * user in the current user namespace are considered. If @uid_keyring is %true,
1106 * skipped). Keyrings whose usage points have reached zero or who have been 1102 * the keyring additionally must have been allocated as a user or user session
1107 * revoked are skipped. 1103 * keyring; otherwise, it must grant Search permission directly to the caller.
1108 * 1104 *
1109 * Returns a pointer to the keyring with the keyring's refcount having being 1105 * Returns a pointer to the keyring with the keyring's refcount having being
1110 * incremented on success. -ENOKEY is returned if a key could not be found. 1106 * incremented on success. -ENOKEY is returned if a key could not be found.
1111 */ 1107 */
1112struct key *find_keyring_by_name(const char *name, bool skip_perm_check) 1108struct key *find_keyring_by_name(const char *name, bool uid_keyring)
1113{ 1109{
1114 struct key *keyring; 1110 struct key *keyring;
1115 int bucket; 1111 int bucket;
@@ -1137,10 +1133,15 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
1137 if (strcmp(keyring->description, name) != 0) 1133 if (strcmp(keyring->description, name) != 0)
1138 continue; 1134 continue;
1139 1135
1140 if (!skip_perm_check && 1136 if (uid_keyring) {
1141 key_permission(make_key_ref(keyring, 0), 1137 if (!test_bit(KEY_FLAG_UID_KEYRING,
1142 KEY_NEED_SEARCH) < 0) 1138 &keyring->flags))
1143 continue; 1139 continue;
1140 } else {
1141 if (key_permission(make_key_ref(keyring, 0),
1142 KEY_NEED_SEARCH) < 0)
1143 continue;
1144 }
1144 1145
1145 /* we've got a match but we might end up racing with 1146 /* we've got a match but we might end up racing with
1146 * key_cleanup() if the keyring is currently 'dead' 1147 * key_cleanup() if the keyring is currently 'dead'
diff --git a/security/keys/proc.c b/security/keys/proc.c
index bf08d02b6646..de834309d100 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -187,7 +187,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
187 struct keyring_search_context ctx = { 187 struct keyring_search_context ctx = {
188 .index_key.type = key->type, 188 .index_key.type = key->type,
189 .index_key.description = key->description, 189 .index_key.description = key->description,
190 .cred = current_cred(), 190 .cred = m->file->f_cred,
191 .match_data.cmp = lookup_user_key_possessed, 191 .match_data.cmp = lookup_user_key_possessed,
192 .match_data.raw_data = key, 192 .match_data.raw_data = key,
193 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 193 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
@@ -207,11 +207,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
207 } 207 }
208 } 208 }
209 209
210 /* check whether the current task is allowed to view the key (assuming 210 /* check whether the current task is allowed to view the key */
211 * non-possession)
212 * - the caller holds a spinlock, and thus the RCU read lock, making our
213 * access to __current_cred() safe
214 */
215 rc = key_task_permission(key_ref, ctx.cred, KEY_NEED_VIEW); 211 rc = key_task_permission(key_ref, ctx.cred, KEY_NEED_VIEW);
216 if (rc < 0) 212 if (rc < 0)
217 return 0; 213 return 0;
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 86bced9fdbdf..293d3598153b 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -77,7 +77,8 @@ int install_user_keyrings(void)
77 if (IS_ERR(uid_keyring)) { 77 if (IS_ERR(uid_keyring)) {
78 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID, 78 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID,
79 cred, user_keyring_perm, 79 cred, user_keyring_perm,
80 KEY_ALLOC_IN_QUOTA, 80 KEY_ALLOC_UID_KEYRING |
81 KEY_ALLOC_IN_QUOTA,
81 NULL, NULL); 82 NULL, NULL);
82 if (IS_ERR(uid_keyring)) { 83 if (IS_ERR(uid_keyring)) {
83 ret = PTR_ERR(uid_keyring); 84 ret = PTR_ERR(uid_keyring);
@@ -94,7 +95,8 @@ int install_user_keyrings(void)
94 session_keyring = 95 session_keyring =
95 keyring_alloc(buf, user->uid, INVALID_GID, 96 keyring_alloc(buf, user->uid, INVALID_GID,
96 cred, user_keyring_perm, 97 cred, user_keyring_perm,
97 KEY_ALLOC_IN_QUOTA, 98 KEY_ALLOC_UID_KEYRING |
99 KEY_ALLOC_IN_QUOTA,
98 NULL, NULL); 100 NULL, NULL);
99 if (IS_ERR(session_keyring)) { 101 if (IS_ERR(session_keyring)) {
100 ret = PTR_ERR(session_keyring); 102 ret = PTR_ERR(session_keyring);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index afe9d22ab361..6ebf1af8fce9 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -120,6 +120,18 @@ static void request_key_auth_revoke(struct key *key)
120 } 120 }
121} 121}
122 122
123static void free_request_key_auth(struct request_key_auth *rka)
124{
125 if (!rka)
126 return;
127 key_put(rka->target_key);
128 key_put(rka->dest_keyring);
129 if (rka->cred)
130 put_cred(rka->cred);
131 kfree(rka->callout_info);
132 kfree(rka);
133}
134
123/* 135/*
124 * Destroy an instantiation authorisation token key. 136 * Destroy an instantiation authorisation token key.
125 */ 137 */
@@ -129,15 +141,7 @@ static void request_key_auth_destroy(struct key *key)
129 141
130 kenter("{%d}", key->serial); 142 kenter("{%d}", key->serial);
131 143
132 if (rka->cred) { 144 free_request_key_auth(rka);
133 put_cred(rka->cred);
134 rka->cred = NULL;
135 }
136
137 key_put(rka->target_key);
138 key_put(rka->dest_keyring);
139 kfree(rka->callout_info);
140 kfree(rka);
141} 145}
142 146
143/* 147/*
@@ -151,22 +155,18 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
151 const struct cred *cred = current->cred; 155 const struct cred *cred = current->cred;
152 struct key *authkey = NULL; 156 struct key *authkey = NULL;
153 char desc[20]; 157 char desc[20];
154 int ret; 158 int ret = -ENOMEM;
155 159
156 kenter("%d,", target->serial); 160 kenter("%d,", target->serial);
157 161
158 /* allocate a auth record */ 162 /* allocate a auth record */
159 rka = kmalloc(sizeof(*rka), GFP_KERNEL); 163 rka = kzalloc(sizeof(*rka), GFP_KERNEL);
160 if (!rka) { 164 if (!rka)
161 kleave(" = -ENOMEM"); 165 goto error;
162 return ERR_PTR(-ENOMEM); 166 rka->callout_info = kmemdup(callout_info, callout_len, GFP_KERNEL);
163 } 167 if (!rka->callout_info)
164 rka->callout_info = kmalloc(callout_len, GFP_KERNEL); 168 goto error_free_rka;
165 if (!rka->callout_info) { 169 rka->callout_len = callout_len;
166 kleave(" = -ENOMEM");
167 kfree(rka);
168 return ERR_PTR(-ENOMEM);
169 }
170 170
171 /* see if the calling process is already servicing the key request of 171 /* see if the calling process is already servicing the key request of
172 * another process */ 172 * another process */
@@ -176,8 +176,12 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
176 176
177 /* if the auth key has been revoked, then the key we're 177 /* if the auth key has been revoked, then the key we're
178 * servicing is already instantiated */ 178 * servicing is already instantiated */
179 if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags)) 179 if (test_bit(KEY_FLAG_REVOKED,
180 goto auth_key_revoked; 180 &cred->request_key_auth->flags)) {
181 up_read(&cred->request_key_auth->sem);
182 ret = -EKEYREVOKED;
183 goto error_free_rka;
184 }
181 185
182 irka = cred->request_key_auth->payload.data[0]; 186 irka = cred->request_key_auth->payload.data[0];
183 rka->cred = get_cred(irka->cred); 187 rka->cred = get_cred(irka->cred);
@@ -193,8 +197,6 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
193 197
194 rka->target_key = key_get(target); 198 rka->target_key = key_get(target);
195 rka->dest_keyring = key_get(dest_keyring); 199 rka->dest_keyring = key_get(dest_keyring);
196 memcpy(rka->callout_info, callout_info, callout_len);
197 rka->callout_len = callout_len;
198 200
199 /* allocate the auth key */ 201 /* allocate the auth key */
200 sprintf(desc, "%x", target->serial); 202 sprintf(desc, "%x", target->serial);
@@ -205,32 +207,22 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
205 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL); 207 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL);
206 if (IS_ERR(authkey)) { 208 if (IS_ERR(authkey)) {
207 ret = PTR_ERR(authkey); 209 ret = PTR_ERR(authkey);
208 goto error_alloc; 210 goto error_free_rka;
209 } 211 }
210 212
211 /* construct the auth key */ 213 /* construct the auth key */
212 ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL); 214 ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
213 if (ret < 0) 215 if (ret < 0)
214 goto error_inst; 216 goto error_put_authkey;
215 217
216 kleave(" = {%d,%d}", authkey->serial, refcount_read(&authkey->usage)); 218 kleave(" = {%d,%d}", authkey->serial, refcount_read(&authkey->usage));
217 return authkey; 219 return authkey;
218 220
219auth_key_revoked: 221error_put_authkey:
220 up_read(&cred->request_key_auth->sem);
221 kfree(rka->callout_info);
222 kfree(rka);
223 kleave("= -EKEYREVOKED");
224 return ERR_PTR(-EKEYREVOKED);
225
226error_inst:
227 key_revoke(authkey);
228 key_put(authkey); 222 key_put(authkey);
229error_alloc: 223error_free_rka:
230 key_put(rka->target_key); 224 free_request_key_auth(rka);
231 key_put(rka->dest_keyring); 225error:
232 kfree(rka->callout_info);
233 kfree(rka);
234 kleave("= %d", ret); 226 kleave("= %d", ret);
235 return ERR_PTR(ret); 227 return ERR_PTR(ret);
236} 228}
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 319add31b4a4..286171a16ed2 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1473,7 +1473,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
1473 * @inode: the object 1473 * @inode: the object
1474 * @name: attribute name 1474 * @name: attribute name
1475 * @buffer: where to put the result 1475 * @buffer: where to put the result
1476 * @alloc: unused 1476 * @alloc: duplicate memory
1477 * 1477 *
1478 * Returns the size of the attribute or an error code 1478 * Returns the size of the attribute or an error code
1479 */ 1479 */
@@ -1486,43 +1486,38 @@ static int smack_inode_getsecurity(struct inode *inode,
1486 struct super_block *sbp; 1486 struct super_block *sbp;
1487 struct inode *ip = (struct inode *)inode; 1487 struct inode *ip = (struct inode *)inode;
1488 struct smack_known *isp; 1488 struct smack_known *isp;
1489 int ilen;
1490 int rc = 0;
1491 1489
1492 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { 1490 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0)
1493 isp = smk_of_inode(inode); 1491 isp = smk_of_inode(inode);
1494 ilen = strlen(isp->smk_known); 1492 else {
1495 *buffer = isp->smk_known; 1493 /*
1496 return ilen; 1494 * The rest of the Smack xattrs are only on sockets.
1497 } 1495 */
1496 sbp = ip->i_sb;
1497 if (sbp->s_magic != SOCKFS_MAGIC)
1498 return -EOPNOTSUPP;
1498 1499
1499 /* 1500 sock = SOCKET_I(ip);
1500 * The rest of the Smack xattrs are only on sockets. 1501 if (sock == NULL || sock->sk == NULL)
1501 */ 1502 return -EOPNOTSUPP;
1502 sbp = ip->i_sb;
1503 if (sbp->s_magic != SOCKFS_MAGIC)
1504 return -EOPNOTSUPP;
1505 1503
1506 sock = SOCKET_I(ip); 1504 ssp = sock->sk->sk_security;
1507 if (sock == NULL || sock->sk == NULL)
1508 return -EOPNOTSUPP;
1509
1510 ssp = sock->sk->sk_security;
1511 1505
1512 if (strcmp(name, XATTR_SMACK_IPIN) == 0) 1506 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
1513 isp = ssp->smk_in; 1507 isp = ssp->smk_in;
1514 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) 1508 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
1515 isp = ssp->smk_out; 1509 isp = ssp->smk_out;
1516 else 1510 else
1517 return -EOPNOTSUPP; 1511 return -EOPNOTSUPP;
1512 }
1518 1513
1519 ilen = strlen(isp->smk_known); 1514 if (alloc) {
1520 if (rc == 0) { 1515 *buffer = kstrdup(isp->smk_known, GFP_KERNEL);
1521 *buffer = isp->smk_known; 1516 if (*buffer == NULL)
1522 rc = ilen; 1517 return -ENOMEM;
1523 } 1518 }
1524 1519
1525 return rc; 1520 return strlen(isp->smk_known);
1526} 1521}
1527 1522
1528 1523