aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-05 14:26:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-05 14:26:35 -0400
commite24dd9ee5399747b71c1d982a484fc7601795f31 (patch)
tree14fcec8728916092a9f6dbeb0f2b8d5c5a4e5c9a /security
parent7391786a64dcfe9c609a1f8e2204c1abf42ded23 (diff)
parentc4758fa59285fe4dbfeab4364a6957936d040fbf (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security layer updates from James Morris: - a major update for AppArmor. From JJ: * several bug fixes and cleanups * the patch to add symlink support to securityfs that was floated on the list earlier and the apparmorfs changes that make use of securityfs symlinks * it introduces the domain labeling base code that Ubuntu has been carrying for several years, with several cleanups applied. And it converts the current mediation over to using the domain labeling base, which brings domain stacking support with it. This finally will bring the base upstream code in line with Ubuntu and provide a base to upstream the new feature work that Ubuntu carries. * This does _not_ contain any of the newer apparmor mediation features/controls (mount, signals, network, keys, ...) that Ubuntu is currently carrying, all of which will be RFC'd on top of this. - Notable also is the Infiniband work in SELinux, and the new file:map permission. From Paul: "While we're down to 21 patches for v4.13 (it was 31 for v4.12), the diffstat jumps up tremendously with over 2k of line changes. Almost all of these changes are the SELinux/IB work done by Daniel Jurgens; some other noteworthy changes include a NFS v4.2 labeling fix, a new file:map permission, and reporting of policy capabilities on policy load" There's also now genfscon labeling support for tracefs, which was lost in v4.1 with the separation from debugfs. - Smack incorporates a safer socket check in file_receive, and adds a cap_capable call in privilege check. - TPM as usual has a bunch of fixes and enhancements. - Multiple calls to security_add_hooks() can now be made for the same LSM, to allow LSMs to have hook declarations across multiple files. - IMA now supports different "ima_appraise=" modes (eg. log, fix) from the boot command line. * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (126 commits) apparmor: put back designators in struct initialisers seccomp: Switch from atomic_t to recount_t seccomp: Adjust selftests to avoid double-join seccomp: Clean up core dump logic IMA: update IMA policy documentation to include pcr= option ima: Log the same audit cause whenever a file has no signature ima: Simplify policy_func_show. integrity: Small code improvements ima: fix get_binary_runtime_size() ima: use ima_parse_buf() to parse template data ima: use ima_parse_buf() to parse measurements headers ima: introduce ima_parse_buf() ima: Add cgroups2 to the defaults list ima: use memdup_user_nul ima: fix up #endif comments IMA: Correct Kconfig dependencies for hash selection ima: define is_ima_appraise_enabled() ima: define Kconfig IMA_APPRAISE_BOOTPARAM option ima: define a set of appraisal rules requiring file signatures ima: extend the "ima_policy" boot command line to support multiple policies ...
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig11
-rw-r--r--security/apparmor/Makefile8
-rw-r--r--security/apparmor/apparmorfs.c1672
-rw-r--r--security/apparmor/audit.c27
-rw-r--r--security/apparmor/capability.c61
-rw-r--r--security/apparmor/context.c87
-rw-r--r--security/apparmor/domain.c1393
-rw-r--r--security/apparmor/file.c517
-rw-r--r--security/apparmor/include/apparmor.h6
-rw-r--r--security/apparmor/include/apparmorfs.h67
-rw-r--r--security/apparmor/include/audit.h17
-rw-r--r--security/apparmor/include/capability.h8
-rw-r--r--security/apparmor/include/context.h201
-rw-r--r--security/apparmor/include/domain.h13
-rw-r--r--security/apparmor/include/file.h114
-rw-r--r--security/apparmor/include/ipc.h16
-rw-r--r--security/apparmor/include/label.h441
-rw-r--r--security/apparmor/include/lib.h120
-rw-r--r--security/apparmor/include/path.h7
-rw-r--r--security/apparmor/include/perms.h155
-rw-r--r--security/apparmor/include/policy.h131
-rw-r--r--security/apparmor/include/policy_ns.h21
-rw-r--r--security/apparmor/include/policy_unpack.h68
-rw-r--r--security/apparmor/include/procattr.h8
-rw-r--r--security/apparmor/include/resource.h6
-rw-r--r--security/apparmor/ipc.c140
-rw-r--r--security/apparmor/label.c2120
-rw-r--r--security/apparmor/lib.c368
-rw-r--r--security/apparmor/lsm.c245
-rw-r--r--security/apparmor/path.c130
-rw-r--r--security/apparmor/policy.c392
-rw-r--r--security/apparmor/policy_ns.c80
-rw-r--r--security/apparmor/policy_unpack.c96
-rw-r--r--security/apparmor/procattr.c71
-rw-r--r--security/apparmor/resource.c116
-rw-r--r--security/inode.c144
-rw-r--r--security/integrity/digsig_asymmetric.c4
-rw-r--r--security/integrity/iint.c2
-rw-r--r--security/integrity/ima/Kconfig16
-rw-r--r--security/integrity/ima/ima.h31
-rw-r--r--security/integrity/ima/ima_appraise.c16
-rw-r--r--security/integrity/ima/ima_fs.c13
-rw-r--r--security/integrity/ima/ima_policy.c106
-rw-r--r--security/integrity/ima/ima_queue.c2
-rw-r--r--security/integrity/ima/ima_template.c124
-rw-r--r--security/integrity/ima/ima_template_lib.c61
-rw-r--r--security/integrity/ima/ima_template_lib.h6
-rw-r--r--security/integrity/integrity.h7
-rw-r--r--security/lsm_audit.c16
-rw-r--r--security/security.c74
-rw-r--r--security/selinux/Makefile2
-rw-r--r--security/selinux/hooks.c212
-rw-r--r--security/selinux/ibpkey.c245
-rw-r--r--security/selinux/include/classmap.h6
-rw-r--r--security/selinux/include/ibpkey.h31
-rw-r--r--security/selinux/include/objsec.h11
-rw-r--r--security/selinux/include/security.h9
-rw-r--r--security/selinux/selinuxfs.c15
-rw-r--r--security/selinux/ss/ebitmap.c26
-rw-r--r--security/selinux/ss/ebitmap.h3
-rw-r--r--security/selinux/ss/policydb.c127
-rw-r--r--security/selinux/ss/policydb.h27
-rw-r--r--security/selinux/ss/services.c108
-rw-r--r--security/selinux/ss/sidtab.c27
-rw-r--r--security/smack/smack.h2
-rw-r--r--security/smack/smack_access.c19
-rw-r--r--security/smack/smack_lsm.c2
-rw-r--r--security/smack/smack_netfilter.c26
68 files changed, 8342 insertions, 2111 deletions
diff --git a/security/Kconfig b/security/Kconfig
index 93027fdf47d1..d540bfe73190 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -54,6 +54,15 @@ config SECURITY_NETWORK
54 implement socket and networking access controls. 54 implement socket and networking access controls.
55 If you are unsure how to answer this question, answer N. 55 If you are unsure how to answer this question, answer N.
56 56
57config SECURITY_INFINIBAND
58 bool "Infiniband Security Hooks"
59 depends on SECURITY && INFINIBAND
60 help
61 This enables the Infiniband security hooks.
62 If enabled, a security module can use these hooks to
63 implement Infiniband access controls.
64 If you are unsure how to answer this question, answer N.
65
57config SECURITY_NETWORK_XFRM 66config SECURITY_NETWORK_XFRM
58 bool "XFRM (IPSec) Networking Security Hooks" 67 bool "XFRM (IPSec) Networking Security Hooks"
59 depends on XFRM && SECURITY_NETWORK 68 depends on XFRM && SECURITY_NETWORK
@@ -139,7 +148,7 @@ config HARDENED_USERCOPY
139 copying memory to/from the kernel (via copy_to_user() and 148 copying memory to/from the kernel (via copy_to_user() and
140 copy_from_user() functions) by rejecting memory ranges that 149 copy_from_user() functions) by rejecting memory ranges that
141 are larger than the specified heap object, span multiple 150 are larger than the specified heap object, span multiple
142 separately allocates pages, are not on the process stack, 151 separately allocated pages, are not on the process stack,
143 or are part of the kernel text. This kills entire classes 152 or are part of the kernel text. This kills entire classes
144 of heap overflow exploits and similar kernel memory exposures. 153 of heap overflow exploits and similar kernel memory exposures.
145 154
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index ad369a7aac24..a16b195274de 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -4,7 +4,7 @@ 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 7 resource.o secid.o file.o policy_ns.o label.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
@@ -20,7 +20,7 @@ cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\
20 sed $< >>$@ -r -n -e '/CAP_FS_MASK/d' \ 20 sed $< >>$@ -r -n -e '/CAP_FS_MASK/d' \
21 -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\ 21 -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\
22 echo "};" >> $@ ;\ 22 echo "};" >> $@ ;\
23 echo -n '\#define AA_FS_CAPS_MASK "' >> $@ ;\ 23 printf '%s' '\#define AA_SFS_CAPS_MASK "' >> $@ ;\
24 sed $< -r -n -e '/CAP_FS_MASK/d' \ 24 sed $< -r -n -e '/CAP_FS_MASK/d' \
25 -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/\L\1/p' | \ 25 -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/\L\1/p' | \
26 tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@ 26 tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
@@ -46,7 +46,7 @@ cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\
46# #define RLIMIT_FSIZE 1 /* Maximum filesize */ 46# #define RLIMIT_FSIZE 1 /* Maximum filesize */
47# #define RLIMIT_STACK 3 /* max stack size */ 47# #define RLIMIT_STACK 3 /* max stack size */
48# to 48# to
49# #define AA_FS_RLIMIT_MASK "fsize stack" 49# #define AA_SFS_RLIMIT_MASK "fsize stack"
50quiet_cmd_make-rlim = GEN $@ 50quiet_cmd_make-rlim = GEN $@
51cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \ 51cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
52 > $@ ;\ 52 > $@ ;\
@@ -56,7 +56,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
56 echo "static const int rlim_map[RLIM_NLIMITS] = {" >> $@ ;\ 56 echo "static const int rlim_map[RLIM_NLIMITS] = {" >> $@ ;\
57 sed -r -n "s/^\# ?define[ \t]+(RLIMIT_[A-Z0-9_]+).*/\1,/p" $< >> $@ ;\ 57 sed -r -n "s/^\# ?define[ \t]+(RLIMIT_[A-Z0-9_]+).*/\1,/p" $< >> $@ ;\
58 echo "};" >> $@ ; \ 58 echo "};" >> $@ ; \
59 echo -n '\#define AA_FS_RLIMIT_MASK "' >> $@ ;\ 59 printf '%s' '\#define AA_SFS_RLIMIT_MASK "' >> $@ ;\
60 sed -r -n 's/^\# ?define[ \t]+RLIMIT_([A-Z0-9_]+).*/\L\1/p' $< | \ 60 sed -r -n 's/^\# ?define[ \t]+RLIMIT_([A-Z0-9_]+).*/\L\1/p' $< | \
61 tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@ 61 tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
62 62
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 4f6ac9dbc65d..853c2ec8e0c9 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -22,19 +22,52 @@
22#include <linux/namei.h> 22#include <linux/namei.h>
23#include <linux/capability.h> 23#include <linux/capability.h>
24#include <linux/rcupdate.h> 24#include <linux/rcupdate.h>
25#include <uapi/linux/major.h>
26#include <linux/fs.h> 25#include <linux/fs.h>
26#include <linux/poll.h>
27#include <uapi/linux/major.h>
28#include <uapi/linux/magic.h>
27 29
28#include "include/apparmor.h" 30#include "include/apparmor.h"
29#include "include/apparmorfs.h" 31#include "include/apparmorfs.h"
30#include "include/audit.h" 32#include "include/audit.h"
31#include "include/context.h" 33#include "include/context.h"
32#include "include/crypto.h" 34#include "include/crypto.h"
35#include "include/policy_ns.h"
36#include "include/label.h"
33#include "include/policy.h" 37#include "include/policy.h"
34#include "include/policy_ns.h" 38#include "include/policy_ns.h"
35#include "include/resource.h" 39#include "include/resource.h"
36#include "include/policy_unpack.h" 40#include "include/policy_unpack.h"
37 41
42/*
43 * The apparmor filesystem interface used for policy load and introspection
44 * The interface is split into two main components based on their function
45 * a securityfs component:
46 * used for static files that are always available, and which allows
47 * userspace to specificy the location of the security filesystem.
48 *
49 * fns and data are prefixed with
50 * aa_sfs_
51 *
52 * an apparmorfs component:
53 * used loaded policy content and introspection. It is not part of a
54 * regular mounted filesystem and is available only through the magic
55 * policy symlink in the root of the securityfs apparmor/ directory.
56 * Tasks queries will be magically redirected to the correct portion
57 * of the policy tree based on their confinement.
58 *
59 * fns and data are prefixed with
60 * aafs_
61 *
62 * The aa_fs_ prefix is used to indicate the fn is used by both the
63 * securityfs and apparmorfs filesystems.
64 */
65
66
67/*
68 * support fns
69 */
70
38/** 71/**
39 * aa_mangle_name - mangle a profile name to std profile layout form 72 * aa_mangle_name - mangle a profile name to std profile layout form
40 * @name: profile name to mangle (NOT NULL) 73 * @name: profile name to mangle (NOT NULL)
@@ -74,6 +107,265 @@ static int mangle_name(const char *name, char *target)
74 return t - target; 107 return t - target;
75} 108}
76 109
110
111/*
112 * aafs - core fns and data for the policy tree
113 */
114
115#define AAFS_NAME "apparmorfs"
116static struct vfsmount *aafs_mnt;
117static int aafs_count;
118
119
120static int aafs_show_path(struct seq_file *seq, struct dentry *dentry)
121{
122 struct inode *inode = d_inode(dentry);
123
124 seq_printf(seq, "%s:[%lu]", AAFS_NAME, inode->i_ino);
125 return 0;
126}
127
128static void aafs_evict_inode(struct inode *inode)
129{
130 truncate_inode_pages_final(&inode->i_data);
131 clear_inode(inode);
132 if (S_ISLNK(inode->i_mode))
133 kfree(inode->i_link);
134}
135
136static const struct super_operations aafs_super_ops = {
137 .statfs = simple_statfs,
138 .evict_inode = aafs_evict_inode,
139 .show_path = aafs_show_path,
140};
141
142static int fill_super(struct super_block *sb, void *data, int silent)
143{
144 static struct tree_descr files[] = { {""} };
145 int error;
146
147 error = simple_fill_super(sb, AAFS_MAGIC, files);
148 if (error)
149 return error;
150 sb->s_op = &aafs_super_ops;
151
152 return 0;
153}
154
155static struct dentry *aafs_mount(struct file_system_type *fs_type,
156 int flags, const char *dev_name, void *data)
157{
158 return mount_single(fs_type, flags, data, fill_super);
159}
160
161static struct file_system_type aafs_ops = {
162 .owner = THIS_MODULE,
163 .name = AAFS_NAME,
164 .mount = aafs_mount,
165 .kill_sb = kill_anon_super,
166};
167
168/**
169 * __aafs_setup_d_inode - basic inode setup for apparmorfs
170 * @dir: parent directory for the dentry
171 * @dentry: dentry we are seting the inode up for
172 * @mode: permissions the file should have
173 * @data: data to store on inode.i_private, available in open()
174 * @link: if symlink, symlink target string
175 * @fops: struct file_operations that should be used
176 * @iops: struct of inode_operations that should be used
177 */
178static int __aafs_setup_d_inode(struct inode *dir, struct dentry *dentry,
179 umode_t mode, void *data, char *link,
180 const struct file_operations *fops,
181 const struct inode_operations *iops)
182{
183 struct inode *inode = new_inode(dir->i_sb);
184
185 AA_BUG(!dir);
186 AA_BUG(!dentry);
187
188 if (!inode)
189 return -ENOMEM;
190
191 inode->i_ino = get_next_ino();
192 inode->i_mode = mode;
193 inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
194 inode->i_private = data;
195 if (S_ISDIR(mode)) {
196 inode->i_op = iops ? iops : &simple_dir_inode_operations;
197 inode->i_fop = &simple_dir_operations;
198 inc_nlink(inode);
199 inc_nlink(dir);
200 } else if (S_ISLNK(mode)) {
201 inode->i_op = iops ? iops : &simple_symlink_inode_operations;
202 inode->i_link = link;
203 } else {
204 inode->i_fop = fops;
205 }
206 d_instantiate(dentry, inode);
207 dget(dentry);
208
209 return 0;
210}
211
212/**
213 * aafs_create - create a dentry in the apparmorfs filesystem
214 *
215 * @name: name of dentry to create
216 * @mode: permissions the file should have
217 * @parent: parent directory for this dentry
218 * @data: data to store on inode.i_private, available in open()
219 * @link: if symlink, symlink target string
220 * @fops: struct file_operations that should be used for
221 * @iops: struct of inode_operations that should be used
222 *
223 * This is the basic "create a xxx" function for apparmorfs.
224 *
225 * Returns a pointer to a dentry if it succeeds, that must be free with
226 * aafs_remove(). Will return ERR_PTR on failure.
227 */
228static struct dentry *aafs_create(const char *name, umode_t mode,
229 struct dentry *parent, void *data, void *link,
230 const struct file_operations *fops,
231 const struct inode_operations *iops)
232{
233 struct dentry *dentry;
234 struct inode *dir;
235 int error;
236
237 AA_BUG(!name);
238 AA_BUG(!parent);
239
240 if (!(mode & S_IFMT))
241 mode = (mode & S_IALLUGO) | S_IFREG;
242
243 error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count);
244 if (error)
245 return ERR_PTR(error);
246
247 dir = d_inode(parent);
248
249 inode_lock(dir);
250 dentry = lookup_one_len(name, parent, strlen(name));
251 if (IS_ERR(dentry))
252 goto fail_lock;
253
254 if (d_really_is_positive(dentry)) {
255 error = -EEXIST;
256 goto fail_dentry;
257 }
258
259 error = __aafs_setup_d_inode(dir, dentry, mode, data, link, fops, iops);
260 if (error)
261 goto fail_dentry;
262 inode_unlock(dir);
263
264 return dentry;
265
266fail_dentry:
267 dput(dentry);
268
269fail_lock:
270 inode_unlock(dir);
271 simple_release_fs(&aafs_mnt, &aafs_count);
272
273 return ERR_PTR(error);
274}
275
276/**
277 * aafs_create_file - create a file in the apparmorfs filesystem
278 *
279 * @name: name of dentry to create
280 * @mode: permissions the file should have
281 * @parent: parent directory for this dentry
282 * @data: data to store on inode.i_private, available in open()
283 * @fops: struct file_operations that should be used for
284 *
285 * see aafs_create
286 */
287static struct dentry *aafs_create_file(const char *name, umode_t mode,
288 struct dentry *parent, void *data,
289 const struct file_operations *fops)
290{
291 return aafs_create(name, mode, parent, data, NULL, fops, NULL);
292}
293
294/**
295 * aafs_create_dir - create a directory in the apparmorfs filesystem
296 *
297 * @name: name of dentry to create
298 * @parent: parent directory for this dentry
299 *
300 * see aafs_create
301 */
302static struct dentry *aafs_create_dir(const char *name, struct dentry *parent)
303{
304 return aafs_create(name, S_IFDIR | 0755, parent, NULL, NULL, NULL,
305 NULL);
306}
307
308/**
309 * aafs_create_symlink - create a symlink in the apparmorfs filesystem
310 * @name: name of dentry to create
311 * @parent: parent directory for this dentry
312 * @target: if symlink, symlink target string
313 * @iops: struct of inode_operations that should be used
314 *
315 * If @target parameter is %NULL, then the @iops parameter needs to be
316 * setup to handle .readlink and .get_link inode_operations.
317 */
318static struct dentry *aafs_create_symlink(const char *name,
319 struct dentry *parent,
320 const char *target,
321 const struct inode_operations *iops)
322{
323 struct dentry *dent;
324 char *link = NULL;
325
326 if (target) {
327 link = kstrdup(target, GFP_KERNEL);
328 if (!link)
329 return ERR_PTR(-ENOMEM);
330 }
331 dent = aafs_create(name, S_IFLNK | 0444, parent, NULL, link, NULL,
332 iops);
333 if (IS_ERR(dent))
334 kfree(link);
335
336 return dent;
337}
338
339/**
340 * aafs_remove - removes a file or directory from the apparmorfs filesystem
341 *
342 * @dentry: dentry of the file/directory/symlink to removed.
343 */
344static void aafs_remove(struct dentry *dentry)
345{
346 struct inode *dir;
347
348 if (!dentry || IS_ERR(dentry))
349 return;
350
351 dir = d_inode(dentry->d_parent);
352 inode_lock(dir);
353 if (simple_positive(dentry)) {
354 if (d_is_dir(dentry))
355 simple_rmdir(dir, dentry);
356 else
357 simple_unlink(dir, dentry);
358 dput(dentry);
359 }
360 inode_unlock(dir);
361 simple_release_fs(&aafs_mnt, &aafs_count);
362}
363
364
365/*
366 * aa_fs - policy load/replace/remove
367 */
368
77/** 369/**
78 * aa_simple_write_to_buffer - common routine for getting policy from user 370 * aa_simple_write_to_buffer - common routine for getting policy from user
79 * @userbuf: user buffer to copy data from (NOT NULL) 371 * @userbuf: user buffer to copy data from (NOT NULL)
@@ -98,14 +390,11 @@ static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf,
98 return ERR_PTR(-ESPIPE); 390 return ERR_PTR(-ESPIPE);
99 391
100 /* freed by caller to simple_write_to_buffer */ 392 /* freed by caller to simple_write_to_buffer */
101 data = kvmalloc(sizeof(*data) + alloc_size, GFP_KERNEL); 393 data = aa_loaddata_alloc(alloc_size);
102 if (data == NULL) 394 if (IS_ERR(data))
103 return ERR_PTR(-ENOMEM); 395 return data;
104 kref_init(&data->count);
105 data->size = copy_size;
106 data->hash = NULL;
107 data->abi = 0;
108 396
397 data->size = copy_size;
109 if (copy_from_user(data->data, userbuf, copy_size)) { 398 if (copy_from_user(data->data, userbuf, copy_size)) {
110 kvfree(data); 399 kvfree(data);
111 return ERR_PTR(-EFAULT); 400 return ERR_PTR(-EFAULT);
@@ -114,27 +403,29 @@ static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf,
114 return data; 403 return data;
115} 404}
116 405
117static ssize_t policy_update(int binop, const char __user *buf, size_t size, 406static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
118 loff_t *pos, struct aa_ns *ns) 407 loff_t *pos, struct aa_ns *ns)
119{ 408{
120 ssize_t error;
121 struct aa_loaddata *data; 409 struct aa_loaddata *data;
122 struct aa_profile *profile = aa_current_profile(); 410 struct aa_label *label;
123 const char *op = binop == PROF_ADD ? OP_PROF_LOAD : OP_PROF_REPL; 411 ssize_t error;
412
413 label = begin_current_label_crit_section();
414
124 /* high level check about policy management - fine grained in 415 /* high level check about policy management - fine grained in
125 * below after unpack 416 * below after unpack
126 */ 417 */
127 error = aa_may_manage_policy(profile, ns, op); 418 error = aa_may_manage_policy(label, ns, mask);
128 if (error) 419 if (error)
129 return error; 420 return error;
130 421
131 data = aa_simple_write_to_buffer(buf, size, size, pos); 422 data = aa_simple_write_to_buffer(buf, size, size, pos);
132 error = PTR_ERR(data); 423 error = PTR_ERR(data);
133 if (!IS_ERR(data)) { 424 if (!IS_ERR(data)) {
134 error = aa_replace_profiles(ns ? ns : profile->ns, profile, 425 error = aa_replace_profiles(ns, label, mask, data);
135 binop, data);
136 aa_put_loaddata(data); 426 aa_put_loaddata(data);
137 } 427 }
428 end_current_label_crit_section(label);
138 429
139 return error; 430 return error;
140} 431}
@@ -144,7 +435,7 @@ static ssize_t profile_load(struct file *f, const char __user *buf, size_t size,
144 loff_t *pos) 435 loff_t *pos)
145{ 436{
146 struct aa_ns *ns = aa_get_ns(f->f_inode->i_private); 437 struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
147 int error = policy_update(PROF_ADD, buf, size, pos, ns); 438 int error = policy_update(AA_MAY_LOAD_POLICY, buf, size, pos, ns);
148 439
149 aa_put_ns(ns); 440 aa_put_ns(ns);
150 441
@@ -161,8 +452,8 @@ static ssize_t profile_replace(struct file *f, const char __user *buf,
161 size_t size, loff_t *pos) 452 size_t size, loff_t *pos)
162{ 453{
163 struct aa_ns *ns = aa_get_ns(f->f_inode->i_private); 454 struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
164 int error = policy_update(PROF_REPLACE, buf, size, pos, ns); 455 int error = policy_update(AA_MAY_LOAD_POLICY | AA_MAY_REPLACE_POLICY,
165 456 buf, size, pos, ns);
166 aa_put_ns(ns); 457 aa_put_ns(ns);
167 458
168 return error; 459 return error;
@@ -178,15 +469,15 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,
178 size_t size, loff_t *pos) 469 size_t size, loff_t *pos)
179{ 470{
180 struct aa_loaddata *data; 471 struct aa_loaddata *data;
181 struct aa_profile *profile; 472 struct aa_label *label;
182 ssize_t error; 473 ssize_t error;
183 struct aa_ns *ns = aa_get_ns(f->f_inode->i_private); 474 struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
184 475
185 profile = aa_current_profile(); 476 label = begin_current_label_crit_section();
186 /* high level check about policy management - fine grained in 477 /* high level check about policy management - fine grained in
187 * below after unpack 478 * below after unpack
188 */ 479 */
189 error = aa_may_manage_policy(profile, ns, OP_PROF_RM); 480 error = aa_may_manage_policy(label, ns, AA_MAY_REMOVE_POLICY);
190 if (error) 481 if (error)
191 goto out; 482 goto out;
192 483
@@ -199,11 +490,11 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,
199 error = PTR_ERR(data); 490 error = PTR_ERR(data);
200 if (!IS_ERR(data)) { 491 if (!IS_ERR(data)) {
201 data->data[size] = 0; 492 data->data[size] = 0;
202 error = aa_remove_profiles(ns ? ns : profile->ns, profile, 493 error = aa_remove_profiles(ns, label, data->data, size);
203 data->data, size);
204 aa_put_loaddata(data); 494 aa_put_loaddata(data);
205 } 495 }
206 out: 496 out:
497 end_current_label_crit_section(label);
207 aa_put_ns(ns); 498 aa_put_ns(ns);
208 return error; 499 return error;
209} 500}
@@ -213,6 +504,136 @@ static const struct file_operations aa_fs_profile_remove = {
213 .llseek = default_llseek, 504 .llseek = default_llseek,
214}; 505};
215 506
507struct aa_revision {
508 struct aa_ns *ns;
509 long last_read;
510};
511
512/* revision file hook fn for policy loads */
513static int ns_revision_release(struct inode *inode, struct file *file)
514{
515 struct aa_revision *rev = file->private_data;
516
517 if (rev) {
518 aa_put_ns(rev->ns);
519 kfree(rev);
520 }
521
522 return 0;
523}
524
525static ssize_t ns_revision_read(struct file *file, char __user *buf,
526 size_t size, loff_t *ppos)
527{
528 struct aa_revision *rev = file->private_data;
529 char buffer[32];
530 long last_read;
531 int avail;
532
533 mutex_lock(&rev->ns->lock);
534 last_read = rev->last_read;
535 if (last_read == rev->ns->revision) {
536 mutex_unlock(&rev->ns->lock);
537 if (file->f_flags & O_NONBLOCK)
538 return -EAGAIN;
539 if (wait_event_interruptible(rev->ns->wait,
540 last_read !=
541 READ_ONCE(rev->ns->revision)))
542 return -ERESTARTSYS;
543 mutex_lock(&rev->ns->lock);
544 }
545
546 avail = sprintf(buffer, "%ld\n", rev->ns->revision);
547 if (*ppos + size > avail) {
548 rev->last_read = rev->ns->revision;
549 *ppos = 0;
550 }
551 mutex_unlock(&rev->ns->lock);
552
553 return simple_read_from_buffer(buf, size, ppos, buffer, avail);
554}
555
556static int ns_revision_open(struct inode *inode, struct file *file)
557{
558 struct aa_revision *rev = kzalloc(sizeof(*rev), GFP_KERNEL);
559
560 if (!rev)
561 return -ENOMEM;
562
563 rev->ns = aa_get_ns(inode->i_private);
564 if (!rev->ns)
565 rev->ns = aa_get_current_ns();
566 file->private_data = rev;
567
568 return 0;
569}
570
571static unsigned int ns_revision_poll(struct file *file, poll_table *pt)
572{
573 struct aa_revision *rev = file->private_data;
574 unsigned int mask = 0;
575
576 if (rev) {
577 mutex_lock(&rev->ns->lock);
578 poll_wait(file, &rev->ns->wait, pt);
579 if (rev->last_read < rev->ns->revision)
580 mask |= POLLIN | POLLRDNORM;
581 mutex_unlock(&rev->ns->lock);
582 }
583
584 return mask;
585}
586
587void __aa_bump_ns_revision(struct aa_ns *ns)
588{
589 ns->revision++;
590 wake_up_interruptible(&ns->wait);
591}
592
593static const struct file_operations aa_fs_ns_revision_fops = {
594 .owner = THIS_MODULE,
595 .open = ns_revision_open,
596 .poll = ns_revision_poll,
597 .read = ns_revision_read,
598 .llseek = generic_file_llseek,
599 .release = ns_revision_release,
600};
601
602static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
603 const char *match_str, size_t match_len)
604{
605 struct aa_perms tmp;
606 struct aa_dfa *dfa;
607 unsigned int state = 0;
608
609 if (profile_unconfined(profile))
610 return;
611 if (profile->file.dfa && *match_str == AA_CLASS_FILE) {
612 dfa = profile->file.dfa;
613 state = aa_dfa_match_len(dfa, profile->file.start,
614 match_str + 1, match_len - 1);
615 tmp = nullperms;
616 if (state) {
617 struct path_cond cond = { };
618
619 tmp = aa_compute_fperms(dfa, state, &cond);
620 }
621 } else if (profile->policy.dfa) {
622 if (!PROFILE_MEDIATES_SAFE(profile, *match_str))
623 return; /* no change to current perms */
624 dfa = profile->policy.dfa;
625 state = aa_dfa_match_len(dfa, profile->policy.start[0],
626 match_str, match_len);
627 if (state)
628 aa_compute_perms(dfa, state, &tmp);
629 else
630 tmp = nullperms;
631 }
632 aa_apply_modes_to_perms(profile, &tmp);
633 aa_perms_accum_raw(perms, &tmp);
634}
635
636
216/** 637/**
217 * query_data - queries a policy and writes its data to buf 638 * query_data - queries a policy and writes its data to buf
218 * @buf: the resulting data is stored here (NOT NULL) 639 * @buf: the resulting data is stored here (NOT NULL)
@@ -236,6 +657,8 @@ static ssize_t query_data(char *buf, size_t buf_len,
236{ 657{
237 char *out; 658 char *out;
238 const char *key; 659 const char *key;
660 struct label_it i;
661 struct aa_label *label, *curr;
239 struct aa_profile *profile; 662 struct aa_profile *profile;
240 struct aa_data *data; 663 struct aa_data *data;
241 u32 bytes, blocks; 664 u32 bytes, blocks;
@@ -253,7 +676,11 @@ static ssize_t query_data(char *buf, size_t buf_len,
253 if (buf_len < sizeof(bytes) + sizeof(blocks)) 676 if (buf_len < sizeof(bytes) + sizeof(blocks))
254 return -EINVAL; /* not enough space */ 677 return -EINVAL; /* not enough space */
255 678
256 profile = aa_current_profile(); 679 curr = begin_current_label_crit_section();
680 label = aa_label_parse(curr, query, GFP_KERNEL, false, false);
681 end_current_label_crit_section(curr);
682 if (IS_ERR(label))
683 return PTR_ERR(label);
257 684
258 /* We are going to leave space for two numbers. The first is the total 685 /* We are going to leave space for two numbers. The first is the total
259 * number of bytes we are writing after the first number. This is so 686 * number of bytes we are writing after the first number. This is so
@@ -267,13 +694,19 @@ static ssize_t query_data(char *buf, size_t buf_len,
267 out = buf + sizeof(bytes) + sizeof(blocks); 694 out = buf + sizeof(bytes) + sizeof(blocks);
268 695
269 blocks = 0; 696 blocks = 0;
270 if (profile->data) { 697 label_for_each_confined(i, label, profile) {
698 if (!profile->data)
699 continue;
700
271 data = rhashtable_lookup_fast(profile->data, &key, 701 data = rhashtable_lookup_fast(profile->data, &key,
272 profile->data->p); 702 profile->data->p);
273 703
274 if (data) { 704 if (data) {
275 if (out + sizeof(outle32) + data->size > buf + buf_len) 705 if (out + sizeof(outle32) + data->size > buf +
706 buf_len) {
707 aa_put_label(label);
276 return -EINVAL; /* not enough space */ 708 return -EINVAL; /* not enough space */
709 }
277 outle32 = __cpu_to_le32(data->size); 710 outle32 = __cpu_to_le32(data->size);
278 memcpy(out, &outle32, sizeof(outle32)); 711 memcpy(out, &outle32, sizeof(outle32));
279 out += sizeof(outle32); 712 out += sizeof(outle32);
@@ -282,6 +715,7 @@ static ssize_t query_data(char *buf, size_t buf_len,
282 blocks++; 715 blocks++;
283 } 716 }
284 } 717 }
718 aa_put_label(label);
285 719
286 outle32 = __cpu_to_le32(out - buf - sizeof(bytes)); 720 outle32 = __cpu_to_le32(out - buf - sizeof(bytes));
287 memcpy(buf, &outle32, sizeof(outle32)); 721 memcpy(buf, &outle32, sizeof(outle32));
@@ -291,6 +725,182 @@ static ssize_t query_data(char *buf, size_t buf_len,
291 return out - buf; 725 return out - buf;
292} 726}
293 727
728/**
729 * query_label - queries a label and writes permissions to buf
730 * @buf: the resulting permissions string is stored here (NOT NULL)
731 * @buf_len: size of buf
732 * @query: binary query string to match against the dfa
733 * @query_len: size of query
734 * @view_only: only compute for querier's view
735 *
736 * The buffers pointed to by buf and query may overlap. The query buffer is
737 * parsed before buf is written to.
738 *
739 * The query should look like "LABEL_NAME\0DFA_STRING" where LABEL_NAME is
740 * the name of the label, in the current namespace, that is to be queried and
741 * DFA_STRING is a binary string to match against the label(s)'s DFA.
742 *
743 * LABEL_NAME must be NUL terminated. DFA_STRING may contain NUL characters
744 * but must *not* be NUL terminated.
745 *
746 * Returns: number of characters written to buf or -errno on failure
747 */
748static ssize_t query_label(char *buf, size_t buf_len,
749 char *query, size_t query_len, bool view_only)
750{
751 struct aa_profile *profile;
752 struct aa_label *label, *curr;
753 char *label_name, *match_str;
754 size_t label_name_len, match_len;
755 struct aa_perms perms;
756 struct label_it i;
757
758 if (!query_len)
759 return -EINVAL;
760
761 label_name = query;
762 label_name_len = strnlen(query, query_len);
763 if (!label_name_len || label_name_len == query_len)
764 return -EINVAL;
765
766 /**
767 * The extra byte is to account for the null byte between the
768 * profile name and dfa string. profile_name_len is greater
769 * than zero and less than query_len, so a byte can be safely
770 * added or subtracted.
771 */
772 match_str = label_name + label_name_len + 1;
773 match_len = query_len - label_name_len - 1;
774
775 curr = begin_current_label_crit_section();
776 label = aa_label_parse(curr, label_name, GFP_KERNEL, false, false);
777 end_current_label_crit_section(curr);
778 if (IS_ERR(label))
779 return PTR_ERR(label);
780
781 perms = allperms;
782 if (view_only) {
783 label_for_each_in_ns(i, labels_ns(label), label, profile) {
784 profile_query_cb(profile, &perms, match_str, match_len);
785 }
786 } else {
787 label_for_each(i, label, profile) {
788 profile_query_cb(profile, &perms, match_str, match_len);
789 }
790 }
791 aa_put_label(label);
792
793 return scnprintf(buf, buf_len,
794 "allow 0x%08x\ndeny 0x%08x\naudit 0x%08x\nquiet 0x%08x\n",
795 perms.allow, perms.deny, perms.audit, perms.quiet);
796}
797
798/*
799 * Transaction based IO.
800 * The file expects a write which triggers the transaction, and then
801 * possibly a read(s) which collects the result - which is stored in a
802 * file-local buffer. Once a new write is performed, a new set of results
803 * are stored in the file-local buffer.
804 */
805struct multi_transaction {
806 struct kref count;
807 ssize_t size;
808 char data[0];
809};
810
811#define MULTI_TRANSACTION_LIMIT (PAGE_SIZE - sizeof(struct multi_transaction))
812/* TODO: replace with per file lock */
813static DEFINE_SPINLOCK(multi_transaction_lock);
814
815static void multi_transaction_kref(struct kref *kref)
816{
817 struct multi_transaction *t;
818
819 t = container_of(kref, struct multi_transaction, count);
820 free_page((unsigned long) t);
821}
822
823static struct multi_transaction *
824get_multi_transaction(struct multi_transaction *t)
825{
826 if (t)
827 kref_get(&(t->count));
828
829 return t;
830}
831
832static void put_multi_transaction(struct multi_transaction *t)
833{
834 if (t)
835 kref_put(&(t->count), multi_transaction_kref);
836}
837
838/* does not increment @new's count */
839static void multi_transaction_set(struct file *file,
840 struct multi_transaction *new, size_t n)
841{
842 struct multi_transaction *old;
843
844 AA_BUG(n > MULTI_TRANSACTION_LIMIT);
845
846 new->size = n;
847 spin_lock(&multi_transaction_lock);
848 old = (struct multi_transaction *) file->private_data;
849 file->private_data = new;
850 spin_unlock(&multi_transaction_lock);
851 put_multi_transaction(old);
852}
853
854static struct multi_transaction *multi_transaction_new(struct file *file,
855 const char __user *buf,
856 size_t size)
857{
858 struct multi_transaction *t;
859
860 if (size > MULTI_TRANSACTION_LIMIT - 1)
861 return ERR_PTR(-EFBIG);
862
863 t = (struct multi_transaction *)get_zeroed_page(GFP_KERNEL);
864 if (!t)
865 return ERR_PTR(-ENOMEM);
866 kref_init(&t->count);
867 if (copy_from_user(t->data, buf, size))
868 return ERR_PTR(-EFAULT);
869
870 return t;
871}
872
873static ssize_t multi_transaction_read(struct file *file, char __user *buf,
874 size_t size, loff_t *pos)
875{
876 struct multi_transaction *t;
877 ssize_t ret;
878
879 spin_lock(&multi_transaction_lock);
880 t = get_multi_transaction(file->private_data);
881 spin_unlock(&multi_transaction_lock);
882 if (!t)
883 return 0;
884
885 ret = simple_read_from_buffer(buf, size, pos, t->data, t->size);
886 put_multi_transaction(t);
887
888 return ret;
889}
890
891static int multi_transaction_release(struct inode *inode, struct file *file)
892{
893 put_multi_transaction(file->private_data);
894
895 return 0;
896}
897
898#define QUERY_CMD_LABEL "label\0"
899#define QUERY_CMD_LABEL_LEN 6
900#define QUERY_CMD_PROFILE "profile\0"
901#define QUERY_CMD_PROFILE_LEN 8
902#define QUERY_CMD_LABELALL "labelall\0"
903#define QUERY_CMD_LABELALL_LEN 9
294#define QUERY_CMD_DATA "data\0" 904#define QUERY_CMD_DATA "data\0"
295#define QUERY_CMD_DATA_LEN 5 905#define QUERY_CMD_DATA_LEN 5
296 906
@@ -318,54 +928,72 @@ static ssize_t query_data(char *buf, size_t buf_len,
318static ssize_t aa_write_access(struct file *file, const char __user *ubuf, 928static ssize_t aa_write_access(struct file *file, const char __user *ubuf,
319 size_t count, loff_t *ppos) 929 size_t count, loff_t *ppos)
320{ 930{
321 char *buf; 931 struct multi_transaction *t;
322 ssize_t len; 932 ssize_t len;
323 933
324 if (*ppos) 934 if (*ppos)
325 return -ESPIPE; 935 return -ESPIPE;
326 936
327 buf = simple_transaction_get(file, ubuf, count); 937 t = multi_transaction_new(file, ubuf, count);
328 if (IS_ERR(buf)) 938 if (IS_ERR(t))
329 return PTR_ERR(buf); 939 return PTR_ERR(t);
330 940
331 if (count > QUERY_CMD_DATA_LEN && 941 if (count > QUERY_CMD_PROFILE_LEN &&
332 !memcmp(buf, QUERY_CMD_DATA, QUERY_CMD_DATA_LEN)) { 942 !memcmp(t->data, QUERY_CMD_PROFILE, QUERY_CMD_PROFILE_LEN)) {
333 len = query_data(buf, SIMPLE_TRANSACTION_LIMIT, 943 len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
334 buf + QUERY_CMD_DATA_LEN, 944 t->data + QUERY_CMD_PROFILE_LEN,
945 count - QUERY_CMD_PROFILE_LEN, true);
946 } else if (count > QUERY_CMD_LABEL_LEN &&
947 !memcmp(t->data, QUERY_CMD_LABEL, QUERY_CMD_LABEL_LEN)) {
948 len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
949 t->data + QUERY_CMD_LABEL_LEN,
950 count - QUERY_CMD_LABEL_LEN, true);
951 } else if (count > QUERY_CMD_LABELALL_LEN &&
952 !memcmp(t->data, QUERY_CMD_LABELALL,
953 QUERY_CMD_LABELALL_LEN)) {
954 len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
955 t->data + QUERY_CMD_LABELALL_LEN,
956 count - QUERY_CMD_LABELALL_LEN, false);
957 } else if (count > QUERY_CMD_DATA_LEN &&
958 !memcmp(t->data, QUERY_CMD_DATA, QUERY_CMD_DATA_LEN)) {
959 len = query_data(t->data, MULTI_TRANSACTION_LIMIT,
960 t->data + QUERY_CMD_DATA_LEN,
335 count - QUERY_CMD_DATA_LEN); 961 count - QUERY_CMD_DATA_LEN);
336 } else 962 } else
337 len = -EINVAL; 963 len = -EINVAL;
338 964
339 if (len < 0) 965 if (len < 0) {
966 put_multi_transaction(t);
340 return len; 967 return len;
968 }
341 969
342 simple_transaction_set(file, len); 970 multi_transaction_set(file, t, len);
343 971
344 return count; 972 return count;
345} 973}
346 974
347static const struct file_operations aa_fs_access = { 975static const struct file_operations aa_sfs_access = {
348 .write = aa_write_access, 976 .write = aa_write_access,
349 .read = simple_transaction_read, 977 .read = multi_transaction_read,
350 .release = simple_transaction_release, 978 .release = multi_transaction_release,
351 .llseek = generic_file_llseek, 979 .llseek = generic_file_llseek,
352}; 980};
353 981
354static int aa_fs_seq_show(struct seq_file *seq, void *v) 982static int aa_sfs_seq_show(struct seq_file *seq, void *v)
355{ 983{
356 struct aa_fs_entry *fs_file = seq->private; 984 struct aa_sfs_entry *fs_file = seq->private;
357 985
358 if (!fs_file) 986 if (!fs_file)
359 return 0; 987 return 0;
360 988
361 switch (fs_file->v_type) { 989 switch (fs_file->v_type) {
362 case AA_FS_TYPE_BOOLEAN: 990 case AA_SFS_TYPE_BOOLEAN:
363 seq_printf(seq, "%s\n", fs_file->v.boolean ? "yes" : "no"); 991 seq_printf(seq, "%s\n", fs_file->v.boolean ? "yes" : "no");
364 break; 992 break;
365 case AA_FS_TYPE_STRING: 993 case AA_SFS_TYPE_STRING:
366 seq_printf(seq, "%s\n", fs_file->v.string); 994 seq_printf(seq, "%s\n", fs_file->v.string);
367 break; 995 break;
368 case AA_FS_TYPE_U64: 996 case AA_SFS_TYPE_U64:
369 seq_printf(seq, "%#08lx\n", fs_file->v.u64); 997 seq_printf(seq, "%#08lx\n", fs_file->v.u64);
370 break; 998 break;
371 default: 999 default:
@@ -376,21 +1004,40 @@ static int aa_fs_seq_show(struct seq_file *seq, void *v)
376 return 0; 1004 return 0;
377} 1005}
378 1006
379static int aa_fs_seq_open(struct inode *inode, struct file *file) 1007static int aa_sfs_seq_open(struct inode *inode, struct file *file)
380{ 1008{
381 return single_open(file, aa_fs_seq_show, inode->i_private); 1009 return single_open(file, aa_sfs_seq_show, inode->i_private);
382} 1010}
383 1011
384const struct file_operations aa_fs_seq_file_ops = { 1012const struct file_operations aa_sfs_seq_file_ops = {
385 .owner = THIS_MODULE, 1013 .owner = THIS_MODULE,
386 .open = aa_fs_seq_open, 1014 .open = aa_sfs_seq_open,
387 .read = seq_read, 1015 .read = seq_read,
388 .llseek = seq_lseek, 1016 .llseek = seq_lseek,
389 .release = single_release, 1017 .release = single_release,
390}; 1018};
391 1019
392static int aa_fs_seq_profile_open(struct inode *inode, struct file *file, 1020/*
393 int (*show)(struct seq_file *, void *)) 1021 * profile based file operations
1022 * policy/profiles/XXXX/profiles/ *
1023 */
1024
1025#define SEQ_PROFILE_FOPS(NAME) \
1026static int seq_profile_ ##NAME ##_open(struct inode *inode, struct file *file)\
1027{ \
1028 return seq_profile_open(inode, file, seq_profile_ ##NAME ##_show); \
1029} \
1030 \
1031static const struct file_operations seq_profile_ ##NAME ##_fops = { \
1032 .owner = THIS_MODULE, \
1033 .open = seq_profile_ ##NAME ##_open, \
1034 .read = seq_read, \
1035 .llseek = seq_lseek, \
1036 .release = seq_profile_release, \
1037} \
1038
1039static int seq_profile_open(struct inode *inode, struct file *file,
1040 int (*show)(struct seq_file *, void *))
394{ 1041{
395 struct aa_proxy *proxy = aa_get_proxy(inode->i_private); 1042 struct aa_proxy *proxy = aa_get_proxy(inode->i_private);
396 int error = single_open(file, show, proxy); 1043 int error = single_open(file, show, proxy);
@@ -403,7 +1050,7 @@ static int aa_fs_seq_profile_open(struct inode *inode, struct file *file,
403 return error; 1050 return error;
404} 1051}
405 1052
406static int aa_fs_seq_profile_release(struct inode *inode, struct file *file) 1053static int seq_profile_release(struct inode *inode, struct file *file)
407{ 1054{
408 struct seq_file *seq = (struct seq_file *) file->private_data; 1055 struct seq_file *seq = (struct seq_file *) file->private_data;
409 if (seq) 1056 if (seq)
@@ -411,217 +1058,229 @@ static int aa_fs_seq_profile_release(struct inode *inode, struct file *file)
411 return single_release(inode, file); 1058 return single_release(inode, file);
412} 1059}
413 1060
414static int aa_fs_seq_profname_show(struct seq_file *seq, void *v) 1061static int seq_profile_name_show(struct seq_file *seq, void *v)
415{ 1062{
416 struct aa_proxy *proxy = seq->private; 1063 struct aa_proxy *proxy = seq->private;
417 struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile); 1064 struct aa_label *label = aa_get_label_rcu(&proxy->label);
1065 struct aa_profile *profile = labels_profile(label);
418 seq_printf(seq, "%s\n", profile->base.name); 1066 seq_printf(seq, "%s\n", profile->base.name);
419 aa_put_profile(profile); 1067 aa_put_label(label);
420 1068
421 return 0; 1069 return 0;
422} 1070}
423 1071
424static int aa_fs_seq_profname_open(struct inode *inode, struct file *file) 1072static int seq_profile_mode_show(struct seq_file *seq, void *v)
425{
426 return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profname_show);
427}
428
429static const struct file_operations aa_fs_profname_fops = {
430 .owner = THIS_MODULE,
431 .open = aa_fs_seq_profname_open,
432 .read = seq_read,
433 .llseek = seq_lseek,
434 .release = aa_fs_seq_profile_release,
435};
436
437static int aa_fs_seq_profmode_show(struct seq_file *seq, void *v)
438{ 1073{
439 struct aa_proxy *proxy = seq->private; 1074 struct aa_proxy *proxy = seq->private;
440 struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile); 1075 struct aa_label *label = aa_get_label_rcu(&proxy->label);
1076 struct aa_profile *profile = labels_profile(label);
441 seq_printf(seq, "%s\n", aa_profile_mode_names[profile->mode]); 1077 seq_printf(seq, "%s\n", aa_profile_mode_names[profile->mode]);
442 aa_put_profile(profile); 1078 aa_put_label(label);
443 1079
444 return 0; 1080 return 0;
445} 1081}
446 1082
447static int aa_fs_seq_profmode_open(struct inode *inode, struct file *file) 1083static int seq_profile_attach_show(struct seq_file *seq, void *v)
448{
449 return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profmode_show);
450}
451
452static const struct file_operations aa_fs_profmode_fops = {
453 .owner = THIS_MODULE,
454 .open = aa_fs_seq_profmode_open,
455 .read = seq_read,
456 .llseek = seq_lseek,
457 .release = aa_fs_seq_profile_release,
458};
459
460static int aa_fs_seq_profattach_show(struct seq_file *seq, void *v)
461{ 1084{
462 struct aa_proxy *proxy = seq->private; 1085 struct aa_proxy *proxy = seq->private;
463 struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile); 1086 struct aa_label *label = aa_get_label_rcu(&proxy->label);
1087 struct aa_profile *profile = labels_profile(label);
464 if (profile->attach) 1088 if (profile->attach)
465 seq_printf(seq, "%s\n", profile->attach); 1089 seq_printf(seq, "%s\n", profile->attach);
466 else if (profile->xmatch) 1090 else if (profile->xmatch)
467 seq_puts(seq, "<unknown>\n"); 1091 seq_puts(seq, "<unknown>\n");
468 else 1092 else
469 seq_printf(seq, "%s\n", profile->base.name); 1093 seq_printf(seq, "%s\n", profile->base.name);
470 aa_put_profile(profile); 1094 aa_put_label(label);
471 1095
472 return 0; 1096 return 0;
473} 1097}
474 1098
475static int aa_fs_seq_profattach_open(struct inode *inode, struct file *file) 1099static int seq_profile_hash_show(struct seq_file *seq, void *v)
476{
477 return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profattach_show);
478}
479
480static const struct file_operations aa_fs_profattach_fops = {
481 .owner = THIS_MODULE,
482 .open = aa_fs_seq_profattach_open,
483 .read = seq_read,
484 .llseek = seq_lseek,
485 .release = aa_fs_seq_profile_release,
486};
487
488static int aa_fs_seq_hash_show(struct seq_file *seq, void *v)
489{ 1100{
490 struct aa_proxy *proxy = seq->private; 1101 struct aa_proxy *proxy = seq->private;
491 struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile); 1102 struct aa_label *label = aa_get_label_rcu(&proxy->label);
1103 struct aa_profile *profile = labels_profile(label);
492 unsigned int i, size = aa_hash_size(); 1104 unsigned int i, size = aa_hash_size();
493 1105
494 if (profile->hash) { 1106 if (profile->hash) {
495 for (i = 0; i < size; i++) 1107 for (i = 0; i < size; i++)
496 seq_printf(seq, "%.2x", profile->hash[i]); 1108 seq_printf(seq, "%.2x", profile->hash[i]);
497 seq_puts(seq, "\n"); 1109 seq_putc(seq, '\n');
498 } 1110 }
499 aa_put_profile(profile); 1111 aa_put_label(label);
500 1112
501 return 0; 1113 return 0;
502} 1114}
503 1115
504static int aa_fs_seq_hash_open(struct inode *inode, struct file *file) 1116SEQ_PROFILE_FOPS(name);
1117SEQ_PROFILE_FOPS(mode);
1118SEQ_PROFILE_FOPS(attach);
1119SEQ_PROFILE_FOPS(hash);
1120
1121/*
1122 * namespace based files
1123 * several root files and
1124 * policy/ *
1125 */
1126
1127#define SEQ_NS_FOPS(NAME) \
1128static int seq_ns_ ##NAME ##_open(struct inode *inode, struct file *file) \
1129{ \
1130 return single_open(file, seq_ns_ ##NAME ##_show, inode->i_private); \
1131} \
1132 \
1133static const struct file_operations seq_ns_ ##NAME ##_fops = { \
1134 .owner = THIS_MODULE, \
1135 .open = seq_ns_ ##NAME ##_open, \
1136 .read = seq_read, \
1137 .llseek = seq_lseek, \
1138 .release = single_release, \
1139} \
1140
1141static int seq_ns_stacked_show(struct seq_file *seq, void *v)
505{ 1142{
506 return single_open(file, aa_fs_seq_hash_show, inode->i_private); 1143 struct aa_label *label;
507}
508 1144
509static const struct file_operations aa_fs_seq_hash_fops = { 1145 label = begin_current_label_crit_section();
510 .owner = THIS_MODULE, 1146 seq_printf(seq, "%s\n", label->size > 1 ? "yes" : "no");
511 .open = aa_fs_seq_hash_open, 1147 end_current_label_crit_section(label);
512 .read = seq_read,
513 .llseek = seq_lseek,
514 .release = single_release,
515};
516 1148
1149 return 0;
1150}
517 1151
518static int aa_fs_seq_show_ns_level(struct seq_file *seq, void *v) 1152static int seq_ns_nsstacked_show(struct seq_file *seq, void *v)
519{ 1153{
520 struct aa_ns *ns = aa_current_profile()->ns; 1154 struct aa_label *label;
1155 struct aa_profile *profile;
1156 struct label_it it;
1157 int count = 1;
521 1158
522 seq_printf(seq, "%d\n", ns->level); 1159 label = begin_current_label_crit_section();
1160
1161 if (label->size > 1) {
1162 label_for_each(it, label, profile)
1163 if (profile->ns != labels_ns(label)) {
1164 count++;
1165 break;
1166 }
1167 }
1168
1169 seq_printf(seq, "%s\n", count > 1 ? "yes" : "no");
1170 end_current_label_crit_section(label);
523 1171
524 return 0; 1172 return 0;
525} 1173}
526 1174
527static int aa_fs_seq_open_ns_level(struct inode *inode, struct file *file) 1175static int seq_ns_level_show(struct seq_file *seq, void *v)
528{ 1176{
529 return single_open(file, aa_fs_seq_show_ns_level, inode->i_private); 1177 struct aa_label *label;
530}
531 1178
532static const struct file_operations aa_fs_ns_level = { 1179 label = begin_current_label_crit_section();
533 .owner = THIS_MODULE, 1180 seq_printf(seq, "%d\n", labels_ns(label)->level);
534 .open = aa_fs_seq_open_ns_level, 1181 end_current_label_crit_section(label);
535 .read = seq_read, 1182
536 .llseek = seq_lseek, 1183 return 0;
537 .release = single_release, 1184}
538};
539 1185
540static int aa_fs_seq_show_ns_name(struct seq_file *seq, void *v) 1186static int seq_ns_name_show(struct seq_file *seq, void *v)
541{ 1187{
542 struct aa_ns *ns = aa_current_profile()->ns; 1188 struct aa_label *label = begin_current_label_crit_section();
543 1189
544 seq_printf(seq, "%s\n", ns->base.name); 1190 seq_printf(seq, "%s\n", aa_ns_name(labels_ns(label),
1191 labels_ns(label), true));
1192 end_current_label_crit_section(label);
545 1193
546 return 0; 1194 return 0;
547} 1195}
548 1196
549static int aa_fs_seq_open_ns_name(struct inode *inode, struct file *file) 1197SEQ_NS_FOPS(stacked);
1198SEQ_NS_FOPS(nsstacked);
1199SEQ_NS_FOPS(level);
1200SEQ_NS_FOPS(name);
1201
1202
1203/* policy/raw_data/ * file ops */
1204
1205#define SEQ_RAWDATA_FOPS(NAME) \
1206static int seq_rawdata_ ##NAME ##_open(struct inode *inode, struct file *file)\
1207{ \
1208 return seq_rawdata_open(inode, file, seq_rawdata_ ##NAME ##_show); \
1209} \
1210 \
1211static const struct file_operations seq_rawdata_ ##NAME ##_fops = { \
1212 .owner = THIS_MODULE, \
1213 .open = seq_rawdata_ ##NAME ##_open, \
1214 .read = seq_read, \
1215 .llseek = seq_lseek, \
1216 .release = seq_rawdata_release, \
1217} \
1218
1219static int seq_rawdata_open(struct inode *inode, struct file *file,
1220 int (*show)(struct seq_file *, void *))
550{ 1221{
551 return single_open(file, aa_fs_seq_show_ns_name, inode->i_private); 1222 struct aa_loaddata *data = __aa_get_loaddata(inode->i_private);
552} 1223 int error;
553 1224
554static const struct file_operations aa_fs_ns_name = { 1225 if (!data)
555 .owner = THIS_MODULE, 1226 /* lost race this ent is being reaped */
556 .open = aa_fs_seq_open_ns_name, 1227 return -ENOENT;
557 .read = seq_read,
558 .llseek = seq_lseek,
559 .release = single_release,
560};
561 1228
562static int rawdata_release(struct inode *inode, struct file *file) 1229 error = single_open(file, show, data);
1230 if (error) {
1231 AA_BUG(file->private_data &&
1232 ((struct seq_file *)file->private_data)->private);
1233 aa_put_loaddata(data);
1234 }
1235
1236 return error;
1237}
1238
1239static int seq_rawdata_release(struct inode *inode, struct file *file)
563{ 1240{
564 /* TODO: switch to loaddata when profile switched to symlink */ 1241 struct seq_file *seq = (struct seq_file *) file->private_data;
565 aa_put_loaddata(file->private_data);
566 1242
567 return 0; 1243 if (seq)
1244 aa_put_loaddata(seq->private);
1245
1246 return single_release(inode, file);
568} 1247}
569 1248
570static int aa_fs_seq_raw_abi_show(struct seq_file *seq, void *v) 1249static int seq_rawdata_abi_show(struct seq_file *seq, void *v)
571{ 1250{
572 struct aa_proxy *proxy = seq->private; 1251 struct aa_loaddata *data = seq->private;
573 struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
574 1252
575 if (profile->rawdata->abi) { 1253 seq_printf(seq, "v%d\n", data->abi);
576 seq_printf(seq, "v%d", profile->rawdata->abi);
577 seq_puts(seq, "\n");
578 }
579 aa_put_profile(profile);
580 1254
581 return 0; 1255 return 0;
582} 1256}
583 1257
584static int aa_fs_seq_raw_abi_open(struct inode *inode, struct file *file) 1258static int seq_rawdata_revision_show(struct seq_file *seq, void *v)
585{ 1259{
586 return aa_fs_seq_profile_open(inode, file, aa_fs_seq_raw_abi_show); 1260 struct aa_loaddata *data = seq->private;
587}
588 1261
589static const struct file_operations aa_fs_seq_raw_abi_fops = { 1262 seq_printf(seq, "%ld\n", data->revision);
590 .owner = THIS_MODULE, 1263
591 .open = aa_fs_seq_raw_abi_open, 1264 return 0;
592 .read = seq_read, 1265}
593 .llseek = seq_lseek,
594 .release = aa_fs_seq_profile_release,
595};
596 1266
597static int aa_fs_seq_raw_hash_show(struct seq_file *seq, void *v) 1267static int seq_rawdata_hash_show(struct seq_file *seq, void *v)
598{ 1268{
599 struct aa_proxy *proxy = seq->private; 1269 struct aa_loaddata *data = seq->private;
600 struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
601 unsigned int i, size = aa_hash_size(); 1270 unsigned int i, size = aa_hash_size();
602 1271
603 if (profile->rawdata->hash) { 1272 if (data->hash) {
604 for (i = 0; i < size; i++) 1273 for (i = 0; i < size; i++)
605 seq_printf(seq, "%.2x", profile->rawdata->hash[i]); 1274 seq_printf(seq, "%.2x", data->hash[i]);
606 seq_puts(seq, "\n"); 1275 seq_putc(seq, '\n');
607 } 1276 }
608 aa_put_profile(profile);
609 1277
610 return 0; 1278 return 0;
611} 1279}
612 1280
613static int aa_fs_seq_raw_hash_open(struct inode *inode, struct file *file) 1281SEQ_RAWDATA_FOPS(abi);
614{ 1282SEQ_RAWDATA_FOPS(revision);
615 return aa_fs_seq_profile_open(inode, file, aa_fs_seq_raw_hash_show); 1283SEQ_RAWDATA_FOPS(hash);
616}
617
618static const struct file_operations aa_fs_seq_raw_hash_fops = {
619 .owner = THIS_MODULE,
620 .open = aa_fs_seq_raw_hash_open,
621 .read = seq_read,
622 .llseek = seq_lseek,
623 .release = aa_fs_seq_profile_release,
624};
625 1284
626static ssize_t rawdata_read(struct file *file, char __user *buf, size_t size, 1285static ssize_t rawdata_read(struct file *file, char __user *buf, size_t size,
627 loff_t *ppos) 1286 loff_t *ppos)
@@ -632,29 +1291,127 @@ static ssize_t rawdata_read(struct file *file, char __user *buf, size_t size,
632 rawdata->size); 1291 rawdata->size);
633} 1292}
634 1293
635static int rawdata_open(struct inode *inode, struct file *file) 1294static int rawdata_release(struct inode *inode, struct file *file)
636{ 1295{
637 struct aa_proxy *proxy = inode->i_private; 1296 aa_put_loaddata(file->private_data);
638 struct aa_profile *profile;
639 1297
1298 return 0;
1299}
1300
1301static int rawdata_open(struct inode *inode, struct file *file)
1302{
640 if (!policy_view_capable(NULL)) 1303 if (!policy_view_capable(NULL))
641 return -EACCES; 1304 return -EACCES;
642 profile = aa_get_profile_rcu(&proxy->profile); 1305 file->private_data = __aa_get_loaddata(inode->i_private);
643 file->private_data = aa_get_loaddata(profile->rawdata); 1306 if (!file->private_data)
644 aa_put_profile(profile); 1307 /* lost race: this entry is being reaped */
1308 return -ENOENT;
645 1309
646 return 0; 1310 return 0;
647} 1311}
648 1312
649static const struct file_operations aa_fs_rawdata_fops = { 1313static const struct file_operations rawdata_fops = {
650 .open = rawdata_open, 1314 .open = rawdata_open,
651 .read = rawdata_read, 1315 .read = rawdata_read,
652 .llseek = generic_file_llseek, 1316 .llseek = generic_file_llseek,
653 .release = rawdata_release, 1317 .release = rawdata_release,
654}; 1318};
655 1319
1320static void remove_rawdata_dents(struct aa_loaddata *rawdata)
1321{
1322 int i;
1323
1324 for (i = 0; i < AAFS_LOADDATA_NDENTS; i++) {
1325 if (!IS_ERR_OR_NULL(rawdata->dents[i])) {
1326 /* no refcounts on i_private */
1327 aafs_remove(rawdata->dents[i]);
1328 rawdata->dents[i] = NULL;
1329 }
1330 }
1331}
1332
1333void __aa_fs_remove_rawdata(struct aa_loaddata *rawdata)
1334{
1335 AA_BUG(rawdata->ns && !mutex_is_locked(&rawdata->ns->lock));
1336
1337 if (rawdata->ns) {
1338 remove_rawdata_dents(rawdata);
1339 list_del_init(&rawdata->list);
1340 aa_put_ns(rawdata->ns);
1341 rawdata->ns = NULL;
1342 }
1343}
1344
1345int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata)
1346{
1347 struct dentry *dent, *dir;
1348
1349 AA_BUG(!ns);
1350 AA_BUG(!rawdata);
1351 AA_BUG(!mutex_is_locked(&ns->lock));
1352 AA_BUG(!ns_subdata_dir(ns));
1353
1354 /*
1355 * just use ns revision dir was originally created at. This is
1356 * under ns->lock and if load is successful revision will be
1357 * bumped and is guaranteed to be unique
1358 */
1359 rawdata->name = kasprintf(GFP_KERNEL, "%ld", ns->revision);
1360 if (!rawdata->name)
1361 return -ENOMEM;
1362
1363 dir = aafs_create_dir(rawdata->name, ns_subdata_dir(ns));
1364 if (IS_ERR(dir))
1365 /* ->name freed when rawdata freed */
1366 return PTR_ERR(dir);
1367 rawdata->dents[AAFS_LOADDATA_DIR] = dir;
1368
1369 dent = aafs_create_file("abi", S_IFREG | 0444, dir, rawdata,
1370 &seq_rawdata_abi_fops);
1371 if (IS_ERR(dent))
1372 goto fail;
1373 rawdata->dents[AAFS_LOADDATA_ABI] = dent;
1374
1375 dent = aafs_create_file("revision", S_IFREG | 0444, dir, rawdata,
1376 &seq_rawdata_revision_fops);
1377 if (IS_ERR(dent))
1378 goto fail;
1379 rawdata->dents[AAFS_LOADDATA_REVISION] = dent;
1380
1381 if (aa_g_hash_policy) {
1382 dent = aafs_create_file("sha1", S_IFREG | 0444, dir,
1383 rawdata, &seq_rawdata_hash_fops);
1384 if (IS_ERR(dent))
1385 goto fail;
1386 rawdata->dents[AAFS_LOADDATA_HASH] = dent;
1387 }
1388
1389 dent = aafs_create_file("raw_data", S_IFREG | 0444,
1390 dir, rawdata, &rawdata_fops);
1391 if (IS_ERR(dent))
1392 goto fail;
1393 rawdata->dents[AAFS_LOADDATA_DATA] = dent;
1394 d_inode(dent)->i_size = rawdata->size;
1395
1396 rawdata->ns = aa_get_ns(ns);
1397 list_add(&rawdata->list, &ns->rawdata_list);
1398 /* no refcount on inode rawdata */
1399
1400 return 0;
1401
1402fail:
1403 remove_rawdata_dents(rawdata);
1404
1405 return PTR_ERR(dent);
1406}
1407
656/** fns to setup dynamic per profile/namespace files **/ 1408/** fns to setup dynamic per profile/namespace files **/
657void __aa_fs_profile_rmdir(struct aa_profile *profile) 1409
1410/**
1411 *
1412 * Requires: @profile->ns->lock held
1413 */
1414void __aafs_profile_rmdir(struct aa_profile *profile)
658{ 1415{
659 struct aa_profile *child; 1416 struct aa_profile *child;
660 int i; 1417 int i;
@@ -663,7 +1420,7 @@ void __aa_fs_profile_rmdir(struct aa_profile *profile)
663 return; 1420 return;
664 1421
665 list_for_each_entry(child, &profile->base.profiles, base.list) 1422 list_for_each_entry(child, &profile->base.profiles, base.list)
666 __aa_fs_profile_rmdir(child); 1423 __aafs_profile_rmdir(child);
667 1424
668 for (i = AAFS_PROF_SIZEOF - 1; i >= 0; --i) { 1425 for (i = AAFS_PROF_SIZEOF - 1; i >= 0; --i) {
669 struct aa_proxy *proxy; 1426 struct aa_proxy *proxy;
@@ -671,14 +1428,18 @@ void __aa_fs_profile_rmdir(struct aa_profile *profile)
671 continue; 1428 continue;
672 1429
673 proxy = d_inode(profile->dents[i])->i_private; 1430 proxy = d_inode(profile->dents[i])->i_private;
674 securityfs_remove(profile->dents[i]); 1431 aafs_remove(profile->dents[i]);
675 aa_put_proxy(proxy); 1432 aa_put_proxy(proxy);
676 profile->dents[i] = NULL; 1433 profile->dents[i] = NULL;
677 } 1434 }
678} 1435}
679 1436
680void __aa_fs_profile_migrate_dents(struct aa_profile *old, 1437/**
681 struct aa_profile *new) 1438 *
1439 * Requires: @old->ns->lock held
1440 */
1441void __aafs_profile_migrate_dents(struct aa_profile *old,
1442 struct aa_profile *new)
682{ 1443{
683 int i; 1444 int i;
684 1445
@@ -694,18 +1455,52 @@ static struct dentry *create_profile_file(struct dentry *dir, const char *name,
694 struct aa_profile *profile, 1455 struct aa_profile *profile,
695 const struct file_operations *fops) 1456 const struct file_operations *fops)
696{ 1457{
697 struct aa_proxy *proxy = aa_get_proxy(profile->proxy); 1458 struct aa_proxy *proxy = aa_get_proxy(profile->label.proxy);
698 struct dentry *dent; 1459 struct dentry *dent;
699 1460
700 dent = securityfs_create_file(name, S_IFREG | 0444, dir, proxy, fops); 1461 dent = aafs_create_file(name, S_IFREG | 0444, dir, proxy, fops);
701 if (IS_ERR(dent)) 1462 if (IS_ERR(dent))
702 aa_put_proxy(proxy); 1463 aa_put_proxy(proxy);
703 1464
704 return dent; 1465 return dent;
705} 1466}
706 1467
707/* requires lock be held */ 1468static int profile_depth(struct aa_profile *profile)
708int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent) 1469{
1470 int depth = 0;
1471
1472 rcu_read_lock();
1473 for (depth = 0; profile; profile = rcu_access_pointer(profile->parent))
1474 depth++;
1475 rcu_read_unlock();
1476
1477 return depth;
1478}
1479
1480static int gen_symlink_name(char *buffer, size_t bsize, int depth,
1481 const char *dirname, const char *fname)
1482{
1483 int error;
1484
1485 for (; depth > 0; depth--) {
1486 if (bsize < 7)
1487 return -ENAMETOOLONG;
1488 strcpy(buffer, "../../");
1489 buffer += 6;
1490 bsize -= 6;
1491 }
1492
1493 error = snprintf(buffer, bsize, "raw_data/%s/%s", dirname, fname);
1494 if (error >= bsize || error < 0)
1495 return -ENAMETOOLONG;
1496
1497 return 0;
1498}
1499
1500/*
1501 * Requires: @profile->ns->lock held
1502 */
1503int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
709{ 1504{
710 struct aa_profile *child; 1505 struct aa_profile *child;
711 struct dentry *dent = NULL, *dir; 1506 struct dentry *dent = NULL, *dir;
@@ -716,7 +1511,7 @@ int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
716 p = aa_deref_parent(profile); 1511 p = aa_deref_parent(profile);
717 dent = prof_dir(p); 1512 dent = prof_dir(p);
718 /* adding to parent that previously didn't have children */ 1513 /* adding to parent that previously didn't have children */
719 dent = securityfs_create_dir("profiles", dent); 1514 dent = aafs_create_dir("profiles", dent);
720 if (IS_ERR(dent)) 1515 if (IS_ERR(dent))
721 goto fail; 1516 goto fail;
722 prof_child_dir(p) = parent = dent; 1517 prof_child_dir(p) = parent = dent;
@@ -728,67 +1523,80 @@ int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
728 id_len = snprintf(NULL, 0, ".%ld", profile->ns->uniq_id); 1523 id_len = snprintf(NULL, 0, ".%ld", profile->ns->uniq_id);
729 1524
730 profile->dirname = kmalloc(len + id_len + 1, GFP_KERNEL); 1525 profile->dirname = kmalloc(len + id_len + 1, GFP_KERNEL);
731 if (!profile->dirname) 1526 if (!profile->dirname) {
732 goto fail; 1527 error = -ENOMEM;
1528 goto fail2;
1529 }
733 1530
734 mangle_name(profile->base.name, profile->dirname); 1531 mangle_name(profile->base.name, profile->dirname);
735 sprintf(profile->dirname + len, ".%ld", profile->ns->uniq_id++); 1532 sprintf(profile->dirname + len, ".%ld", profile->ns->uniq_id++);
736 } 1533 }
737 1534
738 dent = securityfs_create_dir(profile->dirname, parent); 1535 dent = aafs_create_dir(profile->dirname, parent);
739 if (IS_ERR(dent)) 1536 if (IS_ERR(dent))
740 goto fail; 1537 goto fail;
741 prof_dir(profile) = dir = dent; 1538 prof_dir(profile) = dir = dent;
742 1539
743 dent = create_profile_file(dir, "name", profile, &aa_fs_profname_fops); 1540 dent = create_profile_file(dir, "name", profile,
1541 &seq_profile_name_fops);
744 if (IS_ERR(dent)) 1542 if (IS_ERR(dent))
745 goto fail; 1543 goto fail;
746 profile->dents[AAFS_PROF_NAME] = dent; 1544 profile->dents[AAFS_PROF_NAME] = dent;
747 1545
748 dent = create_profile_file(dir, "mode", profile, &aa_fs_profmode_fops); 1546 dent = create_profile_file(dir, "mode", profile,
1547 &seq_profile_mode_fops);
749 if (IS_ERR(dent)) 1548 if (IS_ERR(dent))
750 goto fail; 1549 goto fail;
751 profile->dents[AAFS_PROF_MODE] = dent; 1550 profile->dents[AAFS_PROF_MODE] = dent;
752 1551
753 dent = create_profile_file(dir, "attach", profile, 1552 dent = create_profile_file(dir, "attach", profile,
754 &aa_fs_profattach_fops); 1553 &seq_profile_attach_fops);
755 if (IS_ERR(dent)) 1554 if (IS_ERR(dent))
756 goto fail; 1555 goto fail;
757 profile->dents[AAFS_PROF_ATTACH] = dent; 1556 profile->dents[AAFS_PROF_ATTACH] = dent;
758 1557
759 if (profile->hash) { 1558 if (profile->hash) {
760 dent = create_profile_file(dir, "sha1", profile, 1559 dent = create_profile_file(dir, "sha1", profile,
761 &aa_fs_seq_hash_fops); 1560 &seq_profile_hash_fops);
762 if (IS_ERR(dent)) 1561 if (IS_ERR(dent))
763 goto fail; 1562 goto fail;
764 profile->dents[AAFS_PROF_HASH] = dent; 1563 profile->dents[AAFS_PROF_HASH] = dent;
765 } 1564 }
766 1565
767 if (profile->rawdata) { 1566 if (profile->rawdata) {
768 dent = create_profile_file(dir, "raw_sha1", profile, 1567 char target[64];
769 &aa_fs_seq_raw_hash_fops); 1568 int depth = profile_depth(profile);
1569
1570 error = gen_symlink_name(target, sizeof(target), depth,
1571 profile->rawdata->name, "sha1");
1572 if (error < 0)
1573 goto fail2;
1574 dent = aafs_create_symlink("raw_sha1", dir, target, NULL);
770 if (IS_ERR(dent)) 1575 if (IS_ERR(dent))
771 goto fail; 1576 goto fail;
772 profile->dents[AAFS_PROF_RAW_HASH] = dent; 1577 profile->dents[AAFS_PROF_RAW_HASH] = dent;
773 1578
774 dent = create_profile_file(dir, "raw_abi", profile, 1579 error = gen_symlink_name(target, sizeof(target), depth,
775 &aa_fs_seq_raw_abi_fops); 1580 profile->rawdata->name, "abi");
1581 if (error < 0)
1582 goto fail2;
1583 dent = aafs_create_symlink("raw_abi", dir, target, NULL);
776 if (IS_ERR(dent)) 1584 if (IS_ERR(dent))
777 goto fail; 1585 goto fail;
778 profile->dents[AAFS_PROF_RAW_ABI] = dent; 1586 profile->dents[AAFS_PROF_RAW_ABI] = dent;
779 1587
780 dent = securityfs_create_file("raw_data", S_IFREG | 0444, dir, 1588 error = gen_symlink_name(target, sizeof(target), depth,
781 profile->proxy, 1589 profile->rawdata->name, "raw_data");
782 &aa_fs_rawdata_fops); 1590 if (error < 0)
1591 goto fail2;
1592 dent = aafs_create_symlink("raw_data", dir, target, NULL);
783 if (IS_ERR(dent)) 1593 if (IS_ERR(dent))
784 goto fail; 1594 goto fail;
785 profile->dents[AAFS_PROF_RAW_DATA] = dent; 1595 profile->dents[AAFS_PROF_RAW_DATA] = dent;
786 d_inode(dent)->i_size = profile->rawdata->size;
787 aa_get_proxy(profile->proxy);
788 } 1596 }
789 1597
790 list_for_each_entry(child, &profile->base.profiles, base.list) { 1598 list_for_each_entry(child, &profile->base.profiles, base.list) {
791 error = __aa_fs_profile_mkdir(child, prof_child_dir(profile)); 1599 error = __aafs_profile_mkdir(child, prof_child_dir(profile));
792 if (error) 1600 if (error)
793 goto fail2; 1601 goto fail2;
794 } 1602 }
@@ -799,12 +1607,123 @@ fail:
799 error = PTR_ERR(dent); 1607 error = PTR_ERR(dent);
800 1608
801fail2: 1609fail2:
802 __aa_fs_profile_rmdir(profile); 1610 __aafs_profile_rmdir(profile);
803 1611
804 return error; 1612 return error;
805} 1613}
806 1614
807void __aa_fs_ns_rmdir(struct aa_ns *ns) 1615static int ns_mkdir_op(struct inode *dir, struct dentry *dentry, umode_t mode)
1616{
1617 struct aa_ns *ns, *parent;
1618 /* TODO: improve permission check */
1619 struct aa_label *label;
1620 int error;
1621
1622 label = begin_current_label_crit_section();
1623 error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
1624 end_current_label_crit_section(label);
1625 if (error)
1626 return error;
1627
1628 parent = aa_get_ns(dir->i_private);
1629 AA_BUG(d_inode(ns_subns_dir(parent)) != dir);
1630
1631 /* we have to unlock and then relock to get locking order right
1632 * for pin_fs
1633 */
1634 inode_unlock(dir);
1635 error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count);
1636 mutex_lock(&parent->lock);
1637 inode_lock_nested(dir, I_MUTEX_PARENT);
1638 if (error)
1639 goto out;
1640
1641 error = __aafs_setup_d_inode(dir, dentry, mode | S_IFDIR, NULL,
1642 NULL, NULL, NULL);
1643 if (error)
1644 goto out_pin;
1645
1646 ns = __aa_find_or_create_ns(parent, READ_ONCE(dentry->d_name.name),
1647 dentry);
1648 if (IS_ERR(ns)) {
1649 error = PTR_ERR(ns);
1650 ns = NULL;
1651 }
1652
1653 aa_put_ns(ns); /* list ref remains */
1654out_pin:
1655 if (error)
1656 simple_release_fs(&aafs_mnt, &aafs_count);
1657out:
1658 mutex_unlock(&parent->lock);
1659 aa_put_ns(parent);
1660
1661 return error;
1662}
1663
1664static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)
1665{
1666 struct aa_ns *ns, *parent;
1667 /* TODO: improve permission check */
1668 struct aa_label *label;
1669 int error;
1670
1671 label = begin_current_label_crit_section();
1672 error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
1673 end_current_label_crit_section(label);
1674 if (error)
1675 return error;
1676
1677 parent = aa_get_ns(dir->i_private);
1678 /* rmdir calls the generic securityfs functions to remove files
1679 * from the apparmor dir. It is up to the apparmor ns locking
1680 * to avoid races.
1681 */
1682 inode_unlock(dir);
1683 inode_unlock(dentry->d_inode);
1684
1685 mutex_lock(&parent->lock);
1686 ns = aa_get_ns(__aa_findn_ns(&parent->sub_ns, dentry->d_name.name,
1687 dentry->d_name.len));
1688 if (!ns) {
1689 error = -ENOENT;
1690 goto out;
1691 }
1692 AA_BUG(ns_dir(ns) != dentry);
1693
1694 __aa_remove_ns(ns);
1695 aa_put_ns(ns);
1696
1697out:
1698 mutex_unlock(&parent->lock);
1699 inode_lock_nested(dir, I_MUTEX_PARENT);
1700 inode_lock(dentry->d_inode);
1701 aa_put_ns(parent);
1702
1703 return error;
1704}
1705
1706static const struct inode_operations ns_dir_inode_operations = {
1707 .lookup = simple_lookup,
1708 .mkdir = ns_mkdir_op,
1709 .rmdir = ns_rmdir_op,
1710};
1711
1712static void __aa_fs_list_remove_rawdata(struct aa_ns *ns)
1713{
1714 struct aa_loaddata *ent, *tmp;
1715
1716 AA_BUG(!mutex_is_locked(&ns->lock));
1717
1718 list_for_each_entry_safe(ent, tmp, &ns->rawdata_list, list)
1719 __aa_fs_remove_rawdata(ent);
1720}
1721
1722/**
1723 *
1724 * Requires: @ns->lock held
1725 */
1726void __aafs_ns_rmdir(struct aa_ns *ns)
808{ 1727{
809 struct aa_ns *sub; 1728 struct aa_ns *sub;
810 struct aa_profile *child; 1729 struct aa_profile *child;
@@ -814,14 +1733,16 @@ void __aa_fs_ns_rmdir(struct aa_ns *ns)
814 return; 1733 return;
815 1734
816 list_for_each_entry(child, &ns->base.profiles, base.list) 1735 list_for_each_entry(child, &ns->base.profiles, base.list)
817 __aa_fs_profile_rmdir(child); 1736 __aafs_profile_rmdir(child);
818 1737
819 list_for_each_entry(sub, &ns->sub_ns, base.list) { 1738 list_for_each_entry(sub, &ns->sub_ns, base.list) {
820 mutex_lock(&sub->lock); 1739 mutex_lock(&sub->lock);
821 __aa_fs_ns_rmdir(sub); 1740 __aafs_ns_rmdir(sub);
822 mutex_unlock(&sub->lock); 1741 mutex_unlock(&sub->lock);
823 } 1742 }
824 1743
1744 __aa_fs_list_remove_rawdata(ns);
1745
825 if (ns_subns_dir(ns)) { 1746 if (ns_subns_dir(ns)) {
826 sub = d_inode(ns_subns_dir(ns))->i_private; 1747 sub = d_inode(ns_subns_dir(ns))->i_private;
827 aa_put_ns(sub); 1748 aa_put_ns(sub);
@@ -838,53 +1759,66 @@ void __aa_fs_ns_rmdir(struct aa_ns *ns)
838 sub = d_inode(ns_subremove(ns))->i_private; 1759 sub = d_inode(ns_subremove(ns))->i_private;
839 aa_put_ns(sub); 1760 aa_put_ns(sub);
840 } 1761 }
1762 if (ns_subrevision(ns)) {
1763 sub = d_inode(ns_subrevision(ns))->i_private;
1764 aa_put_ns(sub);
1765 }
841 1766
842 for (i = AAFS_NS_SIZEOF - 1; i >= 0; --i) { 1767 for (i = AAFS_NS_SIZEOF - 1; i >= 0; --i) {
843 securityfs_remove(ns->dents[i]); 1768 aafs_remove(ns->dents[i]);
844 ns->dents[i] = NULL; 1769 ns->dents[i] = NULL;
845 } 1770 }
846} 1771}
847 1772
848/* assumes cleanup in caller */ 1773/* assumes cleanup in caller */
849static int __aa_fs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir) 1774static int __aafs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
850{ 1775{
851 struct dentry *dent; 1776 struct dentry *dent;
852 1777
853 AA_BUG(!ns); 1778 AA_BUG(!ns);
854 AA_BUG(!dir); 1779 AA_BUG(!dir);
855 1780
856 dent = securityfs_create_dir("profiles", dir); 1781 dent = aafs_create_dir("profiles", dir);
857 if (IS_ERR(dent)) 1782 if (IS_ERR(dent))
858 return PTR_ERR(dent); 1783 return PTR_ERR(dent);
859 ns_subprofs_dir(ns) = dent; 1784 ns_subprofs_dir(ns) = dent;
860 1785
861 dent = securityfs_create_dir("raw_data", dir); 1786 dent = aafs_create_dir("raw_data", dir);
862 if (IS_ERR(dent)) 1787 if (IS_ERR(dent))
863 return PTR_ERR(dent); 1788 return PTR_ERR(dent);
864 ns_subdata_dir(ns) = dent; 1789 ns_subdata_dir(ns) = dent;
865 1790
866 dent = securityfs_create_file(".load", 0640, dir, ns, 1791 dent = aafs_create_file("revision", 0444, dir, ns,
1792 &aa_fs_ns_revision_fops);
1793 if (IS_ERR(dent))
1794 return PTR_ERR(dent);
1795 aa_get_ns(ns);
1796 ns_subrevision(ns) = dent;
1797
1798 dent = aafs_create_file(".load", 0640, dir, ns,
867 &aa_fs_profile_load); 1799 &aa_fs_profile_load);
868 if (IS_ERR(dent)) 1800 if (IS_ERR(dent))
869 return PTR_ERR(dent); 1801 return PTR_ERR(dent);
870 aa_get_ns(ns); 1802 aa_get_ns(ns);
871 ns_subload(ns) = dent; 1803 ns_subload(ns) = dent;
872 1804
873 dent = securityfs_create_file(".replace", 0640, dir, ns, 1805 dent = aafs_create_file(".replace", 0640, dir, ns,
874 &aa_fs_profile_replace); 1806 &aa_fs_profile_replace);
875 if (IS_ERR(dent)) 1807 if (IS_ERR(dent))
876 return PTR_ERR(dent); 1808 return PTR_ERR(dent);
877 aa_get_ns(ns); 1809 aa_get_ns(ns);
878 ns_subreplace(ns) = dent; 1810 ns_subreplace(ns) = dent;
879 1811
880 dent = securityfs_create_file(".remove", 0640, dir, ns, 1812 dent = aafs_create_file(".remove", 0640, dir, ns,
881 &aa_fs_profile_remove); 1813 &aa_fs_profile_remove);
882 if (IS_ERR(dent)) 1814 if (IS_ERR(dent))
883 return PTR_ERR(dent); 1815 return PTR_ERR(dent);
884 aa_get_ns(ns); 1816 aa_get_ns(ns);
885 ns_subremove(ns) = dent; 1817 ns_subremove(ns) = dent;
886 1818
887 dent = securityfs_create_dir("namespaces", dir); 1819 /* use create_dentry so we can supply private data */
1820 dent = aafs_create("namespaces", S_IFDIR | 0755, dir, ns, NULL, NULL,
1821 &ns_dir_inode_operations);
888 if (IS_ERR(dent)) 1822 if (IS_ERR(dent))
889 return PTR_ERR(dent); 1823 return PTR_ERR(dent);
890 aa_get_ns(ns); 1824 aa_get_ns(ns);
@@ -893,11 +1827,15 @@ static int __aa_fs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
893 return 0; 1827 return 0;
894} 1828}
895 1829
896int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name) 1830/*
1831 * Requires: @ns->lock held
1832 */
1833int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name,
1834 struct dentry *dent)
897{ 1835{
898 struct aa_ns *sub; 1836 struct aa_ns *sub;
899 struct aa_profile *child; 1837 struct aa_profile *child;
900 struct dentry *dent, *dir; 1838 struct dentry *dir;
901 int error; 1839 int error;
902 1840
903 AA_BUG(!ns); 1841 AA_BUG(!ns);
@@ -907,19 +1845,21 @@ int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name)
907 if (!name) 1845 if (!name)
908 name = ns->base.name; 1846 name = ns->base.name;
909 1847
910 /* create ns dir if it doesn't already exist */ 1848 if (!dent) {
911 dent = securityfs_create_dir(name, parent); 1849 /* create ns dir if it doesn't already exist */
912 if (IS_ERR(dent)) 1850 dent = aafs_create_dir(name, parent);
913 goto fail; 1851 if (IS_ERR(dent))
914 1852 goto fail;
1853 } else
1854 dget(dent);
915 ns_dir(ns) = dir = dent; 1855 ns_dir(ns) = dir = dent;
916 error = __aa_fs_ns_mkdir_entries(ns, dir); 1856 error = __aafs_ns_mkdir_entries(ns, dir);
917 if (error) 1857 if (error)
918 goto fail2; 1858 goto fail2;
919 1859
920 /* profiles */ 1860 /* profiles */
921 list_for_each_entry(child, &ns->base.profiles, base.list) { 1861 list_for_each_entry(child, &ns->base.profiles, base.list) {
922 error = __aa_fs_profile_mkdir(child, ns_subprofs_dir(ns)); 1862 error = __aafs_profile_mkdir(child, ns_subprofs_dir(ns));
923 if (error) 1863 if (error)
924 goto fail2; 1864 goto fail2;
925 } 1865 }
@@ -927,7 +1867,7 @@ int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name)
927 /* subnamespaces */ 1867 /* subnamespaces */
928 list_for_each_entry(sub, &ns->sub_ns, base.list) { 1868 list_for_each_entry(sub, &ns->sub_ns, base.list) {
929 mutex_lock(&sub->lock); 1869 mutex_lock(&sub->lock);
930 error = __aa_fs_ns_mkdir(sub, ns_subns_dir(ns), NULL); 1870 error = __aafs_ns_mkdir(sub, ns_subns_dir(ns), NULL, NULL);
931 mutex_unlock(&sub->lock); 1871 mutex_unlock(&sub->lock);
932 if (error) 1872 if (error)
933 goto fail2; 1873 goto fail2;
@@ -939,7 +1879,7 @@ fail:
939 error = PTR_ERR(dent); 1879 error = PTR_ERR(dent);
940 1880
941fail2: 1881fail2:
942 __aa_fs_ns_rmdir(ns); 1882 __aafs_ns_rmdir(ns);
943 1883
944 return error; 1884 return error;
945} 1885}
@@ -1074,10 +2014,9 @@ static struct aa_profile *next_profile(struct aa_ns *root,
1074static void *p_start(struct seq_file *f, loff_t *pos) 2014static void *p_start(struct seq_file *f, loff_t *pos)
1075{ 2015{
1076 struct aa_profile *profile = NULL; 2016 struct aa_profile *profile = NULL;
1077 struct aa_ns *root = aa_current_profile()->ns; 2017 struct aa_ns *root = aa_get_current_ns();
1078 loff_t l = *pos; 2018 loff_t l = *pos;
1079 f->private = aa_get_ns(root); 2019 f->private = root;
1080
1081 2020
1082 /* find the first profile */ 2021 /* find the first profile */
1083 mutex_lock(&root->lock); 2022 mutex_lock(&root->lock);
@@ -1141,15 +2080,14 @@ static int seq_show_profile(struct seq_file *f, void *p)
1141 struct aa_profile *profile = (struct aa_profile *)p; 2080 struct aa_profile *profile = (struct aa_profile *)p;
1142 struct aa_ns *root = f->private; 2081 struct aa_ns *root = f->private;
1143 2082
1144 if (profile->ns != root) 2083 aa_label_seq_xprint(f, root, &profile->label,
1145 seq_printf(f, ":%s://", aa_ns_name(root, profile->ns, true)); 2084 FLAG_SHOW_MODE | FLAG_VIEW_SUBNS, GFP_KERNEL);
1146 seq_printf(f, "%s (%s)\n", profile->base.hname, 2085 seq_putc(f, '\n');
1147 aa_profile_mode_names[profile->mode]);
1148 2086
1149 return 0; 2087 return 0;
1150} 2088}
1151 2089
1152static const struct seq_operations aa_fs_profiles_op = { 2090static const struct seq_operations aa_sfs_profiles_op = {
1153 .start = p_start, 2091 .start = p_start,
1154 .next = p_next, 2092 .next = p_next,
1155 .stop = p_stop, 2093 .stop = p_stop,
@@ -1161,7 +2099,7 @@ static int profiles_open(struct inode *inode, struct file *file)
1161 if (!policy_view_capable(NULL)) 2099 if (!policy_view_capable(NULL))
1162 return -EACCES; 2100 return -EACCES;
1163 2101
1164 return seq_open(file, &aa_fs_profiles_op); 2102 return seq_open(file, &aa_sfs_profiles_op);
1165} 2103}
1166 2104
1167static int profiles_release(struct inode *inode, struct file *file) 2105static int profiles_release(struct inode *inode, struct file *file)
@@ -1169,7 +2107,7 @@ static int profiles_release(struct inode *inode, struct file *file)
1169 return seq_release(inode, file); 2107 return seq_release(inode, file);
1170} 2108}
1171 2109
1172static const struct file_operations aa_fs_profiles_fops = { 2110static const struct file_operations aa_sfs_profiles_fops = {
1173 .open = profiles_open, 2111 .open = profiles_open,
1174 .read = seq_read, 2112 .read = seq_read,
1175 .llseek = seq_lseek, 2113 .llseek = seq_lseek,
@@ -1178,64 +2116,94 @@ static const struct file_operations aa_fs_profiles_fops = {
1178 2116
1179 2117
1180/** Base file system setup **/ 2118/** Base file system setup **/
1181static struct aa_fs_entry aa_fs_entry_file[] = { 2119static struct aa_sfs_entry aa_sfs_entry_file[] = {
1182 AA_FS_FILE_STRING("mask", "create read write exec append mmap_exec " \ 2120 AA_SFS_FILE_STRING("mask",
1183 "link lock"), 2121 "create read write exec append mmap_exec link lock"),
2122 { }
2123};
2124
2125static struct aa_sfs_entry aa_sfs_entry_ptrace[] = {
2126 AA_SFS_FILE_STRING("mask", "read trace"),
2127 { }
2128};
2129
2130static struct aa_sfs_entry aa_sfs_entry_domain[] = {
2131 AA_SFS_FILE_BOOLEAN("change_hat", 1),
2132 AA_SFS_FILE_BOOLEAN("change_hatv", 1),
2133 AA_SFS_FILE_BOOLEAN("change_onexec", 1),
2134 AA_SFS_FILE_BOOLEAN("change_profile", 1),
2135 AA_SFS_FILE_BOOLEAN("stack", 1),
2136 AA_SFS_FILE_BOOLEAN("fix_binfmt_elf_mmap", 1),
2137 AA_SFS_FILE_STRING("version", "1.2"),
2138 { }
2139};
2140
2141static struct aa_sfs_entry aa_sfs_entry_versions[] = {
2142 AA_SFS_FILE_BOOLEAN("v5", 1),
2143 AA_SFS_FILE_BOOLEAN("v6", 1),
2144 AA_SFS_FILE_BOOLEAN("v7", 1),
1184 { } 2145 { }
1185}; 2146};
1186 2147
1187static struct aa_fs_entry aa_fs_entry_domain[] = { 2148static struct aa_sfs_entry aa_sfs_entry_policy[] = {
1188 AA_FS_FILE_BOOLEAN("change_hat", 1), 2149 AA_SFS_DIR("versions", aa_sfs_entry_versions),
1189 AA_FS_FILE_BOOLEAN("change_hatv", 1), 2150 AA_SFS_FILE_BOOLEAN("set_load", 1),
1190 AA_FS_FILE_BOOLEAN("change_onexec", 1),
1191 AA_FS_FILE_BOOLEAN("change_profile", 1),
1192 AA_FS_FILE_BOOLEAN("fix_binfmt_elf_mmap", 1),
1193 AA_FS_FILE_STRING("version", "1.2"),
1194 { } 2151 { }
1195}; 2152};
1196 2153
1197static struct aa_fs_entry aa_fs_entry_versions[] = { 2154static struct aa_sfs_entry aa_sfs_entry_ns[] = {
1198 AA_FS_FILE_BOOLEAN("v5", 1), 2155 AA_SFS_FILE_BOOLEAN("profile", 1),
2156 AA_SFS_FILE_BOOLEAN("pivot_root", 1),
1199 { } 2157 { }
1200}; 2158};
1201 2159
1202static struct aa_fs_entry aa_fs_entry_policy[] = { 2160static struct aa_sfs_entry aa_sfs_entry_query_label[] = {
1203 AA_FS_DIR("versions", aa_fs_entry_versions), 2161 AA_SFS_FILE_STRING("perms", "allow deny audit quiet"),
1204 AA_FS_FILE_BOOLEAN("set_load", 1), 2162 AA_SFS_FILE_BOOLEAN("data", 1),
2163 AA_SFS_FILE_BOOLEAN("multi_transaction", 1),
1205 { } 2164 { }
1206}; 2165};
1207 2166
1208static struct aa_fs_entry aa_fs_entry_features[] = { 2167static struct aa_sfs_entry aa_sfs_entry_query[] = {
1209 AA_FS_DIR("policy", aa_fs_entry_policy), 2168 AA_SFS_DIR("label", aa_sfs_entry_query_label),
1210 AA_FS_DIR("domain", aa_fs_entry_domain), 2169 { }
1211 AA_FS_DIR("file", aa_fs_entry_file), 2170};
1212 AA_FS_FILE_U64("capability", VFS_CAP_FLAGS_MASK), 2171static struct aa_sfs_entry aa_sfs_entry_features[] = {
1213 AA_FS_DIR("rlimit", aa_fs_entry_rlimit), 2172 AA_SFS_DIR("policy", aa_sfs_entry_policy),
1214 AA_FS_DIR("caps", aa_fs_entry_caps), 2173 AA_SFS_DIR("domain", aa_sfs_entry_domain),
2174 AA_SFS_DIR("file", aa_sfs_entry_file),
2175 AA_SFS_DIR("namespaces", aa_sfs_entry_ns),
2176 AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
2177 AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit),
2178 AA_SFS_DIR("caps", aa_sfs_entry_caps),
2179 AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace),
2180 AA_SFS_DIR("query", aa_sfs_entry_query),
1215 { } 2181 { }
1216}; 2182};
1217 2183
1218static struct aa_fs_entry aa_fs_entry_apparmor[] = { 2184static struct aa_sfs_entry aa_sfs_entry_apparmor[] = {
1219 AA_FS_FILE_FOPS(".access", 0640, &aa_fs_access), 2185 AA_SFS_FILE_FOPS(".access", 0640, &aa_sfs_access),
1220 AA_FS_FILE_FOPS(".ns_level", 0666, &aa_fs_ns_level), 2186 AA_SFS_FILE_FOPS(".stacked", 0444, &seq_ns_stacked_fops),
1221 AA_FS_FILE_FOPS(".ns_name", 0640, &aa_fs_ns_name), 2187 AA_SFS_FILE_FOPS(".ns_stacked", 0444, &seq_ns_nsstacked_fops),
1222 AA_FS_FILE_FOPS("profiles", 0440, &aa_fs_profiles_fops), 2188 AA_SFS_FILE_FOPS(".ns_level", 0666, &seq_ns_level_fops),
1223 AA_FS_DIR("features", aa_fs_entry_features), 2189 AA_SFS_FILE_FOPS(".ns_name", 0640, &seq_ns_name_fops),
2190 AA_SFS_FILE_FOPS("profiles", 0440, &aa_sfs_profiles_fops),
2191 AA_SFS_DIR("features", aa_sfs_entry_features),
1224 { } 2192 { }
1225}; 2193};
1226 2194
1227static struct aa_fs_entry aa_fs_entry = 2195static struct aa_sfs_entry aa_sfs_entry =
1228 AA_FS_DIR("apparmor", aa_fs_entry_apparmor); 2196 AA_SFS_DIR("apparmor", aa_sfs_entry_apparmor);
1229 2197
1230/** 2198/**
1231 * aafs_create_file - create a file entry in the apparmor securityfs 2199 * entry_create_file - create a file entry in the apparmor securityfs
1232 * @fs_file: aa_fs_entry to build an entry for (NOT NULL) 2200 * @fs_file: aa_sfs_entry to build an entry for (NOT NULL)
1233 * @parent: the parent dentry in the securityfs 2201 * @parent: the parent dentry in the securityfs
1234 * 2202 *
1235 * Use aafs_remove_file to remove entries created with this fn. 2203 * Use entry_remove_file to remove entries created with this fn.
1236 */ 2204 */
1237static int __init aafs_create_file(struct aa_fs_entry *fs_file, 2205static int __init entry_create_file(struct aa_sfs_entry *fs_file,
1238 struct dentry *parent) 2206 struct dentry *parent)
1239{ 2207{
1240 int error = 0; 2208 int error = 0;
1241 2209
@@ -1250,18 +2218,18 @@ static int __init aafs_create_file(struct aa_fs_entry *fs_file,
1250 return error; 2218 return error;
1251} 2219}
1252 2220
1253static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir); 2221static void __init entry_remove_dir(struct aa_sfs_entry *fs_dir);
1254/** 2222/**
1255 * aafs_create_dir - recursively create a directory entry in the securityfs 2223 * entry_create_dir - recursively create a directory entry in the securityfs
1256 * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL) 2224 * @fs_dir: aa_sfs_entry (and all child entries) to build (NOT NULL)
1257 * @parent: the parent dentry in the securityfs 2225 * @parent: the parent dentry in the securityfs
1258 * 2226 *
1259 * Use aafs_remove_dir to remove entries created with this fn. 2227 * Use entry_remove_dir to remove entries created with this fn.
1260 */ 2228 */
1261static int __init aafs_create_dir(struct aa_fs_entry *fs_dir, 2229static int __init entry_create_dir(struct aa_sfs_entry *fs_dir,
1262 struct dentry *parent) 2230 struct dentry *parent)
1263{ 2231{
1264 struct aa_fs_entry *fs_file; 2232 struct aa_sfs_entry *fs_file;
1265 struct dentry *dir; 2233 struct dentry *dir;
1266 int error; 2234 int error;
1267 2235
@@ -1271,10 +2239,10 @@ static int __init aafs_create_dir(struct aa_fs_entry *fs_dir,
1271 fs_dir->dentry = dir; 2239 fs_dir->dentry = dir;
1272 2240
1273 for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) { 2241 for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
1274 if (fs_file->v_type == AA_FS_TYPE_DIR) 2242 if (fs_file->v_type == AA_SFS_TYPE_DIR)
1275 error = aafs_create_dir(fs_file, fs_dir->dentry); 2243 error = entry_create_dir(fs_file, fs_dir->dentry);
1276 else 2244 else
1277 error = aafs_create_file(fs_file, fs_dir->dentry); 2245 error = entry_create_file(fs_file, fs_dir->dentry);
1278 if (error) 2246 if (error)
1279 goto failed; 2247 goto failed;
1280 } 2248 }
@@ -1282,16 +2250,16 @@ static int __init aafs_create_dir(struct aa_fs_entry *fs_dir,
1282 return 0; 2250 return 0;
1283 2251
1284failed: 2252failed:
1285 aafs_remove_dir(fs_dir); 2253 entry_remove_dir(fs_dir);
1286 2254
1287 return error; 2255 return error;
1288} 2256}
1289 2257
1290/** 2258/**
1291 * aafs_remove_file - drop a single file entry in the apparmor securityfs 2259 * entry_remove_file - drop a single file entry in the apparmor securityfs
1292 * @fs_file: aa_fs_entry to detach from the securityfs (NOT NULL) 2260 * @fs_file: aa_sfs_entry to detach from the securityfs (NOT NULL)
1293 */ 2261 */
1294static void __init aafs_remove_file(struct aa_fs_entry *fs_file) 2262static void __init entry_remove_file(struct aa_sfs_entry *fs_file)
1295{ 2263{
1296 if (!fs_file->dentry) 2264 if (!fs_file->dentry)
1297 return; 2265 return;
@@ -1301,21 +2269,21 @@ static void __init aafs_remove_file(struct aa_fs_entry *fs_file)
1301} 2269}
1302 2270
1303/** 2271/**
1304 * aafs_remove_dir - recursively drop a directory entry from the securityfs 2272 * entry_remove_dir - recursively drop a directory entry from the securityfs
1305 * @fs_dir: aa_fs_entry (and all child entries) to detach (NOT NULL) 2273 * @fs_dir: aa_sfs_entry (and all child entries) to detach (NOT NULL)
1306 */ 2274 */
1307static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir) 2275static void __init entry_remove_dir(struct aa_sfs_entry *fs_dir)
1308{ 2276{
1309 struct aa_fs_entry *fs_file; 2277 struct aa_sfs_entry *fs_file;
1310 2278
1311 for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) { 2279 for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
1312 if (fs_file->v_type == AA_FS_TYPE_DIR) 2280 if (fs_file->v_type == AA_SFS_TYPE_DIR)
1313 aafs_remove_dir(fs_file); 2281 entry_remove_dir(fs_file);
1314 else 2282 else
1315 aafs_remove_file(fs_file); 2283 entry_remove_file(fs_file);
1316 } 2284 }
1317 2285
1318 aafs_remove_file(fs_dir); 2286 entry_remove_file(fs_dir);
1319} 2287}
1320 2288
1321/** 2289/**
@@ -1325,7 +2293,7 @@ static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir)
1325 */ 2293 */
1326void __init aa_destroy_aafs(void) 2294void __init aa_destroy_aafs(void)
1327{ 2295{
1328 aafs_remove_dir(&aa_fs_entry); 2296 entry_remove_dir(&aa_sfs_entry);
1329} 2297}
1330 2298
1331 2299
@@ -1374,6 +2342,59 @@ out:
1374 return error; 2342 return error;
1375} 2343}
1376 2344
2345
2346
2347static const char *policy_get_link(struct dentry *dentry,
2348 struct inode *inode,
2349 struct delayed_call *done)
2350{
2351 struct aa_ns *ns;
2352 struct path path;
2353
2354 if (!dentry)
2355 return ERR_PTR(-ECHILD);
2356 ns = aa_get_current_ns();
2357 path.mnt = mntget(aafs_mnt);
2358 path.dentry = dget(ns_dir(ns));
2359 nd_jump_link(&path);
2360 aa_put_ns(ns);
2361
2362 return NULL;
2363}
2364
2365static int ns_get_name(char *buf, size_t size, struct aa_ns *ns,
2366 struct inode *inode)
2367{
2368 int res = snprintf(buf, size, "%s:[%lu]", AAFS_NAME, inode->i_ino);
2369
2370 if (res < 0 || res >= size)
2371 res = -ENOENT;
2372
2373 return res;
2374}
2375
2376static int policy_readlink(struct dentry *dentry, char __user *buffer,
2377 int buflen)
2378{
2379 struct aa_ns *ns;
2380 char name[32];
2381 int res;
2382
2383 ns = aa_get_current_ns();
2384 res = ns_get_name(name, sizeof(name), ns, d_inode(dentry));
2385 if (res >= 0)
2386 res = readlink_copy(buffer, buflen, name);
2387 aa_put_ns(ns);
2388
2389 return res;
2390}
2391
2392static const struct inode_operations policy_link_iops = {
2393 .readlink = policy_readlink,
2394 .get_link = policy_get_link,
2395};
2396
2397
1377/** 2398/**
1378 * aa_create_aafs - create the apparmor security filesystem 2399 * aa_create_aafs - create the apparmor security filesystem
1379 * 2400 *
@@ -1389,17 +2410,23 @@ static int __init aa_create_aafs(void)
1389 if (!apparmor_initialized) 2410 if (!apparmor_initialized)
1390 return 0; 2411 return 0;
1391 2412
1392 if (aa_fs_entry.dentry) { 2413 if (aa_sfs_entry.dentry) {
1393 AA_ERROR("%s: AppArmor securityfs already exists\n", __func__); 2414 AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
1394 return -EEXIST; 2415 return -EEXIST;
1395 } 2416 }
1396 2417
2418 /* setup apparmorfs used to virtualize policy/ */
2419 aafs_mnt = kern_mount(&aafs_ops);
2420 if (IS_ERR(aafs_mnt))
2421 panic("can't set apparmorfs up\n");
2422 aafs_mnt->mnt_sb->s_flags &= ~MS_NOUSER;
2423
1397 /* Populate fs tree. */ 2424 /* Populate fs tree. */
1398 error = aafs_create_dir(&aa_fs_entry, NULL); 2425 error = entry_create_dir(&aa_sfs_entry, NULL);
1399 if (error) 2426 if (error)
1400 goto error; 2427 goto error;
1401 2428
1402 dent = securityfs_create_file(".load", 0666, aa_fs_entry.dentry, 2429 dent = securityfs_create_file(".load", 0666, aa_sfs_entry.dentry,
1403 NULL, &aa_fs_profile_load); 2430 NULL, &aa_fs_profile_load);
1404 if (IS_ERR(dent)) { 2431 if (IS_ERR(dent)) {
1405 error = PTR_ERR(dent); 2432 error = PTR_ERR(dent);
@@ -1407,7 +2434,7 @@ static int __init aa_create_aafs(void)
1407 } 2434 }
1408 ns_subload(root_ns) = dent; 2435 ns_subload(root_ns) = dent;
1409 2436
1410 dent = securityfs_create_file(".replace", 0666, aa_fs_entry.dentry, 2437 dent = securityfs_create_file(".replace", 0666, aa_sfs_entry.dentry,
1411 NULL, &aa_fs_profile_replace); 2438 NULL, &aa_fs_profile_replace);
1412 if (IS_ERR(dent)) { 2439 if (IS_ERR(dent)) {
1413 error = PTR_ERR(dent); 2440 error = PTR_ERR(dent);
@@ -1415,7 +2442,7 @@ static int __init aa_create_aafs(void)
1415 } 2442 }
1416 ns_subreplace(root_ns) = dent; 2443 ns_subreplace(root_ns) = dent;
1417 2444
1418 dent = securityfs_create_file(".remove", 0666, aa_fs_entry.dentry, 2445 dent = securityfs_create_file(".remove", 0666, aa_sfs_entry.dentry,
1419 NULL, &aa_fs_profile_remove); 2446 NULL, &aa_fs_profile_remove);
1420 if (IS_ERR(dent)) { 2447 if (IS_ERR(dent)) {
1421 error = PTR_ERR(dent); 2448 error = PTR_ERR(dent);
@@ -1423,14 +2450,31 @@ static int __init aa_create_aafs(void)
1423 } 2450 }
1424 ns_subremove(root_ns) = dent; 2451 ns_subremove(root_ns) = dent;
1425 2452
2453 dent = securityfs_create_file("revision", 0444, aa_sfs_entry.dentry,
2454 NULL, &aa_fs_ns_revision_fops);
2455 if (IS_ERR(dent)) {
2456 error = PTR_ERR(dent);
2457 goto error;
2458 }
2459 ns_subrevision(root_ns) = dent;
2460
2461 /* policy tree referenced by magic policy symlink */
1426 mutex_lock(&root_ns->lock); 2462 mutex_lock(&root_ns->lock);
1427 error = __aa_fs_ns_mkdir(root_ns, aa_fs_entry.dentry, "policy"); 2463 error = __aafs_ns_mkdir(root_ns, aafs_mnt->mnt_root, ".policy",
2464 aafs_mnt->mnt_root);
1428 mutex_unlock(&root_ns->lock); 2465 mutex_unlock(&root_ns->lock);
1429
1430 if (error) 2466 if (error)
1431 goto error; 2467 goto error;
1432 2468
1433 error = aa_mk_null_file(aa_fs_entry.dentry); 2469 /* magic symlink similar to nsfs redirects based on task policy */
2470 dent = securityfs_create_symlink("policy", aa_sfs_entry.dentry,
2471 NULL, &policy_link_iops);
2472 if (IS_ERR(dent)) {
2473 error = PTR_ERR(dent);
2474 goto error;
2475 }
2476
2477 error = aa_mk_null_file(aa_sfs_entry.dentry);
1434 if (error) 2478 if (error)
1435 goto error; 2479 goto error;
1436 2480
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 87f40fa8c431..8f9ecac7f8de 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -77,14 +77,24 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
77 audit_log_format(ab, " error=%d", aad(sa)->error); 77 audit_log_format(ab, " error=%d", aad(sa)->error);
78 } 78 }
79 79
80 if (aad(sa)->profile) { 80 if (aad(sa)->label) {
81 struct aa_profile *profile = aad(sa)->profile; 81 struct aa_label *label = aad(sa)->label;
82 if (profile->ns != root_ns) { 82
83 audit_log_format(ab, " namespace="); 83 if (label_isprofile(label)) {
84 audit_log_untrustedstring(ab, profile->ns->base.hname); 84 struct aa_profile *profile = labels_profile(label);
85
86 if (profile->ns != root_ns) {
87 audit_log_format(ab, " namespace=");
88 audit_log_untrustedstring(ab,
89 profile->ns->base.hname);
90 }
91 audit_log_format(ab, " profile=");
92 audit_log_untrustedstring(ab, profile->base.hname);
93 } else {
94 audit_log_format(ab, " label=");
95 aa_label_xaudit(ab, root_ns, label, FLAG_VIEW_SUBNS,
96 GFP_ATOMIC);
85 } 97 }
86 audit_log_format(ab, " profile=");
87 audit_log_untrustedstring(ab, profile->base.hname);
88 } 98 }
89 99
90 if (aad(sa)->name) { 100 if (aad(sa)->name) {
@@ -139,8 +149,7 @@ int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
139 if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED) 149 if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
140 type = AUDIT_APPARMOR_KILL; 150 type = AUDIT_APPARMOR_KILL;
141 151
142 if (!unconfined(profile)) 152 aad(sa)->label = &profile->label;
143 aad(sa)->profile = profile;
144 153
145 aa_audit_msg(type, sa, cb); 154 aa_audit_msg(type, sa, cb);
146 155
diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
index ed0a3e6b8022..67e347192a55 100644
--- a/security/apparmor/capability.c
+++ b/security/apparmor/capability.c
@@ -28,8 +28,8 @@
28 */ 28 */
29#include "capability_names.h" 29#include "capability_names.h"
30 30
31struct aa_fs_entry aa_fs_entry_caps[] = { 31struct aa_sfs_entry aa_sfs_entry_caps[] = {
32 AA_FS_FILE_STRING("mask", AA_FS_CAPS_MASK), 32 AA_SFS_FILE_STRING("mask", AA_SFS_CAPS_MASK),
33 { } 33 { }
34}; 34};
35 35
@@ -48,15 +48,16 @@ static DEFINE_PER_CPU(struct audit_cache, audit_cache);
48static void audit_cb(struct audit_buffer *ab, void *va) 48static void audit_cb(struct audit_buffer *ab, void *va)
49{ 49{
50 struct common_audit_data *sa = va; 50 struct common_audit_data *sa = va;
51
51 audit_log_format(ab, " capname="); 52 audit_log_format(ab, " capname=");
52 audit_log_untrustedstring(ab, capability_names[sa->u.cap]); 53 audit_log_untrustedstring(ab, capability_names[sa->u.cap]);
53} 54}
54 55
55/** 56/**
56 * audit_caps - audit a capability 57 * audit_caps - audit a capability
58 * @sa: audit data
57 * @profile: profile being tested for confinement (NOT NULL) 59 * @profile: profile being tested for confinement (NOT NULL)
58 * @cap: capability tested 60 * @cap: capability tested
59 @audit: whether an audit record should be generated
60 * @error: error code returned by test 61 * @error: error code returned by test
61 * 62 *
62 * Do auditing of capability and handle, audit/complain/kill modes switching 63 * Do auditing of capability and handle, audit/complain/kill modes switching
@@ -64,16 +65,13 @@ static void audit_cb(struct audit_buffer *ab, void *va)
64 * 65 *
65 * Returns: 0 or sa->error on success, error code on failure 66 * Returns: 0 or sa->error on success, error code on failure
66 */ 67 */
67static int audit_caps(struct aa_profile *profile, int cap, int audit, 68static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
68 int error) 69 int cap, int error)
69{ 70{
70 struct audit_cache *ent; 71 struct audit_cache *ent;
71 int type = AUDIT_APPARMOR_AUTO; 72 int type = AUDIT_APPARMOR_AUTO;
72 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE); 73
73 sa.u.cap = cap; 74 aad(sa)->error = error;
74 aad(&sa)->error = error;
75 if (audit == SECURITY_CAP_NOAUDIT)
76 aad(&sa)->info = "optional: no audit";
77 75
78 if (likely(!error)) { 76 if (likely(!error)) {
79 /* test if auditing is being forced */ 77 /* test if auditing is being forced */
@@ -105,24 +103,44 @@ static int audit_caps(struct aa_profile *profile, int cap, int audit,
105 } 103 }
106 put_cpu_var(audit_cache); 104 put_cpu_var(audit_cache);
107 105
108 return aa_audit(type, profile, &sa, audit_cb); 106 return aa_audit(type, profile, sa, audit_cb);
109} 107}
110 108
111/** 109/**
112 * profile_capable - test if profile allows use of capability @cap 110 * profile_capable - test if profile allows use of capability @cap
113 * @profile: profile being enforced (NOT NULL, NOT unconfined) 111 * @profile: profile being enforced (NOT NULL, NOT unconfined)
114 * @cap: capability to test if allowed 112 * @cap: capability to test if allowed
113 * @audit: whether an audit record should be generated
114 * @sa: audit data (MAY BE NULL indicating no auditing)
115 * 115 *
116 * Returns: 0 if allowed else -EPERM 116 * Returns: 0 if allowed else -EPERM
117 */ 117 */
118static int profile_capable(struct aa_profile *profile, int cap) 118static int profile_capable(struct aa_profile *profile, int cap, int audit,
119 struct common_audit_data *sa)
119{ 120{
120 return cap_raised(profile->caps.allow, cap) ? 0 : -EPERM; 121 int error;
122
123 if (cap_raised(profile->caps.allow, cap) &&
124 !cap_raised(profile->caps.denied, cap))
125 error = 0;
126 else
127 error = -EPERM;
128
129 if (audit == SECURITY_CAP_NOAUDIT) {
130 if (!COMPLAIN_MODE(profile))
131 return error;
132 /* audit the cap request in complain mode but note that it
133 * should be optional.
134 */
135 aad(sa)->info = "optional: no audit";
136 }
137
138 return audit_caps(sa, profile, cap, error);
121} 139}
122 140
123/** 141/**
124 * aa_capable - test permission to use capability 142 * aa_capable - test permission to use capability
125 * @profile: profile being tested against (NOT NULL) 143 * @label: label being tested for capability (NOT NULL)
126 * @cap: capability to be tested 144 * @cap: capability to be tested
127 * @audit: whether an audit record should be generated 145 * @audit: whether an audit record should be generated
128 * 146 *
@@ -130,14 +148,15 @@ static int profile_capable(struct aa_profile *profile, int cap)
130 * 148 *
131 * Returns: 0 on success, or else an error code. 149 * Returns: 0 on success, or else an error code.
132 */ 150 */
133int aa_capable(struct aa_profile *profile, int cap, int audit) 151int aa_capable(struct aa_label *label, int cap, int audit)
134{ 152{
135 int error = profile_capable(profile, cap); 153 struct aa_profile *profile;
154 int error = 0;
155 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE);
136 156
137 if (audit == SECURITY_CAP_NOAUDIT) { 157 sa.u.cap = cap;
138 if (!COMPLAIN_MODE(profile)) 158 error = fn_for_each_confined(label, profile,
139 return error; 159 profile_capable(profile, cap, audit, &sa));
140 }
141 160
142 return audit_caps(profile, cap, audit, error); 161 return error;
143} 162}
diff --git a/security/apparmor/context.c b/security/apparmor/context.c
index 1fc16b88efbf..c95f1ac6190b 100644
--- a/security/apparmor/context.c
+++ b/security/apparmor/context.c
@@ -14,9 +14,9 @@
14 * 14 *
15 * 15 *
16 * AppArmor sets confinement on every task, via the the aa_task_ctx and 16 * AppArmor sets confinement on every task, via the the aa_task_ctx and
17 * the aa_task_ctx.profile, both of which are required and are not allowed 17 * the aa_task_ctx.label, both of which are required and are not allowed
18 * to be NULL. The aa_task_ctx is not reference counted and is unique 18 * to be NULL. The aa_task_ctx is not reference counted and is unique
19 * to each cred (which is reference count). The profile pointed to by 19 * to each cred (which is reference count). The label pointed to by
20 * the task_ctx is reference counted. 20 * the task_ctx is reference counted.
21 * 21 *
22 * TODO 22 * TODO
@@ -47,9 +47,9 @@ struct aa_task_ctx *aa_alloc_task_context(gfp_t flags)
47void aa_free_task_context(struct aa_task_ctx *ctx) 47void aa_free_task_context(struct aa_task_ctx *ctx)
48{ 48{
49 if (ctx) { 49 if (ctx) {
50 aa_put_profile(ctx->profile); 50 aa_put_label(ctx->label);
51 aa_put_profile(ctx->previous); 51 aa_put_label(ctx->previous);
52 aa_put_profile(ctx->onexec); 52 aa_put_label(ctx->onexec);
53 53
54 kzfree(ctx); 54 kzfree(ctx);
55 } 55 }
@@ -63,41 +63,41 @@ void aa_free_task_context(struct aa_task_ctx *ctx)
63void aa_dup_task_context(struct aa_task_ctx *new, const struct aa_task_ctx *old) 63void aa_dup_task_context(struct aa_task_ctx *new, const struct aa_task_ctx *old)
64{ 64{
65 *new = *old; 65 *new = *old;
66 aa_get_profile(new->profile); 66 aa_get_label(new->label);
67 aa_get_profile(new->previous); 67 aa_get_label(new->previous);
68 aa_get_profile(new->onexec); 68 aa_get_label(new->onexec);
69} 69}
70 70
71/** 71/**
72 * aa_get_task_profile - Get another task's profile 72 * aa_get_task_label - Get another task's label
73 * @task: task to query (NOT NULL) 73 * @task: task to query (NOT NULL)
74 * 74 *
75 * Returns: counted reference to @task's profile 75 * Returns: counted reference to @task's label
76 */ 76 */
77struct aa_profile *aa_get_task_profile(struct task_struct *task) 77struct aa_label *aa_get_task_label(struct task_struct *task)
78{ 78{
79 struct aa_profile *p; 79 struct aa_label *p;
80 80
81 rcu_read_lock(); 81 rcu_read_lock();
82 p = aa_get_profile(__aa_task_profile(task)); 82 p = aa_get_newest_label(__aa_task_raw_label(task));
83 rcu_read_unlock(); 83 rcu_read_unlock();
84 84
85 return p; 85 return p;
86} 86}
87 87
88/** 88/**
89 * aa_replace_current_profile - replace the current tasks profiles 89 * aa_replace_current_label - replace the current tasks label
90 * @profile: new profile (NOT NULL) 90 * @label: new label (NOT NULL)
91 * 91 *
92 * Returns: 0 or error on failure 92 * Returns: 0 or error on failure
93 */ 93 */
94int aa_replace_current_profile(struct aa_profile *profile) 94int aa_replace_current_label(struct aa_label *label)
95{ 95{
96 struct aa_task_ctx *ctx = current_ctx(); 96 struct aa_task_ctx *ctx = current_ctx();
97 struct cred *new; 97 struct cred *new;
98 AA_BUG(!profile); 98 AA_BUG(!label);
99 99
100 if (ctx->profile == profile) 100 if (ctx->label == label)
101 return 0; 101 return 0;
102 102
103 if (current_cred() != current_real_cred()) 103 if (current_cred() != current_real_cred())
@@ -108,8 +108,8 @@ int aa_replace_current_profile(struct aa_profile *profile)
108 return -ENOMEM; 108 return -ENOMEM;
109 109
110 ctx = cred_ctx(new); 110 ctx = cred_ctx(new);
111 if (unconfined(profile) || (ctx->profile->ns != profile->ns)) 111 if (unconfined(label) || (labels_ns(ctx->label) != labels_ns(label)))
112 /* if switching to unconfined or a different profile namespace 112 /* if switching to unconfined or a different label namespace
113 * clear out context state 113 * clear out context state
114 */ 114 */
115 aa_clear_task_ctx_trans(ctx); 115 aa_clear_task_ctx_trans(ctx);
@@ -120,9 +120,9 @@ int aa_replace_current_profile(struct aa_profile *profile)
120 * keeping @profile valid, so make sure to get its reference before 120 * keeping @profile valid, so make sure to get its reference before
121 * dropping the reference on ctx->profile 121 * dropping the reference on ctx->profile
122 */ 122 */
123 aa_get_profile(profile); 123 aa_get_label(label);
124 aa_put_profile(ctx->profile); 124 aa_put_label(ctx->label);
125 ctx->profile = profile; 125 ctx->label = label;
126 126
127 commit_creds(new); 127 commit_creds(new);
128 return 0; 128 return 0;
@@ -130,11 +130,11 @@ int aa_replace_current_profile(struct aa_profile *profile)
130 130
131/** 131/**
132 * aa_set_current_onexec - set the tasks change_profile to happen onexec 132 * aa_set_current_onexec - set the tasks change_profile to happen onexec
133 * @profile: system profile to set at exec (MAYBE NULL to clear value) 133 * @label: system label to set at exec (MAYBE NULL to clear value)
134 * 134 * @stack: whether stacking should be done
135 * Returns: 0 or error on failure 135 * Returns: 0 or error on failure
136 */ 136 */
137int aa_set_current_onexec(struct aa_profile *profile) 137int aa_set_current_onexec(struct aa_label *label, bool stack)
138{ 138{
139 struct aa_task_ctx *ctx; 139 struct aa_task_ctx *ctx;
140 struct cred *new = prepare_creds(); 140 struct cred *new = prepare_creds();
@@ -142,9 +142,10 @@ int aa_set_current_onexec(struct aa_profile *profile)
142 return -ENOMEM; 142 return -ENOMEM;
143 143
144 ctx = cred_ctx(new); 144 ctx = cred_ctx(new);
145 aa_get_profile(profile); 145 aa_get_label(label);
146 aa_put_profile(ctx->onexec); 146 aa_clear_task_ctx_trans(ctx);
147 ctx->onexec = profile; 147 ctx->onexec = label;
148 ctx->token = stack;
148 149
149 commit_creds(new); 150 commit_creds(new);
150 return 0; 151 return 0;
@@ -152,7 +153,7 @@ int aa_set_current_onexec(struct aa_profile *profile)
152 153
153/** 154/**
154 * aa_set_current_hat - set the current tasks hat 155 * aa_set_current_hat - set the current tasks hat
155 * @profile: profile to set as the current hat (NOT NULL) 156 * @label: label to set as the current hat (NOT NULL)
156 * @token: token value that must be specified to change from the hat 157 * @token: token value that must be specified to change from the hat
157 * 158 *
158 * Do switch of tasks hat. If the task is currently in a hat 159 * Do switch of tasks hat. If the task is currently in a hat
@@ -160,29 +161,29 @@ int aa_set_current_onexec(struct aa_profile *profile)
160 * 161 *
161 * Returns: 0 or error on failure 162 * Returns: 0 or error on failure
162 */ 163 */
163int aa_set_current_hat(struct aa_profile *profile, u64 token) 164int aa_set_current_hat(struct aa_label *label, u64 token)
164{ 165{
165 struct aa_task_ctx *ctx; 166 struct aa_task_ctx *ctx;
166 struct cred *new = prepare_creds(); 167 struct cred *new = prepare_creds();
167 if (!new) 168 if (!new)
168 return -ENOMEM; 169 return -ENOMEM;
169 AA_BUG(!profile); 170 AA_BUG(!label);
170 171
171 ctx = cred_ctx(new); 172 ctx = cred_ctx(new);
172 if (!ctx->previous) { 173 if (!ctx->previous) {
173 /* transfer refcount */ 174 /* transfer refcount */
174 ctx->previous = ctx->profile; 175 ctx->previous = ctx->label;
175 ctx->token = token; 176 ctx->token = token;
176 } else if (ctx->token == token) { 177 } else if (ctx->token == token) {
177 aa_put_profile(ctx->profile); 178 aa_put_label(ctx->label);
178 } else { 179 } else {
179 /* previous_profile && ctx->token != token */ 180 /* previous_profile && ctx->token != token */
180 abort_creds(new); 181 abort_creds(new);
181 return -EACCES; 182 return -EACCES;
182 } 183 }
183 ctx->profile = aa_get_newest_profile(profile); 184 ctx->label = aa_get_newest_label(label);
184 /* clear exec on switching context */ 185 /* clear exec on switching context */
185 aa_put_profile(ctx->onexec); 186 aa_put_label(ctx->onexec);
186 ctx->onexec = NULL; 187 ctx->onexec = NULL;
187 188
188 commit_creds(new); 189 commit_creds(new);
@@ -190,15 +191,15 @@ int aa_set_current_hat(struct aa_profile *profile, u64 token)
190} 191}
191 192
192/** 193/**
193 * aa_restore_previous_profile - exit from hat context restoring the profile 194 * aa_restore_previous_label - exit from hat context restoring previous label
194 * @token: the token that must be matched to exit hat context 195 * @token: the token that must be matched to exit hat context
195 * 196 *
196 * Attempt to return out of a hat to the previous profile. The token 197 * Attempt to return out of a hat to the previous label. The token
197 * must match the stored token value. 198 * must match the stored token value.
198 * 199 *
199 * Returns: 0 or error of failure 200 * Returns: 0 or error of failure
200 */ 201 */
201int aa_restore_previous_profile(u64 token) 202int aa_restore_previous_label(u64 token)
202{ 203{
203 struct aa_task_ctx *ctx; 204 struct aa_task_ctx *ctx;
204 struct cred *new = prepare_creds(); 205 struct cred *new = prepare_creds();
@@ -210,15 +211,15 @@ int aa_restore_previous_profile(u64 token)
210 abort_creds(new); 211 abort_creds(new);
211 return -EACCES; 212 return -EACCES;
212 } 213 }
213 /* ignore restores when there is no saved profile */ 214 /* ignore restores when there is no saved label */
214 if (!ctx->previous) { 215 if (!ctx->previous) {
215 abort_creds(new); 216 abort_creds(new);
216 return 0; 217 return 0;
217 } 218 }
218 219
219 aa_put_profile(ctx->profile); 220 aa_put_label(ctx->label);
220 ctx->profile = aa_get_newest_profile(ctx->previous); 221 ctx->label = aa_get_newest_label(ctx->previous);
221 AA_BUG(!ctx->profile); 222 AA_BUG(!ctx->label);
222 /* clear exec && prev information when restoring to previous context */ 223 /* clear exec && prev information when restoring to previous context */
223 aa_clear_task_ctx_trans(ctx); 224 aa_clear_task_ctx_trans(ctx);
224 225
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 001e133a3c8c..d0594446ae3f 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -51,76 +51,254 @@ void aa_free_domain_entries(struct aa_domain *domain)
51 51
52/** 52/**
53 * may_change_ptraced_domain - check if can change profile on ptraced task 53 * may_change_ptraced_domain - check if can change profile on ptraced task
54 * @to_profile: profile to change to (NOT NULL) 54 * @to_label: profile to change to (NOT NULL)
55 * @info: message if there is an error
55 * 56 *
56 * Check if current is ptraced and if so if the tracing task is allowed 57 * Check if current is ptraced and if so if the tracing task is allowed
57 * to trace the new domain 58 * to trace the new domain
58 * 59 *
59 * Returns: %0 or error if change not allowed 60 * Returns: %0 or error if change not allowed
60 */ 61 */
61static int may_change_ptraced_domain(struct aa_profile *to_profile) 62static int may_change_ptraced_domain(struct aa_label *to_label,
63 const char **info)
62{ 64{
63 struct task_struct *tracer; 65 struct task_struct *tracer;
64 struct aa_profile *tracerp = NULL; 66 struct aa_label *tracerl = NULL;
65 int error = 0; 67 int error = 0;
66 68
67 rcu_read_lock(); 69 rcu_read_lock();
68 tracer = ptrace_parent(current); 70 tracer = ptrace_parent(current);
69 if (tracer) 71 if (tracer)
70 /* released below */ 72 /* released below */
71 tracerp = aa_get_task_profile(tracer); 73 tracerl = aa_get_task_label(tracer);
72 74
73 /* not ptraced */ 75 /* not ptraced */
74 if (!tracer || unconfined(tracerp)) 76 if (!tracer || unconfined(tracerl))
75 goto out; 77 goto out;
76 78
77 error = aa_may_ptrace(tracerp, to_profile, PTRACE_MODE_ATTACH); 79 error = aa_may_ptrace(tracerl, to_label, PTRACE_MODE_ATTACH);
78 80
79out: 81out:
80 rcu_read_unlock(); 82 rcu_read_unlock();
81 aa_put_profile(tracerp); 83 aa_put_label(tracerl);
82 84
85 if (error)
86 *info = "ptrace prevents transition";
83 return error; 87 return error;
84} 88}
85 89
90/**** TODO: dedup to aa_label_match - needs perm and dfa, merging
91 * specifically this is an exact copy of aa_label_match except
92 * aa_compute_perms is replaced with aa_compute_fperms
93 * and policy.dfa with file.dfa
94 ****/
95/* match a profile and its associated ns component if needed
96 * Assumes visibility test has already been done.
97 * If a subns profile is not to be matched should be prescreened with
98 * visibility test.
99 */
100static inline unsigned int match_component(struct aa_profile *profile,
101 struct aa_profile *tp,
102 bool stack, unsigned int state)
103{
104 const char *ns_name;
105
106 if (stack)
107 state = aa_dfa_match(profile->file.dfa, state, "&");
108 if (profile->ns == tp->ns)
109 return aa_dfa_match(profile->file.dfa, state, tp->base.hname);
110
111 /* try matching with namespace name and then profile */
112 ns_name = aa_ns_name(profile->ns, tp->ns, true);
113 state = aa_dfa_match_len(profile->file.dfa, state, ":", 1);
114 state = aa_dfa_match(profile->file.dfa, state, ns_name);
115 state = aa_dfa_match_len(profile->file.dfa, state, ":", 1);
116 return aa_dfa_match(profile->file.dfa, state, tp->base.hname);
117}
118
119/**
120 * label_compound_match - find perms for full compound label
121 * @profile: profile to find perms for
122 * @label: label to check access permissions for
123 * @stack: whether this is a stacking request
124 * @start: state to start match in
125 * @subns: whether to do permission checks on components in a subns
126 * @request: permissions to request
127 * @perms: perms struct to set
128 *
129 * Returns: 0 on success else ERROR
130 *
131 * For the label A//&B//&C this does the perm match for A//&B//&C
132 * @perms should be preinitialized with allperms OR a previous permission
133 * check to be stacked.
134 */
135static int label_compound_match(struct aa_profile *profile,
136 struct aa_label *label, bool stack,
137 unsigned int state, bool subns, u32 request,
138 struct aa_perms *perms)
139{
140 struct aa_profile *tp;
141 struct label_it i;
142 struct path_cond cond = { };
143
144 /* find first subcomponent that is visible */
145 label_for_each(i, label, tp) {
146 if (!aa_ns_visible(profile->ns, tp->ns, subns))
147 continue;
148 state = match_component(profile, tp, stack, state);
149 if (!state)
150 goto fail;
151 goto next;
152 }
153
154 /* no component visible */
155 *perms = allperms;
156 return 0;
157
158next:
159 label_for_each_cont(i, label, tp) {
160 if (!aa_ns_visible(profile->ns, tp->ns, subns))
161 continue;
162 state = aa_dfa_match(profile->file.dfa, state, "//&");
163 state = match_component(profile, tp, false, state);
164 if (!state)
165 goto fail;
166 }
167 *perms = aa_compute_fperms(profile->file.dfa, state, &cond);
168 aa_apply_modes_to_perms(profile, perms);
169 if ((perms->allow & request) != request)
170 return -EACCES;
171
172 return 0;
173
174fail:
175 *perms = nullperms;
176 return -EACCES;
177}
178
179/**
180 * label_components_match - find perms for all subcomponents of a label
181 * @profile: profile to find perms for
182 * @label: label to check access permissions for
183 * @stack: whether this is a stacking request
184 * @start: state to start match in
185 * @subns: whether to do permission checks on components in a subns
186 * @request: permissions to request
187 * @perms: an initialized perms struct to add accumulation to
188 *
189 * Returns: 0 on success else ERROR
190 *
191 * For the label A//&B//&C this does the perm match for each of A and B and C
192 * @perms should be preinitialized with allperms OR a previous permission
193 * check to be stacked.
194 */
195static int label_components_match(struct aa_profile *profile,
196 struct aa_label *label, bool stack,
197 unsigned int start, bool subns, u32 request,
198 struct aa_perms *perms)
199{
200 struct aa_profile *tp;
201 struct label_it i;
202 struct aa_perms tmp;
203 struct path_cond cond = { };
204 unsigned int state = 0;
205
206 /* find first subcomponent to test */
207 label_for_each(i, label, tp) {
208 if (!aa_ns_visible(profile->ns, tp->ns, subns))
209 continue;
210 state = match_component(profile, tp, stack, start);
211 if (!state)
212 goto fail;
213 goto next;
214 }
215
216 /* no subcomponents visible - no change in perms */
217 return 0;
218
219next:
220 tmp = aa_compute_fperms(profile->file.dfa, state, &cond);
221 aa_apply_modes_to_perms(profile, &tmp);
222 aa_perms_accum(perms, &tmp);
223 label_for_each_cont(i, label, tp) {
224 if (!aa_ns_visible(profile->ns, tp->ns, subns))
225 continue;
226 state = match_component(profile, tp, stack, start);
227 if (!state)
228 goto fail;
229 tmp = aa_compute_fperms(profile->file.dfa, state, &cond);
230 aa_apply_modes_to_perms(profile, &tmp);
231 aa_perms_accum(perms, &tmp);
232 }
233
234 if ((perms->allow & request) != request)
235 return -EACCES;
236
237 return 0;
238
239fail:
240 *perms = nullperms;
241 return -EACCES;
242}
243
244/**
245 * label_match - do a multi-component label match
246 * @profile: profile to match against (NOT NULL)
247 * @label: label to match (NOT NULL)
248 * @stack: whether this is a stacking request
249 * @state: state to start in
250 * @subns: whether to match subns components
251 * @request: permission request
252 * @perms: Returns computed perms (NOT NULL)
253 *
254 * Returns: the state the match finished in, may be the none matching state
255 */
256static int label_match(struct aa_profile *profile, struct aa_label *label,
257 bool stack, unsigned int state, bool subns, u32 request,
258 struct aa_perms *perms)
259{
260 int error;
261
262 *perms = nullperms;
263 error = label_compound_match(profile, label, stack, state, subns,
264 request, perms);
265 if (!error)
266 return error;
267
268 *perms = allperms;
269 return label_components_match(profile, label, stack, state, subns,
270 request, perms);
271}
272
273/******* end TODO: dedup *****/
274
86/** 275/**
87 * change_profile_perms - find permissions for change_profile 276 * change_profile_perms - find permissions for change_profile
88 * @profile: the current profile (NOT NULL) 277 * @profile: the current profile (NOT NULL)
89 * @ns: the namespace being switched to (NOT NULL) 278 * @target: label to transition to (NOT NULL)
90 * @name: the name of the profile to change to (NOT NULL) 279 * @stack: whether this is a stacking request
91 * @request: requested perms 280 * @request: requested perms
92 * @start: state to start matching in 281 * @start: state to start matching in
93 * 282 *
283 *
94 * Returns: permission set 284 * Returns: permission set
285 *
286 * currently only matches full label A//&B//&C or individual components A, B, C
287 * not arbitrary combinations. Eg. A//&B, C
95 */ 288 */
96static struct file_perms change_profile_perms(struct aa_profile *profile, 289static int change_profile_perms(struct aa_profile *profile,
97 struct aa_ns *ns, 290 struct aa_label *target, bool stack,
98 const char *name, u32 request, 291 u32 request, unsigned int start,
99 unsigned int start) 292 struct aa_perms *perms)
100{ 293{
101 struct file_perms perms; 294 if (profile_unconfined(profile)) {
102 struct path_cond cond = { }; 295 perms->allow = AA_MAY_CHANGE_PROFILE | AA_MAY_ONEXEC;
103 unsigned int state; 296 perms->audit = perms->quiet = perms->kill = 0;
104 297 return 0;
105 if (unconfined(profile)) {
106 perms.allow = AA_MAY_CHANGE_PROFILE | AA_MAY_ONEXEC;
107 perms.audit = perms.quiet = perms.kill = 0;
108 return perms;
109 } else if (!profile->file.dfa) {
110 return nullperms;
111 } else if ((ns == profile->ns)) {
112 /* try matching against rules with out namespace prepended */
113 aa_str_perms(profile->file.dfa, start, name, &cond, &perms);
114 if (COMBINED_PERM_MASK(perms) & request)
115 return perms;
116 } 298 }
117 299
118 /* try matching with namespace name and then profile */ 300 /* TODO: add profile in ns screening */
119 state = aa_dfa_match(profile->file.dfa, start, ns->base.name); 301 return label_match(profile, target, stack, start, true, request, perms);
120 state = aa_dfa_match_len(profile->file.dfa, state, ":", 1);
121 aa_str_perms(profile->file.dfa, state, name, &cond, &perms);
122
123 return perms;
124} 302}
125 303
126/** 304/**
@@ -144,7 +322,7 @@ static struct aa_profile *__attach_match(const char *name,
144 struct aa_profile *profile, *candidate = NULL; 322 struct aa_profile *profile, *candidate = NULL;
145 323
146 list_for_each_entry_rcu(profile, head, base.list) { 324 list_for_each_entry_rcu(profile, head, base.list) {
147 if (profile->flags & PFLAG_NULL) 325 if (profile->label.flags & FLAG_NULL)
148 continue; 326 continue;
149 if (profile->xmatch && profile->xmatch_len > len) { 327 if (profile->xmatch && profile->xmatch_len > len) {
150 unsigned int state = aa_dfa_match(profile->xmatch, 328 unsigned int state = aa_dfa_match(profile->xmatch,
@@ -169,10 +347,10 @@ static struct aa_profile *__attach_match(const char *name,
169 * @list: list to search (NOT NULL) 347 * @list: list to search (NOT NULL)
170 * @name: the executable name to match against (NOT NULL) 348 * @name: the executable name to match against (NOT NULL)
171 * 349 *
172 * Returns: profile or NULL if no match found 350 * Returns: label or NULL if no match found
173 */ 351 */
174static struct aa_profile *find_attach(struct aa_ns *ns, 352static struct aa_label *find_attach(struct aa_ns *ns, struct list_head *list,
175 struct list_head *list, const char *name) 353 const char *name)
176{ 354{
177 struct aa_profile *profile; 355 struct aa_profile *profile;
178 356
@@ -180,49 +358,7 @@ static struct aa_profile *find_attach(struct aa_ns *ns,
180 profile = aa_get_profile(__attach_match(name, list)); 358 profile = aa_get_profile(__attach_match(name, list));
181 rcu_read_unlock(); 359 rcu_read_unlock();
182 360
183 return profile; 361 return profile ? &profile->label : NULL;
184}
185
186/**
187 * separate_fqname - separate the namespace and profile names
188 * @fqname: the fqname name to split (NOT NULL)
189 * @ns_name: the namespace name if it exists (NOT NULL)
190 *
191 * This is the xtable equivalent routine of aa_split_fqname. It finds the
192 * split in an xtable fqname which contains an embedded \0 instead of a :
193 * if a namespace is specified. This is done so the xtable is constant and
194 * isn't re-split on every lookup.
195 *
196 * Either the profile or namespace name may be optional but if the namespace
197 * is specified the profile name termination must be present. This results
198 * in the following possible encodings:
199 * profile_name\0
200 * :ns_name\0profile_name\0
201 * :ns_name\0\0
202 *
203 * NOTE: the xtable fqname is pre-validated at load time in unpack_trans_table
204 *
205 * Returns: profile name if it is specified else NULL
206 */
207static const char *separate_fqname(const char *fqname, const char **ns_name)
208{
209 const char *name;
210
211 if (fqname[0] == ':') {
212 /* In this case there is guaranteed to be two \0 terminators
213 * in the string. They are verified at load time by
214 * by unpack_trans_table
215 */
216 *ns_name = fqname + 1; /* skip : */
217 name = *ns_name + strlen(*ns_name) + 1;
218 if (!*name)
219 name = NULL;
220 } else {
221 *ns_name = NULL;
222 name = fqname;
223 }
224
225 return name;
226} 362}
227 363
228static const char *next_name(int xtype, const char *name) 364static const char *next_name(int xtype, const char *name)
@@ -234,290 +370,477 @@ static const char *next_name(int xtype, const char *name)
234 * x_table_lookup - lookup an x transition name via transition table 370 * x_table_lookup - lookup an x transition name via transition table
235 * @profile: current profile (NOT NULL) 371 * @profile: current profile (NOT NULL)
236 * @xindex: index into x transition table 372 * @xindex: index into x transition table
373 * @name: returns: name tested to find label (NOT NULL)
237 * 374 *
238 * Returns: refcounted profile, or NULL on failure (MAYBE NULL) 375 * Returns: refcounted label, or NULL on failure (MAYBE NULL)
239 */ 376 */
240static struct aa_profile *x_table_lookup(struct aa_profile *profile, u32 xindex) 377static struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
378 const char **name)
241{ 379{
242 struct aa_profile *new_profile = NULL; 380 struct aa_label *label = NULL;
243 struct aa_ns *ns = profile->ns;
244 u32 xtype = xindex & AA_X_TYPE_MASK; 381 u32 xtype = xindex & AA_X_TYPE_MASK;
245 int index = xindex & AA_X_INDEX_MASK; 382 int index = xindex & AA_X_INDEX_MASK;
246 const char *name;
247 383
248 /* index is guaranteed to be in range, validated at load time */ 384 AA_BUG(!name);
249 for (name = profile->file.trans.table[index]; !new_profile && name;
250 name = next_name(xtype, name)) {
251 struct aa_ns *new_ns;
252 const char *xname = NULL;
253 385
254 new_ns = NULL; 386 /* index is guaranteed to be in range, validated at load time */
387 /* TODO: move lookup parsing to unpack time so this is a straight
388 * index into the resultant label
389 */
390 for (*name = profile->file.trans.table[index]; !label && *name;
391 *name = next_name(xtype, *name)) {
255 if (xindex & AA_X_CHILD) { 392 if (xindex & AA_X_CHILD) {
393 struct aa_profile *new_profile;
256 /* release by caller */ 394 /* release by caller */
257 new_profile = aa_find_child(profile, name); 395 new_profile = aa_find_child(profile, *name);
396 if (new_profile)
397 label = &new_profile->label;
258 continue; 398 continue;
259 } else if (*name == ':') {
260 /* switching namespace */
261 const char *ns_name;
262 xname = name = separate_fqname(name, &ns_name);
263 if (!xname)
264 /* no name so use profile name */
265 xname = profile->base.hname;
266 if (*ns_name == '@') {
267 /* TODO: variable support */
268 ;
269 }
270 /* released below */
271 new_ns = aa_find_ns(ns, ns_name);
272 if (!new_ns)
273 continue;
274 } else if (*name == '@') {
275 /* TODO: variable support */
276 continue;
277 } else {
278 /* basic namespace lookup */
279 xname = name;
280 } 399 }
281 400 label = aa_label_parse(&profile->label, *name, GFP_ATOMIC,
282 /* released by caller */ 401 true, false);
283 new_profile = aa_lookup_profile(new_ns ? new_ns : ns, xname); 402 if (IS_ERR(label))
284 aa_put_ns(new_ns); 403 label = NULL;
285 } 404 }
286 405
287 /* released by caller */ 406 /* released by caller */
288 return new_profile; 407
408 return label;
289} 409}
290 410
291/** 411/**
292 * x_to_profile - get target profile for a given xindex 412 * x_to_label - get target label for a given xindex
293 * @profile: current profile (NOT NULL) 413 * @profile: current profile (NOT NULL)
294 * @name: name to lookup (NOT NULL) 414 * @name: name to lookup (NOT NULL)
295 * @xindex: index into x transition table 415 * @xindex: index into x transition table
416 * @lookupname: returns: name used in lookup if one was specified (NOT NULL)
296 * 417 *
297 * find profile for a transition index 418 * find label for a transition index
298 * 419 *
299 * Returns: refcounted profile or NULL if not found available 420 * Returns: refcounted label or NULL if not found available
300 */ 421 */
301static struct aa_profile *x_to_profile(struct aa_profile *profile, 422static struct aa_label *x_to_label(struct aa_profile *profile,
302 const char *name, u32 xindex) 423 const char *name, u32 xindex,
424 const char **lookupname,
425 const char **info)
303{ 426{
304 struct aa_profile *new_profile = NULL; 427 struct aa_label *new = NULL;
305 struct aa_ns *ns = profile->ns; 428 struct aa_ns *ns = profile->ns;
306 u32 xtype = xindex & AA_X_TYPE_MASK; 429 u32 xtype = xindex & AA_X_TYPE_MASK;
430 const char *stack = NULL;
307 431
308 switch (xtype) { 432 switch (xtype) {
309 case AA_X_NONE: 433 case AA_X_NONE:
310 /* fail exec unless ix || ux fallback - handled by caller */ 434 /* fail exec unless ix || ux fallback - handled by caller */
311 return NULL; 435 *lookupname = NULL;
436 break;
437 case AA_X_TABLE:
438 /* TODO: fix when perm mapping done at unload */
439 stack = profile->file.trans.table[xindex & AA_X_INDEX_MASK];
440 if (*stack != '&') {
441 /* released by caller */
442 new = x_table_lookup(profile, xindex, lookupname);
443 stack = NULL;
444 break;
445 }
446 /* fall through to X_NAME */
312 case AA_X_NAME: 447 case AA_X_NAME:
313 if (xindex & AA_X_CHILD) 448 if (xindex & AA_X_CHILD)
314 /* released by caller */ 449 /* released by caller */
315 new_profile = find_attach(ns, &profile->base.profiles, 450 new = find_attach(ns, &profile->base.profiles,
316 name); 451 name);
317 else 452 else
318 /* released by caller */ 453 /* released by caller */
319 new_profile = find_attach(ns, &ns->base.profiles, 454 new = find_attach(ns, &ns->base.profiles,
320 name); 455 name);
321 break; 456 *lookupname = name;
322 case AA_X_TABLE:
323 /* released by caller */
324 new_profile = x_table_lookup(profile, xindex);
325 break; 457 break;
326 } 458 }
327 459
460 if (!new) {
461 if (xindex & AA_X_INHERIT) {
462 /* (p|c|n)ix - don't change profile but do
463 * use the newest version
464 */
465 *info = "ix fallback";
466 /* no profile && no error */
467 new = aa_get_newest_label(&profile->label);
468 } else if (xindex & AA_X_UNCONFINED) {
469 new = aa_get_newest_label(ns_unconfined(profile->ns));
470 *info = "ux fallback";
471 }
472 }
473
474 if (new && stack) {
475 /* base the stack on post domain transition */
476 struct aa_label *base = new;
477
478 new = aa_label_parse(base, stack, GFP_ATOMIC, true, false);
479 if (IS_ERR(new))
480 new = NULL;
481 aa_put_label(base);
482 }
483
328 /* released by caller */ 484 /* released by caller */
329 return new_profile; 485 return new;
330} 486}
331 487
332/** 488static struct aa_label *profile_transition(struct aa_profile *profile,
333 * apparmor_bprm_set_creds - set the new creds on the bprm struct 489 const struct linux_binprm *bprm,
334 * @bprm: binprm for the exec (NOT NULL) 490 char *buffer, struct path_cond *cond,
335 * 491 bool *secure_exec)
336 * Returns: %0 or error on failure
337 */
338int apparmor_bprm_set_creds(struct linux_binprm *bprm)
339{ 492{
340 struct aa_task_ctx *ctx; 493 struct aa_label *new = NULL;
341 struct aa_profile *profile, *new_profile = NULL; 494 const char *info = NULL, *name = NULL, *target = NULL;
342 struct aa_ns *ns; 495 unsigned int state = profile->file.start;
343 char *buffer = NULL; 496 struct aa_perms perms = {};
344 unsigned int state; 497 bool nonewprivs = false;
345 struct file_perms perms = {};
346 struct path_cond cond = {
347 file_inode(bprm->file)->i_uid,
348 file_inode(bprm->file)->i_mode
349 };
350 const char *name = NULL, *info = NULL;
351 int error = 0; 498 int error = 0;
352 499
353 if (bprm->cred_prepared) 500 AA_BUG(!profile);
354 return 0; 501 AA_BUG(!bprm);
355 502 AA_BUG(!buffer);
356 ctx = cred_ctx(bprm->cred);
357 AA_BUG(!ctx);
358
359 profile = aa_get_newest_profile(ctx->profile);
360 /*
361 * get the namespace from the replacement profile as replacement
362 * can change the namespace
363 */
364 ns = profile->ns;
365 state = profile->file.start;
366 503
367 /* buffer freed below, name is pointer into buffer */ 504 error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
368 error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer, 505 &name, &info, profile->disconnected);
369 &name, &info);
370 if (error) { 506 if (error) {
371 if (unconfined(profile) || 507 if (profile_unconfined(profile) ||
372 (profile->flags & PFLAG_IX_ON_NAME_ERROR)) 508 (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) {
509 AA_DEBUG("name lookup ix on error");
373 error = 0; 510 error = 0;
511 new = aa_get_newest_label(&profile->label);
512 }
374 name = bprm->filename; 513 name = bprm->filename;
375 goto audit; 514 goto audit;
376 } 515 }
377 516
378 /* Test for onexec first as onexec directives override other 517 if (profile_unconfined(profile)) {
379 * x transitions. 518 new = find_attach(profile->ns, &profile->ns->base.profiles,
380 */ 519 name);
381 if (unconfined(profile)) { 520 if (new) {
382 /* unconfined task */ 521 AA_DEBUG("unconfined attached to new label");
383 if (ctx->onexec) 522 return new;
384 /* change_profile on exec already been granted */ 523 }
385 new_profile = aa_get_profile(ctx->onexec); 524 AA_DEBUG("unconfined exec no attachment");
386 else 525 return aa_get_newest_label(&profile->label);
387 new_profile = find_attach(ns, &ns->base.profiles, name);
388 if (!new_profile)
389 goto cleanup;
390 /*
391 * NOTE: Domain transitions from unconfined are allowed
392 * even when no_new_privs is set because this aways results
393 * in a further reduction of permissions.
394 */
395 goto apply;
396 } 526 }
397 527
398 /* find exec permissions for name */ 528 /* find exec permissions for name */
399 state = aa_str_perms(profile->file.dfa, state, name, &cond, &perms); 529 state = aa_str_perms(profile->file.dfa, state, name, cond, &perms);
400 if (ctx->onexec) {
401 struct file_perms cp;
402 info = "change_profile onexec";
403 new_profile = aa_get_newest_profile(ctx->onexec);
404 if (!(perms.allow & AA_MAY_ONEXEC))
405 goto audit;
406
407 /* test if this exec can be paired with change_profile onexec.
408 * onexec permission is linked to exec with a standard pairing
409 * exec\0change_profile
410 */
411 state = aa_dfa_null_transition(profile->file.dfa, state);
412 cp = change_profile_perms(profile, ctx->onexec->ns,
413 ctx->onexec->base.name,
414 AA_MAY_ONEXEC, state);
415
416 if (!(cp.allow & AA_MAY_ONEXEC))
417 goto audit;
418 goto apply;
419 }
420
421 if (perms.allow & MAY_EXEC) { 530 if (perms.allow & MAY_EXEC) {
422 /* exec permission determine how to transition */ 531 /* exec permission determine how to transition */
423 new_profile = x_to_profile(profile, name, perms.xindex); 532 new = x_to_label(profile, name, perms.xindex, &target, &info);
424 if (!new_profile) { 533 if (new && new->proxy == profile->label.proxy && info) {
425 if (perms.xindex & AA_X_INHERIT) { 534 /* hack ix fallback - improve how this is detected */
426 /* (p|c|n)ix - don't change profile but do 535 goto audit;
427 * use the newest version, which was picked 536 } else if (!new) {
428 * up above when getting profile 537 error = -EACCES;
429 */ 538 info = "profile transition not found";
430 info = "ix fallback"; 539 /* remove MAY_EXEC to audit as failure */
431 new_profile = aa_get_profile(profile); 540 perms.allow &= ~MAY_EXEC;
432 goto x_clear;
433 } else if (perms.xindex & AA_X_UNCONFINED) {
434 new_profile = aa_get_newest_profile(ns->unconfined);
435 info = "ux fallback";
436 } else {
437 error = -EACCES;
438 info = "profile not found";
439 /* remove MAY_EXEC to audit as failure */
440 perms.allow &= ~MAY_EXEC;
441 }
442 } 541 }
443 } else if (COMPLAIN_MODE(profile)) { 542 } else if (COMPLAIN_MODE(profile)) {
444 /* no exec permission - are we in learning mode */ 543 /* no exec permission - learning mode */
445 new_profile = aa_new_null_profile(profile, false, name, 544 struct aa_profile *new_profile = aa_new_null_profile(profile,
446 GFP_ATOMIC); 545 false, name,
546 GFP_ATOMIC);
447 if (!new_profile) { 547 if (!new_profile) {
448 error = -ENOMEM; 548 error = -ENOMEM;
449 info = "could not create null profile"; 549 info = "could not create null profile";
450 } else 550 } else {
451 error = -EACCES; 551 error = -EACCES;
552 new = &new_profile->label;
553 }
452 perms.xindex |= AA_X_UNSAFE; 554 perms.xindex |= AA_X_UNSAFE;
453 } else 555 } else
454 /* fail exec */ 556 /* fail exec */
455 error = -EACCES; 557 error = -EACCES;
456 558
457 /* 559 if (!new)
458 * Policy has specified a domain transition, if no_new_privs then 560 goto audit;
459 * fail the exec. 561
562 /* Policy has specified a domain transitions. if no_new_privs and
563 * confined and not transitioning to the current domain fail.
564 *
565 * NOTE: Domain transitions from unconfined and to stritly stacked
566 * subsets are allowed even when no_new_privs is set because this
567 * aways results in a further reduction of permissions.
460 */ 568 */
461 if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) { 569 if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) &&
570 !profile_unconfined(profile) &&
571 !aa_label_is_subset(new, &profile->label)) {
462 error = -EPERM; 572 error = -EPERM;
463 goto cleanup; 573 info = "no new privs";
574 nonewprivs = true;
575 perms.allow &= ~MAY_EXEC;
576 goto audit;
577 }
578
579 if (!(perms.xindex & AA_X_UNSAFE)) {
580 if (DEBUG_ON) {
581 dbg_printk("apparmor: scrubbing environment variables"
582 " for %s profile=", name);
583 aa_label_printk(new, GFP_ATOMIC);
584 dbg_printk("\n");
585 }
586 *secure_exec = true;
587 }
588
589audit:
590 aa_audit_file(profile, &perms, OP_EXEC, MAY_EXEC, name, target, new,
591 cond->uid, info, error);
592 if (!new || nonewprivs) {
593 aa_put_label(new);
594 return ERR_PTR(error);
464 } 595 }
465 596
466 if (!new_profile) 597 return new;
598}
599
600static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec,
601 bool stack, const struct linux_binprm *bprm,
602 char *buffer, struct path_cond *cond,
603 bool *secure_exec)
604{
605 unsigned int state = profile->file.start;
606 struct aa_perms perms = {};
607 const char *xname = NULL, *info = "change_profile onexec";
608 int error = -EACCES;
609
610 AA_BUG(!profile);
611 AA_BUG(!onexec);
612 AA_BUG(!bprm);
613 AA_BUG(!buffer);
614
615 if (profile_unconfined(profile)) {
616 /* change_profile on exec already granted */
617 /*
618 * NOTE: Domain transitions from unconfined are allowed
619 * even when no_new_privs is set because this aways results
620 * in a further reduction of permissions.
621 */
622 return 0;
623 }
624
625 error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
626 &xname, &info, profile->disconnected);
627 if (error) {
628 if (profile_unconfined(profile) ||
629 (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) {
630 AA_DEBUG("name lookup ix on error");
631 error = 0;
632 }
633 xname = bprm->filename;
634 goto audit;
635 }
636
637 /* find exec permissions for name */
638 state = aa_str_perms(profile->file.dfa, state, xname, cond, &perms);
639 if (!(perms.allow & AA_MAY_ONEXEC)) {
640 info = "no change_onexec valid for executable";
641 goto audit;
642 }
643 /* test if this exec can be paired with change_profile onexec.
644 * onexec permission is linked to exec with a standard pairing
645 * exec\0change_profile
646 */
647 state = aa_dfa_null_transition(profile->file.dfa, state);
648 error = change_profile_perms(profile, onexec, stack, AA_MAY_ONEXEC,
649 state, &perms);
650 if (error) {
651 perms.allow &= ~AA_MAY_ONEXEC;
467 goto audit; 652 goto audit;
653 }
654 /* Policy has specified a domain transitions. if no_new_privs and
655 * confined and not transitioning to the current domain fail.
656 *
657 * NOTE: Domain transitions from unconfined and to stritly stacked
658 * subsets are allowed even when no_new_privs is set because this
659 * aways results in a further reduction of permissions.
660 */
661 if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) &&
662 !profile_unconfined(profile) &&
663 !aa_label_is_subset(onexec, &profile->label)) {
664 error = -EPERM;
665 info = "no new privs";
666 perms.allow &= ~AA_MAY_ONEXEC;
667 goto audit;
668 }
669
670 if (!(perms.xindex & AA_X_UNSAFE)) {
671 if (DEBUG_ON) {
672 dbg_printk("apparmor: scrubbing environment "
673 "variables for %s label=", xname);
674 aa_label_printk(onexec, GFP_ATOMIC);
675 dbg_printk("\n");
676 }
677 *secure_exec = true;
678 }
679
680audit:
681 return aa_audit_file(profile, &perms, OP_EXEC, AA_MAY_ONEXEC, xname,
682 NULL, onexec, cond->uid, info, error);
683}
684
685/* ensure none ns domain transitions are correctly applied with onexec */
686
687static struct aa_label *handle_onexec(struct aa_label *label,
688 struct aa_label *onexec, bool stack,
689 const struct linux_binprm *bprm,
690 char *buffer, struct path_cond *cond,
691 bool *unsafe)
692{
693 struct aa_profile *profile;
694 struct aa_label *new;
695 int error;
696
697 AA_BUG(!label);
698 AA_BUG(!onexec);
699 AA_BUG(!bprm);
700 AA_BUG(!buffer);
701
702 if (!stack) {
703 error = fn_for_each_in_ns(label, profile,
704 profile_onexec(profile, onexec, stack,
705 bprm, buffer, cond, unsafe));
706 if (error)
707 return ERR_PTR(error);
708 new = fn_label_build_in_ns(label, profile, GFP_ATOMIC,
709 aa_get_newest_label(onexec),
710 profile_transition(profile, bprm, buffer,
711 cond, unsafe));
712
713 } else {
714 /* TODO: determine how much we want to losen this */
715 error = fn_for_each_in_ns(label, profile,
716 profile_onexec(profile, onexec, stack, bprm,
717 buffer, cond, unsafe));
718 if (error)
719 return ERR_PTR(error);
720 new = fn_label_build_in_ns(label, profile, GFP_ATOMIC,
721 aa_label_merge(&profile->label, onexec,
722 GFP_ATOMIC),
723 profile_transition(profile, bprm, buffer,
724 cond, unsafe));
725 }
726
727 if (new)
728 return new;
729
730 /* TODO: get rid of GLOBAL_ROOT_UID */
731 error = fn_for_each_in_ns(label, profile,
732 aa_audit_file(profile, &nullperms, OP_CHANGE_ONEXEC,
733 AA_MAY_ONEXEC, bprm->filename, NULL,
734 onexec, GLOBAL_ROOT_UID,
735 "failed to build target label", -ENOMEM));
736 return ERR_PTR(error);
737}
738
739/**
740 * apparmor_bprm_set_creds - set the new creds on the bprm struct
741 * @bprm: binprm for the exec (NOT NULL)
742 *
743 * Returns: %0 or error on failure
744 *
745 * TODO: once the other paths are done see if we can't refactor into a fn
746 */
747int apparmor_bprm_set_creds(struct linux_binprm *bprm)
748{
749 struct aa_task_ctx *ctx;
750 struct aa_label *label, *new = NULL;
751 struct aa_profile *profile;
752 char *buffer = NULL;
753 const char *info = NULL;
754 int error = 0;
755 bool unsafe = false;
756 struct path_cond cond = {
757 file_inode(bprm->file)->i_uid,
758 file_inode(bprm->file)->i_mode
759 };
760
761 if (bprm->cred_prepared)
762 return 0;
763
764 ctx = cred_ctx(bprm->cred);
765 AA_BUG(!ctx);
766
767 label = aa_get_newest_label(ctx->label);
768
769 /* buffer freed below, name is pointer into buffer */
770 get_buffers(buffer);
771 /* Test for onexec first as onexec override other x transitions. */
772 if (ctx->onexec)
773 new = handle_onexec(label, ctx->onexec, ctx->token,
774 bprm, buffer, &cond, &unsafe);
775 else
776 new = fn_label_build(label, profile, GFP_ATOMIC,
777 profile_transition(profile, bprm, buffer,
778 &cond, &unsafe));
779
780 AA_BUG(!new);
781 if (IS_ERR(new)) {
782 error = PTR_ERR(new);
783 goto done;
784 } else if (!new) {
785 error = -ENOMEM;
786 goto done;
787 }
788
789 /* TODO: Add ns level no_new_privs subset test */
468 790
469 if (bprm->unsafe & LSM_UNSAFE_SHARE) { 791 if (bprm->unsafe & LSM_UNSAFE_SHARE) {
470 /* FIXME: currently don't mediate shared state */ 792 /* FIXME: currently don't mediate shared state */
471 ; 793 ;
472 } 794 }
473 795
474 if (bprm->unsafe & LSM_UNSAFE_PTRACE) { 796 if (bprm->unsafe & (LSM_UNSAFE_PTRACE)) {
475 error = may_change_ptraced_domain(new_profile); 797 /* TODO: test needs to be profile of label to new */
798 error = may_change_ptraced_domain(new, &info);
476 if (error) 799 if (error)
477 goto audit; 800 goto audit;
478 } 801 }
479 802
480 /* Determine if secure exec is needed. 803 if (unsafe) {
481 * Can be at this point for the following reasons: 804 if (DEBUG_ON) {
482 * 1. unconfined switching to confined 805 dbg_printk("scrubbing environment variables for %s "
483 * 2. confined switching to different confinement 806 "label=", bprm->filename);
484 * 3. confined switching to unconfined 807 aa_label_printk(new, GFP_ATOMIC);
485 * 808 dbg_printk("\n");
486 * Cases 2 and 3 are marked as requiring secure exec 809 }
487 * (unless policy specified "unsafe exec")
488 *
489 * bprm->unsafe is used to cache the AA_X_UNSAFE permission
490 * to avoid having to recompute in secureexec
491 */
492 if (!(perms.xindex & AA_X_UNSAFE)) {
493 AA_DEBUG("scrubbing environment variables for %s profile=%s\n",
494 name, new_profile->base.hname);
495 bprm->unsafe |= AA_SECURE_X_NEEDED; 810 bprm->unsafe |= AA_SECURE_X_NEEDED;
496 } 811 }
497apply:
498 /* when transitioning profiles clear unsafe personality bits */
499 bprm->per_clear |= PER_CLEAR_ON_SETID;
500 812
501x_clear: 813 if (label->proxy != new->proxy) {
502 aa_put_profile(ctx->profile); 814 /* when transitioning clear unsafe personality bits */
503 /* transfer new profile reference will be released when ctx is freed */ 815 if (DEBUG_ON) {
504 ctx->profile = new_profile; 816 dbg_printk("apparmor: clearing unsafe personality "
505 new_profile = NULL; 817 "bits. %s label=", bprm->filename);
818 aa_label_printk(new, GFP_ATOMIC);
819 dbg_printk("\n");
820 }
821 bprm->per_clear |= PER_CLEAR_ON_SETID;
822 }
823 aa_put_label(ctx->label);
824 /* transfer reference, released when ctx is freed */
825 ctx->label = new;
506 826
507 /* clear out all temporary/transitional state from the context */ 827done:
828 /* clear out temporary/transitional state from the context */
508 aa_clear_task_ctx_trans(ctx); 829 aa_clear_task_ctx_trans(ctx);
509 830
510audit: 831 aa_put_label(label);
511 error = aa_audit_file(profile, &perms, OP_EXEC, MAY_EXEC, name, 832 put_buffers(buffer);
512 new_profile ? new_profile->base.hname : NULL,
513 cond.uid, info, error);
514
515cleanup:
516 aa_put_profile(new_profile);
517 aa_put_profile(profile);
518 kfree(buffer);
519 833
520 return error; 834 return error;
835
836audit:
837 error = fn_for_each(label, profile,
838 aa_audit_file(profile, &nullperms, OP_EXEC, MAY_EXEC,
839 bprm->filename, NULL, new,
840 file_inode(bprm->file)->i_uid, info,
841 error));
842 aa_put_label(new);
843 goto done;
521} 844}
522 845
523/** 846/**
@@ -537,53 +860,157 @@ int apparmor_bprm_secureexec(struct linux_binprm *bprm)
537 return 0; 860 return 0;
538} 861}
539 862
540/** 863/*
541 * apparmor_bprm_committing_creds - do task cleanup on committing new creds 864 * Functions for self directed profile change
542 * @bprm: binprm for the exec (NOT NULL)
543 */ 865 */
544void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
545{
546 struct aa_profile *profile = __aa_current_profile();
547 struct aa_task_ctx *new_ctx = cred_ctx(bprm->cred);
548 866
549 /* bail out if unconfined or not changing profile */
550 if ((new_ctx->profile == profile) ||
551 (unconfined(new_ctx->profile)))
552 return;
553 867
554 current->pdeath_signal = 0; 868/* helper fn for change_hat
555 869 *
556 /* reset soft limits and set hard limits for the new profile */ 870 * Returns: label for hat transition OR ERR_PTR. Does NOT return NULL
557 __aa_transition_rlimits(profile, new_ctx->profile);
558}
559
560/**
561 * apparmor_bprm_commited_cred - do cleanup after new creds committed
562 * @bprm: binprm for the exec (NOT NULL)
563 */ 871 */
564void apparmor_bprm_committed_creds(struct linux_binprm *bprm) 872static struct aa_label *build_change_hat(struct aa_profile *profile,
873 const char *name, bool sibling)
565{ 874{
566 /* TODO: cleanup signals - ipc mediation */ 875 struct aa_profile *root, *hat = NULL;
567 return; 876 const char *info = NULL;
568} 877 int error = 0;
569 878
570/* 879 if (sibling && PROFILE_IS_HAT(profile)) {
571 * Functions for self directed profile change 880 root = aa_get_profile_rcu(&profile->parent);
572 */ 881 } else if (!sibling && !PROFILE_IS_HAT(profile)) {
882 root = aa_get_profile(profile);
883 } else {
884 info = "conflicting target types";
885 error = -EPERM;
886 goto audit;
887 }
573 888
574/** 889 hat = aa_find_child(root, name);
575 * new_compound_name - create an hname with @n2 appended to @n1 890 if (!hat) {
576 * @n1: base of hname (NOT NULL) 891 error = -ENOENT;
577 * @n2: name to append (NOT NULL) 892 if (COMPLAIN_MODE(profile)) {
893 hat = aa_new_null_profile(profile, true, name,
894 GFP_KERNEL);
895 if (!hat) {
896 info = "failed null profile create";
897 error = -ENOMEM;
898 }
899 }
900 }
901 aa_put_profile(root);
902
903audit:
904 aa_audit_file(profile, &nullperms, OP_CHANGE_HAT, AA_MAY_CHANGEHAT,
905 name, hat ? hat->base.hname : NULL,
906 hat ? &hat->label : NULL, GLOBAL_ROOT_UID, NULL,
907 error);
908 if (!hat || (error && error != -ENOENT))
909 return ERR_PTR(error);
910 /* if hat && error - complain mode, already audited and we adjust for
911 * complain mode allow by returning hat->label
912 */
913 return &hat->label;
914}
915
916/* helper fn for changing into a hat
578 * 917 *
579 * Returns: new name or NULL on error 918 * Returns: label for hat transition or ERR_PTR. Does not return NULL
580 */ 919 */
581static char *new_compound_name(const char *n1, const char *n2) 920static struct aa_label *change_hat(struct aa_label *label, const char *hats[],
921 int count, int flags)
582{ 922{
583 char *name = kmalloc(strlen(n1) + strlen(n2) + 3, GFP_KERNEL); 923 struct aa_profile *profile, *root, *hat = NULL;
584 if (name) 924 struct aa_label *new;
585 sprintf(name, "%s//%s", n1, n2); 925 struct label_it it;
586 return name; 926 bool sibling = false;
927 const char *name, *info = NULL;
928 int i, error;
929
930 AA_BUG(!label);
931 AA_BUG(!hats);
932 AA_BUG(count < 1);
933
934 if (PROFILE_IS_HAT(labels_profile(label)))
935 sibling = true;
936
937 /*find first matching hat */
938 for (i = 0; i < count && !hat; i++) {
939 name = hats[i];
940 label_for_each_in_ns(it, labels_ns(label), label, profile) {
941 if (sibling && PROFILE_IS_HAT(profile)) {
942 root = aa_get_profile_rcu(&profile->parent);
943 } else if (!sibling && !PROFILE_IS_HAT(profile)) {
944 root = aa_get_profile(profile);
945 } else { /* conflicting change type */
946 info = "conflicting targets types";
947 error = -EPERM;
948 goto fail;
949 }
950 hat = aa_find_child(root, name);
951 aa_put_profile(root);
952 if (!hat) {
953 if (!COMPLAIN_MODE(profile))
954 goto outer_continue;
955 /* complain mode succeed as if hat */
956 } else if (!PROFILE_IS_HAT(hat)) {
957 info = "target not hat";
958 error = -EPERM;
959 aa_put_profile(hat);
960 goto fail;
961 }
962 aa_put_profile(hat);
963 }
964 /* found a hat for all profiles in ns */
965 goto build;
966outer_continue:
967 ;
968 }
969 /* no hats that match, find appropriate error
970 *
971 * In complain mode audit of the failure is based off of the first
972 * hat supplied. This is done due how userspace interacts with
973 * change_hat.
974 */
975 name = NULL;
976 label_for_each_in_ns(it, labels_ns(label), label, profile) {
977 if (!list_empty(&profile->base.profiles)) {
978 info = "hat not found";
979 error = -ENOENT;
980 goto fail;
981 }
982 }
983 info = "no hats defined";
984 error = -ECHILD;
985
986fail:
987 label_for_each_in_ns(it, labels_ns(label), label, profile) {
988 /*
989 * no target as it has failed to be found or built
990 *
991 * change_hat uses probing and should not log failures
992 * related to missing hats
993 */
994 /* TODO: get rid of GLOBAL_ROOT_UID */
995 if (count > 1 || COMPLAIN_MODE(profile)) {
996 aa_audit_file(profile, &nullperms, OP_CHANGE_HAT,
997 AA_MAY_CHANGEHAT, name, NULL, NULL,
998 GLOBAL_ROOT_UID, info, error);
999 }
1000 }
1001 return ERR_PTR(error);
1002
1003build:
1004 new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
1005 build_change_hat(profile, name, sibling),
1006 aa_get_label(&profile->label));
1007 if (!new) {
1008 info = "label build failed";
1009 error = -ENOMEM;
1010 goto fail;
1011 } /* else if (IS_ERR) build_change_hat has logged error so return new */
1012
1013 return new;
587} 1014}
588 1015
589/** 1016/**
@@ -591,24 +1018,26 @@ static char *new_compound_name(const char *n1, const char *n2)
591 * @hats: vector of hat names to try changing into (MAYBE NULL if @count == 0) 1018 * @hats: vector of hat names to try changing into (MAYBE NULL if @count == 0)
592 * @count: number of hat names in @hats 1019 * @count: number of hat names in @hats
593 * @token: magic value to validate the hat change 1020 * @token: magic value to validate the hat change
594 * @permtest: true if this is just a permission test 1021 * @flags: flags affecting behavior of the change
1022 *
1023 * Returns %0 on success, error otherwise.
595 * 1024 *
596 * Change to the first profile specified in @hats that exists, and store 1025 * Change to the first profile specified in @hats that exists, and store
597 * the @hat_magic in the current task context. If the count == 0 and the 1026 * the @hat_magic in the current task context. If the count == 0 and the
598 * @token matches that stored in the current task context, return to the 1027 * @token matches that stored in the current task context, return to the
599 * top level profile. 1028 * top level profile.
600 * 1029 *
601 * Returns %0 on success, error otherwise. 1030 * change_hat only applies to profiles in the current ns, and each profile
1031 * in the ns must make the same transition otherwise change_hat will fail.
602 */ 1032 */
603int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) 1033int aa_change_hat(const char *hats[], int count, u64 token, int flags)
604{ 1034{
605 const struct cred *cred; 1035 const struct cred *cred;
606 struct aa_task_ctx *ctx; 1036 struct aa_task_ctx *ctx;
607 struct aa_profile *profile, *previous_profile, *hat = NULL; 1037 struct aa_label *label, *previous, *new = NULL, *target = NULL;
608 char *name = NULL; 1038 struct aa_profile *profile;
609 int i; 1039 struct aa_perms perms = {};
610 struct file_perms perms = {}; 1040 const char *info = NULL;
611 const char *target = NULL, *info = NULL;
612 int error = 0; 1041 int error = 0;
613 1042
614 /* 1043 /*
@@ -616,122 +1045,120 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
616 * There is no exception for unconfined as change_hat is not 1045 * There is no exception for unconfined as change_hat is not
617 * available. 1046 * available.
618 */ 1047 */
619 if (task_no_new_privs(current)) 1048 if (task_no_new_privs(current)) {
1049 /* not an apparmor denial per se, so don't log it */
1050 AA_DEBUG("no_new_privs - change_hat denied");
620 return -EPERM; 1051 return -EPERM;
1052 }
621 1053
622 /* released below */ 1054 /* released below */
623 cred = get_current_cred(); 1055 cred = get_current_cred();
624 ctx = cred_ctx(cred); 1056 ctx = cred_ctx(cred);
625 profile = aa_get_newest_profile(aa_cred_profile(cred)); 1057 label = aa_get_newest_cred_label(cred);
626 previous_profile = aa_get_newest_profile(ctx->previous); 1058 previous = aa_get_newest_label(ctx->previous);
627 1059
628 if (unconfined(profile)) { 1060 if (unconfined(label)) {
629 info = "unconfined"; 1061 info = "unconfined can not change_hat";
630 error = -EPERM; 1062 error = -EPERM;
631 goto audit; 1063 goto fail;
632 } 1064 }
633 1065
634 if (count) { 1066 if (count) {
635 /* attempting to change into a new hat or switch to a sibling */ 1067 new = change_hat(label, hats, count, flags);
636 struct aa_profile *root; 1068 AA_BUG(!new);
637 if (PROFILE_IS_HAT(profile)) 1069 if (IS_ERR(new)) {
638 root = aa_get_profile_rcu(&profile->parent); 1070 error = PTR_ERR(new);
639 else 1071 new = NULL;
640 root = aa_get_profile(profile); 1072 /* already audited */
641 1073 goto out;
642 /* find first matching hat */
643 for (i = 0; i < count && !hat; i++)
644 /* released below */
645 hat = aa_find_child(root, hats[i]);
646 if (!hat) {
647 if (!COMPLAIN_MODE(root) || permtest) {
648 if (list_empty(&root->base.profiles))
649 error = -ECHILD;
650 else
651 error = -ENOENT;
652 aa_put_profile(root);
653 goto out;
654 }
655
656 /*
657 * In complain mode and failed to match any hats.
658 * Audit the failure is based off of the first hat
659 * supplied. This is done due how userspace
660 * interacts with change_hat.
661 *
662 * TODO: Add logging of all failed hats
663 */
664
665 /* freed below */
666 name = new_compound_name(root->base.hname, hats[0]);
667 aa_put_profile(root);
668 target = name;
669 /* released below */
670 hat = aa_new_null_profile(profile, true, hats[0],
671 GFP_KERNEL);
672 if (!hat) {
673 info = "failed null profile create";
674 error = -ENOMEM;
675 goto audit;
676 }
677 } else {
678 aa_put_profile(root);
679 target = hat->base.hname;
680 if (!PROFILE_IS_HAT(hat)) {
681 info = "target not hat";
682 error = -EPERM;
683 goto audit;
684 }
685 } 1074 }
686 1075
687 error = may_change_ptraced_domain(hat); 1076 error = may_change_ptraced_domain(new, &info);
1077 if (error)
1078 goto fail;
1079
1080 if (flags & AA_CHANGE_TEST)
1081 goto out;
1082
1083 target = new;
1084 error = aa_set_current_hat(new, token);
1085 if (error == -EACCES)
1086 /* kill task in case of brute force attacks */
1087 goto kill;
1088 } else if (previous && !(flags & AA_CHANGE_TEST)) {
1089 /* Return to saved label. Kill task if restore fails
1090 * to avoid brute force attacks
1091 */
1092 target = previous;
1093 error = aa_restore_previous_label(token);
688 if (error) { 1094 if (error) {
689 info = "ptraced";
690 error = -EPERM;
691 goto audit;
692 }
693
694 if (!permtest) {
695 error = aa_set_current_hat(hat, token);
696 if (error == -EACCES) 1095 if (error == -EACCES)
697 /* kill task in case of brute force attacks */ 1096 goto kill;
698 perms.kill = AA_MAY_CHANGEHAT; 1097 goto fail;
699 else if (name && !error)
700 /* reset error for learning of new hats */
701 error = -ENOENT;
702 } 1098 }
703 } else if (previous_profile) { 1099 } /* else ignore @flags && restores when there is no saved profile */
704 /* Return to saved profile. Kill task if restore fails
705 * to avoid brute force attacks
706 */
707 target = previous_profile->base.hname;
708 error = aa_restore_previous_profile(token);
709 perms.kill = AA_MAY_CHANGEHAT;
710 } else
711 /* ignore restores when there is no saved profile */
712 goto out;
713
714audit:
715 if (!permtest)
716 error = aa_audit_file(profile, &perms, OP_CHANGE_HAT,
717 AA_MAY_CHANGEHAT, NULL, target,
718 GLOBAL_ROOT_UID, info, error);
719 1100
720out: 1101out:
721 aa_put_profile(hat); 1102 aa_put_label(new);
722 kfree(name); 1103 aa_put_label(previous);
723 aa_put_profile(profile); 1104 aa_put_label(label);
724 aa_put_profile(previous_profile);
725 put_cred(cred); 1105 put_cred(cred);
726 1106
727 return error; 1107 return error;
1108
1109kill:
1110 info = "failed token match";
1111 perms.kill = AA_MAY_CHANGEHAT;
1112
1113fail:
1114 fn_for_each_in_ns(label, profile,
1115 aa_audit_file(profile, &perms, OP_CHANGE_HAT,
1116 AA_MAY_CHANGEHAT, NULL, NULL, target,
1117 GLOBAL_ROOT_UID, info, error));
1118
1119 goto out;
1120}
1121
1122
1123static int change_profile_perms_wrapper(const char *op, const char *name,
1124 struct aa_profile *profile,
1125 struct aa_label *target, bool stack,
1126 u32 request, struct aa_perms *perms)
1127{
1128 const char *info = NULL;
1129 int error = 0;
1130
1131 /*
1132 * Fail explicitly requested domain transitions when no_new_privs
1133 * and not unconfined OR the transition results in a stack on
1134 * the current label.
1135 * Stacking domain transitions and transitions from unconfined are
1136 * allowed even when no_new_privs is set because this aways results
1137 * in a reduction of permissions.
1138 */
1139 if (task_no_new_privs(current) && !stack &&
1140 !profile_unconfined(profile) &&
1141 !aa_label_is_subset(target, &profile->label)) {
1142 info = "no new privs";
1143 error = -EPERM;
1144 }
1145
1146 if (!error)
1147 error = change_profile_perms(profile, target, stack, request,
1148 profile->file.start, perms);
1149 if (error)
1150 error = aa_audit_file(profile, perms, op, request, name,
1151 NULL, target, GLOBAL_ROOT_UID, info,
1152 error);
1153
1154 return error;
728} 1155}
729 1156
730/** 1157/**
731 * aa_change_profile - perform a one-way profile transition 1158 * aa_change_profile - perform a one-way profile transition
732 * @fqname: name of profile may include namespace (NOT NULL) 1159 * @fqname: name of profile may include namespace (NOT NULL)
733 * @onexec: whether this transition is to take place immediately or at exec 1160 * @onexec: whether this transition is to take place immediately or at exec
734 * @permtest: true if this is just a permission test 1161 * @flags: flags affecting change behavior
735 * 1162 *
736 * Change to new profile @name. Unlike with hats, there is no way 1163 * Change to new profile @name. Unlike with hats, there is no way
737 * to change back. If @name isn't specified the current profile name is 1164 * to change back. If @name isn't specified the current profile name is
@@ -741,14 +1168,16 @@ out:
741 * 1168 *
742 * Returns %0 on success, error otherwise. 1169 * Returns %0 on success, error otherwise.
743 */ 1170 */
744int aa_change_profile(const char *fqname, bool onexec, 1171int aa_change_profile(const char *fqname, int flags)
745 bool permtest, bool stack)
746{ 1172{
747 const struct cred *cred; 1173 struct aa_label *label, *new = NULL, *target = NULL;
748 struct aa_profile *profile, *target = NULL; 1174 struct aa_profile *profile;
749 struct file_perms perms = {}; 1175 struct aa_perms perms = {};
750 const char *info = NULL, *op; 1176 const char *info = NULL;
1177 const char *auditname = fqname; /* retain leading & if stack */
1178 bool stack = flags & AA_CHANGE_STACK;
751 int error = 0; 1179 int error = 0;
1180 char *op;
752 u32 request; 1181 u32 request;
753 1182
754 if (!fqname || !*fqname) { 1183 if (!fqname || !*fqname) {
@@ -756,74 +1185,118 @@ int aa_change_profile(const char *fqname, bool onexec,
756 return -EINVAL; 1185 return -EINVAL;
757 } 1186 }
758 1187
759 if (onexec) { 1188 if (flags & AA_CHANGE_ONEXEC) {
760 request = AA_MAY_ONEXEC; 1189 request = AA_MAY_ONEXEC;
761 op = OP_CHANGE_ONEXEC; 1190 if (stack)
1191 op = OP_STACK_ONEXEC;
1192 else
1193 op = OP_CHANGE_ONEXEC;
762 } else { 1194 } else {
763 request = AA_MAY_CHANGE_PROFILE; 1195 request = AA_MAY_CHANGE_PROFILE;
764 op = OP_CHANGE_PROFILE; 1196 if (stack)
1197 op = OP_STACK;
1198 else
1199 op = OP_CHANGE_PROFILE;
765 } 1200 }
766 1201
767 cred = get_current_cred(); 1202 label = aa_get_current_label();
768 profile = aa_cred_profile(cred);
769 1203
770 /* 1204 if (*fqname == '&') {
771 * Fail explicitly requested domain transitions if no_new_privs 1205 stack = true;
772 * and not unconfined. 1206 /* don't have label_parse() do stacking */
773 * Domain transitions from unconfined are allowed even when 1207 fqname++;
774 * no_new_privs is set because this aways results in a reduction
775 * of permissions.
776 */
777 if (task_no_new_privs(current) && !unconfined(profile)) {
778 put_cred(cred);
779 return -EPERM;
780 } 1208 }
1209 target = aa_label_parse(label, fqname, GFP_KERNEL, true, false);
1210 if (IS_ERR(target)) {
1211 struct aa_profile *tprofile;
781 1212
782 target = aa_fqlookupn_profile(profile, fqname, strlen(fqname)); 1213 info = "label not found";
783 if (!target) { 1214 error = PTR_ERR(target);
784 info = "profile not found"; 1215 target = NULL;
785 error = -ENOENT; 1216 /*
786 if (permtest || !COMPLAIN_MODE(profile)) 1217 * TODO: fixme using labels_profile is not right - do profile
1218 * per complain profile
1219 */
1220 if ((flags & AA_CHANGE_TEST) ||
1221 !COMPLAIN_MODE(labels_profile(label)))
787 goto audit; 1222 goto audit;
788 /* released below */ 1223 /* released below */
789 target = aa_new_null_profile(profile, false, fqname, 1224 tprofile = aa_new_null_profile(labels_profile(label), false,
790 GFP_KERNEL); 1225 fqname, GFP_KERNEL);
791 if (!target) { 1226 if (!tprofile) {
792 info = "failed null profile create"; 1227 info = "failed null profile create";
793 error = -ENOMEM; 1228 error = -ENOMEM;
794 goto audit; 1229 goto audit;
795 } 1230 }
1231 target = &tprofile->label;
1232 goto check;
796 } 1233 }
797 1234
798 perms = change_profile_perms(profile, target->ns, target->base.hname, 1235 /*
799 request, profile->file.start); 1236 * self directed transitions only apply to current policy ns
800 if (!(perms.allow & request)) { 1237 * TODO: currently requiring perms for stacking and straight change
801 error = -EACCES; 1238 * stacking doesn't strictly need this. Determine how much
802 goto audit; 1239 * we want to loosen this restriction for stacking
803 } 1240 *
1241 * if (!stack) {
1242 */
1243 error = fn_for_each_in_ns(label, profile,
1244 change_profile_perms_wrapper(op, auditname,
1245 profile, target, stack,
1246 request, &perms));
1247 if (error)
1248 /* auditing done in change_profile_perms_wrapper */
1249 goto out;
1250
1251 /* } */
804 1252
1253check:
805 /* check if tracing task is allowed to trace target domain */ 1254 /* check if tracing task is allowed to trace target domain */
806 error = may_change_ptraced_domain(target); 1255 error = may_change_ptraced_domain(target, &info);
807 if (error) { 1256 if (error && !fn_for_each_in_ns(label, profile,
808 info = "ptrace prevents transition"; 1257 COMPLAIN_MODE(profile)))
809 goto audit; 1258 goto audit;
810 }
811 1259
812 if (permtest) 1260 /* TODO: add permission check to allow this
813 goto audit; 1261 * if ((flags & AA_CHANGE_ONEXEC) && !current_is_single_threaded()) {
1262 * info = "not a single threaded task";
1263 * error = -EACCES;
1264 * goto audit;
1265 * }
1266 */
1267 if (flags & AA_CHANGE_TEST)
1268 goto out;
814 1269
815 if (onexec) 1270 if (!(flags & AA_CHANGE_ONEXEC)) {
816 error = aa_set_current_onexec(target); 1271 /* only transition profiles in the current ns */
817 else 1272 if (stack)
818 error = aa_replace_current_profile(target); 1273 new = aa_label_merge(label, target, GFP_KERNEL);
1274 else
1275 new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
1276 aa_get_label(target),
1277 aa_get_label(&profile->label));
1278 if (IS_ERR_OR_NULL(new)) {
1279 info = "failed to build target label";
1280 error = PTR_ERR(new);
1281 new = NULL;
1282 perms.allow = 0;
1283 goto audit;
1284 }
1285 error = aa_replace_current_label(new);
1286 } else
1287 /* full transition will be built in exec path */
1288 error = aa_set_current_onexec(target, stack);
819 1289
820audit: 1290audit:
821 if (!permtest) 1291 error = fn_for_each_in_ns(label, profile,
822 error = aa_audit_file(profile, &perms, op, request, NULL, 1292 aa_audit_file(profile, &perms, op, request, auditname,
823 fqname, GLOBAL_ROOT_UID, info, error); 1293 NULL, new ? new : target,
1294 GLOBAL_ROOT_UID, info, error));
824 1295
825 aa_put_profile(target); 1296out:
826 put_cred(cred); 1297 aa_put_label(new);
1298 aa_put_label(target);
1299 aa_put_label(label);
827 1300
828 return error; 1301 return error;
829} 1302}
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 750564c3ab71..3382518b87fa 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -12,15 +12,30 @@
12 * License. 12 * License.
13 */ 13 */
14 14
15#include <linux/tty.h>
16#include <linux/fdtable.h>
17#include <linux/file.h>
18
15#include "include/apparmor.h" 19#include "include/apparmor.h"
16#include "include/audit.h" 20#include "include/audit.h"
21#include "include/context.h"
17#include "include/file.h" 22#include "include/file.h"
18#include "include/match.h" 23#include "include/match.h"
19#include "include/path.h" 24#include "include/path.h"
20#include "include/policy.h" 25#include "include/policy.h"
26#include "include/label.h"
21 27
22struct file_perms nullperms; 28static u32 map_mask_to_chr_mask(u32 mask)
29{
30 u32 m = mask & PERMS_CHRS_MASK;
23 31
32 if (mask & AA_MAY_GETATTR)
33 m |= MAY_READ;
34 if (mask & (AA_MAY_SETATTR | AA_MAY_CHMOD | AA_MAY_CHOWN))
35 m |= MAY_WRITE;
36
37 return m;
38}
24 39
25/** 40/**
26 * audit_file_mask - convert mask to permission string 41 * audit_file_mask - convert mask to permission string
@@ -31,29 +46,7 @@ static void audit_file_mask(struct audit_buffer *ab, u32 mask)
31{ 46{
32 char str[10]; 47 char str[10];
33 48
34 char *m = str; 49 aa_perm_mask_to_str(str, aa_file_perm_chrs, map_mask_to_chr_mask(mask));
35
36 if (mask & AA_EXEC_MMAP)
37 *m++ = 'm';
38 if (mask & (MAY_READ | AA_MAY_META_READ))
39 *m++ = 'r';
40 if (mask & (MAY_WRITE | AA_MAY_META_WRITE | AA_MAY_CHMOD |
41 AA_MAY_CHOWN))
42 *m++ = 'w';
43 else if (mask & MAY_APPEND)
44 *m++ = 'a';
45 if (mask & AA_MAY_CREATE)
46 *m++ = 'c';
47 if (mask & AA_MAY_DELETE)
48 *m++ = 'd';
49 if (mask & AA_MAY_LINK)
50 *m++ = 'l';
51 if (mask & AA_MAY_LOCK)
52 *m++ = 'k';
53 if (mask & MAY_EXEC)
54 *m++ = 'x';
55 *m = '\0';
56
57 audit_log_string(ab, str); 50 audit_log_string(ab, str);
58} 51}
59 52
@@ -67,22 +60,26 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
67 struct common_audit_data *sa = va; 60 struct common_audit_data *sa = va;
68 kuid_t fsuid = current_fsuid(); 61 kuid_t fsuid = current_fsuid();
69 62
70 if (aad(sa)->fs.request & AA_AUDIT_FILE_MASK) { 63 if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
71 audit_log_format(ab, " requested_mask="); 64 audit_log_format(ab, " requested_mask=");
72 audit_file_mask(ab, aad(sa)->fs.request); 65 audit_file_mask(ab, aad(sa)->request);
73 } 66 }
74 if (aad(sa)->fs.denied & AA_AUDIT_FILE_MASK) { 67 if (aad(sa)->denied & AA_AUDIT_FILE_MASK) {
75 audit_log_format(ab, " denied_mask="); 68 audit_log_format(ab, " denied_mask=");
76 audit_file_mask(ab, aad(sa)->fs.denied); 69 audit_file_mask(ab, aad(sa)->denied);
77 } 70 }
78 if (aad(sa)->fs.request & AA_AUDIT_FILE_MASK) { 71 if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
79 audit_log_format(ab, " fsuid=%d", 72 audit_log_format(ab, " fsuid=%d",
80 from_kuid(&init_user_ns, fsuid)); 73 from_kuid(&init_user_ns, fsuid));
81 audit_log_format(ab, " ouid=%d", 74 audit_log_format(ab, " ouid=%d",
82 from_kuid(&init_user_ns, aad(sa)->fs.ouid)); 75 from_kuid(&init_user_ns, aad(sa)->fs.ouid));
83 } 76 }
84 77
85 if (aad(sa)->fs.target) { 78 if (aad(sa)->peer) {
79 audit_log_format(ab, " target=");
80 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
81 FLAG_VIEW_SUBNS, GFP_ATOMIC);
82 } else if (aad(sa)->fs.target) {
86 audit_log_format(ab, " target="); 83 audit_log_format(ab, " target=");
87 audit_log_untrustedstring(ab, aad(sa)->fs.target); 84 audit_log_untrustedstring(ab, aad(sa)->fs.target);
88 } 85 }
@@ -92,28 +89,30 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
92 * aa_audit_file - handle the auditing of file operations 89 * aa_audit_file - handle the auditing of file operations
93 * @profile: the profile being enforced (NOT NULL) 90 * @profile: the profile being enforced (NOT NULL)
94 * @perms: the permissions computed for the request (NOT NULL) 91 * @perms: the permissions computed for the request (NOT NULL)
95 * @gfp: allocation flags
96 * @op: operation being mediated 92 * @op: operation being mediated
97 * @request: permissions requested 93 * @request: permissions requested
98 * @name: name of object being mediated (MAYBE NULL) 94 * @name: name of object being mediated (MAYBE NULL)
99 * @target: name of target (MAYBE NULL) 95 * @target: name of target (MAYBE NULL)
96 * @tlabel: target label (MAY BE NULL)
100 * @ouid: object uid 97 * @ouid: object uid
101 * @info: extra information message (MAYBE NULL) 98 * @info: extra information message (MAYBE NULL)
102 * @error: 0 if operation allowed else failure error code 99 * @error: 0 if operation allowed else failure error code
103 * 100 *
104 * Returns: %0 or error on failure 101 * Returns: %0 or error on failure
105 */ 102 */
106int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, 103int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
107 const char *op, u32 request, const char *name, 104 const char *op, u32 request, const char *name,
108 const char *target, kuid_t ouid, const char *info, int error) 105 const char *target, struct aa_label *tlabel,
106 kuid_t ouid, const char *info, int error)
109{ 107{
110 int type = AUDIT_APPARMOR_AUTO; 108 int type = AUDIT_APPARMOR_AUTO;
111 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, op); 109 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, op);
112 110
113 sa.u.tsk = NULL; 111 sa.u.tsk = NULL;
114 aad(&sa)->fs.request = request; 112 aad(&sa)->request = request;
115 aad(&sa)->name = name; 113 aad(&sa)->name = name;
116 aad(&sa)->fs.target = target; 114 aad(&sa)->fs.target = target;
115 aad(&sa)->peer = tlabel;
117 aad(&sa)->fs.ouid = ouid; 116 aad(&sa)->fs.ouid = ouid;
118 aad(&sa)->info = info; 117 aad(&sa)->info = info;
119 aad(&sa)->error = error; 118 aad(&sa)->error = error;
@@ -126,34 +125,67 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
126 mask = 0xffff; 125 mask = 0xffff;
127 126
128 /* mask off perms that are not being force audited */ 127 /* mask off perms that are not being force audited */
129 aad(&sa)->fs.request &= mask; 128 aad(&sa)->request &= mask;
130 129
131 if (likely(!aad(&sa)->fs.request)) 130 if (likely(!aad(&sa)->request))
132 return 0; 131 return 0;
133 type = AUDIT_APPARMOR_AUDIT; 132 type = AUDIT_APPARMOR_AUDIT;
134 } else { 133 } else {
135 /* only report permissions that were denied */ 134 /* only report permissions that were denied */
136 aad(&sa)->fs.request = aad(&sa)->fs.request & ~perms->allow; 135 aad(&sa)->request = aad(&sa)->request & ~perms->allow;
137 AA_BUG(!aad(&sa)->fs.request); 136 AA_BUG(!aad(&sa)->request);
138 137
139 if (aad(&sa)->fs.request & perms->kill) 138 if (aad(&sa)->request & perms->kill)
140 type = AUDIT_APPARMOR_KILL; 139 type = AUDIT_APPARMOR_KILL;
141 140
142 /* quiet known rejects, assumes quiet and kill do not overlap */ 141 /* quiet known rejects, assumes quiet and kill do not overlap */
143 if ((aad(&sa)->fs.request & perms->quiet) && 142 if ((aad(&sa)->request & perms->quiet) &&
144 AUDIT_MODE(profile) != AUDIT_NOQUIET && 143 AUDIT_MODE(profile) != AUDIT_NOQUIET &&
145 AUDIT_MODE(profile) != AUDIT_ALL) 144 AUDIT_MODE(profile) != AUDIT_ALL)
146 aad(&sa)->fs.request &= ~perms->quiet; 145 aad(&sa)->request &= ~perms->quiet;
147 146
148 if (!aad(&sa)->fs.request) 147 if (!aad(&sa)->request)
149 return COMPLAIN_MODE(profile) ? 0 : aad(&sa)->error; 148 return aad(&sa)->error;
150 } 149 }
151 150
152 aad(&sa)->fs.denied = aad(&sa)->fs.request & ~perms->allow; 151 aad(&sa)->denied = aad(&sa)->request & ~perms->allow;
153 return aa_audit(type, profile, &sa, file_audit_cb); 152 return aa_audit(type, profile, &sa, file_audit_cb);
154} 153}
155 154
156/** 155/**
156 * is_deleted - test if a file has been completely unlinked
157 * @dentry: dentry of file to test for deletion (NOT NULL)
158 *
159 * Returns: %1 if deleted else %0
160 */
161static inline bool is_deleted(struct dentry *dentry)
162{
163 if (d_unlinked(dentry) && d_backing_inode(dentry)->i_nlink == 0)
164 return 1;
165 return 0;
166}
167
168static int path_name(const char *op, struct aa_label *label,
169 const struct path *path, int flags, char *buffer,
170 const char **name, struct path_cond *cond, u32 request)
171{
172 struct aa_profile *profile;
173 const char *info = NULL;
174 int error;
175
176 error = aa_path_name(path, flags, buffer, name, &info,
177 labels_profile(label)->disconnected);
178 if (error) {
179 fn_for_each_confined(label, profile,
180 aa_audit_file(profile, &nullperms, op, request, *name,
181 NULL, NULL, cond->uid, info, error));
182 return error;
183 }
184
185 return 0;
186}
187
188/**
157 * map_old_perms - map old file perms layout to the new layout 189 * map_old_perms - map old file perms layout to the new layout
158 * @old: permission set in old mapping 190 * @old: permission set in old mapping
159 * 191 *
@@ -163,10 +195,10 @@ static u32 map_old_perms(u32 old)
163{ 195{
164 u32 new = old & 0xf; 196 u32 new = old & 0xf;
165 if (old & MAY_READ) 197 if (old & MAY_READ)
166 new |= AA_MAY_META_READ; 198 new |= AA_MAY_GETATTR | AA_MAY_OPEN;
167 if (old & MAY_WRITE) 199 if (old & MAY_WRITE)
168 new |= AA_MAY_META_WRITE | AA_MAY_CREATE | AA_MAY_DELETE | 200 new |= AA_MAY_SETATTR | AA_MAY_CREATE | AA_MAY_DELETE |
169 AA_MAY_CHMOD | AA_MAY_CHOWN; 201 AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_OPEN;
170 if (old & 0x10) 202 if (old & 0x10)
171 new |= AA_MAY_LINK; 203 new |= AA_MAY_LINK;
172 /* the old mapping lock and link_subset flags where overlaid 204 /* the old mapping lock and link_subset flags where overlaid
@@ -181,7 +213,7 @@ static u32 map_old_perms(u32 old)
181} 213}
182 214
183/** 215/**
184 * compute_perms - convert dfa compressed perms to internal perms 216 * aa_compute_fperms - convert dfa compressed perms to internal perms
185 * @dfa: dfa to compute perms for (NOT NULL) 217 * @dfa: dfa to compute perms for (NOT NULL)
186 * @state: state in dfa 218 * @state: state in dfa
187 * @cond: conditions to consider (NOT NULL) 219 * @cond: conditions to consider (NOT NULL)
@@ -191,17 +223,21 @@ static u32 map_old_perms(u32 old)
191 * 223 *
192 * Returns: computed permission set 224 * Returns: computed permission set
193 */ 225 */
194static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state, 226struct aa_perms aa_compute_fperms(struct aa_dfa *dfa, unsigned int state,
195 struct path_cond *cond) 227 struct path_cond *cond)
196{ 228{
197 struct file_perms perms; 229 struct aa_perms perms;
198 230
199 /* FIXME: change over to new dfa format 231 /* FIXME: change over to new dfa format
200 * currently file perms are encoded in the dfa, new format 232 * currently file perms are encoded in the dfa, new format
201 * splits the permissions from the dfa. This mapping can be 233 * splits the permissions from the dfa. This mapping can be
202 * done at profile load 234 * done at profile load
203 */ 235 */
204 perms.kill = 0; 236 perms.deny = 0;
237 perms.kill = perms.stop = 0;
238 perms.complain = perms.cond = 0;
239 perms.hide = 0;
240 perms.prompt = 0;
205 241
206 if (uid_eq(current_fsuid(), cond->uid)) { 242 if (uid_eq(current_fsuid(), cond->uid)) {
207 perms.allow = map_old_perms(dfa_user_allow(dfa, state)); 243 perms.allow = map_old_perms(dfa_user_allow(dfa, state));
@@ -214,7 +250,7 @@ static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state,
214 perms.quiet = map_old_perms(dfa_other_quiet(dfa, state)); 250 perms.quiet = map_old_perms(dfa_other_quiet(dfa, state));
215 perms.xindex = dfa_other_xindex(dfa, state); 251 perms.xindex = dfa_other_xindex(dfa, state);
216 } 252 }
217 perms.allow |= AA_MAY_META_READ; 253 perms.allow |= AA_MAY_GETATTR;
218 254
219 /* change_profile wasn't determined by ownership in old mapping */ 255 /* change_profile wasn't determined by ownership in old mapping */
220 if (ACCEPT_TABLE(dfa)[state] & 0x80000000) 256 if (ACCEPT_TABLE(dfa)[state] & 0x80000000)
@@ -237,37 +273,55 @@ static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state,
237 */ 273 */
238unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start, 274unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start,
239 const char *name, struct path_cond *cond, 275 const char *name, struct path_cond *cond,
240 struct file_perms *perms) 276 struct aa_perms *perms)
241{ 277{
242 unsigned int state; 278 unsigned int state;
243 if (!dfa) {
244 *perms = nullperms;
245 return DFA_NOMATCH;
246 }
247
248 state = aa_dfa_match(dfa, start, name); 279 state = aa_dfa_match(dfa, start, name);
249 *perms = compute_perms(dfa, state, cond); 280 *perms = aa_compute_fperms(dfa, state, cond);
250 281
251 return state; 282 return state;
252} 283}
253 284
254/** 285int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name,
255 * is_deleted - test if a file has been completely unlinked 286 u32 request, struct path_cond *cond, int flags,
256 * @dentry: dentry of file to test for deletion (NOT NULL) 287 struct aa_perms *perms)
257 *
258 * Returns: %1 if deleted else %0
259 */
260static inline bool is_deleted(struct dentry *dentry)
261{ 288{
262 if (d_unlinked(dentry) && d_backing_inode(dentry)->i_nlink == 0) 289 int e = 0;
263 return 1; 290
264 return 0; 291 if (profile_unconfined(profile))
292 return 0;
293 aa_str_perms(profile->file.dfa, profile->file.start, name, cond, perms);
294 if (request & ~perms->allow)
295 e = -EACCES;
296 return aa_audit_file(profile, perms, op, request, name, NULL, NULL,
297 cond->uid, NULL, e);
298}
299
300
301static int profile_path_perm(const char *op, struct aa_profile *profile,
302 const struct path *path, char *buffer, u32 request,
303 struct path_cond *cond, int flags,
304 struct aa_perms *perms)
305{
306 const char *name;
307 int error;
308
309 if (profile_unconfined(profile))
310 return 0;
311
312 error = path_name(op, &profile->label, path,
313 flags | profile->path_flags, buffer, &name, cond,
314 request);
315 if (error)
316 return error;
317 return __aa_path_perm(op, profile, name, request, cond, flags,
318 perms);
265} 319}
266 320
267/** 321/**
268 * aa_path_perm - do permissions check & audit for @path 322 * aa_path_perm - do permissions check & audit for @path
269 * @op: operation being checked 323 * @op: operation being checked
270 * @profile: profile being enforced (NOT NULL) 324 * @label: profile being enforced (NOT NULL)
271 * @path: path to check permissions of (NOT NULL) 325 * @path: path to check permissions of (NOT NULL)
272 * @flags: any additional path flags beyond what the profile specifies 326 * @flags: any additional path flags beyond what the profile specifies
273 * @request: requested permissions 327 * @request: requested permissions
@@ -275,35 +329,23 @@ static inline bool is_deleted(struct dentry *dentry)
275 * 329 *
276 * Returns: %0 else error if access denied or other error 330 * Returns: %0 else error if access denied or other error
277 */ 331 */
278int aa_path_perm(const char *op, struct aa_profile *profile, 332int aa_path_perm(const char *op, struct aa_label *label,
279 const struct path *path, int flags, u32 request, 333 const struct path *path, int flags, u32 request,
280 struct path_cond *cond) 334 struct path_cond *cond)
281{ 335{
336 struct aa_perms perms = {};
337 struct aa_profile *profile;
282 char *buffer = NULL; 338 char *buffer = NULL;
283 struct file_perms perms = {};
284 const char *name, *info = NULL;
285 int error; 339 int error;
286 340
287 flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0); 341 flags |= PATH_DELEGATE_DELETED | (S_ISDIR(cond->mode) ? PATH_IS_DIR :
288 error = aa_path_name(path, flags, &buffer, &name, &info); 342 0);
289 if (error) { 343 get_buffers(buffer);
290 if (error == -ENOENT && is_deleted(path->dentry)) { 344 error = fn_for_each_confined(label, profile,
291 /* Access to open files that are deleted are 345 profile_path_perm(op, profile, path, buffer, request,
292 * give a pass (implicit delegation) 346 cond, flags, &perms));
293 */ 347
294 error = 0; 348 put_buffers(buffer);
295 info = NULL;
296 perms.allow = request;
297 }
298 } else {
299 aa_str_perms(profile->file.dfa, profile->file.start, name, cond,
300 &perms);
301 if (request & ~perms.allow)
302 error = -EACCES;
303 }
304 error = aa_audit_file(profile, &perms, op, request, name, NULL,
305 cond->uid, info, error);
306 kfree(buffer);
307 349
308 return error; 350 return error;
309} 351}
@@ -328,65 +370,40 @@ static inline bool xindex_is_subset(u32 link, u32 target)
328 return 1; 370 return 1;
329} 371}
330 372
331/** 373static int profile_path_link(struct aa_profile *profile,
332 * aa_path_link - Handle hard link permission check 374 const struct path *link, char *buffer,
333 * @profile: the profile being enforced (NOT NULL) 375 const struct path *target, char *buffer2,
334 * @old_dentry: the target dentry (NOT NULL) 376 struct path_cond *cond)
335 * @new_dir: directory the new link will be created in (NOT NULL)
336 * @new_dentry: the link being created (NOT NULL)
337 *
338 * Handle the permission test for a link & target pair. Permission
339 * is encoded as a pair where the link permission is determined
340 * first, and if allowed, the target is tested. The target test
341 * is done from the point of the link match (not start of DFA)
342 * making the target permission dependent on the link permission match.
343 *
344 * The subset test if required forces that permissions granted
345 * on link are a subset of the permission granted to target.
346 *
347 * Returns: %0 if allowed else error
348 */
349int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
350 const struct path *new_dir, struct dentry *new_dentry)
351{ 377{
352 struct path link = { .mnt = new_dir->mnt, .dentry = new_dentry }; 378 const char *lname, *tname = NULL;
353 struct path target = { .mnt = new_dir->mnt, .dentry = old_dentry }; 379 struct aa_perms lperms = {}, perms;
354 struct path_cond cond = { 380 const char *info = NULL;
355 d_backing_inode(old_dentry)->i_uid,
356 d_backing_inode(old_dentry)->i_mode
357 };
358 char *buffer = NULL, *buffer2 = NULL;
359 const char *lname, *tname = NULL, *info = NULL;
360 struct file_perms lperms, perms;
361 u32 request = AA_MAY_LINK; 381 u32 request = AA_MAY_LINK;
362 unsigned int state; 382 unsigned int state;
363 int error; 383 int error;
364 384
365 lperms = nullperms; 385 error = path_name(OP_LINK, &profile->label, link, profile->path_flags,
366 386 buffer, &lname, cond, AA_MAY_LINK);
367 /* buffer freed below, lname is pointer in buffer */
368 error = aa_path_name(&link, profile->path_flags, &buffer, &lname,
369 &info);
370 if (error) 387 if (error)
371 goto audit; 388 goto audit;
372 389
373 /* buffer2 freed below, tname is pointer in buffer2 */ 390 /* buffer2 freed below, tname is pointer in buffer2 */
374 error = aa_path_name(&target, profile->path_flags, &buffer2, &tname, 391 error = path_name(OP_LINK, &profile->label, target, profile->path_flags,
375 &info); 392 buffer2, &tname, cond, AA_MAY_LINK);
376 if (error) 393 if (error)
377 goto audit; 394 goto audit;
378 395
379 error = -EACCES; 396 error = -EACCES;
380 /* aa_str_perms - handles the case of the dfa being NULL */ 397 /* aa_str_perms - handles the case of the dfa being NULL */
381 state = aa_str_perms(profile->file.dfa, profile->file.start, lname, 398 state = aa_str_perms(profile->file.dfa, profile->file.start, lname,
382 &cond, &lperms); 399 cond, &lperms);
383 400
384 if (!(lperms.allow & AA_MAY_LINK)) 401 if (!(lperms.allow & AA_MAY_LINK))
385 goto audit; 402 goto audit;
386 403
387 /* test to see if target can be paired with link */ 404 /* test to see if target can be paired with link */
388 state = aa_dfa_null_transition(profile->file.dfa, state); 405 state = aa_dfa_null_transition(profile->file.dfa, state);
389 aa_str_perms(profile->file.dfa, state, tname, &cond, &perms); 406 aa_str_perms(profile->file.dfa, state, tname, cond, &perms);
390 407
391 /* force audit/quiet masks for link are stored in the second entry 408 /* force audit/quiet masks for link are stored in the second entry
392 * in the link pair. 409 * in the link pair.
@@ -397,6 +414,7 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
397 414
398 if (!(perms.allow & AA_MAY_LINK)) { 415 if (!(perms.allow & AA_MAY_LINK)) {
399 info = "target restricted"; 416 info = "target restricted";
417 lperms = perms;
400 goto audit; 418 goto audit;
401 } 419 }
402 420
@@ -404,10 +422,10 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
404 if (!(perms.allow & AA_LINK_SUBSET)) 422 if (!(perms.allow & AA_LINK_SUBSET))
405 goto done_tests; 423 goto done_tests;
406 424
407 /* Do link perm subset test requiring allowed permission on link are a 425 /* Do link perm subset test requiring allowed permission on link are
408 * subset of the allowed permissions on target. 426 * a subset of the allowed permissions on target.
409 */ 427 */
410 aa_str_perms(profile->file.dfa, profile->file.start, tname, &cond, 428 aa_str_perms(profile->file.dfa, profile->file.start, tname, cond,
411 &perms); 429 &perms);
412 430
413 /* AA_MAY_LINK is not considered in the subset test */ 431 /* AA_MAY_LINK is not considered in the subset test */
@@ -429,10 +447,121 @@ done_tests:
429 error = 0; 447 error = 0;
430 448
431audit: 449audit:
432 error = aa_audit_file(profile, &lperms, OP_LINK, request, 450 return aa_audit_file(profile, &lperms, OP_LINK, request, lname, tname,
433 lname, tname, cond.uid, info, error); 451 NULL, cond->uid, info, error);
434 kfree(buffer); 452}
435 kfree(buffer2); 453
454/**
455 * aa_path_link - Handle hard link permission check
456 * @label: the label being enforced (NOT NULL)
457 * @old_dentry: the target dentry (NOT NULL)
458 * @new_dir: directory the new link will be created in (NOT NULL)
459 * @new_dentry: the link being created (NOT NULL)
460 *
461 * Handle the permission test for a link & target pair. Permission
462 * is encoded as a pair where the link permission is determined
463 * first, and if allowed, the target is tested. The target test
464 * is done from the point of the link match (not start of DFA)
465 * making the target permission dependent on the link permission match.
466 *
467 * The subset test if required forces that permissions granted
468 * on link are a subset of the permission granted to target.
469 *
470 * Returns: %0 if allowed else error
471 */
472int aa_path_link(struct aa_label *label, struct dentry *old_dentry,
473 const struct path *new_dir, struct dentry *new_dentry)
474{
475 struct path link = { .mnt = new_dir->mnt, .dentry = new_dentry };
476 struct path target = { .mnt = new_dir->mnt, .dentry = old_dentry };
477 struct path_cond cond = {
478 d_backing_inode(old_dentry)->i_uid,
479 d_backing_inode(old_dentry)->i_mode
480 };
481 char *buffer = NULL, *buffer2 = NULL;
482 struct aa_profile *profile;
483 int error;
484
485 /* buffer freed below, lname is pointer in buffer */
486 get_buffers(buffer, buffer2);
487 error = fn_for_each_confined(label, profile,
488 profile_path_link(profile, &link, buffer, &target,
489 buffer2, &cond));
490 put_buffers(buffer, buffer2);
491
492 return error;
493}
494
495static void update_file_ctx(struct aa_file_ctx *fctx, struct aa_label *label,
496 u32 request)
497{
498 struct aa_label *l, *old;
499
500 /* update caching of label on file_ctx */
501 spin_lock(&fctx->lock);
502 old = rcu_dereference_protected(fctx->label,
503 spin_is_locked(&fctx->lock));
504 l = aa_label_merge(old, label, GFP_ATOMIC);
505 if (l) {
506 if (l != old) {
507 rcu_assign_pointer(fctx->label, l);
508 aa_put_label(old);
509 } else
510 aa_put_label(l);
511 fctx->allow |= request;
512 }
513 spin_unlock(&fctx->lock);
514}
515
516static int __file_path_perm(const char *op, struct aa_label *label,
517 struct aa_label *flabel, struct file *file,
518 u32 request, u32 denied)
519{
520 struct aa_profile *profile;
521 struct aa_perms perms = {};
522 struct path_cond cond = {
523 .uid = file_inode(file)->i_uid,
524 .mode = file_inode(file)->i_mode
525 };
526 char *buffer;
527 int flags, error;
528
529 /* revalidation due to label out of date. No revocation at this time */
530 if (!denied && aa_label_is_subset(flabel, label))
531 /* TODO: check for revocation on stale profiles */
532 return 0;
533
534 flags = PATH_DELEGATE_DELETED | (S_ISDIR(cond.mode) ? PATH_IS_DIR : 0);
535 get_buffers(buffer);
536
537 /* check every profile in task label not in current cache */
538 error = fn_for_each_not_in_set(flabel, label, profile,
539 profile_path_perm(op, profile, &file->f_path, buffer,
540 request, &cond, flags, &perms));
541 if (denied && !error) {
542 /*
543 * check every profile in file label that was not tested
544 * in the initial check above.
545 *
546 * TODO: cache full perms so this only happens because of
547 * conditionals
548 * TODO: don't audit here
549 */
550 if (label == flabel)
551 error = fn_for_each(label, profile,
552 profile_path_perm(op, profile, &file->f_path,
553 buffer, request, &cond, flags,
554 &perms));
555 else
556 error = fn_for_each_not_in_set(label, flabel, profile,
557 profile_path_perm(op, profile, &file->f_path,
558 buffer, request, &cond, flags,
559 &perms));
560 }
561 if (!error)
562 update_file_ctx(file_ctx(file), label, request);
563
564 put_buffers(buffer);
436 565
437 return error; 566 return error;
438} 567}
@@ -440,20 +569,114 @@ audit:
440/** 569/**
441 * aa_file_perm - do permission revalidation check & audit for @file 570 * aa_file_perm - do permission revalidation check & audit for @file
442 * @op: operation being checked 571 * @op: operation being checked
443 * @profile: profile being enforced (NOT NULL) 572 * @label: label being enforced (NOT NULL)
444 * @file: file to revalidate access permissions on (NOT NULL) 573 * @file: file to revalidate access permissions on (NOT NULL)
445 * @request: requested permissions 574 * @request: requested permissions
446 * 575 *
447 * Returns: %0 if access allowed else error 576 * Returns: %0 if access allowed else error
448 */ 577 */
449int aa_file_perm(const char *op, struct aa_profile *profile, struct file *file, 578int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
450 u32 request) 579 u32 request)
451{ 580{
452 struct path_cond cond = { 581 struct aa_file_ctx *fctx;
453 .uid = file_inode(file)->i_uid, 582 struct aa_label *flabel;
454 .mode = file_inode(file)->i_mode 583 u32 denied;
455 }; 584 int error = 0;
585
586 AA_BUG(!label);
587 AA_BUG(!file);
588
589 fctx = file_ctx(file);
590
591 rcu_read_lock();
592 flabel = rcu_dereference(fctx->label);
593 AA_BUG(!flabel);
594
595 /* revalidate access, if task is unconfined, or the cached cred
596 * doesn't match or if the request is for more permissions than
597 * was granted.
598 *
599 * Note: the test for !unconfined(flabel) is to handle file
600 * delegation from unconfined tasks
601 */
602 denied = request & ~fctx->allow;
603 if (unconfined(label) || unconfined(flabel) ||
604 (!denied && aa_label_is_subset(flabel, label)))
605 goto done;
606
607 /* TODO: label cross check */
608
609 if (file->f_path.mnt && path_mediated_fs(file->f_path.dentry))
610 error = __file_path_perm(op, label, flabel, file, request,
611 denied);
612
613done:
614 rcu_read_unlock();
615
616 return error;
617}
618
619static void revalidate_tty(struct aa_label *label)
620{
621 struct tty_struct *tty;
622 int drop_tty = 0;
623
624 tty = get_current_tty();
625 if (!tty)
626 return;
627
628 spin_lock(&tty->files_lock);
629 if (!list_empty(&tty->tty_files)) {
630 struct tty_file_private *file_priv;
631 struct file *file;
632 /* TODO: Revalidate access to controlling tty. */
633 file_priv = list_first_entry(&tty->tty_files,
634 struct tty_file_private, list);
635 file = file_priv->file;
636
637 if (aa_file_perm(OP_INHERIT, label, file, MAY_READ | MAY_WRITE))
638 drop_tty = 1;
639 }
640 spin_unlock(&tty->files_lock);
641 tty_kref_put(tty);
456 642
457 return aa_path_perm(op, profile, &file->f_path, PATH_DELEGATE_DELETED, 643 if (drop_tty)
458 request, &cond); 644 no_tty();
645}
646
647static int match_file(const void *p, struct file *file, unsigned int fd)
648{
649 struct aa_label *label = (struct aa_label *)p;
650
651 if (aa_file_perm(OP_INHERIT, label, file, aa_map_file_to_perms(file)))
652 return fd + 1;
653 return 0;
654}
655
656
657/* based on selinux's flush_unauthorized_files */
658void aa_inherit_files(const struct cred *cred, struct files_struct *files)
659{
660 struct aa_label *label = aa_get_newest_cred_label(cred);
661 struct file *devnull = NULL;
662 unsigned int n;
663
664 revalidate_tty(label);
665
666 /* Revalidate access to inherited open files. */
667 n = iterate_fd(files, 0, match_file, label);
668 if (!n) /* none found? */
669 goto out;
670
671 devnull = dentry_open(&aa_null, O_RDWR, cred);
672 if (IS_ERR(devnull))
673 devnull = NULL;
674 /* replace all the matching ones with this */
675 do {
676 replace_fd(n - 1, devnull, 0);
677 } while ((n = iterate_fd(files, n, match_file, label)) != 0);
678 if (devnull)
679 fput(devnull);
680out:
681 aa_put_label(label);
459} 682}
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
index 1750cc0721c1..aaf893f4e4f5 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -4,7 +4,7 @@
4 * This file contains AppArmor basic global 4 * This file contains AppArmor basic global
5 * 5 *
6 * Copyright (C) 1998-2008 Novell/SUSE 6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2010 Canonical Ltd. 7 * Copyright 2009-2017 Canonical Ltd.
8 * 8 *
9 * This program is free software; you can redistribute it and/or 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 10 * modify it under the terms of the GNU General Public License as
@@ -27,8 +27,10 @@
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_PTRACE 9
31#define AA_CLASS_LABEL 16
30 32
31#define AA_CLASS_LAST AA_CLASS_DOMAIN 33#define AA_CLASS_LAST AA_CLASS_LABEL
32 34
33/* Control parameters settable through module/boot flags */ 35/* Control parameters settable through module/boot flags */
34extern enum audit_mode aa_g_audit; 36extern enum audit_mode aa_g_audit;
diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
index 120a798b5bb0..bd689114bf93 100644
--- a/security/apparmor/include/apparmorfs.h
+++ b/security/apparmor/include/apparmorfs.h
@@ -17,49 +17,49 @@
17 17
18extern struct path aa_null; 18extern struct path aa_null;
19 19
20enum aa_fs_type { 20enum aa_sfs_type {
21 AA_FS_TYPE_BOOLEAN, 21 AA_SFS_TYPE_BOOLEAN,
22 AA_FS_TYPE_STRING, 22 AA_SFS_TYPE_STRING,
23 AA_FS_TYPE_U64, 23 AA_SFS_TYPE_U64,
24 AA_FS_TYPE_FOPS, 24 AA_SFS_TYPE_FOPS,
25 AA_FS_TYPE_DIR, 25 AA_SFS_TYPE_DIR,
26}; 26};
27 27
28struct aa_fs_entry; 28struct aa_sfs_entry;
29 29
30struct aa_fs_entry { 30struct aa_sfs_entry {
31 const char *name; 31 const char *name;
32 struct dentry *dentry; 32 struct dentry *dentry;
33 umode_t mode; 33 umode_t mode;
34 enum aa_fs_type v_type; 34 enum aa_sfs_type v_type;
35 union { 35 union {
36 bool boolean; 36 bool boolean;
37 char *string; 37 char *string;
38 unsigned long u64; 38 unsigned long u64;
39 struct aa_fs_entry *files; 39 struct aa_sfs_entry *files;
40 } v; 40 } v;
41 const struct file_operations *file_ops; 41 const struct file_operations *file_ops;
42}; 42};
43 43
44extern const struct file_operations aa_fs_seq_file_ops; 44extern const struct file_operations aa_sfs_seq_file_ops;
45 45
46#define AA_FS_FILE_BOOLEAN(_name, _value) \ 46#define AA_SFS_FILE_BOOLEAN(_name, _value) \
47 { .name = (_name), .mode = 0444, \ 47 { .name = (_name), .mode = 0444, \
48 .v_type = AA_FS_TYPE_BOOLEAN, .v.boolean = (_value), \ 48 .v_type = AA_SFS_TYPE_BOOLEAN, .v.boolean = (_value), \
49 .file_ops = &aa_fs_seq_file_ops } 49 .file_ops = &aa_sfs_seq_file_ops }
50#define AA_FS_FILE_STRING(_name, _value) \ 50#define AA_SFS_FILE_STRING(_name, _value) \
51 { .name = (_name), .mode = 0444, \ 51 { .name = (_name), .mode = 0444, \
52 .v_type = AA_FS_TYPE_STRING, .v.string = (_value), \ 52 .v_type = AA_SFS_TYPE_STRING, .v.string = (_value), \
53 .file_ops = &aa_fs_seq_file_ops } 53 .file_ops = &aa_sfs_seq_file_ops }
54#define AA_FS_FILE_U64(_name, _value) \ 54#define AA_SFS_FILE_U64(_name, _value) \
55 { .name = (_name), .mode = 0444, \ 55 { .name = (_name), .mode = 0444, \
56 .v_type = AA_FS_TYPE_U64, .v.u64 = (_value), \ 56 .v_type = AA_SFS_TYPE_U64, .v.u64 = (_value), \
57 .file_ops = &aa_fs_seq_file_ops } 57 .file_ops = &aa_sfs_seq_file_ops }
58#define AA_FS_FILE_FOPS(_name, _mode, _fops) \ 58#define AA_SFS_FILE_FOPS(_name, _mode, _fops) \
59 { .name = (_name), .v_type = AA_FS_TYPE_FOPS, \ 59 { .name = (_name), .v_type = AA_SFS_TYPE_FOPS, \
60 .mode = (_mode), .file_ops = (_fops) } 60 .mode = (_mode), .file_ops = (_fops) }
61#define AA_FS_DIR(_name, _value) \ 61#define AA_SFS_DIR(_name, _value) \
62 { .name = (_name), .v_type = AA_FS_TYPE_DIR, .v.files = (_value) } 62 { .name = (_name), .v_type = AA_SFS_TYPE_DIR, .v.files = (_value) }
63 63
64extern void __init aa_destroy_aafs(void); 64extern void __init aa_destroy_aafs(void);
65 65
@@ -74,6 +74,7 @@ enum aafs_ns_type {
74 AAFS_NS_LOAD, 74 AAFS_NS_LOAD,
75 AAFS_NS_REPLACE, 75 AAFS_NS_REPLACE,
76 AAFS_NS_REMOVE, 76 AAFS_NS_REMOVE,
77 AAFS_NS_REVISION,
77 AAFS_NS_COUNT, 78 AAFS_NS_COUNT,
78 AAFS_NS_MAX_COUNT, 79 AAFS_NS_MAX_COUNT,
79 AAFS_NS_SIZE, 80 AAFS_NS_SIZE,
@@ -102,16 +103,22 @@ enum aafs_prof_type {
102#define ns_subload(X) ((X)->dents[AAFS_NS_LOAD]) 103#define ns_subload(X) ((X)->dents[AAFS_NS_LOAD])
103#define ns_subreplace(X) ((X)->dents[AAFS_NS_REPLACE]) 104#define ns_subreplace(X) ((X)->dents[AAFS_NS_REPLACE])
104#define ns_subremove(X) ((X)->dents[AAFS_NS_REMOVE]) 105#define ns_subremove(X) ((X)->dents[AAFS_NS_REMOVE])
106#define ns_subrevision(X) ((X)->dents[AAFS_NS_REVISION])
105 107
106#define prof_dir(X) ((X)->dents[AAFS_PROF_DIR]) 108#define prof_dir(X) ((X)->dents[AAFS_PROF_DIR])
107#define prof_child_dir(X) ((X)->dents[AAFS_PROF_PROFS]) 109#define prof_child_dir(X) ((X)->dents[AAFS_PROF_PROFS])
108 110
109void __aa_fs_profile_rmdir(struct aa_profile *profile); 111void __aa_bump_ns_revision(struct aa_ns *ns);
110void __aa_fs_profile_migrate_dents(struct aa_profile *old, 112void __aafs_profile_rmdir(struct aa_profile *profile);
113void __aafs_profile_migrate_dents(struct aa_profile *old,
111 struct aa_profile *new); 114 struct aa_profile *new);
112int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent); 115int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent);
113void __aa_fs_ns_rmdir(struct aa_ns *ns); 116void __aafs_ns_rmdir(struct aa_ns *ns);
114int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, 117int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name,
115 const char *name); 118 struct dentry *dent);
119
120struct aa_loaddata;
121void __aa_fs_remove_rawdata(struct aa_loaddata *rawdata);
122int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata);
116 123
117#endif /* __AA_APPARMORFS_H */ 124#endif /* __AA_APPARMORFS_H */
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index fdc4774318ba..c68839a44351 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -22,8 +22,7 @@
22#include <linux/slab.h> 22#include <linux/slab.h>
23 23
24#include "file.h" 24#include "file.h"
25 25#include "label.h"
26struct aa_profile;
27 26
28extern const char *const audit_mode_names[]; 27extern const char *const audit_mode_names[];
29#define AUDIT_MAX_INDEX 5 28#define AUDIT_MAX_INDEX 5
@@ -65,10 +64,12 @@ enum audit_type {
65#define OP_GETATTR "getattr" 64#define OP_GETATTR "getattr"
66#define OP_OPEN "open" 65#define OP_OPEN "open"
67 66
67#define OP_FRECEIVE "file_receive"
68#define OP_FPERM "file_perm" 68#define OP_FPERM "file_perm"
69#define OP_FLOCK "file_lock" 69#define OP_FLOCK "file_lock"
70#define OP_FMMAP "file_mmap" 70#define OP_FMMAP "file_mmap"
71#define OP_FMPROT "file_mprotect" 71#define OP_FMPROT "file_mprotect"
72#define OP_INHERIT "file_inherit"
72 73
73#define OP_CREATE "create" 74#define OP_CREATE "create"
74#define OP_POST_CREATE "post_create" 75#define OP_POST_CREATE "post_create"
@@ -91,6 +92,8 @@ enum audit_type {
91#define OP_CHANGE_HAT "change_hat" 92#define OP_CHANGE_HAT "change_hat"
92#define OP_CHANGE_PROFILE "change_profile" 93#define OP_CHANGE_PROFILE "change_profile"
93#define OP_CHANGE_ONEXEC "change_onexec" 94#define OP_CHANGE_ONEXEC "change_onexec"
95#define OP_STACK "stack"
96#define OP_STACK_ONEXEC "stack_onexec"
94 97
95#define OP_SETPROCATTR "setprocattr" 98#define OP_SETPROCATTR "setprocattr"
96#define OP_SETRLIMIT "setrlimit" 99#define OP_SETRLIMIT "setrlimit"
@@ -102,19 +105,19 @@ enum audit_type {
102 105
103struct apparmor_audit_data { 106struct apparmor_audit_data {
104 int error; 107 int error;
105 const char *op;
106 int type; 108 int type;
107 void *profile; 109 const char *op;
110 struct aa_label *label;
108 const char *name; 111 const char *name;
109 const char *info; 112 const char *info;
113 u32 request;
114 u32 denied;
110 union { 115 union {
111 /* these entries require a custom callback fn */ 116 /* these entries require a custom callback fn */
112 struct { 117 struct {
113 struct aa_profile *peer; 118 struct aa_label *peer;
114 struct { 119 struct {
115 const char *target; 120 const char *target;
116 u32 request;
117 u32 denied;
118 kuid_t ouid; 121 kuid_t ouid;
119 } fs; 122 } fs;
120 }; 123 };
diff --git a/security/apparmor/include/capability.h b/security/apparmor/include/capability.h
index fc3fa381d850..e0304e2aeb7f 100644
--- a/security/apparmor/include/capability.h
+++ b/security/apparmor/include/capability.h
@@ -19,11 +19,12 @@
19 19
20#include "apparmorfs.h" 20#include "apparmorfs.h"
21 21
22struct aa_profile; 22struct aa_label;
23 23
24/* aa_caps - confinement data for capabilities 24/* aa_caps - confinement data for capabilities
25 * @allowed: capabilities mask 25 * @allowed: capabilities mask
26 * @audit: caps that are to be audited 26 * @audit: caps that are to be audited
27 * @denied: caps that are explicitly denied
27 * @quiet: caps that should not be audited 28 * @quiet: caps that should not be audited
28 * @kill: caps that when requested will result in the task being killed 29 * @kill: caps that when requested will result in the task being killed
29 * @extended: caps that are subject finer grained mediation 30 * @extended: caps that are subject finer grained mediation
@@ -31,14 +32,15 @@ struct aa_profile;
31struct aa_caps { 32struct aa_caps {
32 kernel_cap_t allow; 33 kernel_cap_t allow;
33 kernel_cap_t audit; 34 kernel_cap_t audit;
35 kernel_cap_t denied;
34 kernel_cap_t quiet; 36 kernel_cap_t quiet;
35 kernel_cap_t kill; 37 kernel_cap_t kill;
36 kernel_cap_t extended; 38 kernel_cap_t extended;
37}; 39};
38 40
39extern struct aa_fs_entry aa_fs_entry_caps[]; 41extern struct aa_sfs_entry aa_sfs_entry_caps[];
40 42
41int aa_capable(struct aa_profile *profile, int cap, int audit); 43int aa_capable(struct aa_label *label, int cap, int audit);
42 44
43static inline void aa_free_cap_rules(struct aa_caps *caps) 45static inline void aa_free_cap_rules(struct aa_caps *caps)
44{ 46{
diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h
index 5b18fedab4c8..6ae07e9aaa17 100644
--- a/security/apparmor/include/context.h
+++ b/security/apparmor/include/context.h
@@ -19,60 +19,28 @@
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/sched.h> 20#include <linux/sched.h>
21 21
22#include "policy.h" 22#include "label.h"
23#include "policy_ns.h" 23#include "policy_ns.h"
24 24
25#define cred_ctx(X) ((X)->security) 25#define cred_ctx(X) ((X)->security)
26#define current_ctx() cred_ctx(current_cred()) 26#define current_ctx() cred_ctx(current_cred())
27 27
28/* struct aa_file_ctx - the AppArmor context the file was opened in
29 * @perms: the permission the file was opened with
30 *
31 * The file_ctx could currently be directly stored in file->f_security
32 * as the profile reference is now stored in the f_cred. However the
33 * ctx struct will expand in the future so we keep the struct.
34 */
35struct aa_file_ctx {
36 u16 allow;
37};
38
39/**
40 * aa_alloc_file_context - allocate file_ctx
41 * @gfp: gfp flags for allocation
42 *
43 * Returns: file_ctx or NULL on failure
44 */
45static inline struct aa_file_ctx *aa_alloc_file_context(gfp_t gfp)
46{
47 return kzalloc(sizeof(struct aa_file_ctx), gfp);
48}
49
50/**
51 * aa_free_file_context - free a file_ctx
52 * @ctx: file_ctx to free (MAYBE_NULL)
53 */
54static inline void aa_free_file_context(struct aa_file_ctx *ctx)
55{
56 if (ctx)
57 kzfree(ctx);
58}
59
60/** 28/**
61 * struct aa_task_ctx - primary label for confined tasks 29 * struct aa_task_ctx - primary label for confined tasks
62 * @profile: the current profile (NOT NULL) 30 * @label: the current label (NOT NULL)
63 * @exec: profile to transition to on next exec (MAYBE NULL) 31 * @exec: label to transition to on next exec (MAYBE NULL)
64 * @previous: profile the task may return to (MAYBE NULL) 32 * @previous: label the task may return to (MAYBE NULL)
65 * @token: magic value the task must know for returning to @previous_profile 33 * @token: magic value the task must know for returning to @previous
66 * 34 *
67 * Contains the task's current profile (which could change due to 35 * Contains the task's current label (which could change due to
68 * change_hat). Plus the hat_magic needed during change_hat. 36 * change_hat). Plus the hat_magic needed during change_hat.
69 * 37 *
70 * TODO: make so a task can be confined by a stack of contexts 38 * TODO: make so a task can be confined by a stack of contexts
71 */ 39 */
72struct aa_task_ctx { 40struct aa_task_ctx {
73 struct aa_profile *profile; 41 struct aa_label *label;
74 struct aa_profile *onexec; 42 struct aa_label *onexec;
75 struct aa_profile *previous; 43 struct aa_label *previous;
76 u64 token; 44 u64 token;
77}; 45};
78 46
@@ -80,40 +48,51 @@ struct aa_task_ctx *aa_alloc_task_context(gfp_t flags);
80void aa_free_task_context(struct aa_task_ctx *ctx); 48void aa_free_task_context(struct aa_task_ctx *ctx);
81void aa_dup_task_context(struct aa_task_ctx *new, 49void aa_dup_task_context(struct aa_task_ctx *new,
82 const struct aa_task_ctx *old); 50 const struct aa_task_ctx *old);
83int aa_replace_current_profile(struct aa_profile *profile); 51int aa_replace_current_label(struct aa_label *label);
84int aa_set_current_onexec(struct aa_profile *profile); 52int aa_set_current_onexec(struct aa_label *label, bool stack);
85int aa_set_current_hat(struct aa_profile *profile, u64 token); 53int aa_set_current_hat(struct aa_label *label, u64 token);
86int aa_restore_previous_profile(u64 cookie); 54int aa_restore_previous_label(u64 cookie);
87struct aa_profile *aa_get_task_profile(struct task_struct *task); 55struct aa_label *aa_get_task_label(struct task_struct *task);
88 56
89 57
90/** 58/**
91 * aa_cred_profile - obtain cred's profiles 59 * aa_cred_raw_label - obtain cred's label
92 * @cred: cred to obtain profiles from (NOT NULL) 60 * @cred: cred to obtain label from (NOT NULL)
93 * 61 *
94 * Returns: confining profile 62 * Returns: confining label
95 * 63 *
96 * does NOT increment reference count 64 * does NOT increment reference count
97 */ 65 */
98static inline struct aa_profile *aa_cred_profile(const struct cred *cred) 66static inline struct aa_label *aa_cred_raw_label(const struct cred *cred)
99{ 67{
100 struct aa_task_ctx *ctx = cred_ctx(cred); 68 struct aa_task_ctx *ctx = cred_ctx(cred);
101 69
102 AA_BUG(!ctx || !ctx->profile); 70 AA_BUG(!ctx || !ctx->label);
103 return ctx->profile; 71 return ctx->label;
72}
73
74/**
75 * aa_get_newest_cred_label - obtain the newest label on a cred
76 * @cred: cred to obtain label from (NOT NULL)
77 *
78 * Returns: newest version of confining label
79 */
80static inline struct aa_label *aa_get_newest_cred_label(const struct cred *cred)
81{
82 return aa_get_newest_label(aa_cred_raw_label(cred));
104} 83}
105 84
106/** 85/**
107 * __aa_task_profile - retrieve another task's profile 86 * __aa_task_raw_label - retrieve another task's label
108 * @task: task to query (NOT NULL) 87 * @task: task to query (NOT NULL)
109 * 88 *
110 * Returns: @task's profile without incrementing its ref count 89 * Returns: @task's label without incrementing its ref count
111 * 90 *
112 * If @task != current needs to be called in RCU safe critical section 91 * If @task != current needs to be called in RCU safe critical section
113 */ 92 */
114static inline struct aa_profile *__aa_task_profile(struct task_struct *task) 93static inline struct aa_label *__aa_task_raw_label(struct task_struct *task)
115{ 94{
116 return aa_cred_profile(__task_cred(task)); 95 return aa_cred_raw_label(__task_cred(task));
117} 96}
118 97
119/** 98/**
@@ -124,50 +103,114 @@ static inline struct aa_profile *__aa_task_profile(struct task_struct *task)
124 */ 103 */
125static inline bool __aa_task_is_confined(struct task_struct *task) 104static inline bool __aa_task_is_confined(struct task_struct *task)
126{ 105{
127 return !unconfined(__aa_task_profile(task)); 106 return !unconfined(__aa_task_raw_label(task));
128} 107}
129 108
130/** 109/**
131 * __aa_current_profile - find the current tasks confining profile 110 * aa_current_raw_label - find the current tasks confining label
132 * 111 *
133 * Returns: up to date confining profile or the ns unconfined profile (NOT NULL) 112 * Returns: up to date confining label or the ns unconfined label (NOT NULL)
134 * 113 *
135 * This fn will not update the tasks cred to the most up to date version 114 * This fn will not update the tasks cred to the most up to date version
136 * of the profile so it is safe to call when inside of locks. 115 * of the label so it is safe to call when inside of locks.
137 */ 116 */
138static inline struct aa_profile *__aa_current_profile(void) 117static inline struct aa_label *aa_current_raw_label(void)
139{ 118{
140 return aa_cred_profile(current_cred()); 119 return aa_cred_raw_label(current_cred());
141} 120}
142 121
143/** 122/**
144 * aa_current_profile - find the current tasks confining profile and do updates 123 * aa_get_current_label - get the newest version of the current tasks label
124 *
125 * Returns: newest version of confining label (NOT NULL)
145 * 126 *
146 * Returns: up to date confining profile or the ns unconfined profile (NOT NULL) 127 * This fn will not update the tasks cred, so it is safe inside of locks
147 * 128 *
148 * This fn will update the tasks cred structure if the profile has been 129 * The returned reference must be put with aa_put_label()
149 * replaced. Not safe to call inside locks
150 */ 130 */
151static inline struct aa_profile *aa_current_profile(void) 131static inline struct aa_label *aa_get_current_label(void)
152{ 132{
153 const struct aa_task_ctx *ctx = current_ctx(); 133 struct aa_label *l = aa_current_raw_label();
154 struct aa_profile *profile;
155 134
156 AA_BUG(!ctx || !ctx->profile); 135 if (label_is_stale(l))
136 return aa_get_newest_label(l);
137 return aa_get_label(l);
138}
139
140#define __end_current_label_crit_section(X) end_current_label_crit_section(X)
157 141
158 if (profile_is_stale(ctx->profile)) { 142/**
159 profile = aa_get_newest_profile(ctx->profile); 143 * end_label_crit_section - put a reference found with begin_current_label..
160 aa_replace_current_profile(profile); 144 * @label: label reference to put
161 aa_put_profile(profile); 145 *
162 ctx = current_ctx(); 146 * Should only be used with a reference obtained with
147 * begin_current_label_crit_section and never used in situations where the
148 * task cred may be updated
149 */
150static inline void end_current_label_crit_section(struct aa_label *label)
151{
152 if (label != aa_current_raw_label())
153 aa_put_label(label);
154}
155
156/**
157 * __begin_current_label_crit_section - current's confining label
158 *
159 * Returns: up to date confining label or the ns unconfined label (NOT NULL)
160 *
161 * safe to call inside locks
162 *
163 * The returned reference must be put with __end_current_label_crit_section()
164 * This must NOT be used if the task cred could be updated within the
165 * critical section between __begin_current_label_crit_section() ..
166 * __end_current_label_crit_section()
167 */
168static inline struct aa_label *__begin_current_label_crit_section(void)
169{
170 struct aa_label *label = aa_current_raw_label();
171
172 if (label_is_stale(label))
173 label = aa_get_newest_label(label);
174
175 return label;
176}
177
178/**
179 * begin_current_label_crit_section - current's confining label and update it
180 *
181 * Returns: up to date confining label or the ns unconfined label (NOT NULL)
182 *
183 * Not safe to call inside locks
184 *
185 * The returned reference must be put with end_current_label_crit_section()
186 * This must NOT be used if the task cred could be updated within the
187 * critical section between begin_current_label_crit_section() ..
188 * end_current_label_crit_section()
189 */
190static inline struct aa_label *begin_current_label_crit_section(void)
191{
192 struct aa_label *label = aa_current_raw_label();
193
194 if (label_is_stale(label)) {
195 label = aa_get_newest_label(label);
196 if (aa_replace_current_label(label) == 0)
197 /* task cred will keep the reference */
198 aa_put_label(label);
163 } 199 }
164 200
165 return ctx->profile; 201 return label;
166} 202}
167 203
168static inline struct aa_ns *aa_get_current_ns(void) 204static inline struct aa_ns *aa_get_current_ns(void)
169{ 205{
170 return aa_get_ns(__aa_current_profile()->ns); 206 struct aa_label *label;
207 struct aa_ns *ns;
208
209 label = __begin_current_label_crit_section();
210 ns = aa_get_ns(labels_ns(label));
211 __end_current_label_crit_section(label);
212
213 return ns;
171} 214}
172 215
173/** 216/**
@@ -176,8 +219,8 @@ static inline struct aa_ns *aa_get_current_ns(void)
176 */ 219 */
177static inline void aa_clear_task_ctx_trans(struct aa_task_ctx *ctx) 220static inline void aa_clear_task_ctx_trans(struct aa_task_ctx *ctx)
178{ 221{
179 aa_put_profile(ctx->previous); 222 aa_put_label(ctx->previous);
180 aa_put_profile(ctx->onexec); 223 aa_put_label(ctx->onexec);
181 ctx->previous = NULL; 224 ctx->previous = NULL;
182 ctx->onexec = NULL; 225 ctx->onexec = NULL;
183 ctx->token = 0; 226 ctx->token = 0;
diff --git a/security/apparmor/include/domain.h b/security/apparmor/include/domain.h
index 30544729878a..bab5810b6e9a 100644
--- a/security/apparmor/include/domain.h
+++ b/security/apparmor/include/domain.h
@@ -23,14 +23,17 @@ struct aa_domain {
23 char **table; 23 char **table;
24}; 24};
25 25
26#define AA_CHANGE_NOFLAGS 0
27#define AA_CHANGE_TEST 1
28#define AA_CHANGE_CHILD 2
29#define AA_CHANGE_ONEXEC 4
30#define AA_CHANGE_STACK 8
31
26int apparmor_bprm_set_creds(struct linux_binprm *bprm); 32int apparmor_bprm_set_creds(struct linux_binprm *bprm);
27int apparmor_bprm_secureexec(struct linux_binprm *bprm); 33int apparmor_bprm_secureexec(struct linux_binprm *bprm);
28void apparmor_bprm_committing_creds(struct linux_binprm *bprm);
29void apparmor_bprm_committed_creds(struct linux_binprm *bprm);
30 34
31void aa_free_domain_entries(struct aa_domain *domain); 35void aa_free_domain_entries(struct aa_domain *domain);
32int aa_change_hat(const char *hats[], int count, u64 token, bool permtest); 36int aa_change_hat(const char *hats[], int count, u64 token, int flags);
33int aa_change_profile(const char *fqname, bool onexec, bool permtest, 37int aa_change_profile(const char *fqname, int flags);
34 bool stack);
35 38
36#endif /* __AA_DOMAIN_H */ 39#endif /* __AA_DOMAIN_H */
diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
index 38f821bf49b6..001e40073ff9 100644
--- a/security/apparmor/include/file.h
+++ b/security/apparmor/include/file.h
@@ -15,38 +15,73 @@
15#ifndef __AA_FILE_H 15#ifndef __AA_FILE_H
16#define __AA_FILE_H 16#define __AA_FILE_H
17 17
18#include <linux/spinlock.h>
19
18#include "domain.h" 20#include "domain.h"
19#include "match.h" 21#include "match.h"
22#include "perms.h"
20 23
21struct aa_profile; 24struct aa_profile;
22struct path; 25struct path;
23 26
24/* 27#define mask_mode_t(X) (X & (MAY_EXEC | MAY_WRITE | MAY_READ | MAY_APPEND))
25 * We use MAY_EXEC, MAY_WRITE, MAY_READ, MAY_APPEND and the following flags
26 * for profile permissions
27 */
28#define AA_MAY_CREATE 0x0010
29#define AA_MAY_DELETE 0x0020
30#define AA_MAY_META_WRITE 0x0040
31#define AA_MAY_META_READ 0x0080
32
33#define AA_MAY_CHMOD 0x0100
34#define AA_MAY_CHOWN 0x0200
35#define AA_MAY_LOCK 0x0400
36#define AA_EXEC_MMAP 0x0800
37
38#define AA_MAY_LINK 0x1000
39#define AA_LINK_SUBSET AA_MAY_LOCK /* overlaid */
40#define AA_MAY_ONEXEC 0x40000000 /* exec allows onexec */
41#define AA_MAY_CHANGE_PROFILE 0x80000000
42#define AA_MAY_CHANGEHAT 0x80000000 /* ctrl auditing only */
43 28
44#define AA_AUDIT_FILE_MASK (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND |\ 29#define AA_AUDIT_FILE_MASK (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND |\
45 AA_MAY_CREATE | AA_MAY_DELETE | \ 30 AA_MAY_CREATE | AA_MAY_DELETE | \
46 AA_MAY_META_READ | AA_MAY_META_WRITE | \ 31 AA_MAY_GETATTR | AA_MAY_SETATTR | \
47 AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_LOCK | \ 32 AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_LOCK | \
48 AA_EXEC_MMAP | AA_MAY_LINK) 33 AA_EXEC_MMAP | AA_MAY_LINK)
49 34
35#define file_ctx(X) ((struct aa_file_ctx *)(X)->f_security)
36
37/* struct aa_file_ctx - the AppArmor context the file was opened in
38 * @lock: lock to update the ctx
39 * @label: label currently cached on the ctx
40 * @perms: the permission the file was opened with
41 */
42struct aa_file_ctx {
43 spinlock_t lock;
44 struct aa_label __rcu *label;
45 u32 allow;
46};
47
48/**
49 * aa_alloc_file_ctx - allocate file_ctx
50 * @label: initial label of task creating the file
51 * @gfp: gfp flags for allocation
52 *
53 * Returns: file_ctx or NULL on failure
54 */
55static inline struct aa_file_ctx *aa_alloc_file_ctx(struct aa_label *label,
56 gfp_t gfp)
57{
58 struct aa_file_ctx *ctx;
59
60 ctx = kzalloc(sizeof(struct aa_file_ctx), gfp);
61 if (ctx) {
62 spin_lock_init(&ctx->lock);
63 rcu_assign_pointer(ctx->label, aa_get_label(label));
64 }
65 return ctx;
66}
67
68/**
69 * aa_free_file_ctx - free a file_ctx
70 * @ctx: file_ctx to free (MAYBE_NULL)
71 */
72static inline void aa_free_file_ctx(struct aa_file_ctx *ctx)
73{
74 if (ctx) {
75 aa_put_label(rcu_access_pointer(ctx->label));
76 kzfree(ctx);
77 }
78}
79
80static inline struct aa_label *aa_get_file_label(struct aa_file_ctx *ctx)
81{
82 return aa_get_label_rcu(&ctx->label);
83}
84
50/* 85/*
51 * The xindex is broken into 3 parts 86 * The xindex is broken into 3 parts
52 * - index - an index into either the exec name table or the variable table 87 * - index - an index into either the exec name table or the variable table
@@ -75,25 +110,6 @@ struct path_cond {
75 umode_t mode; 110 umode_t mode;
76}; 111};
77 112
78/* struct file_perms - file permission
79 * @allow: mask of permissions that are allowed
80 * @audit: mask of permissions to force an audit message for
81 * @quiet: mask of permissions to quiet audit messages for
82 * @kill: mask of permissions that when matched will kill the task
83 * @xindex: exec transition index if @allow contains MAY_EXEC
84 *
85 * The @audit and @queit mask should be mutually exclusive.
86 */
87struct file_perms {
88 u32 allow;
89 u32 audit;
90 u32 quiet;
91 u32 kill;
92 u16 xindex;
93};
94
95extern struct file_perms nullperms;
96
97#define COMBINED_PERM_MASK(X) ((X).allow | (X).audit | (X).quiet | (X).kill) 113#define COMBINED_PERM_MASK(X) ((X).allow | (X).audit | (X).quiet | (X).kill)
98 114
99/* FIXME: split perms from dfa and match this to description 115/* FIXME: split perms from dfa and match this to description
@@ -144,9 +160,10 @@ static inline u16 dfa_map_xindex(u16 mask)
144#define dfa_other_xindex(dfa, state) \ 160#define dfa_other_xindex(dfa, state) \
145 dfa_map_xindex((ACCEPT_TABLE(dfa)[state] >> 14) & 0x3fff) 161 dfa_map_xindex((ACCEPT_TABLE(dfa)[state] >> 14) & 0x3fff)
146 162
147int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, 163int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
148 const char *op, u32 request, const char *name, 164 const char *op, u32 request, const char *name,
149 const char *target, kuid_t ouid, const char *info, int error); 165 const char *target, struct aa_label *tlabel, kuid_t ouid,
166 const char *info, int error);
150 167
151/** 168/**
152 * struct aa_file_rules - components used for file rule permissions 169 * struct aa_file_rules - components used for file rule permissions
@@ -167,20 +184,27 @@ struct aa_file_rules {
167 /* TODO: add delegate table */ 184 /* TODO: add delegate table */
168}; 185};
169 186
187struct aa_perms aa_compute_fperms(struct aa_dfa *dfa, unsigned int state,
188 struct path_cond *cond);
170unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start, 189unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start,
171 const char *name, struct path_cond *cond, 190 const char *name, struct path_cond *cond,
172 struct file_perms *perms); 191 struct aa_perms *perms);
173 192
174int aa_path_perm(const char *op, struct aa_profile *profile, 193int __aa_path_perm(const char *op, struct aa_profile *profile,
194 const char *name, u32 request, struct path_cond *cond,
195 int flags, struct aa_perms *perms);
196int aa_path_perm(const char *op, struct aa_label *label,
175 const struct path *path, int flags, u32 request, 197 const struct path *path, int flags, u32 request,
176 struct path_cond *cond); 198 struct path_cond *cond);
177 199
178int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry, 200int aa_path_link(struct aa_label *label, struct dentry *old_dentry,
179 const struct path *new_dir, struct dentry *new_dentry); 201 const struct path *new_dir, struct dentry *new_dentry);
180 202
181int aa_file_perm(const char *op, struct aa_profile *profile, struct file *file, 203int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
182 u32 request); 204 u32 request);
183 205
206void aa_inherit_files(const struct cred *cred, struct files_struct *files);
207
184static inline void aa_free_file_rules(struct aa_file_rules *rules) 208static inline void aa_free_file_rules(struct aa_file_rules *rules)
185{ 209{
186 aa_put_dfa(rules->dfa); 210 aa_put_dfa(rules->dfa);
diff --git a/security/apparmor/include/ipc.h b/security/apparmor/include/ipc.h
index 288ca76e2fb1..656fdb81c8a0 100644
--- a/security/apparmor/include/ipc.h
+++ b/security/apparmor/include/ipc.h
@@ -4,7 +4,7 @@
4 * This file contains AppArmor ipc mediation function definitions. 4 * This file contains AppArmor ipc mediation function definitions.
5 * 5 *
6 * Copyright (C) 1998-2008 Novell/SUSE 6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2010 Canonical Ltd. 7 * Copyright 2009-2017 Canonical Ltd.
8 * 8 *
9 * This program is free software; you can redistribute it and/or 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 10 * modify it under the terms of the GNU General Public License as
@@ -19,10 +19,16 @@
19 19
20struct aa_profile; 20struct aa_profile;
21 21
22int aa_may_ptrace(struct aa_profile *tracer, struct aa_profile *tracee, 22#define AA_PTRACE_TRACE MAY_WRITE
23 unsigned int mode); 23#define AA_PTRACE_READ MAY_READ
24#define AA_MAY_BE_TRACED AA_MAY_APPEND
25#define AA_MAY_BE_READ AA_MAY_CREATE
26#define PTRACE_PERM_SHIFT 2
24 27
25int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee, 28#define AA_PTRACE_PERM_MASK (AA_PTRACE_READ | AA_PTRACE_TRACE | \
26 unsigned int mode); 29 AA_MAY_BE_READ | AA_MAY_BE_TRACED)
30
31int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
32 u32 request);
27 33
28#endif /* __AA_IPC_H */ 34#endif /* __AA_IPC_H */
diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h
new file mode 100644
index 000000000000..9a283b722755
--- /dev/null
+++ b/security/apparmor/include/label.h
@@ -0,0 +1,441 @@
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor label 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_LABEL_H
15#define __AA_LABEL_H
16
17#include <linux/atomic.h>
18#include <linux/audit.h>
19#include <linux/rbtree.h>
20#include <linux/rcupdate.h>
21
22#include "apparmor.h"
23#include "lib.h"
24
25struct aa_ns;
26
27#define LOCAL_VEC_ENTRIES 8
28#define DEFINE_VEC(T, V) \
29 struct aa_ ## T *(_ ## V ## _localtmp)[LOCAL_VEC_ENTRIES]; \
30 struct aa_ ## T **(V)
31
32#define vec_setup(T, V, N, GFP) \
33({ \
34 if ((N) <= LOCAL_VEC_ENTRIES) { \
35 typeof(N) i; \
36 (V) = (_ ## V ## _localtmp); \
37 for (i = 0; i < (N); i++) \
38 (V)[i] = NULL; \
39 } else \
40 (V) = kzalloc(sizeof(struct aa_ ## T *) * (N), (GFP)); \
41 (V) ? 0 : -ENOMEM; \
42})
43
44#define vec_cleanup(T, V, N) \
45do { \
46 int i; \
47 for (i = 0; i < (N); i++) { \
48 if (!IS_ERR_OR_NULL((V)[i])) \
49 aa_put_ ## T((V)[i]); \
50 } \
51 if ((V) != _ ## V ## _localtmp) \
52 kfree(V); \
53} while (0)
54
55#define vec_last(VEC, SIZE) ((VEC)[(SIZE) - 1])
56#define vec_ns(VEC, SIZE) (vec_last((VEC), (SIZE))->ns)
57#define vec_labelset(VEC, SIZE) (&vec_ns((VEC), (SIZE))->labels)
58#define cleanup_domain_vec(V, L) cleanup_label_vec((V), (L)->size)
59
60struct aa_profile;
61#define VEC_FLAG_TERMINATE 1
62int aa_vec_unique(struct aa_profile **vec, int n, int flags);
63struct aa_label *aa_vec_find_or_create_label(struct aa_profile **vec, int len,
64 gfp_t gfp);
65#define aa_sort_and_merge_vec(N, V) \
66 aa_sort_and_merge_profiles((N), (struct aa_profile **)(V))
67
68
69/* struct aa_labelset - set of labels for a namespace
70 *
71 * Labels are reference counted; aa_labelset does not contribute to label
72 * reference counts. Once a label's last refcount is put it is removed from
73 * the set.
74 */
75struct aa_labelset {
76 rwlock_t lock;
77
78 struct rb_root root;
79};
80
81#define __labelset_for_each(LS, N) \
82 for ((N) = rb_first(&(LS)->root); (N); (N) = rb_next(N))
83
84void aa_labelset_destroy(struct aa_labelset *ls);
85void aa_labelset_init(struct aa_labelset *ls);
86
87
88enum label_flags {
89 FLAG_HAT = 1, /* profile is a hat */
90 FLAG_UNCONFINED = 2, /* label unconfined only if all */
91 FLAG_NULL = 4, /* profile is null learning profile */
92 FLAG_IX_ON_NAME_ERROR = 8, /* fallback to ix on name lookup fail */
93 FLAG_IMMUTIBLE = 0x10, /* don't allow changes/replacement */
94 FLAG_USER_DEFINED = 0x20, /* user based profile - lower privs */
95 FLAG_NO_LIST_REF = 0x40, /* list doesn't keep profile ref */
96 FLAG_NS_COUNT = 0x80, /* carries NS ref count */
97 FLAG_IN_TREE = 0x100, /* label is in tree */
98 FLAG_PROFILE = 0x200, /* label is a profile */
99 FLAG_EXPLICIT = 0x400, /* explicit static label */
100 FLAG_STALE = 0x800, /* replaced/removed */
101 FLAG_RENAMED = 0x1000, /* label has renaming in it */
102 FLAG_REVOKED = 0x2000, /* label has revocation in it */
103
104 /* These flags must correspond with PATH_flags */
105 /* TODO: add new path flags */
106};
107
108struct aa_label;
109struct aa_proxy {
110 struct kref count;
111 struct aa_label __rcu *label;
112};
113
114struct label_it {
115 int i, j;
116};
117
118/* struct aa_label - lazy labeling struct
119 * @count: ref count of active users
120 * @node: rbtree position
121 * @rcu: rcu callback struct
122 * @proxy: is set to the label that replaced this label
123 * @hname: text representation of the label (MAYBE_NULL)
124 * @flags: stale and other flags - values may change under label set lock
125 * @secid: secid that references this label
126 * @size: number of entries in @ent[]
127 * @ent: set of profiles for label, actual size determined by @size
128 */
129struct aa_label {
130 struct kref count;
131 struct rb_node node;
132 struct rcu_head rcu;
133 struct aa_proxy *proxy;
134 __counted char *hname;
135 long flags;
136 u32 secid;
137 int size;
138 struct aa_profile *vec[];
139};
140
141#define last_error(E, FN) \
142do { \
143 int __subE = (FN); \
144 if (__subE) \
145 (E) = __subE; \
146} while (0)
147
148#define label_isprofile(X) ((X)->flags & FLAG_PROFILE)
149#define label_unconfined(X) ((X)->flags & FLAG_UNCONFINED)
150#define unconfined(X) label_unconfined(X)
151#define label_is_stale(X) ((X)->flags & FLAG_STALE)
152#define __label_make_stale(X) ((X)->flags |= FLAG_STALE)
153#define labels_ns(X) (vec_ns(&((X)->vec[0]), (X)->size))
154#define labels_set(X) (&labels_ns(X)->labels)
155#define labels_profile(X) ((X)->vec[(X)->size - 1])
156
157
158int aa_label_next_confined(struct aa_label *l, int i);
159
160/* for each profile in a label */
161#define label_for_each(I, L, P) \
162 for ((I).i = 0; ((P) = (L)->vec[(I).i]); ++((I).i))
163
164/* assumes break/goto ended label_for_each */
165#define label_for_each_cont(I, L, P) \
166 for (++((I).i); ((P) = (L)->vec[(I).i]); ++((I).i))
167
168#define next_comb(I, L1, L2) \
169do { \
170 (I).j++; \
171 if ((I).j >= (L2)->size) { \
172 (I).i++; \
173 (I).j = 0; \
174 } \
175} while (0)
176
177
178/* for each combination of P1 in L1, and P2 in L2 */
179#define label_for_each_comb(I, L1, L2, P1, P2) \
180for ((I).i = (I).j = 0; \
181 ((P1) = (L1)->vec[(I).i]) && ((P2) = (L2)->vec[(I).j]); \
182 (I) = next_comb(I, L1, L2))
183
184#define fn_for_each_comb(L1, L2, P1, P2, FN) \
185({ \
186 struct label_it i; \
187 int __E = 0; \
188 label_for_each_comb(i, (L1), (L2), (P1), (P2)) { \
189 last_error(__E, (FN)); \
190 } \
191 __E; \
192})
193
194/* for each profile that is enforcing confinement in a label */
195#define label_for_each_confined(I, L, P) \
196 for ((I).i = aa_label_next_confined((L), 0); \
197 ((P) = (L)->vec[(I).i]); \
198 (I).i = aa_label_next_confined((L), (I).i + 1))
199
200#define label_for_each_in_merge(I, A, B, P) \
201 for ((I).i = (I).j = 0; \
202 ((P) = aa_label_next_in_merge(&(I), (A), (B))); \
203 )
204
205#define label_for_each_not_in_set(I, SET, SUB, P) \
206 for ((I).i = (I).j = 0; \
207 ((P) = __aa_label_next_not_in_set(&(I), (SET), (SUB))); \
208 )
209
210#define next_in_ns(i, NS, L) \
211({ \
212 typeof(i) ___i = (i); \
213 while ((L)->vec[___i] && (L)->vec[___i]->ns != (NS)) \
214 (___i)++; \
215 (___i); \
216})
217
218#define label_for_each_in_ns(I, NS, L, P) \
219 for ((I).i = next_in_ns(0, (NS), (L)); \
220 ((P) = (L)->vec[(I).i]); \
221 (I).i = next_in_ns((I).i + 1, (NS), (L)))
222
223#define fn_for_each_in_ns(L, P, FN) \
224({ \
225 struct label_it __i; \
226 struct aa_ns *__ns = labels_ns(L); \
227 int __E = 0; \
228 label_for_each_in_ns(__i, __ns, (L), (P)) { \
229 last_error(__E, (FN)); \
230 } \
231 __E; \
232})
233
234
235#define fn_for_each_XXX(L, P, FN, ...) \
236({ \
237 struct label_it i; \
238 int __E = 0; \
239 label_for_each ## __VA_ARGS__(i, (L), (P)) { \
240 last_error(__E, (FN)); \
241 } \
242 __E; \
243})
244
245#define fn_for_each(L, P, FN) fn_for_each_XXX(L, P, FN)
246#define fn_for_each_confined(L, P, FN) fn_for_each_XXX(L, P, FN, _confined)
247
248#define fn_for_each2_XXX(L1, L2, P, FN, ...) \
249({ \
250 struct label_it i; \
251 int __E = 0; \
252 label_for_each ## __VA_ARGS__(i, (L1), (L2), (P)) { \
253 last_error(__E, (FN)); \
254 } \
255 __E; \
256})
257
258#define fn_for_each_in_merge(L1, L2, P, FN) \
259 fn_for_each2_XXX((L1), (L2), P, FN, _in_merge)
260#define fn_for_each_not_in_set(L1, L2, P, FN) \
261 fn_for_each2_XXX((L1), (L2), P, FN, _not_in_set)
262
263#define LABEL_MEDIATES(L, C) \
264({ \
265 struct aa_profile *profile; \
266 struct label_it i; \
267 int ret = 0; \
268 label_for_each(i, (L), profile) { \
269 if (PROFILE_MEDIATES(profile, (C))) { \
270 ret = 1; \
271 break; \
272 } \
273 } \
274 ret; \
275})
276
277
278void aa_labelset_destroy(struct aa_labelset *ls);
279void aa_labelset_init(struct aa_labelset *ls);
280void __aa_labelset_update_subtree(struct aa_ns *ns);
281
282void aa_label_free(struct aa_label *label);
283void aa_label_kref(struct kref *kref);
284bool aa_label_init(struct aa_label *label, int size);
285struct aa_label *aa_label_alloc(int size, struct aa_proxy *proxy, gfp_t gfp);
286
287bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub);
288struct aa_profile *__aa_label_next_not_in_set(struct label_it *I,
289 struct aa_label *set,
290 struct aa_label *sub);
291bool aa_label_remove(struct aa_label *label);
292struct aa_label *aa_label_insert(struct aa_labelset *ls, struct aa_label *l);
293bool aa_label_replace(struct aa_label *old, struct aa_label *new);
294bool aa_label_make_newest(struct aa_labelset *ls, struct aa_label *old,
295 struct aa_label *new);
296
297struct aa_label *aa_label_find(struct aa_label *l);
298
299struct aa_profile *aa_label_next_in_merge(struct label_it *I,
300 struct aa_label *a,
301 struct aa_label *b);
302struct aa_label *aa_label_find_merge(struct aa_label *a, struct aa_label *b);
303struct aa_label *aa_label_merge(struct aa_label *a, struct aa_label *b,
304 gfp_t gfp);
305
306
307bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp);
308
309#define FLAGS_NONE 0
310#define FLAG_SHOW_MODE 1
311#define FLAG_VIEW_SUBNS 2
312#define FLAG_HIDDEN_UNCONFINED 4
313int aa_label_snxprint(char *str, size_t size, struct aa_ns *view,
314 struct aa_label *label, int flags);
315int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label,
316 int flags, gfp_t gfp);
317int aa_label_acntsxprint(char __counted **strp, struct aa_ns *ns,
318 struct aa_label *label, int flags, gfp_t gfp);
319void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns,
320 struct aa_label *label, int flags, gfp_t gfp);
321void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns,
322 struct aa_label *label, int flags, gfp_t gfp);
323void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags,
324 gfp_t gfp);
325void aa_label_audit(struct audit_buffer *ab, struct aa_label *label, gfp_t gfp);
326void aa_label_seq_print(struct seq_file *f, struct aa_label *label, gfp_t gfp);
327void aa_label_printk(struct aa_label *label, gfp_t gfp);
328
329struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
330 gfp_t gfp, bool create, bool force_stack);
331
332
333struct aa_perms;
334int aa_label_match(struct aa_profile *profile, struct aa_label *label,
335 unsigned int state, bool subns, u32 request,
336 struct aa_perms *perms);
337
338
339/**
340 * __aa_get_label - get a reference count to uncounted label reference
341 * @l: reference to get a count on
342 *
343 * Returns: pointer to reference OR NULL if race is lost and reference is
344 * being repeated.
345 * Requires: lock held, and the return code MUST be checked
346 */
347static inline struct aa_label *__aa_get_label(struct aa_label *l)
348{
349 if (l && kref_get_unless_zero(&l->count))
350 return l;
351
352 return NULL;
353}
354
355static inline struct aa_label *aa_get_label(struct aa_label *l)
356{
357 if (l)
358 kref_get(&(l->count));
359
360 return l;
361}
362
363
364/**
365 * aa_get_label_rcu - increment refcount on a label that can be replaced
366 * @l: pointer to label that can be replaced (NOT NULL)
367 *
368 * Returns: pointer to a refcounted label.
369 * else NULL if no label
370 */
371static inline struct aa_label *aa_get_label_rcu(struct aa_label __rcu **l)
372{
373 struct aa_label *c;
374
375 rcu_read_lock();
376 do {
377 c = rcu_dereference(*l);
378 } while (c && !kref_get_unless_zero(&c->count));
379 rcu_read_unlock();
380
381 return c;
382}
383
384/**
385 * aa_get_newest_label - find the newest version of @l
386 * @l: the label to check for newer versions of
387 *
388 * Returns: refcounted newest version of @l taking into account
389 * replacement, renames and removals
390 * return @l.
391 */
392static inline struct aa_label *aa_get_newest_label(struct aa_label *l)
393{
394 if (!l)
395 return NULL;
396
397 if (label_is_stale(l)) {
398 struct aa_label *tmp;
399
400 AA_BUG(!l->proxy);
401 AA_BUG(!l->proxy->label);
402 /* BUG: only way this can happen is @l ref count and its
403 * replacement count have gone to 0 and are on their way
404 * to destruction. ie. we have a refcounting error
405 */
406 tmp = aa_get_label_rcu(&l->proxy->label);
407 AA_BUG(!tmp);
408
409 return tmp;
410 }
411
412 return aa_get_label(l);
413}
414
415static inline void aa_put_label(struct aa_label *l)
416{
417 if (l)
418 kref_put(&l->count, aa_label_kref);
419}
420
421
422struct aa_proxy *aa_alloc_proxy(struct aa_label *l, gfp_t gfp);
423void aa_proxy_kref(struct kref *kref);
424
425static inline struct aa_proxy *aa_get_proxy(struct aa_proxy *proxy)
426{
427 if (proxy)
428 kref_get(&(proxy->count));
429
430 return proxy;
431}
432
433static inline void aa_put_proxy(struct aa_proxy *proxy)
434{
435 if (proxy)
436 kref_put(&proxy->count, aa_proxy_kref);
437}
438
439void __aa_proxy_redirect(struct aa_label *orig, struct aa_label *new);
440
441#endif /* __AA_LABEL_H */
diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h
index 550a700563b4..436b3a722357 100644
--- a/security/apparmor/include/lib.h
+++ b/security/apparmor/include/lib.h
@@ -60,6 +60,7 @@
60extern int apparmor_initialized; 60extern int apparmor_initialized;
61 61
62/* fn's in lib */ 62/* fn's in lib */
63const char *skipn_spaces(const char *str, size_t n);
63char *aa_split_fqname(char *args, char **ns_name); 64char *aa_split_fqname(char *args, char **ns_name);
64const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name, 65const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
65 size_t *ns_len); 66 size_t *ns_len);
@@ -99,6 +100,36 @@ static inline bool path_mediated_fs(struct dentry *dentry)
99 return !(dentry->d_sb->s_flags & MS_NOUSER); 100 return !(dentry->d_sb->s_flags & MS_NOUSER);
100} 101}
101 102
103
104struct counted_str {
105 struct kref count;
106 char name[];
107};
108
109#define str_to_counted(str) \
110 ((struct counted_str *)(str - offsetof(struct counted_str, name)))
111
112#define __counted /* atm just a notation */
113
114void aa_str_kref(struct kref *kref);
115char *aa_str_alloc(int size, gfp_t gfp);
116
117
118static inline __counted char *aa_get_str(__counted char *str)
119{
120 if (str)
121 kref_get(&(str_to_counted(str)->count));
122
123 return str;
124}
125
126static inline void aa_put_str(__counted char *str)
127{
128 if (str)
129 kref_put(&str_to_counted(str)->count, aa_str_kref);
130}
131
132
102/* struct aa_policy - common part of both namespaces and profiles 133/* struct aa_policy - common part of both namespaces and profiles
103 * @name: name of the object 134 * @name: name of the object
104 * @hname - The hierarchical name 135 * @hname - The hierarchical name
@@ -107,7 +138,7 @@ static inline bool path_mediated_fs(struct dentry *dentry)
107 */ 138 */
108struct aa_policy { 139struct aa_policy {
109 const char *name; 140 const char *name;
110 const char *hname; 141 __counted char *hname;
111 struct list_head list; 142 struct list_head list;
112 struct list_head profiles; 143 struct list_head profiles;
113}; 144};
@@ -180,4 +211,89 @@ bool aa_policy_init(struct aa_policy *policy, const char *prefix,
180 const char *name, gfp_t gfp); 211 const char *name, gfp_t gfp);
181void aa_policy_destroy(struct aa_policy *policy); 212void aa_policy_destroy(struct aa_policy *policy);
182 213
183#endif /* AA_LIB_H */ 214
215/*
216 * fn_label_build - abstract out the build of a label transition
217 * @L: label the transition is being computed for
218 * @P: profile parameter derived from L by this macro, can be passed to FN
219 * @GFP: memory allocation type to use
220 * @FN: fn to call for each profile transition. @P is set to the profile
221 *
222 * Returns: new label on success
223 * ERR_PTR if build @FN fails
224 * NULL if label_build fails due to low memory conditions
225 *
226 * @FN must return a label or ERR_PTR on failure. NULL is not allowed
227 */
228#define fn_label_build(L, P, GFP, FN) \
229({ \
230 __label__ __cleanup, __done; \
231 struct aa_label *__new_; \
232 \
233 if ((L)->size > 1) { \
234 /* TODO: add cache of transitions already done */ \
235 struct label_it __i; \
236 int __j, __k, __count; \
237 DEFINE_VEC(label, __lvec); \
238 DEFINE_VEC(profile, __pvec); \
239 if (vec_setup(label, __lvec, (L)->size, (GFP))) { \
240 __new_ = NULL; \
241 goto __done; \
242 } \
243 __j = 0; \
244 label_for_each(__i, (L), (P)) { \
245 __new_ = (FN); \
246 AA_BUG(!__new_); \
247 if (IS_ERR(__new_)) \
248 goto __cleanup; \
249 __lvec[__j++] = __new_; \
250 } \
251 for (__j = __count = 0; __j < (L)->size; __j++) \
252 __count += __lvec[__j]->size; \
253 if (!vec_setup(profile, __pvec, __count, (GFP))) { \
254 for (__j = __k = 0; __j < (L)->size; __j++) { \
255 label_for_each(__i, __lvec[__j], (P)) \
256 __pvec[__k++] = aa_get_profile(P); \
257 } \
258 __count -= aa_vec_unique(__pvec, __count, 0); \
259 if (__count > 1) { \
260 __new_ = aa_vec_find_or_create_label(__pvec,\
261 __count, (GFP)); \
262 /* only fails if out of Mem */ \
263 if (!__new_) \
264 __new_ = NULL; \
265 } else \
266 __new_ = aa_get_label(&__pvec[0]->label); \
267 vec_cleanup(profile, __pvec, __count); \
268 } else \
269 __new_ = NULL; \
270__cleanup: \
271 vec_cleanup(label, __lvec, (L)->size); \
272 } else { \
273 (P) = labels_profile(L); \
274 __new_ = (FN); \
275 } \
276__done: \
277 if (!__new_) \
278 AA_DEBUG("label build failed\n"); \
279 (__new_); \
280})
281
282
283#define __fn_build_in_ns(NS, P, NS_FN, OTHER_FN) \
284({ \
285 struct aa_label *__new; \
286 if ((P)->ns != (NS)) \
287 __new = (OTHER_FN); \
288 else \
289 __new = (NS_FN); \
290 (__new); \
291})
292
293#define fn_label_build_in_ns(L, P, GFP, NS_FN, OTHER_FN) \
294({ \
295 fn_label_build((L), (P), (GFP), \
296 __fn_build_in_ns(labels_ns(L), (P), (NS_FN), (OTHER_FN))); \
297})
298
299#endif /* __AA_LIB_H */
diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
index 0444fdde3918..05fb3305671e 100644
--- a/security/apparmor/include/path.h
+++ b/security/apparmor/include/path.h
@@ -23,11 +23,12 @@ enum path_flags {
23 PATH_CHROOT_NSCONNECT = 0x10, /* connect paths that are at ns root */ 23 PATH_CHROOT_NSCONNECT = 0x10, /* connect paths that are at ns root */
24 24
25 PATH_DELEGATE_DELETED = 0x08000, /* delegate deleted files */ 25 PATH_DELEGATE_DELETED = 0x08000, /* delegate deleted files */
26 PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */ 26 PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */
27}; 27};
28 28
29int aa_path_name(const struct path *path, int flags, char **buffer, 29int aa_path_name(const struct path *path, int flags, char *buffer,
30 const char **name, const char **info); 30 const char **name, const char **info,
31 const char *disconnected);
31 32
32#define MAX_PATH_BUFFERS 2 33#define MAX_PATH_BUFFERS 2
33 34
diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
new file mode 100644
index 000000000000..2b27bb79aec4
--- /dev/null
+++ b/security/apparmor/include/perms.h
@@ -0,0 +1,155 @@
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor basic permission sets 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_PERM_H
15#define __AA_PERM_H
16
17#include <linux/fs.h>
18#include "label.h"
19
20#define AA_MAY_EXEC MAY_EXEC
21#define AA_MAY_WRITE MAY_WRITE
22#define AA_MAY_READ MAY_READ
23#define AA_MAY_APPEND MAY_APPEND
24
25#define AA_MAY_CREATE 0x0010
26#define AA_MAY_DELETE 0x0020
27#define AA_MAY_OPEN 0x0040
28#define AA_MAY_RENAME 0x0080 /* pair */
29
30#define AA_MAY_SETATTR 0x0100 /* meta write */
31#define AA_MAY_GETATTR 0x0200 /* meta read */
32#define AA_MAY_SETCRED 0x0400 /* security cred/attr */
33#define AA_MAY_GETCRED 0x0800
34
35#define AA_MAY_CHMOD 0x1000 /* pair */
36#define AA_MAY_CHOWN 0x2000 /* pair */
37#define AA_MAY_CHGRP 0x4000 /* pair */
38#define AA_MAY_LOCK 0x8000 /* LINK_SUBSET overlaid */
39
40#define AA_EXEC_MMAP 0x00010000
41#define AA_MAY_MPROT 0x00020000 /* extend conditions */
42#define AA_MAY_LINK 0x00040000 /* pair */
43#define AA_MAY_SNAPSHOT 0x00080000 /* pair */
44
45#define AA_MAY_DELEGATE
46#define AA_CONT_MATCH 0x08000000
47
48#define AA_MAY_STACK 0x10000000
49#define AA_MAY_ONEXEC 0x20000000 /* either stack or change_profile */
50#define AA_MAY_CHANGE_PROFILE 0x40000000
51#define AA_MAY_CHANGEHAT 0x80000000
52
53#define AA_LINK_SUBSET AA_MAY_LOCK /* overlaid */
54
55
56#define PERMS_CHRS_MASK (MAY_READ | MAY_WRITE | AA_MAY_CREATE | \
57 AA_MAY_DELETE | AA_MAY_LINK | AA_MAY_LOCK | \
58 AA_MAY_EXEC | AA_EXEC_MMAP | AA_MAY_APPEND)
59
60#define PERMS_NAMES_MASK (PERMS_CHRS_MASK | AA_MAY_OPEN | AA_MAY_RENAME | \
61 AA_MAY_SETATTR | AA_MAY_GETATTR | AA_MAY_SETCRED | \
62 AA_MAY_GETCRED | AA_MAY_CHMOD | AA_MAY_CHOWN | \
63 AA_MAY_CHGRP | AA_MAY_MPROT | AA_MAY_SNAPSHOT | \
64 AA_MAY_STACK | AA_MAY_ONEXEC | \
65 AA_MAY_CHANGE_PROFILE | AA_MAY_CHANGEHAT)
66
67extern const char aa_file_perm_chrs[];
68extern const char *aa_file_perm_names[];
69
70struct aa_perms {
71 u32 allow;
72 u32 audit; /* set only when allow is set */
73
74 u32 deny; /* explicit deny, or conflict if allow also set */
75 u32 quiet; /* set only when ~allow | deny */
76 u32 kill; /* set only when ~allow | deny */
77 u32 stop; /* set only when ~allow | deny */
78
79 u32 complain; /* accumulates only used when ~allow & ~deny */
80 u32 cond; /* set only when ~allow and ~deny */
81
82 u32 hide; /* set only when ~allow | deny */
83 u32 prompt; /* accumulates only used when ~allow & ~deny */
84
85 /* Reserved:
86 * u32 subtree; / * set only when allow is set * /
87 */
88 u16 xindex;
89};
90
91#define ALL_PERMS_MASK 0xffffffff
92extern struct aa_perms nullperms;
93extern struct aa_perms allperms;
94
95
96#define xcheck(FN1, FN2) \
97({ \
98 int e, error = FN1; \
99 e = FN2; \
100 if (e) \
101 error = e; \
102 error; \
103})
104
105
106/*
107 * TODO: update for labels pointing to labels instead of profiles
108 * TODO: optimize the walk, currently does subwalk of L2 for each P in L1
109 * gah this doesn't allow for label compound check!!!!
110 */
111#define xcheck_ns_profile_profile(P1, P2, FN, args...) \
112({ \
113 int ____e = 0; \
114 if (P1->ns == P2->ns) \
115 ____e = FN((P1), (P2), args); \
116 (____e); \
117})
118
119#define xcheck_ns_profile_label(P, L, FN, args...) \
120({ \
121 struct aa_profile *__p2; \
122 fn_for_each((L), __p2, \
123 xcheck_ns_profile_profile((P), __p2, (FN), args)); \
124})
125
126#define xcheck_ns_labels(L1, L2, FN, args...) \
127({ \
128 struct aa_profile *__p1; \
129 fn_for_each((L1), __p1, FN(__p1, (L2), args)); \
130})
131
132/* Do the cross check but applying FN at the profiles level */
133#define xcheck_labels_profiles(L1, L2, FN, args...) \
134 xcheck_ns_labels((L1), (L2), xcheck_ns_profile_label, (FN), args)
135
136
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);
139void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
140 u32 chrsmask, const char **names, u32 namesmask);
141void aa_apply_modes_to_perms(struct aa_profile *profile,
142 struct aa_perms *perms);
143void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
144 struct aa_perms *perms);
145void aa_perms_accum(struct aa_perms *accum, struct aa_perms *addend);
146void aa_perms_accum_raw(struct aa_perms *accum, struct aa_perms *addend);
147void aa_profile_match_label(struct aa_profile *profile, struct aa_label *label,
148 int type, u32 request, struct aa_perms *perms);
149int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,
150 u32 request, int type, u32 *deny,
151 struct common_audit_data *sa);
152int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
153 u32 request, struct common_audit_data *sa,
154 void (*cb)(struct audit_buffer *, void *));
155#endif /* __AA_PERM_H */
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index 67bc96afe541..17fe41a9cac3 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -29,6 +29,8 @@
29#include "domain.h" 29#include "domain.h"
30#include "file.h" 30#include "file.h"
31#include "lib.h" 31#include "lib.h"
32#include "label.h"
33#include "perms.h"
32#include "resource.h" 34#include "resource.h"
33 35
34 36
@@ -47,9 +49,9 @@ extern const char *const aa_profile_mode_names[];
47 49
48#define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL) 50#define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL)
49 51
50#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT) 52#define PROFILE_IS_HAT(_profile) ((_profile)->label.flags & FLAG_HAT)
51 53
52#define profile_is_stale(_profile) ((_profile)->flags & PFLAG_STALE) 54#define profile_is_stale(_profile) (label_is_stale(&(_profile)->label))
53 55
54#define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2) 56#define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2)
55 57
@@ -66,22 +68,6 @@ enum profile_mode {
66 APPARMOR_UNCONFINED, /* profile set to unconfined */ 68 APPARMOR_UNCONFINED, /* profile set to unconfined */
67}; 69};
68 70
69enum profile_flags {
70 PFLAG_HAT = 1, /* profile is a hat */
71 PFLAG_NULL = 4, /* profile is null learning profile */
72 PFLAG_IX_ON_NAME_ERROR = 8, /* fallback to ix on name lookup fail */
73 PFLAG_IMMUTABLE = 0x10, /* don't allow changes/replacement */
74 PFLAG_USER_DEFINED = 0x20, /* user based profile - lower privs */
75 PFLAG_NO_LIST_REF = 0x40, /* list doesn't keep profile ref */
76 PFLAG_OLD_NULL_TRANS = 0x100, /* use // as the null transition */
77 PFLAG_STALE = 0x200, /* profile replaced/removed */
78 PFLAG_NS_COUNT = 0x400, /* carries NS ref count */
79
80 /* These flags must correspond with PATH_flags */
81 PFLAG_MEDIATE_DELETED = 0x10000, /* mediate instead delegate deleted */
82};
83
84struct aa_profile;
85 71
86/* struct aa_policydb - match engine for a policy 72/* struct aa_policydb - match engine for a policy
87 * dfa: dfa pattern match 73 * dfa: dfa pattern match
@@ -94,11 +80,6 @@ struct aa_policydb {
94 80
95}; 81};
96 82
97struct aa_proxy {
98 struct kref count;
99 struct aa_profile __rcu *profile;
100};
101
102/* struct aa_data - generic data structure 83/* struct aa_data - generic data structure
103 * key: name for retrieving this data 84 * key: name for retrieving this data
104 * size: size of data in bytes 85 * size: size of data in bytes
@@ -115,19 +96,17 @@ struct aa_data {
115 96
116/* struct aa_profile - basic confinement data 97/* struct aa_profile - basic confinement data
117 * @base - base components of the profile (name, refcount, lists, lock ...) 98 * @base - base components of the profile (name, refcount, lists, lock ...)
118 * @count: reference count of the obj 99 * @label - label this profile is an extension of
119 * @rcu: rcu head used when removing from @list
120 * @parent: parent of profile 100 * @parent: parent of profile
121 * @ns: namespace the profile is in 101 * @ns: namespace the profile is in
122 * @proxy: is set to the profile that replaced this profile
123 * @rename: optional profile name that this profile renamed 102 * @rename: optional profile name that this profile renamed
124 * @attach: human readable attachment string 103 * @attach: human readable attachment string
125 * @xmatch: optional extended matching for unconfined executables names 104 * @xmatch: optional extended matching for unconfined executables names
126 * @xmatch_len: xmatch prefix len, used to determine xmatch priority 105 * @xmatch_len: xmatch prefix len, used to determine xmatch priority
127 * @audit: the auditing mode of the profile 106 * @audit: the auditing mode of the profile
128 * @mode: the enforcement mode of the profile 107 * @mode: the enforcement mode of the profile
129 * @flags: flags controlling profile behavior
130 * @path_flags: flags controlling path generation behavior 108 * @path_flags: flags controlling path generation behavior
109 * @disconnected: what to prepend if attach_disconnected is specified
131 * @size: the memory consumed by this profiles rules 110 * @size: the memory consumed by this profiles rules
132 * @policy: general match rules governing policy 111 * @policy: general match rules governing policy
133 * @file: The set of rules governing basic file access and domain transitions 112 * @file: The set of rules governing basic file access and domain transitions
@@ -143,8 +122,6 @@ struct aa_data {
143 * used to determine profile attachment against unconfined tasks. All other 122 * used to determine profile attachment against unconfined tasks. All other
144 * attachments are determined by profile X transition rules. 123 * attachments are determined by profile X transition rules.
145 * 124 *
146 * The @proxy struct is write protected by the profile lock.
147 *
148 * Profiles have a hierarchy where hats and children profiles keep 125 * Profiles have a hierarchy where hats and children profiles keep
149 * a reference to their parent. 126 * a reference to their parent.
150 * 127 *
@@ -154,12 +131,9 @@ struct aa_data {
154 */ 131 */
155struct aa_profile { 132struct aa_profile {
156 struct aa_policy base; 133 struct aa_policy base;
157 struct kref count;
158 struct rcu_head rcu;
159 struct aa_profile __rcu *parent; 134 struct aa_profile __rcu *parent;
160 135
161 struct aa_ns *ns; 136 struct aa_ns *ns;
162 struct aa_proxy *proxy;
163 const char *rename; 137 const char *rename;
164 138
165 const char *attach; 139 const char *attach;
@@ -167,8 +141,8 @@ struct aa_profile {
167 int xmatch_len; 141 int xmatch_len;
168 enum audit_mode audit; 142 enum audit_mode audit;
169 long mode; 143 long mode;
170 long flags;
171 u32 path_flags; 144 u32 path_flags;
145 const char *disconnected;
172 int size; 146 int size;
173 147
174 struct aa_policydb policy; 148 struct aa_policydb policy;
@@ -181,17 +155,24 @@ struct aa_profile {
181 char *dirname; 155 char *dirname;
182 struct dentry *dents[AAFS_PROF_SIZEOF]; 156 struct dentry *dents[AAFS_PROF_SIZEOF];
183 struct rhashtable *data; 157 struct rhashtable *data;
158 struct aa_label label;
184}; 159};
185 160
186extern enum profile_mode aa_g_profile_mode; 161extern enum profile_mode aa_g_profile_mode;
187 162
188void __aa_update_proxy(struct aa_profile *orig, struct aa_profile *new); 163#define AA_MAY_LOAD_POLICY AA_MAY_APPEND
164#define AA_MAY_REPLACE_POLICY AA_MAY_WRITE
165#define AA_MAY_REMOVE_POLICY AA_MAY_DELETE
166
167#define profiles_ns(P) ((P)->ns)
168#define name_is_shared(A, B) ((A)->hname && (A)->hname == (B)->hname)
189 169
190void aa_add_profile(struct aa_policy *common, struct aa_profile *profile); 170void aa_add_profile(struct aa_policy *common, struct aa_profile *profile);
191 171
192 172
193void aa_free_proxy_kref(struct kref *kref); 173void aa_free_proxy_kref(struct kref *kref);
194struct aa_profile *aa_alloc_profile(const char *name, gfp_t gfp); 174struct aa_profile *aa_alloc_profile(const char *name, struct aa_proxy *proxy,
175 gfp_t gfp);
195struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat, 176struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
196 const char *base, gfp_t gfp); 177 const char *base, gfp_t gfp);
197void aa_free_profile(struct aa_profile *profile); 178void aa_free_profile(struct aa_profile *profile);
@@ -200,21 +181,44 @@ struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
200struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname, 181struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname,
201 size_t n); 182 size_t n);
202struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *name); 183struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *name);
203struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base, 184struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
204 const char *fqname, size_t n); 185 const char *fqname, size_t n);
205struct aa_profile *aa_match_profile(struct aa_ns *ns, const char *name); 186struct aa_profile *aa_match_profile(struct aa_ns *ns, const char *name);
206 187
207ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile, 188ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_label *label,
208 bool noreplace, struct aa_loaddata *udata); 189 u32 mask, struct aa_loaddata *udata);
209ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *profile, 190ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_label *label,
210 char *name, size_t size); 191 char *name, size_t size);
211void __aa_profile_list_release(struct list_head *head); 192void __aa_profile_list_release(struct list_head *head);
212 193
213#define PROF_ADD 1 194#define PROF_ADD 1
214#define PROF_REPLACE 0 195#define PROF_REPLACE 0
215 196
216#define unconfined(X) ((X)->mode == APPARMOR_UNCONFINED) 197#define profile_unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
198
199/**
200 * aa_get_newest_profile - simple wrapper fn to wrap the label version
201 * @p: profile (NOT NULL)
202 *
203 * Returns refcount to newest version of the profile (maybe @p)
204 *
205 * Requires: @p must be held with a valid refcount
206 */
207static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
208{
209 return labels_profile(aa_get_newest_label(&p->label));
210}
217 211
212#define PROFILE_MEDIATES(P, T) ((P)->policy.start[(T)])
213/* safe version of POLICY_MEDIATES for full range input */
214static inline unsigned int PROFILE_MEDIATES_SAFE(struct aa_profile *profile,
215 unsigned char class)
216{
217 if (profile->policy.dfa)
218 return aa_dfa_match_len(profile->policy.dfa,
219 profile->policy.start[0], &class, 1);
220 return 0;
221}
218 222
219/** 223/**
220 * aa_get_profile - increment refcount on profile @p 224 * aa_get_profile - increment refcount on profile @p
@@ -226,7 +230,7 @@ void __aa_profile_list_release(struct list_head *head);
226static inline struct aa_profile *aa_get_profile(struct aa_profile *p) 230static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
227{ 231{
228 if (p) 232 if (p)
229 kref_get(&(p->count)); 233 kref_get(&(p->label.count));
230 234
231 return p; 235 return p;
232} 236}
@@ -240,7 +244,7 @@ static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
240 */ 244 */
241static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p) 245static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p)
242{ 246{
243 if (p && kref_get_unless_zero(&p->count)) 247 if (p && kref_get_unless_zero(&p->label.count))
244 return p; 248 return p;
245 249
246 return NULL; 250 return NULL;
@@ -260,53 +264,20 @@ static inline struct aa_profile *aa_get_profile_rcu(struct aa_profile __rcu **p)
260 rcu_read_lock(); 264 rcu_read_lock();
261 do { 265 do {
262 c = rcu_dereference(*p); 266 c = rcu_dereference(*p);
263 } while (c && !kref_get_unless_zero(&c->count)); 267 } while (c && !kref_get_unless_zero(&c->label.count));
264 rcu_read_unlock(); 268 rcu_read_unlock();
265 269
266 return c; 270 return c;
267} 271}
268 272
269/** 273/**
270 * aa_get_newest_profile - find the newest version of @profile
271 * @profile: the profile to check for newer versions of
272 *
273 * Returns: refcounted newest version of @profile taking into account
274 * replacement, renames and removals
275 * return @profile.
276 */
277static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
278{
279 if (!p)
280 return NULL;
281
282 if (profile_is_stale(p))
283 return aa_get_profile_rcu(&p->proxy->profile);
284
285 return aa_get_profile(p);
286}
287
288/**
289 * aa_put_profile - decrement refcount on profile @p 274 * aa_put_profile - decrement refcount on profile @p
290 * @p: profile (MAYBE NULL) 275 * @p: profile (MAYBE NULL)
291 */ 276 */
292static inline void aa_put_profile(struct aa_profile *p) 277static inline void aa_put_profile(struct aa_profile *p)
293{ 278{
294 if (p) 279 if (p)
295 kref_put(&p->count, aa_free_profile_kref); 280 kref_put(&p->label.count, aa_label_kref);
296}
297
298static inline struct aa_proxy *aa_get_proxy(struct aa_proxy *p)
299{
300 if (p)
301 kref_get(&(p->count));
302
303 return p;
304}
305
306static inline void aa_put_proxy(struct aa_proxy *p)
307{
308 if (p)
309 kref_put(&p->count, aa_free_proxy_kref);
310} 281}
311 282
312static inline int AUDIT_MODE(struct aa_profile *profile) 283static inline int AUDIT_MODE(struct aa_profile *profile)
@@ -319,7 +290,7 @@ static inline int AUDIT_MODE(struct aa_profile *profile)
319 290
320bool policy_view_capable(struct aa_ns *ns); 291bool policy_view_capable(struct aa_ns *ns);
321bool policy_admin_capable(struct aa_ns *ns); 292bool policy_admin_capable(struct aa_ns *ns);
322int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns, 293int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns,
323 const char *op); 294 u32 mask);
324 295
325#endif /* __AA_POLICY_H */ 296#endif /* __AA_POLICY_H */
diff --git a/security/apparmor/include/policy_ns.h b/security/apparmor/include/policy_ns.h
index 89cffddd7e75..9605f18624e2 100644
--- a/security/apparmor/include/policy_ns.h
+++ b/security/apparmor/include/policy_ns.h
@@ -19,6 +19,7 @@
19 19
20#include "apparmor.h" 20#include "apparmor.h"
21#include "apparmorfs.h" 21#include "apparmorfs.h"
22#include "label.h"
22#include "policy.h" 23#include "policy.h"
23 24
24 25
@@ -68,6 +69,11 @@ struct aa_ns {
68 atomic_t uniq_null; 69 atomic_t uniq_null;
69 long uniq_id; 70 long uniq_id;
70 int level; 71 int level;
72 long revision;
73 wait_queue_head_t wait;
74
75 struct aa_labelset labels;
76 struct list_head rawdata_list;
71 77
72 struct dentry *dents[AAFS_NS_SIZEOF]; 78 struct dentry *dents[AAFS_NS_SIZEOF];
73}; 79};
@@ -76,6 +82,8 @@ extern struct aa_ns *root_ns;
76 82
77extern const char *aa_hidden_ns_name; 83extern const char *aa_hidden_ns_name;
78 84
85#define ns_unconfined(NS) (&(NS)->unconfined->label)
86
79bool aa_ns_visible(struct aa_ns *curr, struct aa_ns *view, bool subns); 87bool aa_ns_visible(struct aa_ns *curr, struct aa_ns *view, bool subns);
80const char *aa_ns_name(struct aa_ns *parent, struct aa_ns *child, bool subns); 88const char *aa_ns_name(struct aa_ns *parent, struct aa_ns *child, bool subns);
81void aa_free_ns(struct aa_ns *ns); 89void aa_free_ns(struct aa_ns *ns);
@@ -85,6 +93,8 @@ void aa_free_ns_kref(struct kref *kref);
85 93
86struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name); 94struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name);
87struct aa_ns *aa_findn_ns(struct aa_ns *root, const char *name, size_t n); 95struct aa_ns *aa_findn_ns(struct aa_ns *root, const char *name, size_t n);
96struct aa_ns *__aa_lookupn_ns(struct aa_ns *view, const char *hname, size_t n);
97struct aa_ns *aa_lookupn_ns(struct aa_ns *view, const char *name, size_t n);
88struct aa_ns *__aa_find_or_create_ns(struct aa_ns *parent, const char *name, 98struct aa_ns *__aa_find_or_create_ns(struct aa_ns *parent, const char *name,
89 struct dentry *dir); 99 struct dentry *dir);
90struct aa_ns *aa_prepare_ns(struct aa_ns *root, const char *name); 100struct aa_ns *aa_prepare_ns(struct aa_ns *root, const char *name);
@@ -144,4 +154,15 @@ static inline struct aa_ns *__aa_find_ns(struct list_head *head,
144 return __aa_findn_ns(head, name, strlen(name)); 154 return __aa_findn_ns(head, name, strlen(name));
145} 155}
146 156
157static inline struct aa_ns *__aa_lookup_ns(struct aa_ns *base,
158 const char *hname)
159{
160 return __aa_lookupn_ns(base, hname, strlen(hname));
161}
162
163static inline struct aa_ns *aa_lookup_ns(struct aa_ns *view, const char *name)
164{
165 return aa_lookupn_ns(view, name, strlen(name));
166}
167
147#endif /* AA_NAMESPACE_H */ 168#endif /* AA_NAMESPACE_H */
diff --git a/security/apparmor/include/policy_unpack.h b/security/apparmor/include/policy_unpack.h
index 4c1319eebc42..be6cd69ac319 100644
--- a/security/apparmor/include/policy_unpack.h
+++ b/security/apparmor/include/policy_unpack.h
@@ -17,6 +17,8 @@
17 17
18#include <linux/list.h> 18#include <linux/list.h>
19#include <linux/kref.h> 19#include <linux/kref.h>
20#include <linux/dcache.h>
21#include <linux/workqueue.h>
20 22
21struct aa_load_ent { 23struct aa_load_ent {
22 struct list_head list; 24 struct list_head list;
@@ -36,26 +38,84 @@ struct aa_load_ent *aa_load_ent_alloc(void);
36#define PACKED_MODE_KILL 2 38#define PACKED_MODE_KILL 2
37#define PACKED_MODE_UNCONFINED 3 39#define PACKED_MODE_UNCONFINED 3
38 40
39/* struct aa_loaddata - buffer of policy load data set */ 41struct aa_ns;
42
43enum {
44 AAFS_LOADDATA_ABI = 0,
45 AAFS_LOADDATA_REVISION,
46 AAFS_LOADDATA_HASH,
47 AAFS_LOADDATA_DATA,
48 AAFS_LOADDATA_DIR, /* must be last actual entry */
49 AAFS_LOADDATA_NDENTS /* count of entries */
50};
51
52/*
53 * struct aa_loaddata - buffer of policy raw_data set
54 *
55 * there is no loaddata ref for being on ns list, nor a ref from
56 * d_inode(@dentry) when grab a ref from these, @ns->lock must be held
57 * && __aa_get_loaddata() needs to be used, and the return value
58 * checked, if NULL the loaddata is already being reaped and should be
59 * considered dead.
60 */
40struct aa_loaddata { 61struct aa_loaddata {
41 struct kref count; 62 struct kref count;
63 struct list_head list;
64 struct work_struct work;
65 struct dentry *dents[AAFS_LOADDATA_NDENTS];
66 struct aa_ns *ns;
67 char *name;
42 size_t size; 68 size_t size;
69 long revision; /* the ns policy revision this caused */
43 int abi; 70 int abi;
44 unsigned char *hash; 71 unsigned char *hash;
72
45 char data[]; 73 char data[];
46}; 74};
47 75
48int aa_unpack(struct aa_loaddata *udata, struct list_head *lh, const char **ns); 76int aa_unpack(struct aa_loaddata *udata, struct list_head *lh, const char **ns);
49 77
78/**
79 * __aa_get_loaddata - get a reference count to uncounted data reference
80 * @data: reference to get a count on
81 *
82 * Returns: pointer to reference OR NULL if race is lost and reference is
83 * being repeated.
84 * Requires: @data->ns->lock held, and the return code MUST be checked
85 *
86 * Use only from inode->i_private and @data->list found references
87 */
88static inline struct aa_loaddata *
89__aa_get_loaddata(struct aa_loaddata *data)
90{
91 if (data && kref_get_unless_zero(&(data->count)))
92 return data;
93
94 return NULL;
95}
96
97/**
98 * aa_get_loaddata - get a reference count from a counted data reference
99 * @data: reference to get a count on
100 *
101 * Returns: point to reference
102 * Requires: @data to have a valid reference count on it. It is a bug
103 * if the race to reap can be encountered when it is used.
104 */
50static inline struct aa_loaddata * 105static inline struct aa_loaddata *
51aa_get_loaddata(struct aa_loaddata *data) 106aa_get_loaddata(struct aa_loaddata *data)
52{ 107{
53 if (data) 108 struct aa_loaddata *tmp = __aa_get_loaddata(data);
54 kref_get(&(data->count)); 109
55 return data; 110 AA_BUG(data && !tmp);
111
112 return tmp;
56} 113}
57 114
115void __aa_loaddata_update(struct aa_loaddata *data, long revision);
116bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r);
58void aa_loaddata_kref(struct kref *kref); 117void aa_loaddata_kref(struct kref *kref);
118struct aa_loaddata *aa_loaddata_alloc(size_t size);
59static inline void aa_put_loaddata(struct aa_loaddata *data) 119static inline void aa_put_loaddata(struct aa_loaddata *data)
60{ 120{
61 if (data) 121 if (data)
diff --git a/security/apparmor/include/procattr.h b/security/apparmor/include/procattr.h
index 6bd5f33d9533..c8fd99c9357d 100644
--- a/security/apparmor/include/procattr.h
+++ b/security/apparmor/include/procattr.h
@@ -15,11 +15,7 @@
15#ifndef __AA_PROCATTR_H 15#ifndef __AA_PROCATTR_H
16#define __AA_PROCATTR_H 16#define __AA_PROCATTR_H
17 17
18#define AA_DO_TEST 1 18int aa_getprocattr(struct aa_label *label, char **string);
19#define AA_ONEXEC 1 19int aa_setprocattr_changehat(char *args, size_t size, int flags);
20
21int aa_getprocattr(struct aa_profile *profile, char **string);
22int aa_setprocattr_changehat(char *args, size_t size, int test);
23int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test);
24 20
25#endif /* __AA_PROCATTR_H */ 21#endif /* __AA_PROCATTR_H */
diff --git a/security/apparmor/include/resource.h b/security/apparmor/include/resource.h
index d3f4cf027957..76f1586c9adb 100644
--- a/security/apparmor/include/resource.h
+++ b/security/apparmor/include/resource.h
@@ -34,13 +34,13 @@ struct aa_rlimit {
34 struct rlimit limits[RLIM_NLIMITS]; 34 struct rlimit limits[RLIM_NLIMITS];
35}; 35};
36 36
37extern struct aa_fs_entry aa_fs_entry_rlimit[]; 37extern struct aa_sfs_entry aa_sfs_entry_rlimit[];
38 38
39int aa_map_resource(int resource); 39int aa_map_resource(int resource);
40int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *, 40int aa_task_setrlimit(struct aa_label *label, struct task_struct *task,
41 unsigned int resource, struct rlimit *new_rlim); 41 unsigned int resource, struct rlimit *new_rlim);
42 42
43void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new); 43void __aa_transition_rlimits(struct aa_label *old, struct aa_label *new);
44 44
45static inline void aa_free_rlimit_rules(struct aa_rlimit *rlims) 45static inline void aa_free_rlimit_rules(struct aa_rlimit *rlims)
46{ 46{
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
index edac790923c3..11e66b5bbc42 100644
--- a/security/apparmor/ipc.c
+++ b/security/apparmor/ipc.c
@@ -4,7 +4,7 @@
4 * This file contains AppArmor ipc mediation 4 * This file contains AppArmor ipc mediation
5 * 5 *
6 * Copyright (C) 1998-2008 Novell/SUSE 6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2010 Canonical Ltd. 7 * Copyright 2009-2017 Canonical Ltd.
8 * 8 *
9 * This program is free software; you can redistribute it and/or 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 10 * modify it under the terms of the GNU General Public License as
@@ -21,87 +21,103 @@
21#include "include/policy.h" 21#include "include/policy.h"
22#include "include/ipc.h" 22#include "include/ipc.h"
23 23
24/**
25 * audit_ptrace_mask - convert mask to permission string
26 * @buffer: buffer to write string to (NOT NULL)
27 * @mask: permission mask to convert
28 */
29static void audit_ptrace_mask(struct audit_buffer *ab, u32 mask)
30{
31 switch (mask) {
32 case MAY_READ:
33 audit_log_string(ab, "read");
34 break;
35 case MAY_WRITE:
36 audit_log_string(ab, "trace");
37 break;
38 case AA_MAY_BE_READ:
39 audit_log_string(ab, "readby");
40 break;
41 case AA_MAY_BE_TRACED:
42 audit_log_string(ab, "tracedby");
43 break;
44 }
45}
46
24/* call back to audit ptrace fields */ 47/* call back to audit ptrace fields */
25static void audit_cb(struct audit_buffer *ab, void *va) 48static void audit_ptrace_cb(struct audit_buffer *ab, void *va)
26{ 49{
27 struct common_audit_data *sa = va; 50 struct common_audit_data *sa = va;
51
52 if (aad(sa)->request & AA_PTRACE_PERM_MASK) {
53 audit_log_format(ab, " requested_mask=");
54 audit_ptrace_mask(ab, aad(sa)->request);
55
56 if (aad(sa)->denied & AA_PTRACE_PERM_MASK) {
57 audit_log_format(ab, " denied_mask=");
58 audit_ptrace_mask(ab, aad(sa)->denied);
59 }
60 }
28 audit_log_format(ab, " peer="); 61 audit_log_format(ab, " peer=");
29 audit_log_untrustedstring(ab, aad(sa)->peer->base.hname); 62 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
63 FLAGS_NONE, GFP_ATOMIC);
30} 64}
31 65
32/** 66/* TODO: conditionals */
33 * aa_audit_ptrace - do auditing for ptrace 67static int profile_ptrace_perm(struct aa_profile *profile,
34 * @profile: profile being enforced (NOT NULL) 68 struct aa_profile *peer, u32 request,
35 * @target: profile being traced (NOT NULL) 69 struct common_audit_data *sa)
36 * @error: error condition
37 *
38 * Returns: %0 or error code
39 */
40static int aa_audit_ptrace(struct aa_profile *profile,
41 struct aa_profile *target, int error)
42{ 70{
43 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE); 71 struct aa_perms perms = { };
44 72
45 aad(&sa)->peer = target; 73 /* need because of peer in cross check */
46 aad(&sa)->error = error; 74 if (profile_unconfined(profile) ||
75 !PROFILE_MEDIATES(profile, AA_CLASS_PTRACE))
76 return 0;
47 77
48 return aa_audit(AUDIT_APPARMOR_AUTO, profile, &sa, audit_cb); 78 aad(sa)->peer = &peer->label;
79 aa_profile_match_label(profile, &peer->label, AA_CLASS_PTRACE, request,
80 &perms);
81 aa_apply_modes_to_perms(profile, &perms);
82 return aa_check_perms(profile, &perms, request, sa, audit_ptrace_cb);
49} 83}
50 84
51/** 85static int cross_ptrace_perm(struct aa_profile *tracer,
52 * aa_may_ptrace - test if tracer task can trace the tracee 86 struct aa_profile *tracee, u32 request,
53 * @tracer: profile of the task doing the tracing (NOT NULL) 87 struct common_audit_data *sa)
54 * @tracee: task to be traced
55 * @mode: whether PTRACE_MODE_READ || PTRACE_MODE_ATTACH
56 *
57 * Returns: %0 else error code if permission denied or error
58 */
59int aa_may_ptrace(struct aa_profile *tracer, struct aa_profile *tracee,
60 unsigned int mode)
61{ 88{
62 /* TODO: currently only based on capability, not extended ptrace 89 if (PROFILE_MEDIATES(tracer, AA_CLASS_PTRACE))
63 * rules, 90 return xcheck(profile_ptrace_perm(tracer, tracee, request, sa),
64 * Test mode for PTRACE_MODE_READ || PTRACE_MODE_ATTACH 91 profile_ptrace_perm(tracee, tracer,
65 */ 92 request << PTRACE_PERM_SHIFT,
66 93 sa));
67 if (unconfined(tracer) || tracer == tracee) 94 /* policy uses the old style capability check for ptrace */
95 if (profile_unconfined(tracer) || tracer == tracee)
68 return 0; 96 return 0;
69 /* log this capability request */ 97
70 return aa_capable(tracer, CAP_SYS_PTRACE, 1); 98 aad(sa)->label = &tracer->label;
99 aad(sa)->peer = &tracee->label;
100 aad(sa)->request = 0;
101 aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, 1);
102
103 return aa_audit(AUDIT_APPARMOR_AUTO, tracer, sa, audit_ptrace_cb);
71} 104}
72 105
73/** 106/**
74 * aa_ptrace - do ptrace permission check and auditing 107 * aa_may_ptrace - test if tracer task can trace the tracee
75 * @tracer: task doing the tracing (NOT NULL) 108 * @tracer: label of the task doing the tracing (NOT NULL)
76 * @tracee: task being traced (NOT NULL) 109 * @tracee: task label to be traced
77 * @mode: ptrace mode either PTRACE_MODE_READ || PTRACE_MODE_ATTACH 110 * @request: permission request
78 * 111 *
79 * Returns: %0 else error code if permission denied or error 112 * Returns: %0 else error code if permission denied or error
80 */ 113 */
81int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee, 114int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
82 unsigned int mode) 115 u32 request)
83{ 116{
84 /* 117 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE);
85 * tracer can ptrace tracee when
86 * - tracer is unconfined ||
87 * - tracer is in complain mode
88 * - tracer has rules allowing it to trace tracee currently this is:
89 * - confined by the same profile ||
90 * - tracer profile has CAP_SYS_PTRACE
91 */
92
93 struct aa_profile *tracer_p = aa_get_task_profile(tracer);
94 int error = 0;
95
96 if (!unconfined(tracer_p)) {
97 struct aa_profile *tracee_p = aa_get_task_profile(tracee);
98 118
99 error = aa_may_ptrace(tracer_p, tracee_p, mode); 119 return xcheck_labels_profiles(tracer, tracee, cross_ptrace_perm,
100 error = aa_audit_ptrace(tracer_p, tracee_p, error); 120 request, &sa);
121}
101 122
102 aa_put_profile(tracee_p);
103 }
104 aa_put_profile(tracer_p);
105 123
106 return error;
107}
diff --git a/security/apparmor/label.c b/security/apparmor/label.c
new file mode 100644
index 000000000000..e052eaba1cf6
--- /dev/null
+++ b/security/apparmor/label.c
@@ -0,0 +1,2120 @@
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor label 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#include <linux/audit.h>
15#include <linux/seq_file.h>
16#include <linux/sort.h>
17
18#include "include/apparmor.h"
19#include "include/context.h"
20#include "include/label.h"
21#include "include/policy.h"
22#include "include/secid.h"
23
24
25/*
26 * the aa_label represents the set of profiles confining an object
27 *
28 * Labels maintain a reference count to the set of pointers they reference
29 * Labels are ref counted by
30 * tasks and object via the security field/security context off the field
31 * code - will take a ref count on a label if it needs the label
32 * beyond what is possible with an rcu_read_lock.
33 * profiles - each profile is a label
34 * secids - a pinned secid will keep a refcount of the label it is
35 * referencing
36 * objects - inode, files, sockets, ...
37 *
38 * Labels are not ref counted by the label set, so they maybe removed and
39 * freed when no longer in use.
40 *
41 */
42
43#define PROXY_POISON 97
44#define LABEL_POISON 100
45
46static void free_proxy(struct aa_proxy *proxy)
47{
48 if (proxy) {
49 /* p->label will not updated any more as p is dead */
50 aa_put_label(rcu_dereference_protected(proxy->label, true));
51 memset(proxy, 0, sizeof(*proxy));
52 proxy->label = (struct aa_label *) PROXY_POISON;
53 kfree(proxy);
54 }
55}
56
57void aa_proxy_kref(struct kref *kref)
58{
59 struct aa_proxy *proxy = container_of(kref, struct aa_proxy, count);
60
61 free_proxy(proxy);
62}
63
64struct aa_proxy *aa_alloc_proxy(struct aa_label *label, gfp_t gfp)
65{
66 struct aa_proxy *new;
67
68 new = kzalloc(sizeof(struct aa_proxy), gfp);
69 if (new) {
70 kref_init(&new->count);
71 rcu_assign_pointer(new->label, aa_get_label(label));
72 }
73 return new;
74}
75
76/* requires profile list write lock held */
77void __aa_proxy_redirect(struct aa_label *orig, struct aa_label *new)
78{
79 struct aa_label *tmp;
80
81 AA_BUG(!orig);
82 AA_BUG(!new);
83 AA_BUG(!write_is_locked(&labels_set(orig)->lock));
84
85 tmp = rcu_dereference_protected(orig->proxy->label,
86 &labels_ns(orig)->lock);
87 rcu_assign_pointer(orig->proxy->label, aa_get_label(new));
88 orig->flags |= FLAG_STALE;
89 aa_put_label(tmp);
90}
91
92static void __proxy_share(struct aa_label *old, struct aa_label *new)
93{
94 struct aa_proxy *proxy = new->proxy;
95
96 new->proxy = aa_get_proxy(old->proxy);
97 __aa_proxy_redirect(old, new);
98 aa_put_proxy(proxy);
99}
100
101
102/**
103 * ns_cmp - compare ns for label set ordering
104 * @a: ns to compare (NOT NULL)
105 * @b: ns to compare (NOT NULL)
106 *
107 * Returns: <0 if a < b
108 * ==0 if a == b
109 * >0 if a > b
110 */
111static int ns_cmp(struct aa_ns *a, struct aa_ns *b)
112{
113 int res;
114
115 AA_BUG(!a);
116 AA_BUG(!b);
117 AA_BUG(!a->base.hname);
118 AA_BUG(!b->base.hname);
119
120 if (a == b)
121 return 0;
122
123 res = a->level - b->level;
124 if (res)
125 return res;
126
127 return strcmp(a->base.hname, b->base.hname);
128}
129
130/**
131 * profile_cmp - profile comparision for set ordering
132 * @a: profile to compare (NOT NULL)
133 * @b: profile to compare (NOT NULL)
134 *
135 * Returns: <0 if a < b
136 * ==0 if a == b
137 * >0 if a > b
138 */
139static int profile_cmp(struct aa_profile *a, struct aa_profile *b)
140{
141 int res;
142
143 AA_BUG(!a);
144 AA_BUG(!b);
145 AA_BUG(!a->ns);
146 AA_BUG(!b->ns);
147 AA_BUG(!a->base.hname);
148 AA_BUG(!b->base.hname);
149
150 if (a == b || a->base.hname == b->base.hname)
151 return 0;
152 res = ns_cmp(a->ns, b->ns);
153 if (res)
154 return res;
155
156 return strcmp(a->base.hname, b->base.hname);
157}
158
159/**
160 * vec_cmp - label comparision for set ordering
161 * @a: label to compare (NOT NULL)
162 * @vec: vector of profiles to compare (NOT NULL)
163 * @n: length of @vec
164 *
165 * Returns: <0 if a < vec
166 * ==0 if a == vec
167 * >0 if a > vec
168 */
169static int vec_cmp(struct aa_profile **a, int an, struct aa_profile **b, int bn)
170{
171 int i;
172
173 AA_BUG(!a);
174 AA_BUG(!*a);
175 AA_BUG(!b);
176 AA_BUG(!*b);
177 AA_BUG(an <= 0);
178 AA_BUG(bn <= 0);
179
180 for (i = 0; i < an && i < bn; i++) {
181 int res = profile_cmp(a[i], b[i]);
182
183 if (res != 0)
184 return res;
185 }
186
187 return an - bn;
188}
189
190static bool vec_is_stale(struct aa_profile **vec, int n)
191{
192 int i;
193
194 AA_BUG(!vec);
195
196 for (i = 0; i < n; i++) {
197 if (profile_is_stale(vec[i]))
198 return true;
199 }
200
201 return false;
202}
203
204static bool vec_unconfined(struct aa_profile **vec, int n)
205{
206 int i;
207
208 AA_BUG(!vec);
209
210 for (i = 0; i < n; i++) {
211 if (!profile_unconfined(vec[i]))
212 return false;
213 }
214
215 return true;
216}
217
218static int sort_cmp(const void *a, const void *b)
219{
220 return profile_cmp(*(struct aa_profile **)a, *(struct aa_profile **)b);
221}
222
223/*
224 * assumes vec is sorted
225 * Assumes @vec has null terminator at vec[n], and will null terminate
226 * vec[n - dups]
227 */
228static inline int unique(struct aa_profile **vec, int n)
229{
230 int i, pos, dups = 0;
231
232 AA_BUG(n < 1);
233 AA_BUG(!vec);
234
235 pos = 0;
236 for (i = 1; i < n; i++) {
237 int res = profile_cmp(vec[pos], vec[i]);
238
239 AA_BUG(res > 0, "vec not sorted");
240 if (res == 0) {
241 /* drop duplicate */
242 aa_put_profile(vec[i]);
243 dups++;
244 continue;
245 }
246 pos++;
247 if (dups)
248 vec[pos] = vec[i];
249 }
250
251 AA_BUG(dups < 0);
252
253 return dups;
254}
255
256/**
257 * aa_vec_unique - canonical sort and unique a list of profiles
258 * @n: number of refcounted profiles in the list (@n > 0)
259 * @vec: list of profiles to sort and merge
260 *
261 * Returns: the number of duplicates eliminated == references put
262 *
263 * If @flags & VEC_FLAG_TERMINATE @vec has null terminator at vec[n], and will
264 * null terminate vec[n - dups]
265 */
266int aa_vec_unique(struct aa_profile **vec, int n, int flags)
267{
268 int i, dups = 0;
269
270 AA_BUG(n < 1);
271 AA_BUG(!vec);
272
273 /* vecs are usually small and inorder, have a fallback for larger */
274 if (n > 8) {
275 sort(vec, n, sizeof(struct aa_profile *), sort_cmp, NULL);
276 dups = unique(vec, n);
277 goto out;
278 }
279
280 /* insertion sort + unique in one */
281 for (i = 1; i < n; i++) {
282 struct aa_profile *tmp = vec[i];
283 int pos, j;
284
285 for (pos = i - 1 - dups; pos >= 0; pos--) {
286 int res = profile_cmp(vec[pos], tmp);
287
288 if (res == 0) {
289 /* drop duplicate entry */
290 aa_put_profile(tmp);
291 dups++;
292 goto continue_outer;
293 } else if (res < 0)
294 break;
295 }
296 /* pos is at entry < tmp, or index -1. Set to insert pos */
297 pos++;
298
299 for (j = i - dups; j > pos; j--)
300 vec[j] = vec[j - 1];
301 vec[pos] = tmp;
302continue_outer:
303 ;
304 }
305
306 AA_BUG(dups < 0);
307
308out:
309 if (flags & VEC_FLAG_TERMINATE)
310 vec[n - dups] = NULL;
311
312 return dups;
313}
314
315
316static void label_destroy(struct aa_label *label)
317{
318 struct aa_label *tmp;
319
320 AA_BUG(!label);
321
322 if (!label_isprofile(label)) {
323 struct aa_profile *profile;
324 struct label_it i;
325
326 aa_put_str(label->hname);
327
328 label_for_each(i, label, profile) {
329 aa_put_profile(profile);
330 label->vec[i.i] = (struct aa_profile *)
331 (LABEL_POISON + (long) i.i);
332 }
333 }
334
335 if (rcu_dereference_protected(label->proxy->label, true) == label)
336 rcu_assign_pointer(label->proxy->label, NULL);
337
338 aa_free_secid(label->secid);
339
340 tmp = rcu_dereference_protected(label->proxy->label, true);
341 if (tmp == label)
342 rcu_assign_pointer(label->proxy->label, NULL);
343
344 aa_put_proxy(label->proxy);
345 label->proxy = (struct aa_proxy *) PROXY_POISON + 1;
346}
347
348void aa_label_free(struct aa_label *label)
349{
350 if (!label)
351 return;
352
353 label_destroy(label);
354 kfree(label);
355}
356
357static void label_free_switch(struct aa_label *label)
358{
359 if (label->flags & FLAG_NS_COUNT)
360 aa_free_ns(labels_ns(label));
361 else if (label_isprofile(label))
362 aa_free_profile(labels_profile(label));
363 else
364 aa_label_free(label);
365}
366
367static void label_free_rcu(struct rcu_head *head)
368{
369 struct aa_label *label = container_of(head, struct aa_label, rcu);
370
371 if (label->flags & FLAG_IN_TREE)
372 (void) aa_label_remove(label);
373 label_free_switch(label);
374}
375
376void aa_label_kref(struct kref *kref)
377{
378 struct aa_label *label = container_of(kref, struct aa_label, count);
379 struct aa_ns *ns = labels_ns(label);
380
381 if (!ns) {
382 /* never live, no rcu callback needed, just using the fn */
383 label_free_switch(label);
384 return;
385 }
386 /* TODO: update labels_profile macro so it works here */
387 AA_BUG(label_isprofile(label) &&
388 on_list_rcu(&label->vec[0]->base.profiles));
389 AA_BUG(label_isprofile(label) &&
390 on_list_rcu(&label->vec[0]->base.list));
391
392 /* TODO: if compound label and not stale add to reclaim cache */
393 call_rcu(&label->rcu, label_free_rcu);
394}
395
396static void label_free_or_put_new(struct aa_label *label, struct aa_label *new)
397{
398 if (label != new)
399 /* need to free directly to break circular ref with proxy */
400 aa_label_free(new);
401 else
402 aa_put_label(new);
403}
404
405bool aa_label_init(struct aa_label *label, int size)
406{
407 AA_BUG(!label);
408 AA_BUG(size < 1);
409
410 label->secid = aa_alloc_secid();
411 if (label->secid == AA_SECID_INVALID)
412 return false;
413
414 label->size = size; /* doesn't include null */
415 label->vec[size] = NULL; /* null terminate */
416 kref_init(&label->count);
417 RB_CLEAR_NODE(&label->node);
418
419 return true;
420}
421
422/**
423 * aa_label_alloc - allocate a label with a profile vector of @size length
424 * @size: size of profile vector in the label
425 * @proxy: proxy to use OR null if to allocate a new one
426 * @gfp: memory allocation type
427 *
428 * Returns: new label
429 * else NULL if failed
430 */
431struct aa_label *aa_label_alloc(int size, struct aa_proxy *proxy, gfp_t gfp)
432{
433 struct aa_label *new;
434
435 AA_BUG(size < 1);
436
437 /* + 1 for null terminator entry on vec */
438 new = kzalloc(sizeof(*new) + sizeof(struct aa_profile *) * (size + 1),
439 gfp);
440 AA_DEBUG("%s (%p)\n", __func__, new);
441 if (!new)
442 goto fail;
443
444 if (!aa_label_init(new, size))
445 goto fail;
446
447 if (!proxy) {
448 proxy = aa_alloc_proxy(new, gfp);
449 if (!proxy)
450 goto fail;
451 } else
452 aa_get_proxy(proxy);
453 /* just set new's proxy, don't redirect proxy here if it was passed in*/
454 new->proxy = proxy;
455
456 return new;
457
458fail:
459 kfree(new);
460
461 return NULL;
462}
463
464
465/**
466 * label_cmp - label comparision for set ordering
467 * @a: label to compare (NOT NULL)
468 * @b: label to compare (NOT NULL)
469 *
470 * Returns: <0 if a < b
471 * ==0 if a == b
472 * >0 if a > b
473 */
474static int label_cmp(struct aa_label *a, struct aa_label *b)
475{
476 AA_BUG(!b);
477
478 if (a == b)
479 return 0;
480
481 return vec_cmp(a->vec, a->size, b->vec, b->size);
482}
483
484/* helper fn for label_for_each_confined */
485int aa_label_next_confined(struct aa_label *label, int i)
486{
487 AA_BUG(!label);
488 AA_BUG(i < 0);
489
490 for (; i < label->size; i++) {
491 if (!profile_unconfined(label->vec[i]))
492 return i;
493 }
494
495 return i;
496}
497
498/**
499 * aa_label_next_not_in_set - return the next profile of @sub not in @set
500 * @I: label iterator
501 * @set: label to test against
502 * @sub: label to if is subset of @set
503 *
504 * Returns: profile in @sub that is not in @set, with iterator set pos after
505 * else NULL if @sub is a subset of @set
506 */
507struct aa_profile *__aa_label_next_not_in_set(struct label_it *I,
508 struct aa_label *set,
509 struct aa_label *sub)
510{
511 AA_BUG(!set);
512 AA_BUG(!I);
513 AA_BUG(I->i < 0);
514 AA_BUG(I->i > set->size);
515 AA_BUG(!sub);
516 AA_BUG(I->j < 0);
517 AA_BUG(I->j > sub->size);
518
519 while (I->j < sub->size && I->i < set->size) {
520 int res = profile_cmp(sub->vec[I->j], set->vec[I->i]);
521
522 if (res == 0) {
523 (I->j)++;
524 (I->i)++;
525 } else if (res > 0)
526 (I->i)++;
527 else
528 return sub->vec[(I->j)++];
529 }
530
531 if (I->j < sub->size)
532 return sub->vec[(I->j)++];
533
534 return NULL;
535}
536
537/**
538 * aa_label_is_subset - test if @sub is a subset of @set
539 * @set: label to test against
540 * @sub: label to test if is subset of @set
541 *
542 * Returns: true if @sub is subset of @set
543 * else false
544 */
545bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub)
546{
547 struct label_it i = { };
548
549 AA_BUG(!set);
550 AA_BUG(!sub);
551
552 if (sub == set)
553 return true;
554
555 return __aa_label_next_not_in_set(&i, set, sub) == NULL;
556}
557
558
559
560/**
561 * __label_remove - remove @label from the label set
562 * @l: label to remove
563 * @new: label to redirect to
564 *
565 * Requires: labels_set(@label)->lock write_lock
566 * Returns: true if the label was in the tree and removed
567 */
568static bool __label_remove(struct aa_label *label, struct aa_label *new)
569{
570 struct aa_labelset *ls = labels_set(label);
571
572 AA_BUG(!ls);
573 AA_BUG(!label);
574 AA_BUG(!write_is_locked(&ls->lock));
575
576 if (new)
577 __aa_proxy_redirect(label, new);
578
579 if (!label_is_stale(label))
580 __label_make_stale(label);
581
582 if (label->flags & FLAG_IN_TREE) {
583 rb_erase(&label->node, &ls->root);
584 label->flags &= ~FLAG_IN_TREE;
585 return true;
586 }
587
588 return false;
589}
590
591/**
592 * __label_replace - replace @old with @new in label set
593 * @old: label to remove from label set
594 * @new: label to replace @old with
595 *
596 * Requires: labels_set(@old)->lock write_lock
597 * valid ref count be held on @new
598 * Returns: true if @old was in set and replaced by @new
599 *
600 * Note: current implementation requires label set be order in such a way
601 * that @new directly replaces @old position in the set (ie.
602 * using pointer comparison of the label address would not work)
603 */
604static bool __label_replace(struct aa_label *old, struct aa_label *new)
605{
606 struct aa_labelset *ls = labels_set(old);
607
608 AA_BUG(!ls);
609 AA_BUG(!old);
610 AA_BUG(!new);
611 AA_BUG(!write_is_locked(&ls->lock));
612 AA_BUG(new->flags & FLAG_IN_TREE);
613
614 if (!label_is_stale(old))
615 __label_make_stale(old);
616
617 if (old->flags & FLAG_IN_TREE) {
618 rb_replace_node(&old->node, &new->node, &ls->root);
619 old->flags &= ~FLAG_IN_TREE;
620 new->flags |= FLAG_IN_TREE;
621 return true;
622 }
623
624 return false;
625}
626
627/**
628 * __label_insert - attempt to insert @l into a label set
629 * @ls: set of labels to insert @l into (NOT NULL)
630 * @label: new label to insert (NOT NULL)
631 * @replace: whether insertion should replace existing entry that is not stale
632 *
633 * Requires: @ls->lock
634 * caller to hold a valid ref on l
635 * if @replace is true l has a preallocated proxy associated
636 * Returns: @l if successful in inserting @l - with additional refcount
637 * else ref counted equivalent label that is already in the set,
638 * the else condition only happens if @replace is false
639 */
640static struct aa_label *__label_insert(struct aa_labelset *ls,
641 struct aa_label *label, bool replace)
642{
643 struct rb_node **new, *parent = NULL;
644
645 AA_BUG(!ls);
646 AA_BUG(!label);
647 AA_BUG(labels_set(label) != ls);
648 AA_BUG(!write_is_locked(&ls->lock));
649 AA_BUG(label->flags & FLAG_IN_TREE);
650
651 /* Figure out where to put new node */
652 new = &ls->root.rb_node;
653 while (*new) {
654 struct aa_label *this = rb_entry(*new, struct aa_label, node);
655 int result = label_cmp(label, this);
656
657 parent = *new;
658 if (result == 0) {
659 /* !__aa_get_label means queued for destruction,
660 * so replace in place, however the label has
661 * died before the replacement so do not share
662 * the proxy
663 */
664 if (!replace && !label_is_stale(this)) {
665 if (__aa_get_label(this))
666 return this;
667 } else
668 __proxy_share(this, label);
669 AA_BUG(!__label_replace(this, label));
670 return aa_get_label(label);
671 } else if (result < 0)
672 new = &((*new)->rb_left);
673 else /* (result > 0) */
674 new = &((*new)->rb_right);
675 }
676
677 /* Add new node and rebalance tree. */
678 rb_link_node(&label->node, parent, new);
679 rb_insert_color(&label->node, &ls->root);
680 label->flags |= FLAG_IN_TREE;
681
682 return aa_get_label(label);
683}
684
685/**
686 * __vec_find - find label that matches @vec in label set
687 * @vec: vec of profiles to find matching label for (NOT NULL)
688 * @n: length of @vec
689 *
690 * Requires: @vec_labelset(vec) lock held
691 * caller to hold a valid ref on l
692 *
693 * Returns: ref counted @label if matching label is in tree
694 * ref counted label that is equiv to @l in tree
695 * else NULL if @vec equiv is not in tree
696 */
697static struct aa_label *__vec_find(struct aa_profile **vec, int n)
698{
699 struct rb_node *node;
700
701 AA_BUG(!vec);
702 AA_BUG(!*vec);
703 AA_BUG(n <= 0);
704
705 node = vec_labelset(vec, n)->root.rb_node;
706 while (node) {
707 struct aa_label *this = rb_entry(node, struct aa_label, node);
708 int result = vec_cmp(this->vec, this->size, vec, n);
709
710 if (result > 0)
711 node = node->rb_left;
712 else if (result < 0)
713 node = node->rb_right;
714 else
715 return __aa_get_label(this);
716 }
717
718 return NULL;
719}
720
721/**
722 * __label_find - find label @label in label set
723 * @label: label to find (NOT NULL)
724 *
725 * Requires: labels_set(@label)->lock held
726 * caller to hold a valid ref on l
727 *
728 * Returns: ref counted @label if @label is in tree OR
729 * ref counted label that is equiv to @label in tree
730 * else NULL if @label or equiv is not in tree
731 */
732static struct aa_label *__label_find(struct aa_label *label)
733{
734 AA_BUG(!label);
735
736 return __vec_find(label->vec, label->size);
737}
738
739
740/**
741 * aa_label_remove - remove a label from the labelset
742 * @label: label to remove
743 *
744 * Returns: true if @label was removed from the tree
745 * else @label was not in tree so it could not be removed
746 */
747bool aa_label_remove(struct aa_label *label)
748{
749 struct aa_labelset *ls = labels_set(label);
750 unsigned long flags;
751 bool res;
752
753 AA_BUG(!ls);
754
755 write_lock_irqsave(&ls->lock, flags);
756 res = __label_remove(label, ns_unconfined(labels_ns(label)));
757 write_unlock_irqrestore(&ls->lock, flags);
758
759 return res;
760}
761
762/**
763 * aa_label_replace - replace a label @old with a new version @new
764 * @old: label to replace
765 * @new: label replacing @old
766 *
767 * Returns: true if @old was in tree and replaced
768 * else @old was not in tree, and @new was not inserted
769 */
770bool aa_label_replace(struct aa_label *old, struct aa_label *new)
771{
772 unsigned long flags;
773 bool res;
774
775 if (name_is_shared(old, new) && labels_ns(old) == labels_ns(new)) {
776 write_lock_irqsave(&labels_set(old)->lock, flags);
777 if (old->proxy != new->proxy)
778 __proxy_share(old, new);
779 else
780 __aa_proxy_redirect(old, new);
781 res = __label_replace(old, new);
782 write_unlock_irqrestore(&labels_set(old)->lock, flags);
783 } else {
784 struct aa_label *l;
785 struct aa_labelset *ls = labels_set(old);
786
787 write_lock_irqsave(&ls->lock, flags);
788 res = __label_remove(old, new);
789 if (labels_ns(old) != labels_ns(new)) {
790 write_unlock_irqrestore(&ls->lock, flags);
791 ls = labels_set(new);
792 write_lock_irqsave(&ls->lock, flags);
793 }
794 l = __label_insert(ls, new, true);
795 res = (l == new);
796 write_unlock_irqrestore(&ls->lock, flags);
797 aa_put_label(l);
798 }
799
800 return res;
801}
802
803/**
804 * vec_find - find label @l in label set
805 * @vec: array of profiles to find equiv label for (NOT NULL)
806 * @n: length of @vec
807 *
808 * Returns: refcounted label if @vec equiv is in tree
809 * else NULL if @vec equiv is not in tree
810 */
811static struct aa_label *vec_find(struct aa_profile **vec, int n)
812{
813 struct aa_labelset *ls;
814 struct aa_label *label;
815 unsigned long flags;
816
817 AA_BUG(!vec);
818 AA_BUG(!*vec);
819 AA_BUG(n <= 0);
820
821 ls = vec_labelset(vec, n);
822 read_lock_irqsave(&ls->lock, flags);
823 label = __vec_find(vec, n);
824 read_unlock_irqrestore(&ls->lock, flags);
825
826 return label;
827}
828
829/* requires sort and merge done first */
830static struct aa_label *vec_create_and_insert_label(struct aa_profile **vec,
831 int len, gfp_t gfp)
832{
833 struct aa_label *label = NULL;
834 struct aa_labelset *ls;
835 unsigned long flags;
836 struct aa_label *new;
837 int i;
838
839 AA_BUG(!vec);
840
841 if (len == 1)
842 return aa_get_label(&vec[0]->label);
843
844 ls = labels_set(&vec[len - 1]->label);
845
846 /* TODO: enable when read side is lockless
847 * check if label exists before taking locks
848 */
849 new = aa_label_alloc(len, NULL, gfp);
850 if (!new)
851 return NULL;
852
853 for (i = 0; i < len; i++)
854 new->vec[i] = aa_get_profile(vec[i]);
855
856 write_lock_irqsave(&ls->lock, flags);
857 label = __label_insert(ls, new, false);
858 write_unlock_irqrestore(&ls->lock, flags);
859 label_free_or_put_new(label, new);
860
861 return label;
862}
863
864struct aa_label *aa_vec_find_or_create_label(struct aa_profile **vec, int len,
865 gfp_t gfp)
866{
867 struct aa_label *label = vec_find(vec, len);
868
869 if (label)
870 return label;
871
872 return vec_create_and_insert_label(vec, len, gfp);
873}
874
875/**
876 * aa_label_find - find label @label in label set
877 * @label: label to find (NOT NULL)
878 *
879 * Requires: caller to hold a valid ref on l
880 *
881 * Returns: refcounted @label if @label is in tree
882 * refcounted label that is equiv to @label in tree
883 * else NULL if @label or equiv is not in tree
884 */
885struct aa_label *aa_label_find(struct aa_label *label)
886{
887 AA_BUG(!label);
888
889 return vec_find(label->vec, label->size);
890}
891
892
893/**
894 * aa_label_insert - insert label @label into @ls or return existing label
895 * @ls - labelset to insert @label into
896 * @label - label to insert
897 *
898 * Requires: caller to hold a valid ref on @label
899 *
900 * Returns: ref counted @label if successful in inserting @label
901 * else ref counted equivalent label that is already in the set
902 */
903struct aa_label *aa_label_insert(struct aa_labelset *ls, struct aa_label *label)
904{
905 struct aa_label *l;
906 unsigned long flags;
907
908 AA_BUG(!ls);
909 AA_BUG(!label);
910
911 /* check if label exists before taking lock */
912 if (!label_is_stale(label)) {
913 read_lock_irqsave(&ls->lock, flags);
914 l = __label_find(label);
915 read_unlock_irqrestore(&ls->lock, flags);
916 if (l)
917 return l;
918 }
919
920 write_lock_irqsave(&ls->lock, flags);
921 l = __label_insert(ls, label, false);
922 write_unlock_irqrestore(&ls->lock, flags);
923
924 return l;
925}
926
927
928/**
929 * aa_label_next_in_merge - find the next profile when merging @a and @b
930 * @I: label iterator
931 * @a: label to merge
932 * @b: label to merge
933 *
934 * Returns: next profile
935 * else null if no more profiles
936 */
937struct aa_profile *aa_label_next_in_merge(struct label_it *I,
938 struct aa_label *a,
939 struct aa_label *b)
940{
941 AA_BUG(!a);
942 AA_BUG(!b);
943 AA_BUG(!I);
944 AA_BUG(I->i < 0);
945 AA_BUG(I->i > a->size);
946 AA_BUG(I->j < 0);
947 AA_BUG(I->j > b->size);
948
949 if (I->i < a->size) {
950 if (I->j < b->size) {
951 int res = profile_cmp(a->vec[I->i], b->vec[I->j]);
952
953 if (res > 0)
954 return b->vec[(I->j)++];
955 if (res == 0)
956 (I->j)++;
957 }
958
959 return a->vec[(I->i)++];
960 }
961
962 if (I->j < b->size)
963 return b->vec[(I->j)++];
964
965 return NULL;
966}
967
968/**
969 * label_merge_cmp - cmp of @a merging with @b against @z for set ordering
970 * @a: label to merge then compare (NOT NULL)
971 * @b: label to merge then compare (NOT NULL)
972 * @z: label to compare merge against (NOT NULL)
973 *
974 * Assumes: using the most recent versions of @a, @b, and @z
975 *
976 * Returns: <0 if a < b
977 * ==0 if a == b
978 * >0 if a > b
979 */
980static int label_merge_cmp(struct aa_label *a, struct aa_label *b,
981 struct aa_label *z)
982{
983 struct aa_profile *p = NULL;
984 struct label_it i = { };
985 int k;
986
987 AA_BUG(!a);
988 AA_BUG(!b);
989 AA_BUG(!z);
990
991 for (k = 0;
992 k < z->size && (p = aa_label_next_in_merge(&i, a, b));
993 k++) {
994 int res = profile_cmp(p, z->vec[k]);
995
996 if (res != 0)
997 return res;
998 }
999
1000 if (p)
1001 return 1;
1002 else if (k < z->size)
1003 return -1;
1004 return 0;
1005}
1006
1007/**
1008 * label_merge_insert - create a new label by merging @a and @b
1009 * @new: preallocated label to merge into (NOT NULL)
1010 * @a: label to merge with @b (NOT NULL)
1011 * @b: label to merge with @a (NOT NULL)
1012 *
1013 * Requires: preallocated proxy
1014 *
1015 * Returns: ref counted label either @new if merge is unique
1016 * @a if @b is a subset of @a
1017 * @b if @a is a subset of @b
1018 *
1019 * NOTE: will not use @new if the merge results in @new == @a or @b
1020 *
1021 * Must be used within labelset write lock to avoid racing with
1022 * setting labels stale.
1023 */
1024static struct aa_label *label_merge_insert(struct aa_label *new,
1025 struct aa_label *a,
1026 struct aa_label *b)
1027{
1028 struct aa_label *label;
1029 struct aa_labelset *ls;
1030 struct aa_profile *next;
1031 struct label_it i;
1032 unsigned long flags;
1033 int k = 0, invcount = 0;
1034 bool stale = false;
1035
1036 AA_BUG(!a);
1037 AA_BUG(a->size < 0);
1038 AA_BUG(!b);
1039 AA_BUG(b->size < 0);
1040 AA_BUG(!new);
1041 AA_BUG(new->size < a->size + b->size);
1042
1043 label_for_each_in_merge(i, a, b, next) {
1044 AA_BUG(!next);
1045 if (profile_is_stale(next)) {
1046 new->vec[k] = aa_get_newest_profile(next);
1047 AA_BUG(!new->vec[k]->label.proxy);
1048 AA_BUG(!new->vec[k]->label.proxy->label);
1049 if (next->label.proxy != new->vec[k]->label.proxy)
1050 invcount++;
1051 k++;
1052 stale = true;
1053 } else
1054 new->vec[k++] = aa_get_profile(next);
1055 }
1056 /* set to actual size which is <= allocated len */
1057 new->size = k;
1058 new->vec[k] = NULL;
1059
1060 if (invcount) {
1061 new->size -= aa_vec_unique(&new->vec[0], new->size,
1062 VEC_FLAG_TERMINATE);
1063 /* TODO: deal with reference labels */
1064 if (new->size == 1) {
1065 label = aa_get_label(&new->vec[0]->label);
1066 return label;
1067 }
1068 } else if (!stale) {
1069 /*
1070 * merge could be same as a || b, note: it is not possible
1071 * for new->size == a->size == b->size unless a == b
1072 */
1073 if (k == a->size)
1074 return aa_get_label(a);
1075 else if (k == b->size)
1076 return aa_get_label(b);
1077 }
1078 if (vec_unconfined(new->vec, new->size))
1079 new->flags |= FLAG_UNCONFINED;
1080 ls = labels_set(new);
1081 write_lock_irqsave(&ls->lock, flags);
1082 label = __label_insert(labels_set(new), new, false);
1083 write_unlock_irqrestore(&ls->lock, flags);
1084
1085 return label;
1086}
1087
1088/**
1089 * labelset_of_merge - find which labelset a merged label should be inserted
1090 * @a: label to merge and insert
1091 * @b: label to merge and insert
1092 *
1093 * Returns: labelset that the merged label should be inserted into
1094 */
1095static struct aa_labelset *labelset_of_merge(struct aa_label *a,
1096 struct aa_label *b)
1097{
1098 struct aa_ns *nsa = labels_ns(a);
1099 struct aa_ns *nsb = labels_ns(b);
1100
1101 if (ns_cmp(nsa, nsb) <= 0)
1102 return &nsa->labels;
1103 return &nsb->labels;
1104}
1105
1106/**
1107 * __label_find_merge - find label that is equiv to merge of @a and @b
1108 * @ls: set of labels to search (NOT NULL)
1109 * @a: label to merge with @b (NOT NULL)
1110 * @b: label to merge with @a (NOT NULL)
1111 *
1112 * Requires: ls->lock read_lock held
1113 *
1114 * Returns: ref counted label that is equiv to merge of @a and @b
1115 * else NULL if merge of @a and @b is not in set
1116 */
1117static struct aa_label *__label_find_merge(struct aa_labelset *ls,
1118 struct aa_label *a,
1119 struct aa_label *b)
1120{
1121 struct rb_node *node;
1122
1123 AA_BUG(!ls);
1124 AA_BUG(!a);
1125 AA_BUG(!b);
1126
1127 if (a == b)
1128 return __label_find(a);
1129
1130 node = ls->root.rb_node;
1131 while (node) {
1132 struct aa_label *this = container_of(node, struct aa_label,
1133 node);
1134 int result = label_merge_cmp(a, b, this);
1135
1136 if (result < 0)
1137 node = node->rb_left;
1138 else if (result > 0)
1139 node = node->rb_right;
1140 else
1141 return __aa_get_label(this);
1142 }
1143
1144 return NULL;
1145}
1146
1147
1148/**
1149 * aa_label_find_merge - find label that is equiv to merge of @a and @b
1150 * @a: label to merge with @b (NOT NULL)
1151 * @b: label to merge with @a (NOT NULL)
1152 *
1153 * Requires: labels be fully constructed with a valid ns
1154 *
1155 * Returns: ref counted label that is equiv to merge of @a and @b
1156 * else NULL if merge of @a and @b is not in set
1157 */
1158struct aa_label *aa_label_find_merge(struct aa_label *a, struct aa_label *b)
1159{
1160 struct aa_labelset *ls;
1161 struct aa_label *label, *ar = NULL, *br = NULL;
1162 unsigned long flags;
1163
1164 AA_BUG(!a);
1165 AA_BUG(!b);
1166
1167 if (label_is_stale(a))
1168 a = ar = aa_get_newest_label(a);
1169 if (label_is_stale(b))
1170 b = br = aa_get_newest_label(b);
1171 ls = labelset_of_merge(a, b);
1172 read_lock_irqsave(&ls->lock, flags);
1173 label = __label_find_merge(ls, a, b);
1174 read_unlock_irqrestore(&ls->lock, flags);
1175 aa_put_label(ar);
1176 aa_put_label(br);
1177
1178 return label;
1179}
1180
1181/**
1182 * aa_label_merge - attempt to insert new merged label of @a and @b
1183 * @ls: set of labels to insert label into (NOT NULL)
1184 * @a: label to merge with @b (NOT NULL)
1185 * @b: label to merge with @a (NOT NULL)
1186 * @gfp: memory allocation type
1187 *
1188 * Requires: caller to hold valid refs on @a and @b
1189 * labels be fully constructed with a valid ns
1190 *
1191 * Returns: ref counted new label if successful in inserting merge of a & b
1192 * else ref counted equivalent label that is already in the set.
1193 * else NULL if could not create label (-ENOMEM)
1194 */
1195struct aa_label *aa_label_merge(struct aa_label *a, struct aa_label *b,
1196 gfp_t gfp)
1197{
1198 struct aa_label *label = NULL;
1199
1200 AA_BUG(!a);
1201 AA_BUG(!b);
1202
1203 if (a == b)
1204 return aa_get_newest_label(a);
1205
1206 /* TODO: enable when read side is lockless
1207 * check if label exists before taking locks
1208 if (!label_is_stale(a) && !label_is_stale(b))
1209 label = aa_label_find_merge(a, b);
1210 */
1211
1212 if (!label) {
1213 struct aa_label *new;
1214
1215 a = aa_get_newest_label(a);
1216 b = aa_get_newest_label(b);
1217
1218 /* could use label_merge_len(a, b), but requires double
1219 * comparison for small savings
1220 */
1221 new = aa_label_alloc(a->size + b->size, NULL, gfp);
1222 if (!new)
1223 goto out;
1224
1225 label = label_merge_insert(new, a, b);
1226 label_free_or_put_new(label, new);
1227out:
1228 aa_put_label(a);
1229 aa_put_label(b);
1230 }
1231
1232 return label;
1233}
1234
1235static inline bool label_is_visible(struct aa_profile *profile,
1236 struct aa_label *label)
1237{
1238 return aa_ns_visible(profile->ns, labels_ns(label), true);
1239}
1240
1241/* match a profile and its associated ns component if needed
1242 * Assumes visibility test has already been done.
1243 * If a subns profile is not to be matched should be prescreened with
1244 * visibility test.
1245 */
1246static inline unsigned int match_component(struct aa_profile *profile,
1247 struct aa_profile *tp,
1248 unsigned int state)
1249{
1250 const char *ns_name;
1251
1252 if (profile->ns == tp->ns)
1253 return aa_dfa_match(profile->policy.dfa, state, tp->base.hname);
1254
1255 /* try matching with namespace name and then profile */
1256 ns_name = aa_ns_name(profile->ns, tp->ns, true);
1257 state = aa_dfa_match_len(profile->policy.dfa, state, ":", 1);
1258 state = aa_dfa_match(profile->policy.dfa, state, ns_name);
1259 state = aa_dfa_match_len(profile->policy.dfa, state, ":", 1);
1260 return aa_dfa_match(profile->policy.dfa, state, tp->base.hname);
1261}
1262
1263/**
1264 * label_compound_match - find perms for full compound label
1265 * @profile: profile to find perms for
1266 * @label: label to check access permissions for
1267 * @start: state to start match in
1268 * @subns: whether to do permission checks on components in a subns
1269 * @request: permissions to request
1270 * @perms: perms struct to set
1271 *
1272 * Returns: 0 on success else ERROR
1273 *
1274 * For the label A//&B//&C this does the perm match for A//&B//&C
1275 * @perms should be preinitialized with allperms OR a previous permission
1276 * check to be stacked.
1277 */
1278static int label_compound_match(struct aa_profile *profile,
1279 struct aa_label *label,
1280 unsigned int state, bool subns, u32 request,
1281 struct aa_perms *perms)
1282{
1283 struct aa_profile *tp;
1284 struct label_it i;
1285
1286 /* find first subcomponent that is visible */
1287 label_for_each(i, label, tp) {
1288 if (!aa_ns_visible(profile->ns, tp->ns, subns))
1289 continue;
1290 state = match_component(profile, tp, state);
1291 if (!state)
1292 goto fail;
1293 goto next;
1294 }
1295
1296 /* no component visible */
1297 *perms = allperms;
1298 return 0;
1299
1300next:
1301 label_for_each_cont(i, label, tp) {
1302 if (!aa_ns_visible(profile->ns, tp->ns, subns))
1303 continue;
1304 state = aa_dfa_match(profile->policy.dfa, state, "//&");
1305 state = match_component(profile, tp, state);
1306 if (!state)
1307 goto fail;
1308 }
1309 aa_compute_perms(profile->policy.dfa, state, perms);
1310 aa_apply_modes_to_perms(profile, perms);
1311 if ((perms->allow & request) != request)
1312 return -EACCES;
1313
1314 return 0;
1315
1316fail:
1317 *perms = nullperms;
1318 return state;
1319}
1320
1321/**
1322 * label_components_match - find perms for all subcomponents of a label
1323 * @profile: profile to find perms for
1324 * @label: label to check access permissions for
1325 * @start: state to start match in
1326 * @subns: whether to do permission checks on components in a subns
1327 * @request: permissions to request
1328 * @perms: an initialized perms struct to add accumulation to
1329 *
1330 * Returns: 0 on success else ERROR
1331 *
1332 * For the label A//&B//&C this does the perm match for each of A and B and C
1333 * @perms should be preinitialized with allperms OR a previous permission
1334 * check to be stacked.
1335 */
1336static int label_components_match(struct aa_profile *profile,
1337 struct aa_label *label, unsigned int start,
1338 bool subns, u32 request,
1339 struct aa_perms *perms)
1340{
1341 struct aa_profile *tp;
1342 struct label_it i;
1343 struct aa_perms tmp;
1344 unsigned int state = 0;
1345
1346 /* find first subcomponent to test */
1347 label_for_each(i, label, tp) {
1348 if (!aa_ns_visible(profile->ns, tp->ns, subns))
1349 continue;
1350 state = match_component(profile, tp, start);
1351 if (!state)
1352 goto fail;
1353 goto next;
1354 }
1355
1356 /* no subcomponents visible - no change in perms */
1357 return 0;
1358
1359next:
1360 aa_compute_perms(profile->policy.dfa, state, &tmp);
1361 aa_apply_modes_to_perms(profile, &tmp);
1362 aa_perms_accum(perms, &tmp);
1363 label_for_each_cont(i, label, tp) {
1364 if (!aa_ns_visible(profile->ns, tp->ns, subns))
1365 continue;
1366 state = match_component(profile, tp, start);
1367 if (!state)
1368 goto fail;
1369 aa_compute_perms(profile->policy.dfa, state, &tmp);
1370 aa_apply_modes_to_perms(profile, &tmp);
1371 aa_perms_accum(perms, &tmp);
1372 }
1373
1374 if ((perms->allow & request) != request)
1375 return -EACCES;
1376
1377 return 0;
1378
1379fail:
1380 *perms = nullperms;
1381 return -EACCES;
1382}
1383
1384/**
1385 * aa_label_match - do a multi-component label match
1386 * @profile: profile to match against (NOT NULL)
1387 * @label: label to match (NOT NULL)
1388 * @state: state to start in
1389 * @subns: whether to match subns components
1390 * @request: permission request
1391 * @perms: Returns computed perms (NOT NULL)
1392 *
1393 * Returns: the state the match finished in, may be the none matching state
1394 */
1395int aa_label_match(struct aa_profile *profile, struct aa_label *label,
1396 unsigned int state, bool subns, u32 request,
1397 struct aa_perms *perms)
1398{
1399 int error = label_compound_match(profile, label, state, subns, request,
1400 perms);
1401 if (!error)
1402 return error;
1403
1404 *perms = allperms;
1405 return label_components_match(profile, label, state, subns, request,
1406 perms);
1407}
1408
1409
1410/**
1411 * aa_update_label_name - update a label to have a stored name
1412 * @ns: ns being viewed from (NOT NULL)
1413 * @label: label to update (NOT NULL)
1414 * @gfp: type of memory allocation
1415 *
1416 * Requires: labels_set(label) not locked in caller
1417 *
1418 * note: only updates the label name if it does not have a name already
1419 * and if it is in the labelset
1420 */
1421bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp)
1422{
1423 struct aa_labelset *ls;
1424 unsigned long flags;
1425 char __counted *name;
1426 bool res = false;
1427
1428 AA_BUG(!ns);
1429 AA_BUG(!label);
1430
1431 if (label->hname || labels_ns(label) != ns)
1432 return res;
1433
1434 if (aa_label_acntsxprint(&name, ns, label, FLAGS_NONE, gfp) == -1)
1435 return res;
1436
1437 ls = labels_set(label);
1438 write_lock_irqsave(&ls->lock, flags);
1439 if (!label->hname && label->flags & FLAG_IN_TREE) {
1440 label->hname = name;
1441 res = true;
1442 } else
1443 aa_put_str(name);
1444 write_unlock_irqrestore(&ls->lock, flags);
1445
1446 return res;
1447}
1448
1449/*
1450 * cached label name is present and visible
1451 * @label->hname only exists if label is namespace hierachical
1452 */
1453static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label)
1454{
1455 if (label->hname && labels_ns(label) == ns)
1456 return true;
1457
1458 return false;
1459}
1460
1461/* helper macro for snprint routines */
1462#define update_for_len(total, len, size, str) \
1463do { \
1464 AA_BUG(len < 0); \
1465 total += len; \
1466 len = min(len, size); \
1467 size -= len; \
1468 str += len; \
1469} while (0)
1470
1471/**
1472 * aa_profile_snxprint - print a profile name to a buffer
1473 * @str: buffer to write to. (MAY BE NULL if @size == 0)
1474 * @size: size of buffer
1475 * @view: namespace profile is being viewed from
1476 * @profile: profile to view (NOT NULL)
1477 * @flags: whether to include the mode string
1478 * @prev_ns: last ns printed when used in compound print
1479 *
1480 * Returns: size of name written or would be written if larger than
1481 * available buffer
1482 *
1483 * Note: will not print anything if the profile is not visible
1484 */
1485static int aa_profile_snxprint(char *str, size_t size, struct aa_ns *view,
1486 struct aa_profile *profile, int flags,
1487 struct aa_ns **prev_ns)
1488{
1489 const char *ns_name = NULL;
1490
1491 AA_BUG(!str && size != 0);
1492 AA_BUG(!profile);
1493
1494 if (!view)
1495 view = profiles_ns(profile);
1496
1497 if (view != profile->ns &&
1498 (!prev_ns || (prev_ns && *prev_ns != profile->ns))) {
1499 if (prev_ns)
1500 *prev_ns = profile->ns;
1501 ns_name = aa_ns_name(view, profile->ns,
1502 flags & FLAG_VIEW_SUBNS);
1503 if (ns_name == aa_hidden_ns_name) {
1504 if (flags & FLAG_HIDDEN_UNCONFINED)
1505 return snprintf(str, size, "%s", "unconfined");
1506 return snprintf(str, size, "%s", ns_name);
1507 }
1508 }
1509
1510 if ((flags & FLAG_SHOW_MODE) && profile != profile->ns->unconfined) {
1511 const char *modestr = aa_profile_mode_names[profile->mode];
1512
1513 if (ns_name)
1514 return snprintf(str, size, ":%s:%s (%s)", ns_name,
1515 profile->base.hname, modestr);
1516 return snprintf(str, size, "%s (%s)", profile->base.hname,
1517 modestr);
1518 }
1519
1520 if (ns_name)
1521 return snprintf(str, size, ":%s:%s", ns_name,
1522 profile->base.hname);
1523 return snprintf(str, size, "%s", profile->base.hname);
1524}
1525
1526static const char *label_modename(struct aa_ns *ns, struct aa_label *label,
1527 int flags)
1528{
1529 struct aa_profile *profile;
1530 struct label_it i;
1531 int mode = -1, count = 0;
1532
1533 label_for_each(i, label, profile) {
1534 if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) {
1535 if (profile->mode == APPARMOR_UNCONFINED)
1536 /* special case unconfined so stacks with
1537 * unconfined don't report as mixed. ie.
1538 * profile_foo//&:ns1:unconfined (mixed)
1539 */
1540 continue;
1541 count++;
1542 if (mode == -1)
1543 mode = profile->mode;
1544 else if (mode != profile->mode)
1545 return "mixed";
1546 }
1547 }
1548
1549 if (count == 0)
1550 return "-";
1551 if (mode == -1)
1552 /* everything was unconfined */
1553 mode = APPARMOR_UNCONFINED;
1554
1555 return aa_profile_mode_names[mode];
1556}
1557
1558/* if any visible label is not unconfined the display_mode returns true */
1559static inline bool display_mode(struct aa_ns *ns, struct aa_label *label,
1560 int flags)
1561{
1562 if ((flags & FLAG_SHOW_MODE)) {
1563 struct aa_profile *profile;
1564 struct label_it i;
1565
1566 label_for_each(i, label, profile) {
1567 if (aa_ns_visible(ns, profile->ns,
1568 flags & FLAG_VIEW_SUBNS) &&
1569 profile != profile->ns->unconfined)
1570 return true;
1571 }
1572 /* only ns->unconfined in set of profiles in ns */
1573 return false;
1574 }
1575
1576 return false;
1577}
1578
1579/**
1580 * aa_label_snxprint - print a label name to a string buffer
1581 * @str: buffer to write to. (MAY BE NULL if @size == 0)
1582 * @size: size of buffer
1583 * @ns: namespace profile is being viewed from
1584 * @label: label to view (NOT NULL)
1585 * @flags: whether to include the mode string
1586 *
1587 * Returns: size of name written or would be written if larger than
1588 * available buffer
1589 *
1590 * Note: labels do not have to be strictly hierarchical to the ns as
1591 * objects may be shared across different namespaces and thus
1592 * pickup labeling from each ns. If a particular part of the
1593 * label is not visible it will just be excluded. And if none
1594 * of the label is visible "---" will be used.
1595 */
1596int aa_label_snxprint(char *str, size_t size, struct aa_ns *ns,
1597 struct aa_label *label, int flags)
1598{
1599 struct aa_profile *profile;
1600 struct aa_ns *prev_ns = NULL;
1601 struct label_it i;
1602 int count = 0, total = 0;
1603 size_t len;
1604
1605 AA_BUG(!str && size != 0);
1606 AA_BUG(!label);
1607
1608 if (!ns)
1609 ns = labels_ns(label);
1610
1611 label_for_each(i, label, profile) {
1612 if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) {
1613 if (count > 0) {
1614 len = snprintf(str, size, "//&");
1615 update_for_len(total, len, size, str);
1616 }
1617 len = aa_profile_snxprint(str, size, ns, profile,
1618 flags & FLAG_VIEW_SUBNS,
1619 &prev_ns);
1620 update_for_len(total, len, size, str);
1621 count++;
1622 }
1623 }
1624
1625 if (count == 0) {
1626 if (flags & FLAG_HIDDEN_UNCONFINED)
1627 return snprintf(str, size, "%s", "unconfined");
1628 return snprintf(str, size, "%s", aa_hidden_ns_name);
1629 }
1630
1631 /* count == 1 && ... is for backwards compat where the mode
1632 * is not displayed for 'unconfined' in the current ns
1633 */
1634 if (display_mode(ns, label, flags)) {
1635 len = snprintf(str, size, " (%s)",
1636 label_modename(ns, label, flags));
1637 update_for_len(total, len, size, str);
1638 }
1639
1640 return total;
1641}
1642#undef update_for_len
1643
1644/**
1645 * aa_label_asxprint - allocate a string buffer and print label into it
1646 * @strp: Returns - the allocated buffer with the label name. (NOT NULL)
1647 * @ns: namespace profile is being viewed from
1648 * @label: label to view (NOT NULL)
1649 * @flags: flags controlling what label info is printed
1650 * @gfp: kernel memory allocation type
1651 *
1652 * Returns: size of name written or would be written if larger than
1653 * available buffer
1654 */
1655int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label,
1656 int flags, gfp_t gfp)
1657{
1658 int size;
1659
1660 AA_BUG(!strp);
1661 AA_BUG(!label);
1662
1663 size = aa_label_snxprint(NULL, 0, ns, label, flags);
1664 if (size < 0)
1665 return size;
1666
1667 *strp = kmalloc(size + 1, gfp);
1668 if (!*strp)
1669 return -ENOMEM;
1670 return aa_label_snxprint(*strp, size + 1, ns, label, flags);
1671}
1672
1673/**
1674 * aa_label_acntsxprint - allocate a __counted string buffer and print label
1675 * @strp: buffer to write to. (MAY BE NULL if @size == 0)
1676 * @ns: namespace profile is being viewed from
1677 * @label: label to view (NOT NULL)
1678 * @flags: flags controlling what label info is printed
1679 * @gfp: kernel memory allocation type
1680 *
1681 * Returns: size of name written or would be written if larger than
1682 * available buffer
1683 */
1684int aa_label_acntsxprint(char __counted **strp, struct aa_ns *ns,
1685 struct aa_label *label, int flags, gfp_t gfp)
1686{
1687 int size;
1688
1689 AA_BUG(!strp);
1690 AA_BUG(!label);
1691
1692 size = aa_label_snxprint(NULL, 0, ns, label, flags);
1693 if (size < 0)
1694 return size;
1695
1696 *strp = aa_str_alloc(size + 1, gfp);
1697 if (!*strp)
1698 return -ENOMEM;
1699 return aa_label_snxprint(*strp, size + 1, ns, label, flags);
1700}
1701
1702
1703void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns,
1704 struct aa_label *label, int flags, gfp_t gfp)
1705{
1706 const char *str;
1707 char *name = NULL;
1708 int len;
1709
1710 AA_BUG(!ab);
1711 AA_BUG(!label);
1712
1713 if (!ns)
1714 ns = labels_ns(label);
1715
1716 if (!use_label_hname(ns, label) || display_mode(ns, label, flags)) {
1717 len = aa_label_asxprint(&name, ns, label, flags, gfp);
1718 if (len == -1) {
1719 AA_DEBUG("label print error");
1720 return;
1721 }
1722 str = name;
1723 } else {
1724 str = (char *) label->hname;
1725 len = strlen(str);
1726 }
1727 if (audit_string_contains_control(str, len))
1728 audit_log_n_hex(ab, str, len);
1729 else
1730 audit_log_n_string(ab, str, len);
1731
1732 kfree(name);
1733}
1734
1735void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns,
1736 struct aa_label *label, int flags, gfp_t gfp)
1737{
1738 AA_BUG(!f);
1739 AA_BUG(!label);
1740
1741 if (!ns)
1742 ns = labels_ns(label);
1743
1744 if (!use_label_hname(ns, label)) {
1745 char *str;
1746 int len;
1747
1748 len = aa_label_asxprint(&str, ns, label, flags, gfp);
1749 if (len == -1) {
1750 AA_DEBUG("label print error");
1751 return;
1752 }
1753 seq_printf(f, "%s", str);
1754 kfree(str);
1755 } else if (display_mode(ns, label, flags))
1756 seq_printf(f, "%s (%s)", label->hname,
1757 label_modename(ns, label, flags));
1758 else
1759 seq_printf(f, "%s", label->hname);
1760}
1761
1762void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags,
1763 gfp_t gfp)
1764{
1765 AA_BUG(!label);
1766
1767 if (!ns)
1768 ns = labels_ns(label);
1769
1770 if (!use_label_hname(ns, label)) {
1771 char *str;
1772 int len;
1773
1774 len = aa_label_asxprint(&str, ns, label, flags, gfp);
1775 if (len == -1) {
1776 AA_DEBUG("label print error");
1777 return;
1778 }
1779 pr_info("%s", str);
1780 kfree(str);
1781 } else if (display_mode(ns, label, flags))
1782 pr_info("%s (%s)", label->hname,
1783 label_modename(ns, label, flags));
1784 else
1785 pr_info("%s", label->hname);
1786}
1787
1788void aa_label_audit(struct audit_buffer *ab, struct aa_label *label, gfp_t gfp)
1789{
1790 struct aa_ns *ns = aa_get_current_ns();
1791
1792 aa_label_xaudit(ab, ns, label, FLAG_VIEW_SUBNS, gfp);
1793 aa_put_ns(ns);
1794}
1795
1796void aa_label_seq_print(struct seq_file *f, struct aa_label *label, gfp_t gfp)
1797{
1798 struct aa_ns *ns = aa_get_current_ns();
1799
1800 aa_label_seq_xprint(f, ns, label, FLAG_VIEW_SUBNS, gfp);
1801 aa_put_ns(ns);
1802}
1803
1804void aa_label_printk(struct aa_label *label, gfp_t gfp)
1805{
1806 struct aa_ns *ns = aa_get_current_ns();
1807
1808 aa_label_xprintk(ns, label, FLAG_VIEW_SUBNS, gfp);
1809 aa_put_ns(ns);
1810}
1811
1812static int label_count_str_entries(const char *str)
1813{
1814 const char *split;
1815 int count = 1;
1816
1817 AA_BUG(!str);
1818
1819 for (split = strstr(str, "//&"); split; split = strstr(str, "//&")) {
1820 count++;
1821 str = split + 3;
1822 }
1823
1824 return count;
1825}
1826
1827/*
1828 * ensure stacks with components like
1829 * :ns:A//&B
1830 * have :ns: applied to both 'A' and 'B' by making the lookup relative
1831 * to the base if the lookup specifies an ns, else making the stacked lookup
1832 * relative to the last embedded ns in the string.
1833 */
1834static struct aa_profile *fqlookupn_profile(struct aa_label *base,
1835 struct aa_label *currentbase,
1836 const char *str, size_t n)
1837{
1838 const char *first = skipn_spaces(str, n);
1839
1840 if (first && *first == ':')
1841 return aa_fqlookupn_profile(base, str, n);
1842
1843 return aa_fqlookupn_profile(currentbase, str, n);
1844}
1845
1846/**
1847 * aa_label_parse - parse, validate and convert a text string to a label
1848 * @base: base label to use for lookups (NOT NULL)
1849 * @str: null terminated text string (NOT NULL)
1850 * @gfp: allocation type
1851 * @create: true if should create compound labels if they don't exist
1852 * @force_stack: true if should stack even if no leading &
1853 *
1854 * Returns: the matching refcounted label if present
1855 * else ERRPTR
1856 */
1857struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
1858 gfp_t gfp, bool create, bool force_stack)
1859{
1860 DEFINE_VEC(profile, vec);
1861 struct aa_label *label, *currbase = base;
1862 int i, len, stack = 0, error;
1863 char *split;
1864
1865 AA_BUG(!base);
1866 AA_BUG(!str);
1867
1868 str = skip_spaces(str);
1869 len = label_count_str_entries(str);
1870 if (*str == '&' || force_stack) {
1871 /* stack on top of base */
1872 stack = base->size;
1873 len += stack;
1874 if (*str == '&')
1875 str++;
1876 }
1877 error = vec_setup(profile, vec, len, gfp);
1878 if (error)
1879 return ERR_PTR(error);
1880
1881 for (i = 0; i < stack; i++)
1882 vec[i] = aa_get_profile(base->vec[i]);
1883
1884 for (split = strstr(str, "//&"), i = stack; split && i < len; i++) {
1885 vec[i] = fqlookupn_profile(base, currbase, str, split - str);
1886 if (!vec[i])
1887 goto fail;
1888 /*
1889 * if component specified a new ns it becomes the new base
1890 * so that subsequent lookups are relative to it
1891 */
1892 if (vec[i]->ns != labels_ns(currbase))
1893 currbase = &vec[i]->label;
1894 str = split + 3;
1895 split = strstr(str, "//&");
1896 }
1897 /* last element doesn't have a split */
1898 if (i < len) {
1899 vec[i] = fqlookupn_profile(base, currbase, str, strlen(str));
1900 if (!vec[i])
1901 goto fail;
1902 }
1903 if (len == 1)
1904 /* no need to free vec as len < LOCAL_VEC_ENTRIES */
1905 return &vec[0]->label;
1906
1907 len -= aa_vec_unique(vec, len, VEC_FLAG_TERMINATE);
1908 /* TODO: deal with reference labels */
1909 if (len == 1) {
1910 label = aa_get_label(&vec[0]->label);
1911 goto out;
1912 }
1913
1914 if (create)
1915 label = aa_vec_find_or_create_label(vec, len, gfp);
1916 else
1917 label = vec_find(vec, len);
1918 if (!label)
1919 goto fail;
1920
1921out:
1922 /* use adjusted len from after vec_unique, not original */
1923 vec_cleanup(profile, vec, len);
1924 return label;
1925
1926fail:
1927 label = ERR_PTR(-ENOENT);
1928 goto out;
1929}
1930
1931
1932/**
1933 * aa_labelset_destroy - remove all labels from the label set
1934 * @ls: label set to cleanup (NOT NULL)
1935 *
1936 * Labels that are removed from the set may still exist beyond the set
1937 * being destroyed depending on their reference counting
1938 */
1939void aa_labelset_destroy(struct aa_labelset *ls)
1940{
1941 struct rb_node *node;
1942 unsigned long flags;
1943
1944 AA_BUG(!ls);
1945
1946 write_lock_irqsave(&ls->lock, flags);
1947 for (node = rb_first(&ls->root); node; node = rb_first(&ls->root)) {
1948 struct aa_label *this = rb_entry(node, struct aa_label, node);
1949
1950 if (labels_ns(this) != root_ns)
1951 __label_remove(this,
1952 ns_unconfined(labels_ns(this)->parent));
1953 else
1954 __label_remove(this, NULL);
1955 }
1956 write_unlock_irqrestore(&ls->lock, flags);
1957}
1958
1959/*
1960 * @ls: labelset to init (NOT NULL)
1961 */
1962void aa_labelset_init(struct aa_labelset *ls)
1963{
1964 AA_BUG(!ls);
1965
1966 rwlock_init(&ls->lock);
1967 ls->root = RB_ROOT;
1968}
1969
1970static struct aa_label *labelset_next_stale(struct aa_labelset *ls)
1971{
1972 struct aa_label *label;
1973 struct rb_node *node;
1974 unsigned long flags;
1975
1976 AA_BUG(!ls);
1977
1978 read_lock_irqsave(&ls->lock, flags);
1979
1980 __labelset_for_each(ls, node) {
1981 label = rb_entry(node, struct aa_label, node);
1982 if ((label_is_stale(label) ||
1983 vec_is_stale(label->vec, label->size)) &&
1984 __aa_get_label(label))
1985 goto out;
1986
1987 }
1988 label = NULL;
1989
1990out:
1991 read_unlock_irqrestore(&ls->lock, flags);
1992
1993 return label;
1994}
1995
1996/**
1997 * __label_update - insert updated version of @label into labelset
1998 * @label - the label to update/repace
1999 *
2000 * Returns: new label that is up to date
2001 * else NULL on failure
2002 *
2003 * Requires: @ns lock be held
2004 *
2005 * Note: worst case is the stale @label does not get updated and has
2006 * to be updated at a later time.
2007 */
2008static struct aa_label *__label_update(struct aa_label *label)
2009{
2010 struct aa_label *new, *tmp;
2011 struct aa_labelset *ls;
2012 unsigned long flags;
2013 int i, invcount = 0;
2014
2015 AA_BUG(!label);
2016 AA_BUG(!mutex_is_locked(&labels_ns(label)->lock));
2017
2018 new = aa_label_alloc(label->size, label->proxy, GFP_KERNEL);
2019 if (!new)
2020 return NULL;
2021
2022 /*
2023 * while holding the ns_lock will stop profile replacement, removal,
2024 * and label updates, label merging and removal can be occurring
2025 */
2026 ls = labels_set(label);
2027 write_lock_irqsave(&ls->lock, flags);
2028 for (i = 0; i < label->size; i++) {
2029 AA_BUG(!label->vec[i]);
2030 new->vec[i] = aa_get_newest_profile(label->vec[i]);
2031 AA_BUG(!new->vec[i]);
2032 AA_BUG(!new->vec[i]->label.proxy);
2033 AA_BUG(!new->vec[i]->label.proxy->label);
2034 if (new->vec[i]->label.proxy != label->vec[i]->label.proxy)
2035 invcount++;
2036 }
2037
2038 /* updated stale label by being removed/renamed from labelset */
2039 if (invcount) {
2040 new->size -= aa_vec_unique(&new->vec[0], new->size,
2041 VEC_FLAG_TERMINATE);
2042 /* TODO: deal with reference labels */
2043 if (new->size == 1) {
2044 tmp = aa_get_label(&new->vec[0]->label);
2045 AA_BUG(tmp == label);
2046 goto remove;
2047 }
2048 if (labels_set(label) != labels_set(new)) {
2049 write_unlock_irqrestore(&ls->lock, flags);
2050 tmp = aa_label_insert(labels_set(new), new);
2051 write_lock_irqsave(&ls->lock, flags);
2052 goto remove;
2053 }
2054 } else
2055 AA_BUG(labels_ns(label) != labels_ns(new));
2056
2057 tmp = __label_insert(labels_set(label), new, true);
2058remove:
2059 /* ensure label is removed, and redirected correctly */
2060 __label_remove(label, tmp);
2061 write_unlock_irqrestore(&ls->lock, flags);
2062 label_free_or_put_new(tmp, new);
2063
2064 return tmp;
2065}
2066
2067/**
2068 * __labelset_update - update labels in @ns
2069 * @ns: namespace to update labels in (NOT NULL)
2070 *
2071 * Requires: @ns lock be held
2072 *
2073 * Walk the labelset ensuring that all labels are up to date and valid
2074 * Any label that has a stale component is marked stale and replaced and
2075 * by an updated version.
2076 *
2077 * If failures happen due to memory pressures then stale labels will
2078 * be left in place until the next pass.
2079 */
2080static void __labelset_update(struct aa_ns *ns)
2081{
2082 struct aa_label *label;
2083
2084 AA_BUG(!ns);
2085 AA_BUG(!mutex_is_locked(&ns->lock));
2086
2087 do {
2088 label = labelset_next_stale(&ns->labels);
2089 if (label) {
2090 struct aa_label *l = __label_update(label);
2091
2092 aa_put_label(l);
2093 aa_put_label(label);
2094 }
2095 } while (label);
2096}
2097
2098/**
2099 * __aa_labelset_udate_subtree - update all labels with a stale component
2100 * @ns: ns to start update at (NOT NULL)
2101 *
2102 * Requires: @ns lock be held
2103 *
2104 * Invalidates labels based on @p in @ns and any children namespaces.
2105 */
2106void __aa_labelset_update_subtree(struct aa_ns *ns)
2107{
2108 struct aa_ns *child;
2109
2110 AA_BUG(!ns);
2111 AA_BUG(!mutex_is_locked(&ns->lock));
2112
2113 __labelset_update(ns);
2114
2115 list_for_each_entry(child, &ns->sub_ns, base.list) {
2116 mutex_lock(&child->lock);
2117 __aa_labelset_update_subtree(child);
2118 mutex_unlock(&child->lock);
2119 }
2120}
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index 7cd788a9445b..08ca26bcca77 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -21,8 +21,14 @@
21#include "include/audit.h" 21#include "include/audit.h"
22#include "include/apparmor.h" 22#include "include/apparmor.h"
23#include "include/lib.h" 23#include "include/lib.h"
24#include "include/perms.h"
24#include "include/policy.h" 25#include "include/policy.h"
25 26
27struct aa_perms nullperms;
28struct aa_perms allperms = { .allow = ALL_PERMS_MASK,
29 .quiet = ALL_PERMS_MASK,
30 .hide = ALL_PERMS_MASK };
31
26/** 32/**
27 * aa_split_fqname - split a fqname into a profile and namespace name 33 * aa_split_fqname - split a fqname into a profile and namespace name
28 * @fqname: a full qualified name in namespace profile format (NOT NULL) 34 * @fqname: a full qualified name in namespace profile format (NOT NULL)
@@ -69,7 +75,7 @@ char *aa_split_fqname(char *fqname, char **ns_name)
69 * if all whitespace will return NULL 75 * if all whitespace will return NULL
70 */ 76 */
71 77
72static const char *skipn_spaces(const char *str, size_t n) 78const char *skipn_spaces(const char *str, size_t n)
73{ 79{
74 for (; n && isspace(*str); --n) 80 for (; n && isspace(*str); --n)
75 ++str; 81 ++str;
@@ -128,11 +134,350 @@ void aa_info_message(const char *str)
128 printk(KERN_INFO "AppArmor: %s\n", str); 134 printk(KERN_INFO "AppArmor: %s\n", str);
129} 135}
130 136
137__counted char *aa_str_alloc(int size, gfp_t gfp)
138{
139 struct counted_str *str;
140
141 str = kmalloc(sizeof(struct counted_str) + size, gfp);
142 if (!str)
143 return NULL;
144
145 kref_init(&str->count);
146 return str->name;
147}
148
149void aa_str_kref(struct kref *kref)
150{
151 kfree(container_of(kref, struct counted_str, count));
152}
153
154
155const char aa_file_perm_chrs[] = "xwracd km l ";
156const char *aa_file_perm_names[] = {
157 "exec",
158 "write",
159 "read",
160 "append",
161
162 "create",
163 "delete",
164 "open",
165 "rename",
166
167 "setattr",
168 "getattr",
169 "setcred",
170 "getcred",
171
172 "chmod",
173 "chown",
174 "chgrp",
175 "lock",
176
177 "mmap",
178 "mprot",
179 "link",
180 "snapshot",
181
182 "unknown",
183 "unknown",
184 "unknown",
185 "unknown",
186
187 "unknown",
188 "unknown",
189 "unknown",
190 "unknown",
191
192 "stack",
193 "change_onexec",
194 "change_profile",
195 "change_hat",
196};
197
198/**
199 * aa_perm_mask_to_str - convert a perm mask to its short string
200 * @str: character buffer to store string in (at least 10 characters)
201 * @mask: permission mask to convert
202 */
203void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask)
204{
205 unsigned int i, perm = 1;
206
207 for (i = 0; i < 32; perm <<= 1, i++) {
208 if (mask & perm)
209 *str++ = chrs[i];
210 }
211 *str = '\0';
212}
213
214void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask)
215{
216 const char *fmt = "%s";
217 unsigned int i, perm = 1;
218 bool prev = false;
219
220 for (i = 0; i < 32; perm <<= 1, i++) {
221 if (mask & perm) {
222 audit_log_format(ab, fmt, names[i]);
223 if (!prev) {
224 prev = true;
225 fmt = " %s";
226 }
227 }
228 }
229}
230
231void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
232 u32 chrsmask, const char **names, u32 namesmask)
233{
234 char str[33];
235
236 audit_log_format(ab, "\"");
237 if ((mask & chrsmask) && chrs) {
238 aa_perm_mask_to_str(str, chrs, mask & chrsmask);
239 mask &= ~chrsmask;
240 audit_log_format(ab, "%s", str);
241 if (mask & namesmask)
242 audit_log_format(ab, " ");
243 }
244 if ((mask & namesmask) && names)
245 aa_audit_perm_names(ab, names, mask & namesmask);
246 audit_log_format(ab, "\"");
247}
248
249/**
250 * aa_audit_perms_cb - generic callback fn for auditing perms
251 * @ab: audit buffer (NOT NULL)
252 * @va: audit struct to audit values of (NOT NULL)
253 */
254static void aa_audit_perms_cb(struct audit_buffer *ab, void *va)
255{
256 struct common_audit_data *sa = va;
257
258 if (aad(sa)->request) {
259 audit_log_format(ab, " requested_mask=");
260 aa_audit_perm_mask(ab, aad(sa)->request, aa_file_perm_chrs,
261 PERMS_CHRS_MASK, aa_file_perm_names,
262 PERMS_NAMES_MASK);
263 }
264 if (aad(sa)->denied) {
265 audit_log_format(ab, "denied_mask=");
266 aa_audit_perm_mask(ab, aad(sa)->denied, aa_file_perm_chrs,
267 PERMS_CHRS_MASK, aa_file_perm_names,
268 PERMS_NAMES_MASK);
269 }
270 audit_log_format(ab, " peer=");
271 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
272 FLAGS_NONE, GFP_ATOMIC);
273}
274
275/**
276 * aa_apply_modes_to_perms - apply namespace and profile flags to perms
277 * @profile: that perms where computed from
278 * @perms: perms to apply mode modifiers to
279 *
280 * TODO: split into profile and ns based flags for when accumulating perms
281 */
282void aa_apply_modes_to_perms(struct aa_profile *profile, struct aa_perms *perms)
283{
284 switch (AUDIT_MODE(profile)) {
285 case AUDIT_ALL:
286 perms->audit = ALL_PERMS_MASK;
287 /* fall through */
288 case AUDIT_NOQUIET:
289 perms->quiet = 0;
290 break;
291 case AUDIT_QUIET:
292 perms->audit = 0;
293 /* fall through */
294 case AUDIT_QUIET_DENIED:
295 perms->quiet = ALL_PERMS_MASK;
296 break;
297 }
298
299 if (KILL_MODE(profile))
300 perms->kill = ALL_PERMS_MASK;
301 else if (COMPLAIN_MODE(profile))
302 perms->complain = ALL_PERMS_MASK;
303/*
304 * TODO:
305 * else if (PROMPT_MODE(profile))
306 * perms->prompt = ALL_PERMS_MASK;
307 */
308}
309
310static u32 map_other(u32 x)
311{
312 return ((x & 0x3) << 8) | /* SETATTR/GETATTR */
313 ((x & 0x1c) << 18) | /* ACCEPT/BIND/LISTEN */
314 ((x & 0x60) << 19); /* SETOPT/GETOPT */
315}
316
317void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
318 struct aa_perms *perms)
319{
320 perms->deny = 0;
321 perms->kill = perms->stop = 0;
322 perms->complain = perms->cond = 0;
323 perms->hide = 0;
324 perms->prompt = 0;
325 perms->allow = dfa_user_allow(dfa, state);
326 perms->audit = dfa_user_audit(dfa, state);
327 perms->quiet = dfa_user_quiet(dfa, state);
328
329 /* for v5 perm mapping in the policydb, the other set is used
330 * to extend the general perm set
331 */
332 perms->allow |= map_other(dfa_other_allow(dfa, state));
333 perms->audit |= map_other(dfa_other_audit(dfa, state));
334 perms->quiet |= map_other(dfa_other_quiet(dfa, state));
335// perms->xindex = dfa_user_xindex(dfa, state);
336}
337
338/**
339 * aa_perms_accum_raw - accumulate perms with out masking off overlapping perms
340 * @accum - perms struct to accumulate into
341 * @addend - perms struct to add to @accum
342 */
343void aa_perms_accum_raw(struct aa_perms *accum, struct aa_perms *addend)
344{
345 accum->deny |= addend->deny;
346 accum->allow &= addend->allow & ~addend->deny;
347 accum->audit |= addend->audit & addend->allow;
348 accum->quiet &= addend->quiet & ~addend->allow;
349 accum->kill |= addend->kill & ~addend->allow;
350 accum->stop |= addend->stop & ~addend->allow;
351 accum->complain |= addend->complain & ~addend->allow & ~addend->deny;
352 accum->cond |= addend->cond & ~addend->allow & ~addend->deny;
353 accum->hide &= addend->hide & ~addend->allow;
354 accum->prompt |= addend->prompt & ~addend->allow & ~addend->deny;
355}
356
357/**
358 * aa_perms_accum - accumulate perms, masking off overlapping perms
359 * @accum - perms struct to accumulate into
360 * @addend - perms struct to add to @accum
361 */
362void aa_perms_accum(struct aa_perms *accum, struct aa_perms *addend)
363{
364 accum->deny |= addend->deny;
365 accum->allow &= addend->allow & ~accum->deny;
366 accum->audit |= addend->audit & accum->allow;
367 accum->quiet &= addend->quiet & ~accum->allow;
368 accum->kill |= addend->kill & ~accum->allow;
369 accum->stop |= addend->stop & ~accum->allow;
370 accum->complain |= addend->complain & ~accum->allow & ~accum->deny;
371 accum->cond |= addend->cond & ~accum->allow & ~accum->deny;
372 accum->hide &= addend->hide & ~accum->allow;
373 accum->prompt |= addend->prompt & ~accum->allow & ~accum->deny;
374}
375
376void aa_profile_match_label(struct aa_profile *profile, struct aa_label *label,
377 int type, u32 request, struct aa_perms *perms)
378{
379 /* TODO: doesn't yet handle extended types */
380 unsigned int state;
381
382 state = aa_dfa_next(profile->policy.dfa,
383 profile->policy.start[AA_CLASS_LABEL],
384 type);
385 aa_label_match(profile, label, state, false, request, perms);
386}
387
388
389/* currently unused */
390int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,
391 u32 request, int type, u32 *deny,
392 struct common_audit_data *sa)
393{
394 struct aa_perms perms;
395
396 aad(sa)->label = &profile->label;
397 aad(sa)->peer = &target->label;
398 aad(sa)->request = request;
399
400 aa_profile_match_label(profile, &target->label, type, request, &perms);
401 aa_apply_modes_to_perms(profile, &perms);
402 *deny |= request & perms.deny;
403 return aa_check_perms(profile, &perms, request, sa, aa_audit_perms_cb);
404}
405
406/**
407 * aa_check_perms - do audit mode selection based on perms set
408 * @profile: profile being checked
409 * @perms: perms computed for the request
410 * @request: requested perms
411 * @deny: Returns: explicit deny set
412 * @sa: initialized audit structure (MAY BE NULL if not auditing)
413 * @cb: callback fn for tpye specific fields (MAY BE NULL)
414 *
415 * Returns: 0 if permission else error code
416 *
417 * Note: profile audit modes need to be set before calling by setting the
418 * perm masks appropriately.
419 *
420 * If not auditing then complain mode is not enabled and the
421 * error code will indicate whether there was an explicit deny
422 * with a positive value.
423 */
424int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
425 u32 request, struct common_audit_data *sa,
426 void (*cb)(struct audit_buffer *, void *))
427{
428 int type, error;
429 bool stop = false;
430 u32 denied = request & (~perms->allow | perms->deny);
431
432 if (likely(!denied)) {
433 /* mask off perms that are not being force audited */
434 request &= perms->audit;
435 if (!request || !sa)
436 return 0;
437
438 type = AUDIT_APPARMOR_AUDIT;
439 error = 0;
440 } else {
441 error = -EACCES;
442
443 if (denied & perms->kill)
444 type = AUDIT_APPARMOR_KILL;
445 else if (denied == (denied & perms->complain))
446 type = AUDIT_APPARMOR_ALLOWED;
447 else
448 type = AUDIT_APPARMOR_DENIED;
449
450 if (denied & perms->stop)
451 stop = true;
452 if (denied == (denied & perms->hide))
453 error = -ENOENT;
454
455 denied &= ~perms->quiet;
456 if (!sa || !denied)
457 return error;
458 }
459
460 if (sa) {
461 aad(sa)->label = &profile->label;
462 aad(sa)->request = request;
463 aad(sa)->denied = denied;
464 aad(sa)->error = error;
465 aa_audit_msg(type, sa, cb);
466 }
467
468 if (type == AUDIT_APPARMOR_ALLOWED)
469 error = 0;
470
471 return error;
472}
473
474
131/** 475/**
132 * aa_policy_init - initialize a policy structure 476 * aa_policy_init - initialize a policy structure
133 * @policy: policy to initialize (NOT NULL) 477 * @policy: policy to initialize (NOT NULL)
134 * @prefix: prefix name if any is required. (MAYBE NULL) 478 * @prefix: prefix name if any is required. (MAYBE NULL)
135 * @name: name of the policy, init will make a copy of it (NOT NULL) 479 * @name: name of the policy, init will make a copy of it (NOT NULL)
480 * @gfp: allocation mode
136 * 481 *
137 * Note: this fn creates a copy of strings passed in 482 * Note: this fn creates a copy of strings passed in
138 * 483 *
@@ -141,16 +486,21 @@ void aa_info_message(const char *str)
141bool aa_policy_init(struct aa_policy *policy, const char *prefix, 486bool aa_policy_init(struct aa_policy *policy, const char *prefix,
142 const char *name, gfp_t gfp) 487 const char *name, gfp_t gfp)
143{ 488{
489 char *hname;
490
144 /* freed by policy_free */ 491 /* freed by policy_free */
145 if (prefix) { 492 if (prefix) {
146 policy->hname = kmalloc(strlen(prefix) + strlen(name) + 3, 493 hname = aa_str_alloc(strlen(prefix) + strlen(name) + 3, gfp);
147 gfp); 494 if (hname)
148 if (policy->hname) 495 sprintf(hname, "%s//%s", prefix, name);
149 sprintf((char *)policy->hname, "%s//%s", prefix, name); 496 } else {
150 } else 497 hname = aa_str_alloc(strlen(name) + 1, gfp);
151 policy->hname = kstrdup(name, gfp); 498 if (hname)
152 if (!policy->hname) 499 strcpy(hname, name);
500 }
501 if (!hname)
153 return false; 502 return false;
503 policy->hname = hname;
154 /* base.name is a substring of fqname */ 504 /* base.name is a substring of fqname */
155 policy->name = basename(policy->hname); 505 policy->name = basename(policy->hname);
156 INIT_LIST_HEAD(&policy->list); 506 INIT_LIST_HEAD(&policy->list);
@@ -169,5 +519,5 @@ void aa_policy_destroy(struct aa_policy *policy)
169 AA_BUG(on_list_rcu(&policy->list)); 519 AA_BUG(on_list_rcu(&policy->list));
170 520
171 /* don't free name as its a subset of hname */ 521 /* don't free name as its a subset of hname */
172 kzfree(policy->hname); 522 aa_put_str(policy->hname);
173} 523}
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 8f3c0f7aca5a..867bcd154c7e 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -34,6 +34,7 @@
34#include "include/file.h" 34#include "include/file.h"
35#include "include/ipc.h" 35#include "include/ipc.h"
36#include "include/path.h" 36#include "include/path.h"
37#include "include/label.h"
37#include "include/policy.h" 38#include "include/policy.h"
38#include "include/policy_ns.h" 39#include "include/policy_ns.h"
39#include "include/procattr.h" 40#include "include/procattr.h"
@@ -49,7 +50,7 @@ DEFINE_PER_CPU(struct aa_buffers, aa_buffers);
49 */ 50 */
50 51
51/* 52/*
52 * free the associated aa_task_ctx and put its profiles 53 * free the associated aa_task_ctx and put its labels
53 */ 54 */
54static void apparmor_cred_free(struct cred *cred) 55static void apparmor_cred_free(struct cred *cred)
55{ 56{
@@ -103,34 +104,63 @@ static void apparmor_cred_transfer(struct cred *new, const struct cred *old)
103static int apparmor_ptrace_access_check(struct task_struct *child, 104static int apparmor_ptrace_access_check(struct task_struct *child,
104 unsigned int mode) 105 unsigned int mode)
105{ 106{
106 return aa_ptrace(current, child, mode); 107 struct aa_label *tracer, *tracee;
108 int error;
109
110 tracer = begin_current_label_crit_section();
111 tracee = aa_get_task_label(child);
112 error = aa_may_ptrace(tracer, tracee,
113 mode == PTRACE_MODE_READ ? AA_PTRACE_READ : AA_PTRACE_TRACE);
114 aa_put_label(tracee);
115 end_current_label_crit_section(tracer);
116
117 return error;
107} 118}
108 119
109static int apparmor_ptrace_traceme(struct task_struct *parent) 120static int apparmor_ptrace_traceme(struct task_struct *parent)
110{ 121{
111 return aa_ptrace(parent, current, PTRACE_MODE_ATTACH); 122 struct aa_label *tracer, *tracee;
123 int error;
124
125 tracee = begin_current_label_crit_section();
126 tracer = aa_get_task_label(parent);
127 error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE);
128 aa_put_label(tracer);
129 end_current_label_crit_section(tracee);
130
131 return error;
112} 132}
113 133
114/* Derived from security/commoncap.c:cap_capget */ 134/* Derived from security/commoncap.c:cap_capget */
115static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective, 135static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
116 kernel_cap_t *inheritable, kernel_cap_t *permitted) 136 kernel_cap_t *inheritable, kernel_cap_t *permitted)
117{ 137{
118 struct aa_profile *profile; 138 struct aa_label *label;
119 const struct cred *cred; 139 const struct cred *cred;
120 140
121 rcu_read_lock(); 141 rcu_read_lock();
122 cred = __task_cred(target); 142 cred = __task_cred(target);
123 profile = aa_cred_profile(cred); 143 label = aa_get_newest_cred_label(cred);
124 144
125 /* 145 /*
126 * cap_capget is stacked ahead of this and will 146 * cap_capget is stacked ahead of this and will
127 * initialize effective and permitted. 147 * initialize effective and permitted.
128 */ 148 */
129 if (!unconfined(profile) && !COMPLAIN_MODE(profile)) { 149 if (!unconfined(label)) {
130 *effective = cap_intersect(*effective, profile->caps.allow); 150 struct aa_profile *profile;
131 *permitted = cap_intersect(*permitted, profile->caps.allow); 151 struct label_it i;
152
153 label_for_each_confined(i, label, profile) {
154 if (COMPLAIN_MODE(profile))
155 continue;
156 *effective = cap_intersect(*effective,
157 profile->caps.allow);
158 *permitted = cap_intersect(*permitted,
159 profile->caps.allow);
160 }
132 } 161 }
133 rcu_read_unlock(); 162 rcu_read_unlock();
163 aa_put_label(label);
134 164
135 return 0; 165 return 0;
136} 166}
@@ -138,12 +168,14 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
138static int apparmor_capable(const struct cred *cred, struct user_namespace *ns, 168static int apparmor_capable(const struct cred *cred, struct user_namespace *ns,
139 int cap, int audit) 169 int cap, int audit)
140{ 170{
141 struct aa_profile *profile; 171 struct aa_label *label;
142 int error = 0; 172 int error = 0;
143 173
144 profile = aa_cred_profile(cred); 174 label = aa_get_newest_cred_label(cred);
145 if (!unconfined(profile)) 175 if (!unconfined(label))
146 error = aa_capable(profile, cap, audit); 176 error = aa_capable(label, cap, audit);
177 aa_put_label(label);
178
147 return error; 179 return error;
148} 180}
149 181
@@ -159,12 +191,13 @@ static int apparmor_capable(const struct cred *cred, struct user_namespace *ns,
159static int common_perm(const char *op, const struct path *path, u32 mask, 191static int common_perm(const char *op, const struct path *path, u32 mask,
160 struct path_cond *cond) 192 struct path_cond *cond)
161{ 193{
162 struct aa_profile *profile; 194 struct aa_label *label;
163 int error = 0; 195 int error = 0;
164 196
165 profile = __aa_current_profile(); 197 label = __begin_current_label_crit_section();
166 if (!unconfined(profile)) 198 if (!unconfined(label))
167 error = aa_path_perm(op, profile, path, 0, mask, cond); 199 error = aa_path_perm(op, label, path, 0, mask, cond);
200 __end_current_label_crit_section(label);
168 201
169 return error; 202 return error;
170} 203}
@@ -278,7 +311,7 @@ static int apparmor_path_mknod(const struct path *dir, struct dentry *dentry,
278 311
279static int apparmor_path_truncate(const struct path *path) 312static int apparmor_path_truncate(const struct path *path)
280{ 313{
281 return common_perm_cond(OP_TRUNC, path, MAY_WRITE | AA_MAY_META_WRITE); 314 return common_perm_cond(OP_TRUNC, path, MAY_WRITE | AA_MAY_SETATTR);
282} 315}
283 316
284static int apparmor_path_symlink(const struct path *dir, struct dentry *dentry, 317static int apparmor_path_symlink(const struct path *dir, struct dentry *dentry,
@@ -291,29 +324,31 @@ static int apparmor_path_symlink(const struct path *dir, struct dentry *dentry,
291static int apparmor_path_link(struct dentry *old_dentry, const struct path *new_dir, 324static int apparmor_path_link(struct dentry *old_dentry, const struct path *new_dir,
292 struct dentry *new_dentry) 325 struct dentry *new_dentry)
293{ 326{
294 struct aa_profile *profile; 327 struct aa_label *label;
295 int error = 0; 328 int error = 0;
296 329
297 if (!path_mediated_fs(old_dentry)) 330 if (!path_mediated_fs(old_dentry))
298 return 0; 331 return 0;
299 332
300 profile = aa_current_profile(); 333 label = begin_current_label_crit_section();
301 if (!unconfined(profile)) 334 if (!unconfined(label))
302 error = aa_path_link(profile, old_dentry, new_dir, new_dentry); 335 error = aa_path_link(label, old_dentry, new_dir, new_dentry);
336 end_current_label_crit_section(label);
337
303 return error; 338 return error;
304} 339}
305 340
306static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_dentry, 341static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_dentry,
307 const struct path *new_dir, struct dentry *new_dentry) 342 const struct path *new_dir, struct dentry *new_dentry)
308{ 343{
309 struct aa_profile *profile; 344 struct aa_label *label;
310 int error = 0; 345 int error = 0;
311 346
312 if (!path_mediated_fs(old_dentry)) 347 if (!path_mediated_fs(old_dentry))
313 return 0; 348 return 0;
314 349
315 profile = aa_current_profile(); 350 label = begin_current_label_crit_section();
316 if (!unconfined(profile)) { 351 if (!unconfined(label)) {
317 struct path old_path = { .mnt = old_dir->mnt, 352 struct path old_path = { .mnt = old_dir->mnt,
318 .dentry = old_dentry }; 353 .dentry = old_dentry };
319 struct path new_path = { .mnt = new_dir->mnt, 354 struct path new_path = { .mnt = new_dir->mnt,
@@ -322,16 +357,18 @@ static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_d
322 d_backing_inode(old_dentry)->i_mode 357 d_backing_inode(old_dentry)->i_mode
323 }; 358 };
324 359
325 error = aa_path_perm(OP_RENAME_SRC, profile, &old_path, 0, 360 error = aa_path_perm(OP_RENAME_SRC, label, &old_path, 0,
326 MAY_READ | AA_MAY_META_READ | MAY_WRITE | 361 MAY_READ | AA_MAY_GETATTR | MAY_WRITE |
327 AA_MAY_META_WRITE | AA_MAY_DELETE, 362 AA_MAY_SETATTR | AA_MAY_DELETE,
328 &cond); 363 &cond);
329 if (!error) 364 if (!error)
330 error = aa_path_perm(OP_RENAME_DEST, profile, &new_path, 365 error = aa_path_perm(OP_RENAME_DEST, label, &new_path,
331 0, MAY_WRITE | AA_MAY_META_WRITE | 366 0, MAY_WRITE | AA_MAY_SETATTR |
332 AA_MAY_CREATE, &cond); 367 AA_MAY_CREATE, &cond);
333 368
334 } 369 }
370 end_current_label_crit_section(label);
371
335 return error; 372 return error;
336} 373}
337 374
@@ -347,13 +384,13 @@ static int apparmor_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
347 384
348static int apparmor_inode_getattr(const struct path *path) 385static int apparmor_inode_getattr(const struct path *path)
349{ 386{
350 return common_perm_cond(OP_GETATTR, path, AA_MAY_META_READ); 387 return common_perm_cond(OP_GETATTR, path, AA_MAY_GETATTR);
351} 388}
352 389
353static int apparmor_file_open(struct file *file, const struct cred *cred) 390static int apparmor_file_open(struct file *file, const struct cred *cred)
354{ 391{
355 struct aa_file_ctx *fctx = file->f_security; 392 struct aa_file_ctx *fctx = file_ctx(file);
356 struct aa_profile *profile; 393 struct aa_label *label;
357 int error = 0; 394 int error = 0;
358 395
359 if (!path_mediated_fs(file->f_path.dentry)) 396 if (!path_mediated_fs(file->f_path.dentry))
@@ -369,65 +406,61 @@ static int apparmor_file_open(struct file *file, const struct cred *cred)
369 return 0; 406 return 0;
370 } 407 }
371 408
372 profile = aa_cred_profile(cred); 409 label = aa_get_newest_cred_label(cred);
373 if (!unconfined(profile)) { 410 if (!unconfined(label)) {
374 struct inode *inode = file_inode(file); 411 struct inode *inode = file_inode(file);
375 struct path_cond cond = { inode->i_uid, inode->i_mode }; 412 struct path_cond cond = { inode->i_uid, inode->i_mode };
376 413
377 error = aa_path_perm(OP_OPEN, profile, &file->f_path, 0, 414 error = aa_path_perm(OP_OPEN, label, &file->f_path, 0,
378 aa_map_file_to_perms(file), &cond); 415 aa_map_file_to_perms(file), &cond);
379 /* todo cache full allowed permissions set and state */ 416 /* todo cache full allowed permissions set and state */
380 fctx->allow = aa_map_file_to_perms(file); 417 fctx->allow = aa_map_file_to_perms(file);
381 } 418 }
419 aa_put_label(label);
382 420
383 return error; 421 return error;
384} 422}
385 423
386static int apparmor_file_alloc_security(struct file *file) 424static int apparmor_file_alloc_security(struct file *file)
387{ 425{
426 int error = 0;
427
388 /* freed by apparmor_file_free_security */ 428 /* freed by apparmor_file_free_security */
389 file->f_security = aa_alloc_file_context(GFP_KERNEL); 429 struct aa_label *label = begin_current_label_crit_section();
390 if (!file->f_security) 430 file->f_security = aa_alloc_file_ctx(label, GFP_KERNEL);
391 return -ENOMEM; 431 if (!file_ctx(file))
392 return 0; 432 error = -ENOMEM;
433 end_current_label_crit_section(label);
393 434
435 return error;
394} 436}
395 437
396static void apparmor_file_free_security(struct file *file) 438static void apparmor_file_free_security(struct file *file)
397{ 439{
398 struct aa_file_ctx *ctx = file->f_security; 440 aa_free_file_ctx(file_ctx(file));
399
400 aa_free_file_context(ctx);
401} 441}
402 442
403static int common_file_perm(const char *op, struct file *file, u32 mask) 443static int common_file_perm(const char *op, struct file *file, u32 mask)
404{ 444{
405 struct aa_file_ctx *fctx = file->f_security; 445 struct aa_label *label;
406 struct aa_profile *profile, *fprofile = aa_cred_profile(file->f_cred);
407 int error = 0; 446 int error = 0;
408 447
409 AA_BUG(!fprofile); 448 /* don't reaudit files closed during inheritance */
449 if (file->f_path.dentry == aa_null.dentry)
450 return -EACCES;
410 451
411 if (!file->f_path.mnt || 452 label = __begin_current_label_crit_section();
412 !path_mediated_fs(file->f_path.dentry)) 453 error = aa_file_perm(op, label, file, mask);
413 return 0; 454 __end_current_label_crit_section(label);
414
415 profile = __aa_current_profile();
416
417 /* revalidate access, if task is unconfined, or the cached cred
418 * doesn't match or if the request is for more permissions than
419 * was granted.
420 *
421 * Note: the test for !unconfined(fprofile) is to handle file
422 * delegation from unconfined tasks
423 */
424 if (!unconfined(profile) && !unconfined(fprofile) &&
425 ((fprofile != profile) || (mask & ~fctx->allow)))
426 error = aa_file_perm(op, profile, file, mask);
427 455
428 return error; 456 return error;
429} 457}
430 458
459static int apparmor_file_receive(struct file *file)
460{
461 return common_file_perm(OP_FRECEIVE, file, aa_map_file_to_perms(file));
462}
463
431static int apparmor_file_permission(struct file *file, int mask) 464static int apparmor_file_permission(struct file *file, int mask)
432{ 465{
433 return common_file_perm(OP_FPERM, file, mask); 466 return common_file_perm(OP_FPERM, file, mask);
@@ -448,7 +481,7 @@ static int common_mmap(const char *op, struct file *file, unsigned long prot,
448{ 481{
449 int mask = 0; 482 int mask = 0;
450 483
451 if (!file || !file->f_security) 484 if (!file || !file_ctx(file))
452 return 0; 485 return 0;
453 486
454 if (prot & PROT_READ) 487 if (prot & PROT_READ)
@@ -485,21 +518,21 @@ static int apparmor_getprocattr(struct task_struct *task, char *name,
485 /* released below */ 518 /* released below */
486 const struct cred *cred = get_task_cred(task); 519 const struct cred *cred = get_task_cred(task);
487 struct aa_task_ctx *ctx = cred_ctx(cred); 520 struct aa_task_ctx *ctx = cred_ctx(cred);
488 struct aa_profile *profile = NULL; 521 struct aa_label *label = NULL;
489 522
490 if (strcmp(name, "current") == 0) 523 if (strcmp(name, "current") == 0)
491 profile = aa_get_newest_profile(ctx->profile); 524 label = aa_get_newest_label(ctx->label);
492 else if (strcmp(name, "prev") == 0 && ctx->previous) 525 else if (strcmp(name, "prev") == 0 && ctx->previous)
493 profile = aa_get_newest_profile(ctx->previous); 526 label = aa_get_newest_label(ctx->previous);
494 else if (strcmp(name, "exec") == 0 && ctx->onexec) 527 else if (strcmp(name, "exec") == 0 && ctx->onexec)
495 profile = aa_get_newest_profile(ctx->onexec); 528 label = aa_get_newest_label(ctx->onexec);
496 else 529 else
497 error = -EINVAL; 530 error = -EINVAL;
498 531
499 if (profile) 532 if (label)
500 error = aa_getprocattr(profile, value); 533 error = aa_getprocattr(label, value);
501 534
502 aa_put_profile(profile); 535 aa_put_label(label);
503 put_cred(cred); 536 put_cred(cred);
504 537
505 return error; 538 return error;
@@ -539,22 +572,24 @@ static int apparmor_setprocattr(const char *name, void *value,
539 if (strcmp(name, "current") == 0) { 572 if (strcmp(name, "current") == 0) {
540 if (strcmp(command, "changehat") == 0) { 573 if (strcmp(command, "changehat") == 0) {
541 error = aa_setprocattr_changehat(args, arg_size, 574 error = aa_setprocattr_changehat(args, arg_size,
542 !AA_DO_TEST); 575 AA_CHANGE_NOFLAGS);
543 } else if (strcmp(command, "permhat") == 0) { 576 } else if (strcmp(command, "permhat") == 0) {
544 error = aa_setprocattr_changehat(args, arg_size, 577 error = aa_setprocattr_changehat(args, arg_size,
545 AA_DO_TEST); 578 AA_CHANGE_TEST);
546 } else if (strcmp(command, "changeprofile") == 0) { 579 } else if (strcmp(command, "changeprofile") == 0) {
547 error = aa_change_profile(args, !AA_ONEXEC, 580 error = aa_change_profile(args, AA_CHANGE_NOFLAGS);
548 !AA_DO_TEST, false);
549 } else if (strcmp(command, "permprofile") == 0) { 581 } else if (strcmp(command, "permprofile") == 0) {
550 error = aa_change_profile(args, !AA_ONEXEC, AA_DO_TEST, 582 error = aa_change_profile(args, AA_CHANGE_TEST);
551 false); 583 } else if (strcmp(command, "stack") == 0) {
584 error = aa_change_profile(args, AA_CHANGE_STACK);
552 } else 585 } else
553 goto fail; 586 goto fail;
554 } else if (strcmp(name, "exec") == 0) { 587 } else if (strcmp(name, "exec") == 0) {
555 if (strcmp(command, "exec") == 0) 588 if (strcmp(command, "exec") == 0)
556 error = aa_change_profile(args, AA_ONEXEC, !AA_DO_TEST, 589 error = aa_change_profile(args, AA_CHANGE_ONEXEC);
557 false); 590 else if (strcmp(command, "stack") == 0)
591 error = aa_change_profile(args, (AA_CHANGE_ONEXEC |
592 AA_CHANGE_STACK));
558 else 593 else
559 goto fail; 594 goto fail;
560 } else 595 } else
@@ -568,21 +603,55 @@ out:
568 return error; 603 return error;
569 604
570fail: 605fail:
571 aad(&sa)->profile = aa_current_profile(); 606 aad(&sa)->label = begin_current_label_crit_section();
572 aad(&sa)->info = name; 607 aad(&sa)->info = name;
573 aad(&sa)->error = error = -EINVAL; 608 aad(&sa)->error = error = -EINVAL;
574 aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL); 609 aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
610 end_current_label_crit_section(aad(&sa)->label);
575 goto out; 611 goto out;
576} 612}
577 613
614/**
615 * apparmor_bprm_committing_creds - do task cleanup on committing new creds
616 * @bprm: binprm for the exec (NOT NULL)
617 */
618static void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
619{
620 struct aa_label *label = aa_current_raw_label();
621 struct aa_task_ctx *new_ctx = cred_ctx(bprm->cred);
622
623 /* bail out if unconfined or not changing profile */
624 if ((new_ctx->label->proxy == label->proxy) ||
625 (unconfined(new_ctx->label)))
626 return;
627
628 aa_inherit_files(bprm->cred, current->files);
629
630 current->pdeath_signal = 0;
631
632 /* reset soft limits and set hard limits for the new label */
633 __aa_transition_rlimits(label, new_ctx->label);
634}
635
636/**
637 * apparmor_bprm_committed_cred - do cleanup after new creds committed
638 * @bprm: binprm for the exec (NOT NULL)
639 */
640static void apparmor_bprm_committed_creds(struct linux_binprm *bprm)
641{
642 /* TODO: cleanup signals - ipc mediation */
643 return;
644}
645
578static int apparmor_task_setrlimit(struct task_struct *task, 646static int apparmor_task_setrlimit(struct task_struct *task,
579 unsigned int resource, struct rlimit *new_rlim) 647 unsigned int resource, struct rlimit *new_rlim)
580{ 648{
581 struct aa_profile *profile = __aa_current_profile(); 649 struct aa_label *label = __begin_current_label_crit_section();
582 int error = 0; 650 int error = 0;
583 651
584 if (!unconfined(profile)) 652 if (!unconfined(label))
585 error = aa_task_setrlimit(profile, task, resource, new_rlim); 653 error = aa_task_setrlimit(label, task, resource, new_rlim);
654 __end_current_label_crit_section(label);
586 655
587 return error; 656 return error;
588} 657}
@@ -606,6 +675,7 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
606 LSM_HOOK_INIT(inode_getattr, apparmor_inode_getattr), 675 LSM_HOOK_INIT(inode_getattr, apparmor_inode_getattr),
607 676
608 LSM_HOOK_INIT(file_open, apparmor_file_open), 677 LSM_HOOK_INIT(file_open, apparmor_file_open),
678 LSM_HOOK_INIT(file_receive, apparmor_file_receive),
609 LSM_HOOK_INIT(file_permission, apparmor_file_permission), 679 LSM_HOOK_INIT(file_permission, apparmor_file_permission),
610 LSM_HOOK_INIT(file_alloc_security, apparmor_file_alloc_security), 680 LSM_HOOK_INIT(file_alloc_security, apparmor_file_alloc_security),
611 LSM_HOOK_INIT(file_free_security, apparmor_file_free_security), 681 LSM_HOOK_INIT(file_free_security, apparmor_file_free_security),
@@ -774,11 +844,18 @@ static int param_get_aabool(char *buffer, const struct kernel_param *kp)
774 844
775static int param_set_aauint(const char *val, const struct kernel_param *kp) 845static int param_set_aauint(const char *val, const struct kernel_param *kp)
776{ 846{
847 int error;
848
777 if (!apparmor_enabled) 849 if (!apparmor_enabled)
778 return -EINVAL; 850 return -EINVAL;
779 if (apparmor_initialized && !policy_admin_capable(NULL)) 851 /* file is ro but enforce 2nd line check */
852 if (apparmor_initialized)
780 return -EPERM; 853 return -EPERM;
781 return param_set_uint(val, kp); 854
855 error = param_set_uint(val, kp);
856 pr_info("AppArmor: buffer size set to %d bytes\n", aa_g_path_max);
857
858 return error;
782} 859}
783 860
784static int param_get_aauint(char *buffer, const struct kernel_param *kp) 861static int param_get_aauint(char *buffer, const struct kernel_param *kp)
@@ -869,7 +946,7 @@ static int __init set_init_ctx(void)
869 if (!ctx) 946 if (!ctx)
870 return -ENOMEM; 947 return -ENOMEM;
871 948
872 ctx->profile = aa_get_profile(root_ns->unconfined); 949 ctx->label = aa_get_label(ns_unconfined(root_ns));
873 cred_ctx(cred) = ctx; 950 cred_ctx(cred) = ctx;
874 951
875 return 0; 952 return 0;
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index a8fc7d08c144..9d5de1d05be4 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -50,7 +50,7 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen)
50 * namespace root. 50 * namespace root.
51 */ 51 */
52static int disconnect(const struct path *path, char *buf, char **name, 52static int disconnect(const struct path *path, char *buf, char **name,
53 int flags) 53 int flags, const char *disconnected)
54{ 54{
55 int error = 0; 55 int error = 0;
56 56
@@ -63,9 +63,14 @@ static int disconnect(const struct path *path, char *buf, char **name,
63 error = -EACCES; 63 error = -EACCES;
64 if (**name == '/') 64 if (**name == '/')
65 *name = *name + 1; 65 *name = *name + 1;
66 } else if (**name != '/') 66 } else {
67 /* CONNECT_PATH with missing root */ 67 if (**name != '/')
68 error = prepend(name, *name - buf, "/", 1); 68 /* CONNECT_PATH with missing root */
69 error = prepend(name, *name - buf, "/", 1);
70 if (!error && disconnected)
71 error = prepend(name, *name - buf, disconnected,
72 strlen(disconnected));
73 }
69 74
70 return error; 75 return error;
71} 76}
@@ -74,9 +79,9 @@ static int disconnect(const struct path *path, char *buf, char **name,
74 * d_namespace_path - lookup a name associated with a given path 79 * d_namespace_path - lookup a name associated with a given path
75 * @path: path to lookup (NOT NULL) 80 * @path: path to lookup (NOT NULL)
76 * @buf: buffer to store path to (NOT NULL) 81 * @buf: buffer to store path to (NOT NULL)
77 * @buflen: length of @buf
78 * @name: Returns - pointer for start of path name with in @buf (NOT NULL) 82 * @name: Returns - pointer for start of path name with in @buf (NOT NULL)
79 * @flags: flags controlling path lookup 83 * @flags: flags controlling path lookup
84 * @disconnected: string to prefix to disconnected paths
80 * 85 *
81 * Handle path name lookup. 86 * Handle path name lookup.
82 * 87 *
@@ -84,12 +89,14 @@ static int disconnect(const struct path *path, char *buf, char **name,
84 * When no error the path name is returned in @name which points to 89 * When no error the path name is returned in @name which points to
85 * to a position in @buf 90 * to a position in @buf
86 */ 91 */
87static int d_namespace_path(const struct path *path, char *buf, int buflen, 92static int d_namespace_path(const struct path *path, char *buf, char **name,
88 char **name, int flags) 93 int flags, const char *disconnected)
89{ 94{
90 char *res; 95 char *res;
91 int error = 0; 96 int error = 0;
92 int connected = 1; 97 int connected = 1;
98 int isdir = (flags & PATH_IS_DIR) ? 1 : 0;
99 int buflen = aa_g_path_max - isdir;
93 100
94 if (path->mnt->mnt_flags & MNT_INTERNAL) { 101 if (path->mnt->mnt_flags & MNT_INTERNAL) {
95 /* it's not mounted anywhere */ 102 /* it's not mounted anywhere */
@@ -104,10 +111,12 @@ static int d_namespace_path(const struct path *path, char *buf, int buflen,
104 /* TODO: convert over to using a per namespace 111 /* TODO: convert over to using a per namespace
105 * control instead of hard coded /proc 112 * control instead of hard coded /proc
106 */ 113 */
107 return prepend(name, *name - buf, "/proc", 5); 114 error = prepend(name, *name - buf, "/proc", 5);
115 goto out;
108 } else 116 } else
109 return disconnect(path, buf, name, flags); 117 error = disconnect(path, buf, name, flags,
110 return 0; 118 disconnected);
119 goto out;
111 } 120 }
112 121
113 /* resolve paths relative to chroot?*/ 122 /* resolve paths relative to chroot?*/
@@ -126,8 +135,11 @@ static int d_namespace_path(const struct path *path, char *buf, int buflen,
126 * be returned. 135 * be returned.
127 */ 136 */
128 if (!res || IS_ERR(res)) { 137 if (!res || IS_ERR(res)) {
129 if (PTR_ERR(res) == -ENAMETOOLONG) 138 if (PTR_ERR(res) == -ENAMETOOLONG) {
130 return -ENAMETOOLONG; 139 error = -ENAMETOOLONG;
140 *name = buf;
141 goto out;
142 }
131 connected = 0; 143 connected = 0;
132 res = dentry_path_raw(path->dentry, buf, buflen); 144 res = dentry_path_raw(path->dentry, buf, buflen);
133 if (IS_ERR(res)) { 145 if (IS_ERR(res)) {
@@ -140,6 +152,9 @@ static int d_namespace_path(const struct path *path, char *buf, int buflen,
140 152
141 *name = res; 153 *name = res;
142 154
155 if (!connected)
156 error = disconnect(path, buf, name, flags, disconnected);
157
143 /* Handle two cases: 158 /* Handle two cases:
144 * 1. A deleted dentry && profile is not allowing mediation of deleted 159 * 1. A deleted dentry && profile is not allowing mediation of deleted
145 * 2. On some filesystems, newly allocated dentries appear to the 160 * 2. On some filesystems, newly allocated dentries appear to the
@@ -147,62 +162,30 @@ static int d_namespace_path(const struct path *path, char *buf, int buflen,
147 * allocated. 162 * allocated.
148 */ 163 */
149 if (d_unlinked(path->dentry) && d_is_positive(path->dentry) && 164 if (d_unlinked(path->dentry) && d_is_positive(path->dentry) &&
150 !(flags & PATH_MEDIATE_DELETED)) { 165 !(flags & (PATH_MEDIATE_DELETED | PATH_DELEGATE_DELETED))) {
151 error = -ENOENT; 166 error = -ENOENT;
152 goto out; 167 goto out;
153 } 168 }
154 169
155 if (!connected)
156 error = disconnect(path, buf, name, flags);
157
158out: 170out:
159 return error; 171 /*
160} 172 * Append "/" to the pathname. The root directory is a special
161 173 * case; it already ends in slash.
162/** 174 */
163 * get_name_to_buffer - get the pathname to a buffer ensure dir / is appended 175 if (!error && isdir && ((*name)[1] != '\0' || (*name)[0] != '/'))
164 * @path: path to get name for (NOT NULL) 176 strcpy(&buf[aa_g_path_max - 2], "/");
165 * @flags: flags controlling path lookup
166 * @buffer: buffer to put name in (NOT NULL)
167 * @size: size of buffer
168 * @name: Returns - contains position of path name in @buffer (NOT NULL)
169 *
170 * Returns: %0 else error on failure
171 */
172static int get_name_to_buffer(const struct path *path, int flags, char *buffer,
173 int size, char **name, const char **info)
174{
175 int adjust = (flags & PATH_IS_DIR) ? 1 : 0;
176 int error = d_namespace_path(path, buffer, size - adjust, name, flags);
177
178 if (!error && (flags & PATH_IS_DIR) && (*name)[1] != '\0')
179 /*
180 * Append "/" to the pathname. The root directory is a special
181 * case; it already ends in slash.
182 */
183 strcpy(&buffer[size - 2], "/");
184
185 if (info && error) {
186 if (error == -ENOENT)
187 *info = "Failed name lookup - deleted entry";
188 else if (error == -EACCES)
189 *info = "Failed name lookup - disconnected path";
190 else if (error == -ENAMETOOLONG)
191 *info = "Failed name lookup - name too long";
192 else
193 *info = "Failed name lookup";
194 }
195 177
196 return error; 178 return error;
197} 179}
198 180
199/** 181/**
200 * aa_path_name - compute the pathname of a file 182 * aa_path_name - get the pathname to a buffer ensure dir / is appended
201 * @path: path the file (NOT NULL) 183 * @path: path the file (NOT NULL)
202 * @flags: flags controlling path name generation 184 * @flags: flags controlling path name generation
203 * @buffer: buffer that aa_get_name() allocated (NOT NULL) 185 * @buffer: buffer to put name in (NOT NULL)
204 * @name: Returns - the generated path name if !error (NOT NULL) 186 * @name: Returns - the generated path name if !error (NOT NULL)
205 * @info: Returns - information on why the path lookup failed (MAYBE NULL) 187 * @info: Returns - information on why the path lookup failed (MAYBE NULL)
188 * @disconnected: string to prepend to disconnected paths
206 * 189 *
207 * @name is a pointer to the beginning of the pathname (which usually differs 190 * @name is a pointer to the beginning of the pathname (which usually differs
208 * from the beginning of the buffer), or NULL. If there is an error @name 191 * from the beginning of the buffer), or NULL. If there is an error @name
@@ -215,32 +198,23 @@ static int get_name_to_buffer(const struct path *path, int flags, char *buffer,
215 * 198 *
216 * Returns: %0 else error code if could retrieve name 199 * Returns: %0 else error code if could retrieve name
217 */ 200 */
218int aa_path_name(const struct path *path, int flags, char **buffer, 201int aa_path_name(const struct path *path, int flags, char *buffer,
219 const char **name, const char **info) 202 const char **name, const char **info, const char *disconnected)
220{ 203{
221 char *buf, *str = NULL; 204 char *str = NULL;
222 int size = 256; 205 int error = d_namespace_path(path, buffer, &str, flags, disconnected);
223 int error; 206
224 207 if (info && error) {
225 *name = NULL; 208 if (error == -ENOENT)
226 *buffer = NULL; 209 *info = "Failed name lookup - deleted entry";
227 for (;;) { 210 else if (error == -EACCES)
228 /* freed by caller */ 211 *info = "Failed name lookup - disconnected path";
229 buf = kmalloc(size, GFP_KERNEL); 212 else if (error == -ENAMETOOLONG)
230 if (!buf) 213 *info = "Failed name lookup - name too long";
231 return -ENOMEM; 214 else
232 215 *info = "Failed name lookup";
233 error = get_name_to_buffer(path, flags, buf, size, &str, info);
234 if (error != -ENAMETOOLONG)
235 break;
236
237 kfree(buf);
238 size <<= 1;
239 if (size > aa_g_path_max)
240 return -ENAMETOOLONG;
241 *info = NULL;
242 } 216 }
243 *buffer = buf; 217
244 *name = str; 218 *name = str;
245 219
246 return error; 220 return error;
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index cf9d670dca94..244ea4a4a8f0 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -101,20 +101,9 @@ const char *const aa_profile_mode_names[] = {
101 "unconfined", 101 "unconfined",
102}; 102};
103 103
104/* requires profile list write lock held */
105void __aa_update_proxy(struct aa_profile *orig, struct aa_profile *new)
106{
107 struct aa_profile *tmp;
108
109 tmp = rcu_dereference_protected(orig->proxy->profile,
110 mutex_is_locked(&orig->ns->lock));
111 rcu_assign_pointer(orig->proxy->profile, aa_get_profile(new));
112 orig->flags |= PFLAG_STALE;
113 aa_put_profile(tmp);
114}
115 104
116/** 105/**
117 * __list_add_profile - add a profile to a list 106 * __add_profile - add a profiles to list and label tree
118 * @list: list to add it to (NOT NULL) 107 * @list: list to add it to (NOT NULL)
119 * @profile: the profile to add (NOT NULL) 108 * @profile: the profile to add (NOT NULL)
120 * 109 *
@@ -122,12 +111,21 @@ void __aa_update_proxy(struct aa_profile *orig, struct aa_profile *new)
122 * 111 *
123 * Requires: namespace lock be held, or list not be shared 112 * Requires: namespace lock be held, or list not be shared
124 */ 113 */
125static void __list_add_profile(struct list_head *list, 114static void __add_profile(struct list_head *list, struct aa_profile *profile)
126 struct aa_profile *profile)
127{ 115{
116 struct aa_label *l;
117
118 AA_BUG(!list);
119 AA_BUG(!profile);
120 AA_BUG(!profile->ns);
121 AA_BUG(!mutex_is_locked(&profile->ns->lock));
122
128 list_add_rcu(&profile->base.list, list); 123 list_add_rcu(&profile->base.list, list);
129 /* get list reference */ 124 /* get list reference */
130 aa_get_profile(profile); 125 aa_get_profile(profile);
126 l = aa_label_insert(&profile->ns->labels, &profile->label);
127 AA_BUG(l != &profile->label);
128 aa_put_label(l);
131} 129}
132 130
133/** 131/**
@@ -144,6 +142,10 @@ static void __list_add_profile(struct list_head *list,
144 */ 142 */
145static void __list_remove_profile(struct aa_profile *profile) 143static void __list_remove_profile(struct aa_profile *profile)
146{ 144{
145 AA_BUG(!profile);
146 AA_BUG(!profile->ns);
147 AA_BUG(!mutex_is_locked(&profile->ns->lock));
148
147 list_del_rcu(&profile->base.list); 149 list_del_rcu(&profile->base.list);
148 aa_put_profile(profile); 150 aa_put_profile(profile);
149} 151}
@@ -156,11 +158,15 @@ static void __list_remove_profile(struct aa_profile *profile)
156 */ 158 */
157static void __remove_profile(struct aa_profile *profile) 159static void __remove_profile(struct aa_profile *profile)
158{ 160{
161 AA_BUG(!profile);
162 AA_BUG(!profile->ns);
163 AA_BUG(!mutex_is_locked(&profile->ns->lock));
164
159 /* release any children lists first */ 165 /* release any children lists first */
160 __aa_profile_list_release(&profile->base.profiles); 166 __aa_profile_list_release(&profile->base.profiles);
161 /* released by free_profile */ 167 /* released by free_profile */
162 __aa_update_proxy(profile, profile->ns->unconfined); 168 aa_label_remove(&profile->label);
163 __aa_fs_profile_rmdir(profile); 169 __aafs_profile_rmdir(profile);
164 __list_remove_profile(profile); 170 __list_remove_profile(profile);
165} 171}
166 172
@@ -177,24 +183,6 @@ void __aa_profile_list_release(struct list_head *head)
177 __remove_profile(profile); 183 __remove_profile(profile);
178} 184}
179 185
180
181static void free_proxy(struct aa_proxy *p)
182{
183 if (p) {
184 /* r->profile will not be updated any more as r is dead */
185 aa_put_profile(rcu_dereference_protected(p->profile, true));
186 kzfree(p);
187 }
188}
189
190
191void aa_free_proxy_kref(struct kref *kref)
192{
193 struct aa_proxy *p = container_of(kref, struct aa_proxy, count);
194
195 free_proxy(p);
196}
197
198/** 186/**
199 * aa_free_data - free a data blob 187 * aa_free_data - free a data blob
200 * @ptr: data to free 188 * @ptr: data to free
@@ -242,7 +230,6 @@ void aa_free_profile(struct aa_profile *profile)
242 kzfree(profile->dirname); 230 kzfree(profile->dirname);
243 aa_put_dfa(profile->xmatch); 231 aa_put_dfa(profile->xmatch);
244 aa_put_dfa(profile->policy.dfa); 232 aa_put_dfa(profile->policy.dfa);
245 aa_put_proxy(profile->proxy);
246 233
247 if (profile->data) { 234 if (profile->data) {
248 rht = profile->data; 235 rht = profile->data;
@@ -253,30 +240,8 @@ void aa_free_profile(struct aa_profile *profile)
253 240
254 kzfree(profile->hash); 241 kzfree(profile->hash);
255 aa_put_loaddata(profile->rawdata); 242 aa_put_loaddata(profile->rawdata);
256 kzfree(profile);
257}
258
259/**
260 * aa_free_profile_rcu - free aa_profile by rcu (called by aa_free_profile_kref)
261 * @head: rcu_head callback for freeing of a profile (NOT NULL)
262 */
263static void aa_free_profile_rcu(struct rcu_head *head)
264{
265 struct aa_profile *p = container_of(head, struct aa_profile, rcu);
266 if (p->flags & PFLAG_NS_COUNT)
267 aa_free_ns(p->ns);
268 else
269 aa_free_profile(p);
270}
271 243
272/** 244 kzfree(profile);
273 * aa_free_profile_kref - free aa_profile by kref (called by aa_put_profile)
274 * @kr: kref callback for freeing of a profile (NOT NULL)
275 */
276void aa_free_profile_kref(struct kref *kref)
277{
278 struct aa_profile *p = container_of(kref, struct aa_profile, count);
279 call_rcu(&p->rcu, aa_free_profile_rcu);
280} 245}
281 246
282/** 247/**
@@ -286,30 +251,40 @@ void aa_free_profile_kref(struct kref *kref)
286 * 251 *
287 * Returns: refcount profile or NULL on failure 252 * Returns: refcount profile or NULL on failure
288 */ 253 */
289struct aa_profile *aa_alloc_profile(const char *hname, gfp_t gfp) 254struct aa_profile *aa_alloc_profile(const char *hname, struct aa_proxy *proxy,
255 gfp_t gfp)
290{ 256{
291 struct aa_profile *profile; 257 struct aa_profile *profile;
292 258
293 /* freed by free_profile - usually through aa_put_profile */ 259 /* freed by free_profile - usually through aa_put_profile */
294 profile = kzalloc(sizeof(*profile), gfp); 260 profile = kzalloc(sizeof(*profile) + sizeof(struct aa_profile *) * 2,
261 gfp);
295 if (!profile) 262 if (!profile)
296 return NULL; 263 return NULL;
297 264
298 profile->proxy = kzalloc(sizeof(struct aa_proxy), gfp);
299 if (!profile->proxy)
300 goto fail;
301 kref_init(&profile->proxy->count);
302
303 if (!aa_policy_init(&profile->base, NULL, hname, gfp)) 265 if (!aa_policy_init(&profile->base, NULL, hname, gfp))
304 goto fail; 266 goto fail;
305 kref_init(&profile->count); 267 if (!aa_label_init(&profile->label, 1))
268 goto fail;
269
270 /* update being set needed by fs interface */
271 if (!proxy) {
272 proxy = aa_alloc_proxy(&profile->label, gfp);
273 if (!proxy)
274 goto fail;
275 } else
276 aa_get_proxy(proxy);
277 profile->label.proxy = proxy;
278
279 profile->label.hname = profile->base.hname;
280 profile->label.flags |= FLAG_PROFILE;
281 profile->label.vec[0] = profile;
306 282
307 /* refcount released by caller */ 283 /* refcount released by caller */
308 return profile; 284 return profile;
309 285
310fail: 286fail:
311 kzfree(profile->proxy); 287 aa_free_profile(profile);
312 kzfree(profile);
313 288
314 return NULL; 289 return NULL;
315} 290}
@@ -362,14 +337,14 @@ name:
362 if (profile) 337 if (profile)
363 goto out; 338 goto out;
364 339
365 profile = aa_alloc_profile(name, gfp); 340 profile = aa_alloc_profile(name, NULL, gfp);
366 if (!profile) 341 if (!profile)
367 goto fail; 342 goto fail;
368 343
369 profile->mode = APPARMOR_COMPLAIN; 344 profile->mode = APPARMOR_COMPLAIN;
370 profile->flags |= PFLAG_NULL; 345 profile->label.flags |= FLAG_NULL;
371 if (hat) 346 if (hat)
372 profile->flags |= PFLAG_HAT; 347 profile->label.flags |= FLAG_HAT;
373 profile->path_flags = parent->path_flags; 348 profile->path_flags = parent->path_flags;
374 349
375 /* released on free_profile */ 350 /* released on free_profile */
@@ -379,7 +354,7 @@ name:
379 profile->policy.dfa = aa_get_dfa(nulldfa); 354 profile->policy.dfa = aa_get_dfa(nulldfa);
380 355
381 mutex_lock(&profile->ns->lock); 356 mutex_lock(&profile->ns->lock);
382 __list_add_profile(&parent->base.profiles, profile); 357 __add_profile(&parent->base.profiles, profile);
383 mutex_unlock(&profile->ns->lock); 358 mutex_unlock(&profile->ns->lock);
384 359
385 /* refcount released by caller */ 360 /* refcount released by caller */
@@ -389,7 +364,6 @@ out:
389 return profile; 364 return profile;
390 365
391fail: 366fail:
392 kfree(name);
393 aa_free_profile(profile); 367 aa_free_profile(profile);
394 return NULL; 368 return NULL;
395} 369}
@@ -397,33 +371,33 @@ fail:
397/* TODO: profile accounting - setup in remove */ 371/* TODO: profile accounting - setup in remove */
398 372
399/** 373/**
400 * __find_child - find a profile on @head list with a name matching @name 374 * __strn_find_child - find a profile on @head list using substring of @name
401 * @head: list to search (NOT NULL) 375 * @head: list to search (NOT NULL)
402 * @name: name of profile (NOT NULL) 376 * @name: name of profile (NOT NULL)
377 * @len: length of @name substring to match
403 * 378 *
404 * Requires: rcu_read_lock be held 379 * Requires: rcu_read_lock be held
405 * 380 *
406 * Returns: unrefcounted profile ptr, or NULL if not found 381 * Returns: unrefcounted profile ptr, or NULL if not found
407 */ 382 */
408static struct aa_profile *__find_child(struct list_head *head, const char *name) 383static struct aa_profile *__strn_find_child(struct list_head *head,
384 const char *name, int len)
409{ 385{
410 return (struct aa_profile *)__policy_find(head, name); 386 return (struct aa_profile *)__policy_strn_find(head, name, len);
411} 387}
412 388
413/** 389/**
414 * __strn_find_child - find a profile on @head list using substring of @name 390 * __find_child - find a profile on @head list with a name matching @name
415 * @head: list to search (NOT NULL) 391 * @head: list to search (NOT NULL)
416 * @name: name of profile (NOT NULL) 392 * @name: name of profile (NOT NULL)
417 * @len: length of @name substring to match
418 * 393 *
419 * Requires: rcu_read_lock be held 394 * Requires: rcu_read_lock be held
420 * 395 *
421 * Returns: unrefcounted profile ptr, or NULL if not found 396 * Returns: unrefcounted profile ptr, or NULL if not found
422 */ 397 */
423static struct aa_profile *__strn_find_child(struct list_head *head, 398static struct aa_profile *__find_child(struct list_head *head, const char *name)
424 const char *name, int len)
425{ 399{
426 return (struct aa_profile *)__policy_strn_find(head, name, len); 400 return __strn_find_child(head, name, strlen(name));
427} 401}
428 402
429/** 403/**
@@ -556,7 +530,7 @@ struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *hname)
556 return aa_lookupn_profile(ns, hname, strlen(hname)); 530 return aa_lookupn_profile(ns, hname, strlen(hname));
557} 531}
558 532
559struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base, 533struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
560 const char *fqname, size_t n) 534 const char *fqname, size_t n)
561{ 535{
562 struct aa_profile *profile; 536 struct aa_profile *profile;
@@ -566,11 +540,11 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base,
566 540
567 name = aa_splitn_fqname(fqname, n, &ns_name, &ns_len); 541 name = aa_splitn_fqname(fqname, n, &ns_name, &ns_len);
568 if (ns_name) { 542 if (ns_name) {
569 ns = aa_findn_ns(base->ns, ns_name, ns_len); 543 ns = aa_lookupn_ns(labels_ns(base), ns_name, ns_len);
570 if (!ns) 544 if (!ns)
571 return NULL; 545 return NULL;
572 } else 546 } else
573 ns = aa_get_ns(base->ns); 547 ns = aa_get_ns(labels_ns(base));
574 548
575 if (name) 549 if (name)
576 profile = aa_lookupn_profile(ns, name, n - (name - fqname)); 550 profile = aa_lookupn_profile(ns, name, n - (name - fqname));
@@ -596,7 +570,7 @@ static int replacement_allowed(struct aa_profile *profile, int noreplace,
596 const char **info) 570 const char **info)
597{ 571{
598 if (profile) { 572 if (profile) {
599 if (profile->flags & PFLAG_IMMUTABLE) { 573 if (profile->label.flags & FLAG_IMMUTIBLE) {
600 *info = "cannot replace immutible profile"; 574 *info = "cannot replace immutible profile";
601 return -EPERM; 575 return -EPERM;
602 } else if (noreplace) { 576 } else if (noreplace) {
@@ -619,29 +593,31 @@ static void audit_cb(struct audit_buffer *ab, void *va)
619} 593}
620 594
621/** 595/**
622 * aa_audit_policy - Do auditing of policy changes 596 * audit_policy - Do auditing of policy changes
623 * @profile: profile to check if it can manage policy 597 * @label: label to check if it can manage policy
624 * @op: policy operation being performed 598 * @op: policy operation being performed
625 * @gfp: memory allocation flags 599 * @ns_name: name of namespace being manipulated
626 * @nsname: name of the ns being manipulated (MAY BE NULL)
627 * @name: name of profile being manipulated (NOT NULL) 600 * @name: name of profile being manipulated (NOT NULL)
628 * @info: any extra information to be audited (MAYBE NULL) 601 * @info: any extra information to be audited (MAYBE NULL)
629 * @error: error code 602 * @error: error code
630 * 603 *
631 * Returns: the error to be returned after audit is done 604 * Returns: the error to be returned after audit is done
632 */ 605 */
633static int audit_policy(struct aa_profile *profile, const char *op, 606static int audit_policy(struct aa_label *label, const char *op,
634 const char *nsname, const char *name, 607 const char *ns_name, const char *name,
635 const char *info, int error) 608 const char *info, int error)
636{ 609{
637 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, op); 610 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, op);
638 611
639 aad(&sa)->iface.ns = nsname; 612 aad(&sa)->iface.ns = ns_name;
640 aad(&sa)->name = name; 613 aad(&sa)->name = name;
641 aad(&sa)->info = info; 614 aad(&sa)->info = info;
642 aad(&sa)->error = error; 615 aad(&sa)->error = error;
616 aad(&sa)->label = label;
617
618 aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, audit_cb);
643 619
644 return aa_audit(AUDIT_APPARMOR_STATUS, profile, &sa, audit_cb); 620 return error;
645} 621}
646 622
647/** 623/**
@@ -685,22 +661,30 @@ bool policy_admin_capable(struct aa_ns *ns)
685 661
686/** 662/**
687 * aa_may_manage_policy - can the current task manage policy 663 * aa_may_manage_policy - can the current task manage policy
688 * @profile: profile to check if it can manage policy 664 * @label: label to check if it can manage policy
689 * @op: the policy manipulation operation being done 665 * @op: the policy manipulation operation being done
690 * 666 *
691 * Returns: 0 if the task is allowed to manipulate policy else error 667 * Returns: 0 if the task is allowed to manipulate policy else error
692 */ 668 */
693int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns, 669int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns, u32 mask)
694 const char *op)
695{ 670{
671 const char *op;
672
673 if (mask & AA_MAY_REMOVE_POLICY)
674 op = OP_PROF_RM;
675 else if (mask & AA_MAY_REPLACE_POLICY)
676 op = OP_PROF_REPL;
677 else
678 op = OP_PROF_LOAD;
679
696 /* check if loading policy is locked out */ 680 /* check if loading policy is locked out */
697 if (aa_g_lock_policy) 681 if (aa_g_lock_policy)
698 return audit_policy(profile, op, NULL, NULL, 682 return audit_policy(label, op, NULL, NULL, "policy_locked",
699 "policy_locked", -EACCES); 683 -EACCES);
700 684
701 if (!policy_admin_capable(ns)) 685 if (!policy_admin_capable(ns))
702 return audit_policy(profile, op, NULL, NULL, 686 return audit_policy(label, op, NULL, NULL, "not policy admin",
703 "not policy admin", -EACCES); 687 -EACCES);
704 688
705 /* TODO: add fine grained mediation of policy loads */ 689 /* TODO: add fine grained mediation of policy loads */
706 return 0; 690 return 0;
@@ -742,8 +726,7 @@ static struct aa_profile *__list_lookup_parent(struct list_head *lh,
742 * 726 *
743 * Requires: namespace list lock be held, or list not be shared 727 * Requires: namespace list lock be held, or list not be shared
744 */ 728 */
745static void __replace_profile(struct aa_profile *old, struct aa_profile *new, 729static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
746 bool share_proxy)
747{ 730{
748 struct aa_profile *child, *tmp; 731 struct aa_profile *child, *tmp;
749 732
@@ -758,7 +741,7 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new,
758 p = __find_child(&new->base.profiles, child->base.name); 741 p = __find_child(&new->base.profiles, child->base.name);
759 if (p) { 742 if (p) {
760 /* @p replaces @child */ 743 /* @p replaces @child */
761 __replace_profile(child, p, share_proxy); 744 __replace_profile(child, p);
762 continue; 745 continue;
763 } 746 }
764 747
@@ -776,15 +759,9 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new,
776 struct aa_profile *parent = aa_deref_parent(old); 759 struct aa_profile *parent = aa_deref_parent(old);
777 rcu_assign_pointer(new->parent, aa_get_profile(parent)); 760 rcu_assign_pointer(new->parent, aa_get_profile(parent));
778 } 761 }
779 __aa_update_proxy(old, new); 762 aa_label_replace(&old->label, &new->label);
780 if (share_proxy) { 763 /* migrate dents must come after label replacement b/c update */
781 aa_put_proxy(new->proxy); 764 __aafs_profile_migrate_dents(old, new);
782 new->proxy = aa_get_proxy(old->proxy);
783 } else if (!rcu_access_pointer(new->proxy->profile))
784 /* aafs interface uses proxy */
785 rcu_assign_pointer(new->proxy->profile,
786 aa_get_profile(new));
787 __aa_fs_profile_migrate_dents(old, new);
788 765
789 if (list_empty(&new->base.list)) { 766 if (list_empty(&new->base.list)) {
790 /* new is not on a list already */ 767 /* new is not on a list already */
@@ -821,11 +798,41 @@ static int __lookup_replace(struct aa_ns *ns, const char *hname,
821 return 0; 798 return 0;
822} 799}
823 800
801static void share_name(struct aa_profile *old, struct aa_profile *new)
802{
803 aa_put_str(new->base.hname);
804 aa_get_str(old->base.hname);
805 new->base.hname = old->base.hname;
806 new->base.name = old->base.name;
807 new->label.hname = old->label.hname;
808}
809
810/* Update to newest version of parent after previous replacements
811 * Returns: unrefcount newest version of parent
812 */
813static struct aa_profile *update_to_newest_parent(struct aa_profile *new)
814{
815 struct aa_profile *parent, *newest;
816
817 parent = rcu_dereference_protected(new->parent,
818 mutex_is_locked(&new->ns->lock));
819 newest = aa_get_newest_profile(parent);
820
821 /* parent replaced in this atomic set? */
822 if (newest != parent) {
823 aa_put_profile(parent);
824 rcu_assign_pointer(new->parent, newest);
825 } else
826 aa_put_profile(newest);
827
828 return newest;
829}
830
824/** 831/**
825 * aa_replace_profiles - replace profile(s) on the profile list 832 * aa_replace_profiles - replace profile(s) on the profile list
826 * @view: namespace load is viewed from 833 * @policy_ns: namespace load is occurring on
827 * @label: label that is attempting to load/replace policy 834 * @label: label that is attempting to load/replace policy
828 * @noreplace: true if only doing addition, no replacement allowed 835 * @mask: permission mask
829 * @udata: serialized data stream (NOT NULL) 836 * @udata: serialized data stream (NOT NULL)
830 * 837 *
831 * unpack and replace a profile on the profile list and uses of that profile 838 * unpack and replace a profile on the profile list and uses of that profile
@@ -834,16 +841,19 @@ static int __lookup_replace(struct aa_ns *ns, const char *hname,
834 * 841 *
835 * Returns: size of data consumed else error code on failure. 842 * Returns: size of data consumed else error code on failure.
836 */ 843 */
837ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile, 844ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_label *label,
838 bool noreplace, struct aa_loaddata *udata) 845 u32 mask, struct aa_loaddata *udata)
839{ 846{
840 const char *ns_name, *info = NULL; 847 const char *ns_name, *info = NULL;
841 struct aa_ns *ns = NULL; 848 struct aa_ns *ns = NULL;
842 struct aa_load_ent *ent, *tmp; 849 struct aa_load_ent *ent, *tmp;
843 const char *op = OP_PROF_REPL; 850 struct aa_loaddata *rawdata_ent;
851 const char *op;
844 ssize_t count, error; 852 ssize_t count, error;
845 LIST_HEAD(lh); 853 LIST_HEAD(lh);
846 854
855 op = mask & AA_MAY_REPLACE_POLICY ? OP_PROF_REPL : OP_PROF_LOAD;
856 aa_get_loaddata(udata);
847 /* released below */ 857 /* released below */
848 error = aa_unpack(udata, &lh, &ns_name); 858 error = aa_unpack(udata, &lh, &ns_name);
849 if (error) 859 if (error)
@@ -874,7 +884,8 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
874 count++; 884 count++;
875 } 885 }
876 if (ns_name) { 886 if (ns_name) {
877 ns = aa_prepare_ns(view, ns_name); 887 ns = aa_prepare_ns(policy_ns ? policy_ns : labels_ns(label),
888 ns_name);
878 if (IS_ERR(ns)) { 889 if (IS_ERR(ns)) {
879 op = OP_PROF_LOAD; 890 op = OP_PROF_LOAD;
880 info = "failed to prepare namespace"; 891 info = "failed to prepare namespace";
@@ -884,22 +895,38 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
884 goto fail; 895 goto fail;
885 } 896 }
886 } else 897 } else
887 ns = aa_get_ns(view); 898 ns = aa_get_ns(policy_ns ? policy_ns : labels_ns(label));
888 899
889 mutex_lock(&ns->lock); 900 mutex_lock(&ns->lock);
901 /* check for duplicate rawdata blobs: space and file dedup */
902 list_for_each_entry(rawdata_ent, &ns->rawdata_list, list) {
903 if (aa_rawdata_eq(rawdata_ent, udata)) {
904 struct aa_loaddata *tmp;
905
906 tmp = __aa_get_loaddata(rawdata_ent);
907 /* check we didn't fail the race */
908 if (tmp) {
909 aa_put_loaddata(udata);
910 udata = tmp;
911 break;
912 }
913 }
914 }
890 /* setup parent and ns info */ 915 /* setup parent and ns info */
891 list_for_each_entry(ent, &lh, list) { 916 list_for_each_entry(ent, &lh, list) {
892 struct aa_policy *policy; 917 struct aa_policy *policy;
918
893 ent->new->rawdata = aa_get_loaddata(udata); 919 ent->new->rawdata = aa_get_loaddata(udata);
894 error = __lookup_replace(ns, ent->new->base.hname, noreplace, 920 error = __lookup_replace(ns, ent->new->base.hname,
921 !(mask & AA_MAY_REPLACE_POLICY),
895 &ent->old, &info); 922 &ent->old, &info);
896 if (error) 923 if (error)
897 goto fail_lock; 924 goto fail_lock;
898 925
899 if (ent->new->rename) { 926 if (ent->new->rename) {
900 error = __lookup_replace(ns, ent->new->rename, 927 error = __lookup_replace(ns, ent->new->rename,
901 noreplace, &ent->rename, 928 !(mask & AA_MAY_REPLACE_POLICY),
902 &info); 929 &ent->rename, &info);
903 if (error) 930 if (error)
904 goto fail_lock; 931 goto fail_lock;
905 } 932 }
@@ -929,15 +956,16 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
929 } 956 }
930 957
931 /* create new fs entries for introspection if needed */ 958 /* create new fs entries for introspection if needed */
959 if (!udata->dents[AAFS_LOADDATA_DIR]) {
960 error = __aa_fs_create_rawdata(ns, udata);
961 if (error) {
962 info = "failed to create raw_data dir and files";
963 ent = NULL;
964 goto fail_lock;
965 }
966 }
932 list_for_each_entry(ent, &lh, list) { 967 list_for_each_entry(ent, &lh, list) {
933 if (ent->old) { 968 if (!ent->old) {
934 /* inherit old interface files */
935
936 /* if (ent->rename)
937 TODO: support rename */
938 /* } else if (ent->rename) {
939 TODO: support rename */
940 } else {
941 struct dentry *parent; 969 struct dentry *parent;
942 if (rcu_access_pointer(ent->new->parent)) { 970 if (rcu_access_pointer(ent->new->parent)) {
943 struct aa_profile *p; 971 struct aa_profile *p;
@@ -945,65 +973,61 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
945 parent = prof_child_dir(p); 973 parent = prof_child_dir(p);
946 } else 974 } else
947 parent = ns_subprofs_dir(ent->new->ns); 975 parent = ns_subprofs_dir(ent->new->ns);
948 error = __aa_fs_profile_mkdir(ent->new, parent); 976 error = __aafs_profile_mkdir(ent->new, parent);
949 } 977 }
950 978
951 if (error) { 979 if (error) {
952 info = "failed to create "; 980 info = "failed to create";
953 goto fail_lock; 981 goto fail_lock;
954 } 982 }
955 } 983 }
956 984
957 /* Done with checks that may fail - do actual replacement */ 985 /* Done with checks that may fail - do actual replacement */
986 __aa_bump_ns_revision(ns);
987 __aa_loaddata_update(udata, ns->revision);
958 list_for_each_entry_safe(ent, tmp, &lh, list) { 988 list_for_each_entry_safe(ent, tmp, &lh, list) {
959 list_del_init(&ent->list); 989 list_del_init(&ent->list);
960 op = (!ent->old && !ent->rename) ? OP_PROF_LOAD : OP_PROF_REPL; 990 op = (!ent->old && !ent->rename) ? OP_PROF_LOAD : OP_PROF_REPL;
961 991
962 audit_policy(profile, op, NULL, ent->new->base.hname, 992 if (ent->old && ent->old->rawdata == ent->new->rawdata) {
963 NULL, error); 993 /* dedup actual profile replacement */
994 audit_policy(label, op, ns_name, ent->new->base.hname,
995 "same as current profile, skipping",
996 error);
997 goto skip;
998 }
999
1000 /*
1001 * TODO: finer dedup based on profile range in data. Load set
1002 * can differ but profile may remain unchanged
1003 */
1004 audit_policy(label, op, ns_name, ent->new->base.hname, NULL,
1005 error);
964 1006
965 if (ent->old) { 1007 if (ent->old) {
966 __replace_profile(ent->old, ent->new, 1); 1008 share_name(ent->old, ent->new);
967 if (ent->rename) { 1009 __replace_profile(ent->old, ent->new);
968 /* aafs interface uses proxy */
969 struct aa_proxy *r = ent->new->proxy;
970 rcu_assign_pointer(r->profile,
971 aa_get_profile(ent->new));
972 __replace_profile(ent->rename, ent->new, 0);
973 }
974 } else if (ent->rename) {
975 /* aafs interface uses proxy */
976 rcu_assign_pointer(ent->new->proxy->profile,
977 aa_get_profile(ent->new));
978 __replace_profile(ent->rename, ent->new, 0);
979 } else if (ent->new->parent) {
980 struct aa_profile *parent, *newest;
981 parent = aa_deref_parent(ent->new);
982 newest = aa_get_newest_profile(parent);
983
984 /* parent replaced in this atomic set? */
985 if (newest != parent) {
986 aa_get_profile(newest);
987 rcu_assign_pointer(ent->new->parent, newest);
988 aa_put_profile(parent);
989 }
990 /* aafs interface uses proxy */
991 rcu_assign_pointer(ent->new->proxy->profile,
992 aa_get_profile(ent->new));
993 __list_add_profile(&newest->base.profiles, ent->new);
994 aa_put_profile(newest);
995 } else { 1010 } else {
996 /* aafs interface uses proxy */ 1011 struct list_head *lh;
997 rcu_assign_pointer(ent->new->proxy->profile, 1012
998 aa_get_profile(ent->new)); 1013 if (rcu_access_pointer(ent->new->parent)) {
999 __list_add_profile(&ns->base.profiles, ent->new); 1014 struct aa_profile *parent;
1015
1016 parent = update_to_newest_parent(ent->new);
1017 lh = &parent->base.profiles;
1018 } else
1019 lh = &ns->base.profiles;
1020 __add_profile(lh, ent->new);
1000 } 1021 }
1022 skip:
1001 aa_load_ent_free(ent); 1023 aa_load_ent_free(ent);
1002 } 1024 }
1025 __aa_labelset_update_subtree(ns);
1003 mutex_unlock(&ns->lock); 1026 mutex_unlock(&ns->lock);
1004 1027
1005out: 1028out:
1006 aa_put_ns(ns); 1029 aa_put_ns(ns);
1030 aa_put_loaddata(udata);
1007 1031
1008 if (error) 1032 if (error)
1009 return error; 1033 return error;
@@ -1013,10 +1037,10 @@ fail_lock:
1013 mutex_unlock(&ns->lock); 1037 mutex_unlock(&ns->lock);
1014 1038
1015 /* audit cause of failure */ 1039 /* audit cause of failure */
1016 op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL; 1040 op = (ent && !ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
1017fail: 1041fail:
1018 audit_policy(profile, op, ns_name, ent ? ent->new->base.hname : NULL, 1042 audit_policy(label, op, ns_name, ent ? ent->new->base.hname : NULL,
1019 info, error); 1043 info, error);
1020 /* audit status that rest of profiles in the atomic set failed too */ 1044 /* audit status that rest of profiles in the atomic set failed too */
1021 info = "valid profile in failed atomic policy load"; 1045 info = "valid profile in failed atomic policy load";
1022 list_for_each_entry(tmp, &lh, list) { 1046 list_for_each_entry(tmp, &lh, list) {
@@ -1026,8 +1050,8 @@ fail:
1026 continue; 1050 continue;
1027 } 1051 }
1028 op = (!tmp->old) ? OP_PROF_LOAD : OP_PROF_REPL; 1052 op = (!tmp->old) ? OP_PROF_LOAD : OP_PROF_REPL;
1029 audit_policy(profile, op, ns_name, 1053 audit_policy(label, op, ns_name, tmp->new->base.hname, info,
1030 tmp->new->base.hname, info, error); 1054 error);
1031 } 1055 }
1032 list_for_each_entry_safe(ent, tmp, &lh, list) { 1056 list_for_each_entry_safe(ent, tmp, &lh, list) {
1033 list_del_init(&ent->list); 1057 list_del_init(&ent->list);
@@ -1039,8 +1063,8 @@ fail:
1039 1063
1040/** 1064/**
1041 * aa_remove_profiles - remove profile(s) from the system 1065 * aa_remove_profiles - remove profile(s) from the system
1042 * @view: namespace the remove is being done from 1066 * @policy_ns: namespace the remove is being done from
1043 * @subj: profile attempting to remove policy 1067 * @subj: label attempting to remove policy
1044 * @fqname: name of the profile or namespace to remove (NOT NULL) 1068 * @fqname: name of the profile or namespace to remove (NOT NULL)
1045 * @size: size of the name 1069 * @size: size of the name
1046 * 1070 *
@@ -1051,13 +1075,13 @@ fail:
1051 * 1075 *
1052 * Returns: size of data consume else error code if fails 1076 * Returns: size of data consume else error code if fails
1053 */ 1077 */
1054ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj, 1078ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_label *subj,
1055 char *fqname, size_t size) 1079 char *fqname, size_t size)
1056{ 1080{
1057 struct aa_ns *root = NULL, *ns = NULL; 1081 struct aa_ns *ns = NULL;
1058 struct aa_profile *profile = NULL; 1082 struct aa_profile *profile = NULL;
1059 const char *name = fqname, *info = NULL; 1083 const char *name = fqname, *info = NULL;
1060 char *ns_name = NULL; 1084 const char *ns_name = NULL;
1061 ssize_t error = 0; 1085 ssize_t error = 0;
1062 1086
1063 if (*fqname == 0) { 1087 if (*fqname == 0) {
@@ -1066,12 +1090,13 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
1066 goto fail; 1090 goto fail;
1067 } 1091 }
1068 1092
1069 root = view;
1070
1071 if (fqname[0] == ':') { 1093 if (fqname[0] == ':') {
1072 name = aa_split_fqname(fqname, &ns_name); 1094 size_t ns_len;
1095
1096 name = aa_splitn_fqname(fqname, size, &ns_name, &ns_len);
1073 /* released below */ 1097 /* released below */
1074 ns = aa_find_ns(root, ns_name); 1098 ns = aa_lookupn_ns(policy_ns ? policy_ns : labels_ns(subj),
1099 ns_name, ns_len);
1075 if (!ns) { 1100 if (!ns) {
1076 info = "namespace does not exist"; 1101 info = "namespace does not exist";
1077 error = -ENOENT; 1102 error = -ENOENT;
@@ -1079,12 +1104,13 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
1079 } 1104 }
1080 } else 1105 } else
1081 /* released below */ 1106 /* released below */
1082 ns = aa_get_ns(root); 1107 ns = aa_get_ns(policy_ns ? policy_ns : labels_ns(subj));
1083 1108
1084 if (!name) { 1109 if (!name) {
1085 /* remove namespace - can only happen if fqname[0] == ':' */ 1110 /* remove namespace - can only happen if fqname[0] == ':' */
1086 mutex_lock(&ns->parent->lock); 1111 mutex_lock(&ns->parent->lock);
1087 __aa_remove_ns(ns); 1112 __aa_remove_ns(ns);
1113 __aa_bump_ns_revision(ns);
1088 mutex_unlock(&ns->parent->lock); 1114 mutex_unlock(&ns->parent->lock);
1089 } else { 1115 } else {
1090 /* remove profile */ 1116 /* remove profile */
@@ -1097,6 +1123,8 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
1097 } 1123 }
1098 name = profile->base.hname; 1124 name = profile->base.hname;
1099 __remove_profile(profile); 1125 __remove_profile(profile);
1126 __aa_labelset_update_subtree(ns);
1127 __aa_bump_ns_revision(ns);
1100 mutex_unlock(&ns->lock); 1128 mutex_unlock(&ns->lock);
1101 } 1129 }
1102 1130
diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
index 93d1826c4b09..351d3bab3a3d 100644
--- a/security/apparmor/policy_ns.c
+++ b/security/apparmor/policy_ns.c
@@ -23,6 +23,7 @@
23#include "include/apparmor.h" 23#include "include/apparmor.h"
24#include "include/context.h" 24#include "include/context.h"
25#include "include/policy_ns.h" 25#include "include/policy_ns.h"
26#include "include/label.h"
26#include "include/policy.h" 27#include "include/policy.h"
27 28
28/* root profile namespace */ 29/* root profile namespace */
@@ -99,15 +100,17 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
99 goto fail_ns; 100 goto fail_ns;
100 101
101 INIT_LIST_HEAD(&ns->sub_ns); 102 INIT_LIST_HEAD(&ns->sub_ns);
103 INIT_LIST_HEAD(&ns->rawdata_list);
102 mutex_init(&ns->lock); 104 mutex_init(&ns->lock);
105 init_waitqueue_head(&ns->wait);
103 106
104 /* released by aa_free_ns() */ 107 /* released by aa_free_ns() */
105 ns->unconfined = aa_alloc_profile("unconfined", GFP_KERNEL); 108 ns->unconfined = aa_alloc_profile("unconfined", NULL, GFP_KERNEL);
106 if (!ns->unconfined) 109 if (!ns->unconfined)
107 goto fail_unconfined; 110 goto fail_unconfined;
108 111
109 ns->unconfined->flags = PFLAG_IX_ON_NAME_ERROR | 112 ns->unconfined->label.flags |= FLAG_IX_ON_NAME_ERROR |
110 PFLAG_IMMUTABLE | PFLAG_NS_COUNT; 113 FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED;
111 ns->unconfined->mode = APPARMOR_UNCONFINED; 114 ns->unconfined->mode = APPARMOR_UNCONFINED;
112 115
113 /* ns and ns->unconfined share ns->unconfined refcount */ 116 /* ns and ns->unconfined share ns->unconfined refcount */
@@ -115,6 +118,8 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
115 118
116 atomic_set(&ns->uniq_null, 0); 119 atomic_set(&ns->uniq_null, 0);
117 120
121 aa_labelset_init(&ns->labels);
122
118 return ns; 123 return ns;
119 124
120fail_unconfined: 125fail_unconfined:
@@ -137,6 +142,7 @@ void aa_free_ns(struct aa_ns *ns)
137 return; 142 return;
138 143
139 aa_policy_destroy(&ns->base); 144 aa_policy_destroy(&ns->base);
145 aa_labelset_destroy(&ns->labels);
140 aa_put_ns(ns->parent); 146 aa_put_ns(ns->parent);
141 147
142 ns->unconfined->ns = NULL; 148 ns->unconfined->ns = NULL;
@@ -181,6 +187,60 @@ struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name)
181 return aa_findn_ns(root, name, strlen(name)); 187 return aa_findn_ns(root, name, strlen(name));
182} 188}
183 189
190/**
191 * __aa_lookupn_ns - lookup the namespace matching @hname
192 * @base: base list to start looking up profile name from (NOT NULL)
193 * @hname: hierarchical ns name (NOT NULL)
194 * @n: length of @hname
195 *
196 * Requires: rcu_read_lock be held
197 *
198 * Returns: unrefcounted ns pointer or NULL if not found
199 *
200 * Do a relative name lookup, recursing through profile tree.
201 */
202struct aa_ns *__aa_lookupn_ns(struct aa_ns *view, const char *hname, size_t n)
203{
204 struct aa_ns *ns = view;
205 const char *split;
206
207 for (split = strnstr(hname, "//", n); split;
208 split = strnstr(hname, "//", n)) {
209 ns = __aa_findn_ns(&ns->sub_ns, hname, split - hname);
210 if (!ns)
211 return NULL;
212
213 n -= split + 2 - hname;
214 hname = split + 2;
215 }
216
217 if (n)
218 return __aa_findn_ns(&ns->sub_ns, hname, n);
219 return NULL;
220}
221
222/**
223 * aa_lookupn_ns - look up a policy namespace relative to @view
224 * @view: namespace to search in (NOT NULL)
225 * @name: name of namespace to find (NOT NULL)
226 * @n: length of @name
227 *
228 * Returns: a refcounted namespace on the list, or NULL if no namespace
229 * called @name exists.
230 *
231 * refcount released by caller
232 */
233struct aa_ns *aa_lookupn_ns(struct aa_ns *view, const char *name, size_t n)
234{
235 struct aa_ns *ns = NULL;
236
237 rcu_read_lock();
238 ns = aa_get_ns(__aa_lookupn_ns(view, name, n));
239 rcu_read_unlock();
240
241 return ns;
242}
243
184static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name, 244static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
185 struct dentry *dir) 245 struct dentry *dir)
186{ 246{
@@ -195,7 +255,7 @@ static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
195 if (!ns) 255 if (!ns)
196 return NULL; 256 return NULL;
197 mutex_lock(&ns->lock); 257 mutex_lock(&ns->lock);
198 error = __aa_fs_ns_mkdir(ns, ns_subns_dir(parent), name); 258 error = __aafs_ns_mkdir(ns, ns_subns_dir(parent), name, dir);
199 if (error) { 259 if (error) {
200 AA_ERROR("Failed to create interface for ns %s\n", 260 AA_ERROR("Failed to create interface for ns %s\n",
201 ns->base.name); 261 ns->base.name);
@@ -281,9 +341,15 @@ static void destroy_ns(struct aa_ns *ns)
281 /* release all sub namespaces */ 341 /* release all sub namespaces */
282 __ns_list_release(&ns->sub_ns); 342 __ns_list_release(&ns->sub_ns);
283 343
284 if (ns->parent) 344 if (ns->parent) {
285 __aa_update_proxy(ns->unconfined, ns->parent->unconfined); 345 unsigned long flags;
286 __aa_fs_ns_rmdir(ns); 346
347 write_lock_irqsave(&ns->labels.lock, flags);
348 __aa_proxy_redirect(ns_unconfined(ns),
349 ns_unconfined(ns->parent));
350 write_unlock_irqrestore(&ns->labels.lock, flags);
351 }
352 __aafs_ns_rmdir(ns);
287 mutex_unlock(&ns->lock); 353 mutex_unlock(&ns->lock);
288} 354}
289 355
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 981d570eebba..c600f4dd1783 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -26,6 +26,7 @@
26#include "include/context.h" 26#include "include/context.h"
27#include "include/crypto.h" 27#include "include/crypto.h"
28#include "include/match.h" 28#include "include/match.h"
29#include "include/path.h"
29#include "include/policy.h" 30#include "include/policy.h"
30#include "include/policy_unpack.h" 31#include "include/policy_unpack.h"
31 32
@@ -107,7 +108,7 @@ static int audit_iface(struct aa_profile *new, const char *ns_name,
107 const char *name, const char *info, struct aa_ext *e, 108 const char *name, const char *info, struct aa_ext *e,
108 int error) 109 int error)
109{ 110{
110 struct aa_profile *profile = __aa_current_profile(); 111 struct aa_profile *profile = labels_profile(aa_current_raw_label());
111 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, NULL); 112 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, NULL);
112 if (e) 113 if (e)
113 aad(&sa)->iface.pos = e->pos - e->start; 114 aad(&sa)->iface.pos = e->pos - e->start;
@@ -122,16 +123,73 @@ static int audit_iface(struct aa_profile *new, const char *ns_name,
122 return aa_audit(AUDIT_APPARMOR_STATUS, profile, &sa, audit_cb); 123 return aa_audit(AUDIT_APPARMOR_STATUS, profile, &sa, audit_cb);
123} 124}
124 125
126void __aa_loaddata_update(struct aa_loaddata *data, long revision)
127{
128 AA_BUG(!data);
129 AA_BUG(!data->ns);
130 AA_BUG(!data->dents[AAFS_LOADDATA_REVISION]);
131 AA_BUG(!mutex_is_locked(&data->ns->lock));
132 AA_BUG(data->revision > revision);
133
134 data->revision = revision;
135 d_inode(data->dents[AAFS_LOADDATA_DIR])->i_mtime =
136 current_time(d_inode(data->dents[AAFS_LOADDATA_DIR]));
137 d_inode(data->dents[AAFS_LOADDATA_REVISION])->i_mtime =
138 current_time(d_inode(data->dents[AAFS_LOADDATA_REVISION]));
139}
140
141bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r)
142{
143 if (l->size != r->size)
144 return false;
145 if (aa_g_hash_policy && memcmp(l->hash, r->hash, aa_hash_size()) != 0)
146 return false;
147 return memcmp(l->data, r->data, r->size) == 0;
148}
149
150/*
151 * need to take the ns mutex lock which is NOT safe most places that
152 * put_loaddata is called, so we have to delay freeing it
153 */
154static void do_loaddata_free(struct work_struct *work)
155{
156 struct aa_loaddata *d = container_of(work, struct aa_loaddata, work);
157 struct aa_ns *ns = aa_get_ns(d->ns);
158
159 if (ns) {
160 mutex_lock(&ns->lock);
161 __aa_fs_remove_rawdata(d);
162 mutex_unlock(&ns->lock);
163 aa_put_ns(ns);
164 }
165
166 kzfree(d->hash);
167 kfree(d->name);
168 kvfree(d);
169}
170
125void aa_loaddata_kref(struct kref *kref) 171void aa_loaddata_kref(struct kref *kref)
126{ 172{
127 struct aa_loaddata *d = container_of(kref, struct aa_loaddata, count); 173 struct aa_loaddata *d = container_of(kref, struct aa_loaddata, count);
128 174
129 if (d) { 175 if (d) {
130 kzfree(d->hash); 176 INIT_WORK(&d->work, do_loaddata_free);
131 kvfree(d); 177 schedule_work(&d->work);
132 } 178 }
133} 179}
134 180
181struct aa_loaddata *aa_loaddata_alloc(size_t size)
182{
183 struct aa_loaddata *d = kvzalloc(sizeof(*d) + size, GFP_KERNEL);
184
185 if (d == NULL)
186 return ERR_PTR(-ENOMEM);
187 kref_init(&d->count);
188 INIT_LIST_HEAD(&d->list);
189
190 return d;
191}
192
135/* test if read will be in packed data bounds */ 193/* test if read will be in packed data bounds */
136static bool inbounds(struct aa_ext *e, size_t size) 194static bool inbounds(struct aa_ext *e, size_t size)
137{ 195{
@@ -408,7 +466,7 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
408 profile->file.trans.size = size; 466 profile->file.trans.size = size;
409 for (i = 0; i < size; i++) { 467 for (i = 0; i < size; i++) {
410 char *str; 468 char *str;
411 int c, j, size2 = unpack_strdup(e, &str, NULL); 469 int c, j, pos, size2 = unpack_strdup(e, &str, NULL);
412 /* unpack_strdup verifies that the last character is 470 /* unpack_strdup verifies that the last character is
413 * null termination byte. 471 * null termination byte.
414 */ 472 */
@@ -420,19 +478,25 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
420 goto fail; 478 goto fail;
421 479
422 /* count internal # of internal \0 */ 480 /* count internal # of internal \0 */
423 for (c = j = 0; j < size2 - 2; j++) { 481 for (c = j = 0; j < size2 - 1; j++) {
424 if (!str[j]) 482 if (!str[j]) {
483 pos = j;
425 c++; 484 c++;
485 }
426 } 486 }
427 if (*str == ':') { 487 if (*str == ':') {
488 /* first character after : must be valid */
489 if (!str[1])
490 goto fail;
428 /* beginning with : requires an embedded \0, 491 /* beginning with : requires an embedded \0,
429 * verify that exactly 1 internal \0 exists 492 * verify that exactly 1 internal \0 exists
430 * trailing \0 already verified by unpack_strdup 493 * trailing \0 already verified by unpack_strdup
494 *
495 * convert \0 back to : for label_parse
431 */ 496 */
432 if (c != 1) 497 if (c == 1)
433 goto fail; 498 str[pos] = ':';
434 /* first character after : must be valid */ 499 else if (c > 1)
435 if (!str[1])
436 goto fail; 500 goto fail;
437 } else if (c) 501 } else if (c)
438 /* fail - all other cases with embedded \0 */ 502 /* fail - all other cases with embedded \0 */
@@ -545,7 +609,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
545 name = tmpname; 609 name = tmpname;
546 } 610 }
547 611
548 profile = aa_alloc_profile(name, GFP_KERNEL); 612 profile = aa_alloc_profile(name, NULL, GFP_KERNEL);
549 if (!profile) 613 if (!profile)
550 return ERR_PTR(-ENOMEM); 614 return ERR_PTR(-ENOMEM);
551 615
@@ -569,13 +633,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
569 profile->xmatch_len = tmp; 633 profile->xmatch_len = tmp;
570 } 634 }
571 635
636 /* disconnected attachment string is optional */
637 (void) unpack_str(e, &profile->disconnected, "disconnected");
638
572 /* per profile debug flags (complain, audit) */ 639 /* per profile debug flags (complain, audit) */
573 if (!unpack_nameX(e, AA_STRUCT, "flags")) 640 if (!unpack_nameX(e, AA_STRUCT, "flags"))
574 goto fail; 641 goto fail;
575 if (!unpack_u32(e, &tmp, NULL)) 642 if (!unpack_u32(e, &tmp, NULL))
576 goto fail; 643 goto fail;
577 if (tmp & PACKED_FLAG_HAT) 644 if (tmp & PACKED_FLAG_HAT)
578 profile->flags |= PFLAG_HAT; 645 profile->label.flags |= FLAG_HAT;
579 if (!unpack_u32(e, &tmp, NULL)) 646 if (!unpack_u32(e, &tmp, NULL))
580 goto fail; 647 goto fail;
581 if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG)) 648 if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG))
@@ -594,10 +661,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
594 661
595 /* path_flags is optional */ 662 /* path_flags is optional */
596 if (unpack_u32(e, &profile->path_flags, "path_flags")) 663 if (unpack_u32(e, &profile->path_flags, "path_flags"))
597 profile->path_flags |= profile->flags & PFLAG_MEDIATE_DELETED; 664 profile->path_flags |= profile->label.flags &
665 PATH_MEDIATE_DELETED;
598 else 666 else
599 /* set a default value if path_flags field is not present */ 667 /* set a default value if path_flags field is not present */
600 profile->path_flags = PFLAG_MEDIATE_DELETED; 668 profile->path_flags = PATH_MEDIATE_DELETED;
601 669
602 if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL)) 670 if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
603 goto fail; 671 goto fail;
diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
index 3466a27bca09..d81617379d63 100644
--- a/security/apparmor/procattr.c
+++ b/security/apparmor/procattr.c
@@ -34,50 +34,41 @@
34 * 34 *
35 * Returns: size of string placed in @string else error code on failure 35 * Returns: size of string placed in @string else error code on failure
36 */ 36 */
37int aa_getprocattr(struct aa_profile *profile, char **string) 37int aa_getprocattr(struct aa_label *label, char **string)
38{ 38{
39 char *str; 39 struct aa_ns *ns = labels_ns(label);
40 int len = 0, mode_len = 0, ns_len = 0, name_len; 40 struct aa_ns *current_ns = aa_get_current_ns();
41 const char *mode_str = aa_profile_mode_names[profile->mode]; 41 int len;
42 const char *ns_name = NULL;
43 struct aa_ns *ns = profile->ns;
44 struct aa_ns *current_ns = __aa_current_profile()->ns;
45 char *s;
46
47 if (!aa_ns_visible(current_ns, ns, true))
48 return -EACCES;
49
50 ns_name = aa_ns_name(current_ns, ns, true);
51 ns_len = strlen(ns_name);
52 42
53 /* if the visible ns_name is > 0 increase size for : :// seperator */ 43 if (!aa_ns_visible(current_ns, ns, true)) {
54 if (ns_len) 44 aa_put_ns(current_ns);
55 ns_len += 4; 45 return -EACCES;
46 }
56 47
57 /* unconfined profiles don't have a mode string appended */ 48 len = aa_label_snxprint(NULL, 0, current_ns, label,
58 if (!unconfined(profile)) 49 FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
59 mode_len = strlen(mode_str) + 3; /* + 3 for _() */ 50 FLAG_HIDDEN_UNCONFINED);
51 AA_BUG(len < 0);
60 52
61 name_len = strlen(profile->base.hname); 53 *string = kmalloc(len + 2, GFP_KERNEL);
62 len = mode_len + ns_len + name_len + 1; /* + 1 for \n */ 54 if (!*string) {
63 s = str = kmalloc(len + 1, GFP_KERNEL); /* + 1 \0 */ 55 aa_put_ns(current_ns);
64 if (!str)
65 return -ENOMEM; 56 return -ENOMEM;
57 }
66 58
67 if (ns_len) { 59 len = aa_label_snxprint(*string, len + 2, current_ns, label,
68 /* skip over prefix current_ns->base.hname and separating // */ 60 FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
69 sprintf(s, ":%s://", ns_name); 61 FLAG_HIDDEN_UNCONFINED);
70 s += ns_len; 62 if (len < 0) {
63 aa_put_ns(current_ns);
64 return len;
71 } 65 }
72 if (unconfined(profile)) 66
73 /* mode string not being appended */ 67 (*string)[len] = '\n';
74 sprintf(s, "%s\n", profile->base.hname); 68 (*string)[len + 1] = 0;
75 else 69
76 sprintf(s, "%s (%s)\n", profile->base.hname, mode_str); 70 aa_put_ns(current_ns);
77 *string = str; 71 return len + 1;
78
79 /* NOTE: len does not include \0 of string, not saved as part of file */
80 return len;
81} 72}
82 73
83/** 74/**
@@ -108,11 +99,11 @@ static char *split_token_from_name(const char *op, char *args, u64 *token)
108 * aa_setprocattr_chagnehat - handle procattr interface to change_hat 99 * aa_setprocattr_chagnehat - handle procattr interface to change_hat
109 * @args: args received from writing to /proc/<pid>/attr/current (NOT NULL) 100 * @args: args received from writing to /proc/<pid>/attr/current (NOT NULL)
110 * @size: size of the args 101 * @size: size of the args
111 * @test: true if this is a test of change_hat permissions 102 * @flags: set of flags governing behavior
112 * 103 *
113 * Returns: %0 or error code if change_hat fails 104 * Returns: %0 or error code if change_hat fails
114 */ 105 */
115int aa_setprocattr_changehat(char *args, size_t size, int test) 106int aa_setprocattr_changehat(char *args, size_t size, int flags)
116{ 107{
117 char *hat; 108 char *hat;
118 u64 token; 109 u64 token;
@@ -147,5 +138,5 @@ int aa_setprocattr_changehat(char *args, size_t size, int test)
147 AA_DEBUG("%s: (pid %d) Magic 0x%llx count %d Hat '%s'\n", 138 AA_DEBUG("%s: (pid %d) Magic 0x%llx count %d Hat '%s'\n",
148 __func__, current->pid, token, count, "<NULL>"); 139 __func__, current->pid, token, count, "<NULL>");
149 140
150 return aa_change_hat(hats, count, token, test); 141 return aa_change_hat(hats, count, token, flags);
151} 142}
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
index 86a941afd956..d8bc842594ed 100644
--- a/security/apparmor/resource.c
+++ b/security/apparmor/resource.c
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <linux/audit.h> 15#include <linux/audit.h>
16#include <linux/security.h>
16 17
17#include "include/audit.h" 18#include "include/audit.h"
18#include "include/context.h" 19#include "include/context.h"
@@ -24,8 +25,8 @@
24 */ 25 */
25#include "rlim_names.h" 26#include "rlim_names.h"
26 27
27struct aa_fs_entry aa_fs_entry_rlimit[] = { 28struct aa_sfs_entry aa_sfs_entry_rlimit[] = {
28 AA_FS_FILE_STRING("mask", AA_FS_RLIMIT_MASK), 29 AA_SFS_FILE_STRING("mask", AA_SFS_RLIMIT_MASK),
29 { } 30 { }
30}; 31};
31 32
@@ -36,6 +37,11 @@ static void audit_cb(struct audit_buffer *ab, void *va)
36 37
37 audit_log_format(ab, " rlimit=%s value=%lu", 38 audit_log_format(ab, " rlimit=%s value=%lu",
38 rlim_names[aad(sa)->rlim.rlim], aad(sa)->rlim.max); 39 rlim_names[aad(sa)->rlim.rlim], aad(sa)->rlim.max);
40 if (aad(sa)->peer) {
41 audit_log_format(ab, " peer=");
42 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
43 FLAGS_NONE, GFP_ATOMIC);
44 }
39} 45}
40 46
41/** 47/**
@@ -48,13 +54,17 @@ static void audit_cb(struct audit_buffer *ab, void *va)
48 * Returns: 0 or sa->error else other error code on failure 54 * Returns: 0 or sa->error else other error code on failure
49 */ 55 */
50static int audit_resource(struct aa_profile *profile, unsigned int resource, 56static int audit_resource(struct aa_profile *profile, unsigned int resource,
51 unsigned long value, int error) 57 unsigned long value, struct aa_label *peer,
58 const char *info, int error)
52{ 59{
53 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SETRLIMIT); 60 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SETRLIMIT);
54 61
55 aad(&sa)->rlim.rlim = resource; 62 aad(&sa)->rlim.rlim = resource;
56 aad(&sa)->rlim.max = value; 63 aad(&sa)->rlim.max = value;
64 aad(&sa)->peer = peer;
65 aad(&sa)->info = info;
57 aad(&sa)->error = error; 66 aad(&sa)->error = error;
67
58 return aa_audit(AUDIT_APPARMOR_AUTO, profile, &sa, audit_cb); 68 return aa_audit(AUDIT_APPARMOR_AUTO, profile, &sa, audit_cb);
59} 69}
60 70
@@ -72,9 +82,21 @@ int aa_map_resource(int resource)
72 return rlim_map[resource]; 82 return rlim_map[resource];
73} 83}
74 84
85static int profile_setrlimit(struct aa_profile *profile, unsigned int resource,
86 struct rlimit *new_rlim)
87{
88 int e = 0;
89
90 if (profile->rlimits.mask & (1 << resource) && new_rlim->rlim_max >
91 profile->rlimits.limits[resource].rlim_max)
92 e = -EACCES;
93 return audit_resource(profile, resource, new_rlim->rlim_max, NULL, NULL,
94 e);
95}
96
75/** 97/**
76 * aa_task_setrlimit - test permission to set an rlimit 98 * aa_task_setrlimit - test permission to set an rlimit
77 * @profile - profile confining the task (NOT NULL) 99 * @label - label confining the task (NOT NULL)
78 * @task - task the resource is being set on 100 * @task - task the resource is being set on
79 * @resource - the resource being set 101 * @resource - the resource being set
80 * @new_rlim - the new resource limit (NOT NULL) 102 * @new_rlim - the new resource limit (NOT NULL)
@@ -83,14 +105,15 @@ int aa_map_resource(int resource)
83 * 105 *
84 * Returns: 0 or error code if setting resource failed 106 * Returns: 0 or error code if setting resource failed
85 */ 107 */
86int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task, 108int aa_task_setrlimit(struct aa_label *label, struct task_struct *task,
87 unsigned int resource, struct rlimit *new_rlim) 109 unsigned int resource, struct rlimit *new_rlim)
88{ 110{
89 struct aa_profile *task_profile; 111 struct aa_profile *profile;
112 struct aa_label *peer;
90 int error = 0; 113 int error = 0;
91 114
92 rcu_read_lock(); 115 rcu_read_lock();
93 task_profile = aa_get_profile(aa_cred_profile(__task_cred(task))); 116 peer = aa_get_newest_cred_label(__task_cred(task));
94 rcu_read_unlock(); 117 rcu_read_unlock();
95 118
96 /* TODO: extend resource control to handle other (non current) 119 /* TODO: extend resource control to handle other (non current)
@@ -99,53 +122,70 @@ int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
99 * the same profile or that the task setting the resource of another 122 * the same profile or that the task setting the resource of another
100 * task has CAP_SYS_RESOURCE. 123 * task has CAP_SYS_RESOURCE.
101 */ 124 */
102 if ((profile != task_profile &&
103 aa_capable(profile, CAP_SYS_RESOURCE, 1)) ||
104 (profile->rlimits.mask & (1 << resource) &&
105 new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max))
106 error = -EACCES;
107 125
108 aa_put_profile(task_profile); 126 if (label != peer &&
109 127 !aa_capable(label, CAP_SYS_RESOURCE, SECURITY_CAP_NOAUDIT))
110 return audit_resource(profile, resource, new_rlim->rlim_max, error); 128 error = fn_for_each(label, profile,
129 audit_resource(profile, resource,
130 new_rlim->rlim_max, peer,
131 "cap_sys_resoure", -EACCES));
132 else
133 error = fn_for_each_confined(label, profile,
134 profile_setrlimit(profile, resource, new_rlim));
135 aa_put_label(peer);
136
137 return error;
111} 138}
112 139
113/** 140/**
114 * __aa_transition_rlimits - apply new profile rlimits 141 * __aa_transition_rlimits - apply new profile rlimits
115 * @old: old profile on task (NOT NULL) 142 * @old_l: old label on task (NOT NULL)
116 * @new: new profile with rlimits to apply (NOT NULL) 143 * @new_l: new label with rlimits to apply (NOT NULL)
117 */ 144 */
118void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new) 145void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l)
119{ 146{
120 unsigned int mask = 0; 147 unsigned int mask = 0;
121 struct rlimit *rlim, *initrlim; 148 struct rlimit *rlim, *initrlim;
122 int i; 149 struct aa_profile *old, *new;
150 struct label_it i;
151
152 old = labels_profile(old_l);
153 new = labels_profile(new_l);
123 154
124 /* for any rlimits the profile controlled reset the soft limit 155 /* for any rlimits the profile controlled, reset the soft limit
125 * to the less of the tasks hard limit and the init tasks soft limit 156 * to the lesser of the tasks hard limit and the init tasks soft limit
126 */ 157 */
127 if (old->rlimits.mask) { 158 label_for_each_confined(i, old_l, old) {
128 for (i = 0, mask = 1; i < RLIM_NLIMITS; i++, mask <<= 1) { 159 if (old->rlimits.mask) {
129 if (old->rlimits.mask & mask) { 160 int j;
130 rlim = current->signal->rlim + i; 161
131 initrlim = init_task.signal->rlim + i; 162 for (j = 0, mask = 1; j < RLIM_NLIMITS; j++,
132 rlim->rlim_cur = min(rlim->rlim_max, 163 mask <<= 1) {
133 initrlim->rlim_cur); 164 if (old->rlimits.mask & mask) {
165 rlim = current->signal->rlim + j;
166 initrlim = init_task.signal->rlim + j;
167 rlim->rlim_cur = min(rlim->rlim_max,
168 initrlim->rlim_cur);
169 }
134 } 170 }
135 } 171 }
136 } 172 }
137 173
138 /* set any new hard limits as dictated by the new profile */ 174 /* set any new hard limits as dictated by the new profile */
139 if (!new->rlimits.mask) 175 label_for_each_confined(i, new_l, new) {
140 return; 176 int j;
141 for (i = 0, mask = 1; i < RLIM_NLIMITS; i++, mask <<= 1) {
142 if (!(new->rlimits.mask & mask))
143 continue;
144 177
145 rlim = current->signal->rlim + i; 178 if (!new->rlimits.mask)
146 rlim->rlim_max = min(rlim->rlim_max, 179 continue;
147 new->rlimits.limits[i].rlim_max); 180 for (j = 0, mask = 1; j < RLIM_NLIMITS; j++, mask <<= 1) {
148 /* soft limit should not exceed hard limit */ 181 if (!(new->rlimits.mask & mask))
149 rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max); 182 continue;
183
184 rlim = current->signal->rlim + j;
185 rlim->rlim_max = min(rlim->rlim_max,
186 new->rlimits.limits[j].rlim_max);
187 /* soft limit should not exceed hard limit */
188 rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
189 }
150 } 190 }
151} 191}
diff --git a/security/inode.c b/security/inode.c
index eccd58ef2ae8..8dd9ca8848e4 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -26,11 +26,31 @@
26static struct vfsmount *mount; 26static struct vfsmount *mount;
27static int mount_count; 27static int mount_count;
28 28
29static void securityfs_evict_inode(struct inode *inode)
30{
31 truncate_inode_pages_final(&inode->i_data);
32 clear_inode(inode);
33 if (S_ISLNK(inode->i_mode))
34 kfree(inode->i_link);
35}
36
37static const struct super_operations securityfs_super_operations = {
38 .statfs = simple_statfs,
39 .evict_inode = securityfs_evict_inode,
40};
41
29static int fill_super(struct super_block *sb, void *data, int silent) 42static int fill_super(struct super_block *sb, void *data, int silent)
30{ 43{
31 static const struct tree_descr files[] = {{""}}; 44 static const struct tree_descr files[] = {{""}};
45 int error;
46
47 error = simple_fill_super(sb, SECURITYFS_MAGIC, files);
48 if (error)
49 return error;
50
51 sb->s_op = &securityfs_super_operations;
32 52
33 return simple_fill_super(sb, SECURITYFS_MAGIC, files); 53 return 0;
34} 54}
35 55
36static struct dentry *get_sb(struct file_system_type *fs_type, 56static struct dentry *get_sb(struct file_system_type *fs_type,
@@ -48,7 +68,7 @@ static struct file_system_type fs_type = {
48}; 68};
49 69
50/** 70/**
51 * securityfs_create_file - create a file in the securityfs filesystem 71 * securityfs_create_dentry - create a dentry in the securityfs filesystem
52 * 72 *
53 * @name: a pointer to a string containing the name of the file to create. 73 * @name: a pointer to a string containing the name of the file to create.
54 * @mode: the permission that the file should have 74 * @mode: the permission that the file should have
@@ -60,34 +80,35 @@ static struct file_system_type fs_type = {
60 * the open() call. 80 * the open() call.
61 * @fops: a pointer to a struct file_operations that should be used for 81 * @fops: a pointer to a struct file_operations that should be used for
62 * this file. 82 * this file.
83 * @iops: a point to a struct of inode_operations that should be used for
84 * this file/dir
63 * 85 *
64 * This is the basic "create a file" function for securityfs. It allows for a 86 * This is the basic "create a file/dir/symlink" function for
65 * wide range of flexibility in creating a file, or a directory (if you 87 * securityfs. It allows for a wide range of flexibility in creating
66 * want to create a directory, the securityfs_create_dir() function is 88 * a file, or a directory (if you want to create a directory, the
67 * recommended to be used instead). 89 * securityfs_create_dir() function is recommended to be used
90 * instead).
68 * 91 *
69 * This function returns a pointer to a dentry if it succeeds. This 92 * This function returns a pointer to a dentry if it succeeds. This
70 * pointer must be passed to the securityfs_remove() function when the file is 93 * pointer must be passed to the securityfs_remove() function when the
71 * to be removed (no automatic cleanup happens if your module is unloaded, 94 * file is to be removed (no automatic cleanup happens if your module
72 * you are responsible here). If an error occurs, the function will return 95 * is unloaded, you are responsible here). If an error occurs, the
73 * the error value (via ERR_PTR). 96 * function will return the error value (via ERR_PTR).
74 * 97 *
75 * If securityfs is not enabled in the kernel, the value %-ENODEV is 98 * If securityfs is not enabled in the kernel, the value %-ENODEV is
76 * returned. 99 * returned.
77 */ 100 */
78struct dentry *securityfs_create_file(const char *name, umode_t mode, 101static struct dentry *securityfs_create_dentry(const char *name, umode_t mode,
79 struct dentry *parent, void *data, 102 struct dentry *parent, void *data,
80 const struct file_operations *fops) 103 const struct file_operations *fops,
104 const struct inode_operations *iops)
81{ 105{
82 struct dentry *dentry; 106 struct dentry *dentry;
83 int is_dir = S_ISDIR(mode);
84 struct inode *dir, *inode; 107 struct inode *dir, *inode;
85 int error; 108 int error;
86 109
87 if (!is_dir) { 110 if (!(mode & S_IFMT))
88 BUG_ON(!fops);
89 mode = (mode & S_IALLUGO) | S_IFREG; 111 mode = (mode & S_IALLUGO) | S_IFREG;
90 }
91 112
92 pr_debug("securityfs: creating file '%s'\n",name); 113 pr_debug("securityfs: creating file '%s'\n",name);
93 114
@@ -120,11 +141,14 @@ struct dentry *securityfs_create_file(const char *name, umode_t mode,
120 inode->i_mode = mode; 141 inode->i_mode = mode;
121 inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); 142 inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
122 inode->i_private = data; 143 inode->i_private = data;
123 if (is_dir) { 144 if (S_ISDIR(mode)) {
124 inode->i_op = &simple_dir_inode_operations; 145 inode->i_op = &simple_dir_inode_operations;
125 inode->i_fop = &simple_dir_operations; 146 inode->i_fop = &simple_dir_operations;
126 inc_nlink(inode); 147 inc_nlink(inode);
127 inc_nlink(dir); 148 inc_nlink(dir);
149 } else if (S_ISLNK(mode)) {
150 inode->i_op = iops ? iops : &simple_symlink_inode_operations;
151 inode->i_link = data;
128 } else { 152 } else {
129 inode->i_fop = fops; 153 inode->i_fop = fops;
130 } 154 }
@@ -141,6 +165,38 @@ out:
141 simple_release_fs(&mount, &mount_count); 165 simple_release_fs(&mount, &mount_count);
142 return dentry; 166 return dentry;
143} 167}
168
169/**
170 * securityfs_create_file - create a file in the securityfs filesystem
171 *
172 * @name: a pointer to a string containing the name of the file to create.
173 * @mode: the permission that the file should have
174 * @parent: a pointer to the parent dentry for this file. This should be a
175 * directory dentry if set. If this parameter is %NULL, then the
176 * file will be created in the root of the securityfs filesystem.
177 * @data: a pointer to something that the caller will want to get to later
178 * on. The inode.i_private pointer will point to this value on
179 * the open() call.
180 * @fops: a pointer to a struct file_operations that should be used for
181 * this file.
182 *
183 * This function creates a file in securityfs with the given @name.
184 *
185 * This function returns a pointer to a dentry if it succeeds. This
186 * pointer must be passed to the securityfs_remove() function when the file is
187 * to be removed (no automatic cleanup happens if your module is unloaded,
188 * you are responsible here). If an error occurs, the function will return
189 * the error value (via ERR_PTR).
190 *
191 * If securityfs is not enabled in the kernel, the value %-ENODEV is
192 * returned.
193 */
194struct dentry *securityfs_create_file(const char *name, umode_t mode,
195 struct dentry *parent, void *data,
196 const struct file_operations *fops)
197{
198 return securityfs_create_dentry(name, mode, parent, data, fops, NULL);
199}
144EXPORT_SYMBOL_GPL(securityfs_create_file); 200EXPORT_SYMBOL_GPL(securityfs_create_file);
145 201
146/** 202/**
@@ -165,13 +221,59 @@ EXPORT_SYMBOL_GPL(securityfs_create_file);
165 */ 221 */
166struct dentry *securityfs_create_dir(const char *name, struct dentry *parent) 222struct dentry *securityfs_create_dir(const char *name, struct dentry *parent)
167{ 223{
168 return securityfs_create_file(name, 224 return securityfs_create_file(name, S_IFDIR | 0755, parent, NULL, NULL);
169 S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
170 parent, NULL, NULL);
171} 225}
172EXPORT_SYMBOL_GPL(securityfs_create_dir); 226EXPORT_SYMBOL_GPL(securityfs_create_dir);
173 227
174/** 228/**
229 * securityfs_create_symlink - create a symlink in the securityfs filesystem
230 *
231 * @name: a pointer to a string containing the name of the symlink to
232 * create.
233 * @parent: a pointer to the parent dentry for the symlink. This should be a
234 * directory dentry if set. If this parameter is %NULL, then the
235 * directory will be created in the root of the securityfs filesystem.
236 * @target: a pointer to a string containing the name of the symlink's target.
237 * If this parameter is %NULL, then the @iops parameter needs to be
238 * setup to handle .readlink and .get_link inode_operations.
239 * @iops: a pointer to the struct inode_operations to use for the symlink. If
240 * this parameter is %NULL, then the default simple_symlink_inode
241 * operations will be used.
242 *
243 * This function creates a symlink in securityfs with the given @name.
244 *
245 * This function returns a pointer to a dentry if it succeeds. This
246 * pointer must be passed to the securityfs_remove() function when the file is
247 * to be removed (no automatic cleanup happens if your module is unloaded,
248 * you are responsible here). If an error occurs, the function will return
249 * the error value (via ERR_PTR).
250 *
251 * If securityfs is not enabled in the kernel, the value %-ENODEV is
252 * returned.
253 */
254struct dentry *securityfs_create_symlink(const char *name,
255 struct dentry *parent,
256 const char *target,
257 const struct inode_operations *iops)
258{
259 struct dentry *dent;
260 char *link = NULL;
261
262 if (target) {
263 link = kstrdup(target, GFP_KERNEL);
264 if (!link)
265 return ERR_PTR(-ENOMEM);
266 }
267 dent = securityfs_create_dentry(name, S_IFLNK | 0444, parent,
268 link, NULL, iops);
269 if (IS_ERR(dent))
270 kfree(link);
271
272 return dent;
273}
274EXPORT_SYMBOL_GPL(securityfs_create_symlink);
275
276/**
175 * securityfs_remove - removes a file or directory from the securityfs filesystem 277 * securityfs_remove - removes a file or directory from the securityfs filesystem
176 * 278 *
177 * @dentry: a pointer to a the dentry of the file or directory to be removed. 279 * @dentry: a pointer to a the dentry of the file or directory to be removed.
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index 80052ed8d467..ab6a029062a1 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -92,13 +92,13 @@ int asymmetric_verify(struct key *keyring, const char *sig,
92 92
93 siglen -= sizeof(*hdr); 93 siglen -= sizeof(*hdr);
94 94
95 if (siglen != __be16_to_cpu(hdr->sig_size)) 95 if (siglen != be16_to_cpu(hdr->sig_size))
96 return -EBADMSG; 96 return -EBADMSG;
97 97
98 if (hdr->hash_algo >= HASH_ALGO__LAST) 98 if (hdr->hash_algo >= HASH_ALGO__LAST)
99 return -ENOPKG; 99 return -ENOPKG;
100 100
101 key = request_asymmetric_key(keyring, __be32_to_cpu(hdr->keyid)); 101 key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
102 if (IS_ERR(key)) 102 if (IS_ERR(key))
103 return PTR_ERR(key); 103 return PTR_ERR(key);
104 104
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index c710d22042f9..6fc888ca468e 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -182,7 +182,7 @@ security_initcall(integrity_iintcache_init);
182 * 182 *
183 */ 183 */
184int integrity_kernel_read(struct file *file, loff_t offset, 184int integrity_kernel_read(struct file *file, loff_t offset,
185 char *addr, unsigned long count) 185 void *addr, unsigned long count)
186{ 186{
187 mm_segment_t old_fs; 187 mm_segment_t old_fs;
188 char __user *buf = (char __user *)addr; 188 char __user *buf = (char __user *)addr;
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 370eb2f4dd37..35ef69312811 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -96,19 +96,19 @@ choice
96 96
97 config IMA_DEFAULT_HASH_SHA1 97 config IMA_DEFAULT_HASH_SHA1
98 bool "SHA1 (default)" 98 bool "SHA1 (default)"
99 depends on CRYPTO_SHA1 99 depends on CRYPTO_SHA1=y
100 100
101 config IMA_DEFAULT_HASH_SHA256 101 config IMA_DEFAULT_HASH_SHA256
102 bool "SHA256" 102 bool "SHA256"
103 depends on CRYPTO_SHA256 && !IMA_TEMPLATE 103 depends on CRYPTO_SHA256=y && !IMA_TEMPLATE
104 104
105 config IMA_DEFAULT_HASH_SHA512 105 config IMA_DEFAULT_HASH_SHA512
106 bool "SHA512" 106 bool "SHA512"
107 depends on CRYPTO_SHA512 && !IMA_TEMPLATE 107 depends on CRYPTO_SHA512=y && !IMA_TEMPLATE
108 108
109 config IMA_DEFAULT_HASH_WP512 109 config IMA_DEFAULT_HASH_WP512
110 bool "WP512" 110 bool "WP512"
111 depends on CRYPTO_WP512 && !IMA_TEMPLATE 111 depends on CRYPTO_WP512=y && !IMA_TEMPLATE
112endchoice 112endchoice
113 113
114config IMA_DEFAULT_HASH 114config IMA_DEFAULT_HASH
@@ -155,6 +155,14 @@ config IMA_APPRAISE
155 <http://linux-ima.sourceforge.net> 155 <http://linux-ima.sourceforge.net>
156 If unsure, say N. 156 If unsure, say N.
157 157
158config IMA_APPRAISE_BOOTPARAM
159 bool "ima_appraise boot parameter"
160 depends on IMA_APPRAISE
161 default y
162 help
163 This option enables the different "ima_appraise=" modes
164 (eg. fix, log) from the boot command line.
165
158config IMA_TRUSTED_KEYRING 166config IMA_TRUSTED_KEYRING
159 bool "Require all keys on the .ima keyring be signed (deprecated)" 167 bool "Require all keys on the .ima keyring be signed (deprecated)"
160 depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING 168 depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index b563fbd4d122..d52b487ad259 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -172,17 +172,22 @@ static inline unsigned long ima_hash_key(u8 *digest)
172 return hash_long(*digest, IMA_HASH_BITS); 172 return hash_long(*digest, IMA_HASH_BITS);
173} 173}
174 174
175#define __ima_hooks(hook) \
176 hook(NONE) \
177 hook(FILE_CHECK) \
178 hook(MMAP_CHECK) \
179 hook(BPRM_CHECK) \
180 hook(POST_SETATTR) \
181 hook(MODULE_CHECK) \
182 hook(FIRMWARE_CHECK) \
183 hook(KEXEC_KERNEL_CHECK) \
184 hook(KEXEC_INITRAMFS_CHECK) \
185 hook(POLICY_CHECK) \
186 hook(MAX_CHECK)
187#define __ima_hook_enumify(ENUM) ENUM,
188
175enum ima_hooks { 189enum ima_hooks {
176 FILE_CHECK = 1, 190 __ima_hooks(__ima_hook_enumify)
177 MMAP_CHECK,
178 BPRM_CHECK,
179 POST_SETATTR,
180 MODULE_CHECK,
181 FIRMWARE_CHECK,
182 KEXEC_KERNEL_CHECK,
183 KEXEC_INITRAMFS_CHECK,
184 POLICY_CHECK,
185 MAX_CHECK
186}; 191};
187 192
188/* LIM API function definitions */ 193/* LIM API function definitions */
@@ -284,7 +289,7 @@ static inline int ima_read_xattr(struct dentry *dentry,
284 return 0; 289 return 0;
285} 290}
286 291
287#endif 292#endif /* CONFIG_IMA_APPRAISE */
288 293
289/* LSM based policy rules require audit */ 294/* LSM based policy rules require audit */
290#ifdef CONFIG_IMA_LSM_RULES 295#ifdef CONFIG_IMA_LSM_RULES
@@ -306,12 +311,12 @@ static inline int security_filter_rule_match(u32 secid, u32 field, u32 op,
306{ 311{
307 return -EINVAL; 312 return -EINVAL;
308} 313}
309#endif /* CONFIG_IMA_TRUSTED_KEYRING */ 314#endif /* CONFIG_IMA_LSM_RULES */
310 315
311#ifdef CONFIG_IMA_READ_POLICY 316#ifdef CONFIG_IMA_READ_POLICY
312#define POLICY_FILE_FLAGS (S_IWUSR | S_IRUSR) 317#define POLICY_FILE_FLAGS (S_IWUSR | S_IRUSR)
313#else 318#else
314#define POLICY_FILE_FLAGS S_IWUSR 319#define POLICY_FILE_FLAGS S_IWUSR
315#endif /* CONFIG_IMA_WRITE_POLICY */ 320#endif /* CONFIG_IMA_READ_POLICY */
316 321
317#endif /* __LINUX_IMA_H */ 322#endif /* __LINUX_IMA_H */
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 5d0785cfe063..809ba70fbbbf 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -20,18 +20,30 @@
20 20
21static int __init default_appraise_setup(char *str) 21static int __init default_appraise_setup(char *str)
22{ 22{
23#ifdef CONFIG_IMA_APPRAISE_BOOTPARAM
23 if (strncmp(str, "off", 3) == 0) 24 if (strncmp(str, "off", 3) == 0)
24 ima_appraise = 0; 25 ima_appraise = 0;
25 else if (strncmp(str, "log", 3) == 0) 26 else if (strncmp(str, "log", 3) == 0)
26 ima_appraise = IMA_APPRAISE_LOG; 27 ima_appraise = IMA_APPRAISE_LOG;
27 else if (strncmp(str, "fix", 3) == 0) 28 else if (strncmp(str, "fix", 3) == 0)
28 ima_appraise = IMA_APPRAISE_FIX; 29 ima_appraise = IMA_APPRAISE_FIX;
30#endif
29 return 1; 31 return 1;
30} 32}
31 33
32__setup("ima_appraise=", default_appraise_setup); 34__setup("ima_appraise=", default_appraise_setup);
33 35
34/* 36/*
37 * is_ima_appraise_enabled - return appraise status
38 *
39 * Only return enabled, if not in ima_appraise="fix" or "log" modes.
40 */
41bool is_ima_appraise_enabled(void)
42{
43 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? 1 : 0;
44}
45
46/*
35 * ima_must_appraise - set appraise flag 47 * ima_must_appraise - set appraise flag
36 * 48 *
37 * Return 1 to appraise 49 * Return 1 to appraise
@@ -205,7 +217,8 @@ int ima_appraise_measurement(enum ima_hooks func,
205 if (rc && rc != -ENODATA) 217 if (rc && rc != -ENODATA)
206 goto out; 218 goto out;
207 219
208 cause = "missing-hash"; 220 cause = iint->flags & IMA_DIGSIG_REQUIRED ?
221 "IMA-signature-required" : "missing-hash";
209 status = INTEGRITY_NOLABEL; 222 status = INTEGRITY_NOLABEL;
210 if (opened & FILE_CREATED) 223 if (opened & FILE_CREATED)
211 iint->flags |= IMA_NEW_FILE; 224 iint->flags |= IMA_NEW_FILE;
@@ -228,6 +241,7 @@ int ima_appraise_measurement(enum ima_hooks func,
228 case IMA_XATTR_DIGEST_NG: 241 case IMA_XATTR_DIGEST_NG:
229 /* first byte contains algorithm id */ 242 /* first byte contains algorithm id */
230 hash_start = 1; 243 hash_start = 1;
244 /* fall through */
231 case IMA_XATTR_DIGEST: 245 case IMA_XATTR_DIGEST:
232 if (iint->flags & IMA_DIGSIG_REQUIRED) { 246 if (iint->flags & IMA_DIGSIG_REQUIRED) {
233 cause = "IMA-signature-required"; 247 cause = "IMA-signature-required";
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index ca303e5d2b94..ad491c51e833 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -323,16 +323,11 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
323 if (*ppos != 0) 323 if (*ppos != 0)
324 goto out; 324 goto out;
325 325
326 result = -ENOMEM; 326 data = memdup_user_nul(buf, datalen);
327 data = kmalloc(datalen + 1, GFP_KERNEL); 327 if (IS_ERR(data)) {
328 if (!data) 328 result = PTR_ERR(data);
329 goto out; 329 goto out;
330 330 }
331 *(data + datalen) = '\0';
332
333 result = -EFAULT;
334 if (copy_from_user(data, buf, datalen))
335 goto out_free;
336 331
337 result = mutex_lock_interruptible(&ima_write_mutex); 332 result = mutex_lock_interruptible(&ima_write_mutex);
338 if (result < 0) 333 if (result < 0)
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 6f885fab9d84..95209a5f8595 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -96,6 +96,8 @@ static struct ima_rule_entry dont_measure_rules[] __ro_after_init = {
96 {.action = DONT_MEASURE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, 96 {.action = DONT_MEASURE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
97 {.action = DONT_MEASURE, .fsmagic = CGROUP_SUPER_MAGIC, 97 {.action = DONT_MEASURE, .fsmagic = CGROUP_SUPER_MAGIC,
98 .flags = IMA_FSMAGIC}, 98 .flags = IMA_FSMAGIC},
99 {.action = DONT_MEASURE, .fsmagic = CGROUP2_SUPER_MAGIC,
100 .flags = IMA_FSMAGIC},
99 {.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC} 101 {.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}
100}; 102};
101 103
@@ -139,6 +141,7 @@ static struct ima_rule_entry default_appraise_rules[] __ro_after_init = {
139 {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, 141 {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
140 {.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}, 142 {.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC},
141 {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC}, 143 {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC},
144 {.action = DONT_APPRAISE, .fsmagic = CGROUP2_SUPER_MAGIC, .flags = IMA_FSMAGIC},
142#ifdef CONFIG_IMA_WRITE_POLICY 145#ifdef CONFIG_IMA_WRITE_POLICY
143 {.action = APPRAISE, .func = POLICY_CHECK, 146 {.action = APPRAISE, .func = POLICY_CHECK,
144 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, 147 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
@@ -153,6 +156,17 @@ static struct ima_rule_entry default_appraise_rules[] __ro_after_init = {
153#endif 156#endif
154}; 157};
155 158
159static struct ima_rule_entry secure_boot_rules[] __ro_after_init = {
160 {.action = APPRAISE, .func = MODULE_CHECK,
161 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
162 {.action = APPRAISE, .func = FIRMWARE_CHECK,
163 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
164 {.action = APPRAISE, .func = KEXEC_KERNEL_CHECK,
165 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
166 {.action = APPRAISE, .func = POLICY_CHECK,
167 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
168};
169
156static LIST_HEAD(ima_default_rules); 170static LIST_HEAD(ima_default_rules);
157static LIST_HEAD(ima_policy_rules); 171static LIST_HEAD(ima_policy_rules);
158static LIST_HEAD(ima_temp_rules); 172static LIST_HEAD(ima_temp_rules);
@@ -170,19 +184,27 @@ static int __init default_measure_policy_setup(char *str)
170} 184}
171__setup("ima_tcb", default_measure_policy_setup); 185__setup("ima_tcb", default_measure_policy_setup);
172 186
187static bool ima_use_appraise_tcb __initdata;
188static bool ima_use_secure_boot __initdata;
173static int __init policy_setup(char *str) 189static int __init policy_setup(char *str)
174{ 190{
175 if (ima_policy) 191 char *p;
176 return 1;
177 192
178 if (strcmp(str, "tcb") == 0) 193 while ((p = strsep(&str, " |\n")) != NULL) {
179 ima_policy = DEFAULT_TCB; 194 if (*p == ' ')
195 continue;
196 if ((strcmp(p, "tcb") == 0) && !ima_policy)
197 ima_policy = DEFAULT_TCB;
198 else if (strcmp(p, "appraise_tcb") == 0)
199 ima_use_appraise_tcb = 1;
200 else if (strcmp(p, "secure_boot") == 0)
201 ima_use_secure_boot = 1;
202 }
180 203
181 return 1; 204 return 1;
182} 205}
183__setup("ima_policy=", policy_setup); 206__setup("ima_policy=", policy_setup);
184 207
185static bool ima_use_appraise_tcb __initdata;
186static int __init default_appraise_policy_setup(char *str) 208static int __init default_appraise_policy_setup(char *str)
187{ 209{
188 ima_use_appraise_tcb = 1; 210 ima_use_appraise_tcb = 1;
@@ -405,12 +427,14 @@ void ima_update_policy_flag(void)
405 */ 427 */
406void __init ima_init_policy(void) 428void __init ima_init_policy(void)
407{ 429{
408 int i, measure_entries, appraise_entries; 430 int i, measure_entries, appraise_entries, secure_boot_entries;
409 431
410 /* if !ima_policy set entries = 0 so we load NO default rules */ 432 /* if !ima_policy set entries = 0 so we load NO default rules */
411 measure_entries = ima_policy ? ARRAY_SIZE(dont_measure_rules) : 0; 433 measure_entries = ima_policy ? ARRAY_SIZE(dont_measure_rules) : 0;
412 appraise_entries = ima_use_appraise_tcb ? 434 appraise_entries = ima_use_appraise_tcb ?
413 ARRAY_SIZE(default_appraise_rules) : 0; 435 ARRAY_SIZE(default_appraise_rules) : 0;
436 secure_boot_entries = ima_use_secure_boot ?
437 ARRAY_SIZE(secure_boot_rules) : 0;
414 438
415 for (i = 0; i < measure_entries; i++) 439 for (i = 0; i < measure_entries; i++)
416 list_add_tail(&dont_measure_rules[i].list, &ima_default_rules); 440 list_add_tail(&dont_measure_rules[i].list, &ima_default_rules);
@@ -429,6 +453,14 @@ void __init ima_init_policy(void)
429 break; 453 break;
430 } 454 }
431 455
456 /*
457 * Insert the appraise rules requiring file signatures, prior to
458 * any other appraise rules.
459 */
460 for (i = 0; i < secure_boot_entries; i++)
461 list_add_tail(&secure_boot_rules[i].list,
462 &ima_default_rules);
463
432 for (i = 0; i < appraise_entries; i++) { 464 for (i = 0; i < appraise_entries; i++) {
433 list_add_tail(&default_appraise_rules[i].list, 465 list_add_tail(&default_appraise_rules[i].list,
434 &ima_default_rules); 466 &ima_default_rules);
@@ -931,30 +963,17 @@ enum {
931 mask_exec = 0, mask_write, mask_read, mask_append 963 mask_exec = 0, mask_write, mask_read, mask_append
932}; 964};
933 965
934static char *mask_tokens[] = { 966static const char *const mask_tokens[] = {
935 "MAY_EXEC", 967 "MAY_EXEC",
936 "MAY_WRITE", 968 "MAY_WRITE",
937 "MAY_READ", 969 "MAY_READ",
938 "MAY_APPEND" 970 "MAY_APPEND"
939}; 971};
940 972
941enum { 973#define __ima_hook_stringify(str) (#str),
942 func_file = 0, func_mmap, func_bprm,
943 func_module, func_firmware, func_post,
944 func_kexec_kernel, func_kexec_initramfs,
945 func_policy
946};
947 974
948static char *func_tokens[] = { 975static const char *const func_tokens[] = {
949 "FILE_CHECK", 976 __ima_hooks(__ima_hook_stringify)
950 "MMAP_CHECK",
951 "BPRM_CHECK",
952 "MODULE_CHECK",
953 "FIRMWARE_CHECK",
954 "POST_SETATTR",
955 "KEXEC_KERNEL_CHECK",
956 "KEXEC_INITRAMFS_CHECK",
957 "POLICY_CHECK"
958}; 977};
959 978
960void *ima_policy_start(struct seq_file *m, loff_t *pos) 979void *ima_policy_start(struct seq_file *m, loff_t *pos)
@@ -991,49 +1010,16 @@ void ima_policy_stop(struct seq_file *m, void *v)
991 1010
992#define pt(token) policy_tokens[token + Opt_err].pattern 1011#define pt(token) policy_tokens[token + Opt_err].pattern
993#define mt(token) mask_tokens[token] 1012#define mt(token) mask_tokens[token]
994#define ft(token) func_tokens[token]
995 1013
996/* 1014/*
997 * policy_func_show - display the ima_hooks policy rule 1015 * policy_func_show - display the ima_hooks policy rule
998 */ 1016 */
999static void policy_func_show(struct seq_file *m, enum ima_hooks func) 1017static void policy_func_show(struct seq_file *m, enum ima_hooks func)
1000{ 1018{
1001 char tbuf[64] = {0,}; 1019 if (func > 0 && func < MAX_CHECK)
1002 1020 seq_printf(m, "func=%s ", func_tokens[func]);
1003 switch (func) { 1021 else
1004 case FILE_CHECK: 1022 seq_printf(m, "func=%d ", func);
1005 seq_printf(m, pt(Opt_func), ft(func_file));
1006 break;
1007 case MMAP_CHECK:
1008 seq_printf(m, pt(Opt_func), ft(func_mmap));
1009 break;
1010 case BPRM_CHECK:
1011 seq_printf(m, pt(Opt_func), ft(func_bprm));
1012 break;
1013 case MODULE_CHECK:
1014 seq_printf(m, pt(Opt_func), ft(func_module));
1015 break;
1016 case FIRMWARE_CHECK:
1017 seq_printf(m, pt(Opt_func), ft(func_firmware));
1018 break;
1019 case POST_SETATTR:
1020 seq_printf(m, pt(Opt_func), ft(func_post));
1021 break;
1022 case KEXEC_KERNEL_CHECK:
1023 seq_printf(m, pt(Opt_func), ft(func_kexec_kernel));
1024 break;
1025 case KEXEC_INITRAMFS_CHECK:
1026 seq_printf(m, pt(Opt_func), ft(func_kexec_initramfs));
1027 break;
1028 case POLICY_CHECK:
1029 seq_printf(m, pt(Opt_func), ft(func_policy));
1030 break;
1031 default:
1032 snprintf(tbuf, sizeof(tbuf), "%d", func);
1033 seq_printf(m, pt(Opt_func), tbuf);
1034 break;
1035 }
1036 seq_puts(m, " ");
1037} 1023}
1038 1024
1039int ima_policy_show(struct seq_file *m, void *v) 1025int ima_policy_show(struct seq_file *m, void *v)
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index d9aa5ab71204..a02a86d51102 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -81,7 +81,7 @@ static int get_binary_runtime_size(struct ima_template_entry *entry)
81 size += sizeof(u32); /* pcr */ 81 size += sizeof(u32); /* pcr */
82 size += sizeof(entry->digest); 82 size += sizeof(entry->digest);
83 size += sizeof(int); /* template name size field */ 83 size += sizeof(int); /* template name size field */
84 size += strlen(entry->template_desc->name) + 1; 84 size += strlen(entry->template_desc->name);
85 size += sizeof(entry->template_data_len); 85 size += sizeof(entry->template_data_len);
86 size += entry->template_data_len; 86 size += entry->template_data_len;
87 return size; 87 return size;
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index cebb37c63629..7412d0291ab9 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -19,6 +19,9 @@
19#include "ima.h" 19#include "ima.h"
20#include "ima_template_lib.h" 20#include "ima_template_lib.h"
21 21
22enum header_fields { HDR_PCR, HDR_DIGEST, HDR_TEMPLATE_NAME,
23 HDR_TEMPLATE_DATA, HDR__LAST };
24
22static struct ima_template_desc builtin_templates[] = { 25static struct ima_template_desc builtin_templates[] = {
23 {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT}, 26 {.name = IMA_TEMPLATE_IMA_NAME, .fmt = IMA_TEMPLATE_IMA_FMT},
24 {.name = "ima-ng", .fmt = "d-ng|n-ng"}, 27 {.name = "ima-ng", .fmt = "d-ng|n-ng"},
@@ -274,13 +277,6 @@ static int ima_restore_template_data(struct ima_template_desc *template_desc,
274 int template_data_size, 277 int template_data_size,
275 struct ima_template_entry **entry) 278 struct ima_template_entry **entry)
276{ 279{
277 struct binary_field_data {
278 u32 len;
279 u8 data[0];
280 } __packed;
281
282 struct binary_field_data *field_data;
283 int offset = 0;
284 int ret = 0; 280 int ret = 0;
285 int i; 281 int i;
286 282
@@ -290,30 +286,19 @@ static int ima_restore_template_data(struct ima_template_desc *template_desc,
290 if (!*entry) 286 if (!*entry)
291 return -ENOMEM; 287 return -ENOMEM;
292 288
289 ret = ima_parse_buf(template_data, template_data + template_data_size,
290 NULL, template_desc->num_fields,
291 (*entry)->template_data, NULL, NULL,
292 ENFORCE_FIELDS | ENFORCE_BUFEND, "template data");
293 if (ret < 0) {
294 kfree(*entry);
295 return ret;
296 }
297
293 (*entry)->template_desc = template_desc; 298 (*entry)->template_desc = template_desc;
294 for (i = 0; i < template_desc->num_fields; i++) { 299 for (i = 0; i < template_desc->num_fields; i++) {
295 field_data = template_data + offset; 300 struct ima_field_data *field_data = &(*entry)->template_data[i];
296 301 u8 *data = field_data->data;
297 /* Each field of the template data is prefixed with a length. */
298 if (offset > (template_data_size - sizeof(*field_data))) {
299 pr_err("Restoring the template field failed\n");
300 ret = -EINVAL;
301 break;
302 }
303 offset += sizeof(*field_data);
304
305 if (ima_canonical_fmt)
306 field_data->len = le32_to_cpu(field_data->len);
307
308 if (offset > (template_data_size - field_data->len)) {
309 pr_err("Restoring the template field data failed\n");
310 ret = -EINVAL;
311 break;
312 }
313 offset += field_data->len;
314
315 (*entry)->template_data[i].len = field_data->len;
316 (*entry)->template_data_len += sizeof(field_data->len);
317 302
318 (*entry)->template_data[i].data = 303 (*entry)->template_data[i].data =
319 kzalloc(field_data->len + 1, GFP_KERNEL); 304 kzalloc(field_data->len + 1, GFP_KERNEL);
@@ -321,8 +306,8 @@ static int ima_restore_template_data(struct ima_template_desc *template_desc,
321 ret = -ENOMEM; 306 ret = -ENOMEM;
322 break; 307 break;
323 } 308 }
324 memcpy((*entry)->template_data[i].data, field_data->data, 309 memcpy((*entry)->template_data[i].data, data, field_data->len);
325 field_data->len); 310 (*entry)->template_data_len += sizeof(field_data->len);
326 (*entry)->template_data_len += field_data->len; 311 (*entry)->template_data_len += field_data->len;
327 } 312 }
328 313
@@ -337,27 +322,19 @@ static int ima_restore_template_data(struct ima_template_desc *template_desc,
337/* Restore the serialized binary measurement list without extending PCRs. */ 322/* Restore the serialized binary measurement list without extending PCRs. */
338int ima_restore_measurement_list(loff_t size, void *buf) 323int ima_restore_measurement_list(loff_t size, void *buf)
339{ 324{
340 struct binary_hdr_v1 {
341 u32 pcr;
342 u8 digest[TPM_DIGEST_SIZE];
343 u32 template_name_len;
344 char template_name[0];
345 } __packed;
346 char template_name[MAX_TEMPLATE_NAME_LEN]; 325 char template_name[MAX_TEMPLATE_NAME_LEN];
347 326
348 struct binary_data_v1 {
349 u32 template_data_size;
350 char template_data[0];
351 } __packed;
352
353 struct ima_kexec_hdr *khdr = buf; 327 struct ima_kexec_hdr *khdr = buf;
354 struct binary_hdr_v1 *hdr_v1; 328 struct ima_field_data hdr[HDR__LAST] = {
355 struct binary_data_v1 *data_v1; 329 [HDR_PCR] = {.len = sizeof(u32)},
330 [HDR_DIGEST] = {.len = TPM_DIGEST_SIZE},
331 };
356 332
357 void *bufp = buf + sizeof(*khdr); 333 void *bufp = buf + sizeof(*khdr);
358 void *bufendp; 334 void *bufendp;
359 struct ima_template_entry *entry; 335 struct ima_template_entry *entry;
360 struct ima_template_desc *template_desc; 336 struct ima_template_desc *template_desc;
337 DECLARE_BITMAP(hdr_mask, HDR__LAST);
361 unsigned long count = 0; 338 unsigned long count = 0;
362 int ret = 0; 339 int ret = 0;
363 340
@@ -380,6 +357,10 @@ int ima_restore_measurement_list(loff_t size, void *buf)
380 return -EINVAL; 357 return -EINVAL;
381 } 358 }
382 359
360 bitmap_zero(hdr_mask, HDR__LAST);
361 bitmap_set(hdr_mask, HDR_PCR, 1);
362 bitmap_set(hdr_mask, HDR_DIGEST, 1);
363
383 /* 364 /*
384 * ima kexec buffer prefix: version, buffer size, count 365 * ima kexec buffer prefix: version, buffer size, count
385 * v1 format: pcr, digest, template-name-len, template-name, 366 * v1 format: pcr, digest, template-name-len, template-name,
@@ -387,31 +368,25 @@ int ima_restore_measurement_list(loff_t size, void *buf)
387 */ 368 */
388 bufendp = buf + khdr->buffer_size; 369 bufendp = buf + khdr->buffer_size;
389 while ((bufp < bufendp) && (count++ < khdr->count)) { 370 while ((bufp < bufendp) && (count++ < khdr->count)) {
390 hdr_v1 = bufp; 371 int enforce_mask = ENFORCE_FIELDS;
391 if (bufp > (bufendp - sizeof(*hdr_v1))) {
392 pr_err("attempting to restore partial measurement\n");
393 ret = -EINVAL;
394 break;
395 }
396 bufp += sizeof(*hdr_v1);
397 372
398 if (ima_canonical_fmt) 373 enforce_mask |= (count == khdr->count) ? ENFORCE_BUFEND : 0;
399 hdr_v1->template_name_len = 374 ret = ima_parse_buf(bufp, bufendp, &bufp, HDR__LAST, hdr, NULL,
400 le32_to_cpu(hdr_v1->template_name_len); 375 hdr_mask, enforce_mask, "entry header");
376 if (ret < 0)
377 break;
401 378
402 if ((hdr_v1->template_name_len >= MAX_TEMPLATE_NAME_LEN) || 379 if (hdr[HDR_TEMPLATE_NAME].len >= MAX_TEMPLATE_NAME_LEN) {
403 (bufp > (bufendp - hdr_v1->template_name_len))) {
404 pr_err("attempting to restore a template name \ 380 pr_err("attempting to restore a template name \
405 that is too long\n"); 381 that is too long\n");
406 ret = -EINVAL; 382 ret = -EINVAL;
407 break; 383 break;
408 } 384 }
409 data_v1 = bufp += (u_int8_t)hdr_v1->template_name_len;
410 385
411 /* template name is not null terminated */ 386 /* template name is not null terminated */
412 memcpy(template_name, hdr_v1->template_name, 387 memcpy(template_name, hdr[HDR_TEMPLATE_NAME].data,
413 hdr_v1->template_name_len); 388 hdr[HDR_TEMPLATE_NAME].len);
414 template_name[hdr_v1->template_name_len] = 0; 389 template_name[hdr[HDR_TEMPLATE_NAME].len] = 0;
415 390
416 if (strcmp(template_name, "ima") == 0) { 391 if (strcmp(template_name, "ima") == 0) {
417 pr_err("attempting to restore an unsupported \ 392 pr_err("attempting to restore an unsupported \
@@ -441,34 +416,17 @@ int ima_restore_measurement_list(loff_t size, void *buf)
441 break; 416 break;
442 } 417 }
443 418
444 if (bufp > (bufendp - sizeof(data_v1->template_data_size))) {
445 pr_err("restoring the template data size failed\n");
446 ret = -EINVAL;
447 break;
448 }
449 bufp += (u_int8_t) sizeof(data_v1->template_data_size);
450
451 if (ima_canonical_fmt)
452 data_v1->template_data_size =
453 le32_to_cpu(data_v1->template_data_size);
454
455 if (bufp > (bufendp - data_v1->template_data_size)) {
456 pr_err("restoring the template data failed\n");
457 ret = -EINVAL;
458 break;
459 }
460 bufp += data_v1->template_data_size;
461
462 ret = ima_restore_template_data(template_desc, 419 ret = ima_restore_template_data(template_desc,
463 data_v1->template_data, 420 hdr[HDR_TEMPLATE_DATA].data,
464 data_v1->template_data_size, 421 hdr[HDR_TEMPLATE_DATA].len,
465 &entry); 422 &entry);
466 if (ret < 0) 423 if (ret < 0)
467 break; 424 break;
468 425
469 memcpy(entry->digest, hdr_v1->digest, TPM_DIGEST_SIZE); 426 memcpy(entry->digest, hdr[HDR_DIGEST].data,
470 entry->pcr = 427 hdr[HDR_DIGEST].len);
471 !ima_canonical_fmt ? hdr_v1->pcr : le32_to_cpu(hdr_v1->pcr); 428 entry->pcr = !ima_canonical_fmt ? *(hdr[HDR_PCR].data) :
429 le32_to_cpu(*(hdr[HDR_PCR].data));
472 ret = ima_restore_measurement_entry(entry); 430 ret = ima_restore_measurement_entry(entry);
473 if (ret < 0) 431 if (ret < 0)
474 break; 432 break;
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index f9ba37b3928d..28af43f63572 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -159,6 +159,67 @@ void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
159 ima_show_template_field_data(m, show, DATA_FMT_HEX, field_data); 159 ima_show_template_field_data(m, show, DATA_FMT_HEX, field_data);
160} 160}
161 161
162/**
163 * ima_parse_buf() - Parses lengths and data from an input buffer
164 * @bufstartp: Buffer start address.
165 * @bufendp: Buffer end address.
166 * @bufcurp: Pointer to remaining (non-parsed) data.
167 * @maxfields: Length of fields array.
168 * @fields: Array containing lengths and pointers of parsed data.
169 * @curfields: Number of array items containing parsed data.
170 * @len_mask: Bitmap (if bit is set, data length should not be parsed).
171 * @enforce_mask: Check if curfields == maxfields and/or bufcurp == bufendp.
172 * @bufname: String identifier of the input buffer.
173 *
174 * Return: 0 on success, -EINVAL on error.
175 */
176int ima_parse_buf(void *bufstartp, void *bufendp, void **bufcurp,
177 int maxfields, struct ima_field_data *fields, int *curfields,
178 unsigned long *len_mask, int enforce_mask, char *bufname)
179{
180 void *bufp = bufstartp;
181 int i;
182
183 for (i = 0; i < maxfields; i++) {
184 if (len_mask == NULL || !test_bit(i, len_mask)) {
185 if (bufp > (bufendp - sizeof(u32)))
186 break;
187
188 fields[i].len = *(u32 *)bufp;
189 if (ima_canonical_fmt)
190 fields[i].len = le32_to_cpu(fields[i].len);
191
192 bufp += sizeof(u32);
193 }
194
195 if (bufp > (bufendp - fields[i].len))
196 break;
197
198 fields[i].data = bufp;
199 bufp += fields[i].len;
200 }
201
202 if ((enforce_mask & ENFORCE_FIELDS) && i != maxfields) {
203 pr_err("%s: nr of fields mismatch: expected: %d, current: %d\n",
204 bufname, maxfields, i);
205 return -EINVAL;
206 }
207
208 if ((enforce_mask & ENFORCE_BUFEND) && bufp != bufendp) {
209 pr_err("%s: buf end mismatch: expected: %p, current: %p\n",
210 bufname, bufendp, bufp);
211 return -EINVAL;
212 }
213
214 if (curfields)
215 *curfields = i;
216
217 if (bufcurp)
218 *bufcurp = bufp;
219
220 return 0;
221}
222
162static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo, 223static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
163 struct ima_field_data *field_data) 224 struct ima_field_data *field_data)
164{ 225{
diff --git a/security/integrity/ima/ima_template_lib.h b/security/integrity/ima/ima_template_lib.h
index c344530c1d69..6a3d8b831deb 100644
--- a/security/integrity/ima/ima_template_lib.h
+++ b/security/integrity/ima/ima_template_lib.h
@@ -18,6 +18,9 @@
18#include <linux/seq_file.h> 18#include <linux/seq_file.h>
19#include "ima.h" 19#include "ima.h"
20 20
21#define ENFORCE_FIELDS 0x00000001
22#define ENFORCE_BUFEND 0x00000002
23
21void ima_show_template_digest(struct seq_file *m, enum ima_show_type show, 24void ima_show_template_digest(struct seq_file *m, enum ima_show_type show,
22 struct ima_field_data *field_data); 25 struct ima_field_data *field_data);
23void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show, 26void ima_show_template_digest_ng(struct seq_file *m, enum ima_show_type show,
@@ -26,6 +29,9 @@ void ima_show_template_string(struct seq_file *m, enum ima_show_type show,
26 struct ima_field_data *field_data); 29 struct ima_field_data *field_data);
27void ima_show_template_sig(struct seq_file *m, enum ima_show_type show, 30void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
28 struct ima_field_data *field_data); 31 struct ima_field_data *field_data);
32int ima_parse_buf(void *bufstartp, void *bufendp, void **bufcurp,
33 int maxfields, struct ima_field_data *fields, int *curfields,
34 unsigned long *len_mask, int enforce_mask, char *bufname);
29int ima_eventdigest_init(struct ima_event_data *event_data, 35int ima_eventdigest_init(struct ima_event_data *event_data,
30 struct ima_field_data *field_data); 36 struct ima_field_data *field_data);
31int ima_eventname_init(struct ima_event_data *event_data, 37int ima_eventname_init(struct ima_event_data *event_data,
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 24520b4ef3b0..a53e7e4ab06c 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -92,8 +92,8 @@ struct signature_v2_hdr {
92 uint8_t type; /* xattr type */ 92 uint8_t type; /* xattr type */
93 uint8_t version; /* signature format version */ 93 uint8_t version; /* signature format version */
94 uint8_t hash_algo; /* Digest algorithm [enum hash_algo] */ 94 uint8_t hash_algo; /* Digest algorithm [enum hash_algo] */
95 uint32_t keyid; /* IMA key identifier - not X509/PGP specific */ 95 __be32 keyid; /* IMA key identifier - not X509/PGP specific */
96 uint16_t sig_size; /* signature size */ 96 __be16 sig_size; /* signature size */
97 uint8_t sig[0]; /* signature payload */ 97 uint8_t sig[0]; /* signature payload */
98} __packed; 98} __packed;
99 99
@@ -118,7 +118,8 @@ struct integrity_iint_cache {
118struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 118struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
119 119
120int integrity_kernel_read(struct file *file, loff_t offset, 120int integrity_kernel_read(struct file *file, loff_t offset,
121 char *addr, unsigned long count); 121 void *addr, unsigned long count);
122
122int __init integrity_read_file(const char *path, char **data); 123int __init integrity_read_file(const char *path, char **data);
123 124
124#define INTEGRITY_KEYRING_EVM 0 125#define INTEGRITY_KEYRING_EVM 0
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 37f04dadc8d6..28d4c3a528ab 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -410,6 +410,22 @@ static void dump_common_audit_data(struct audit_buffer *ab,
410 audit_log_format(ab, " kmod="); 410 audit_log_format(ab, " kmod=");
411 audit_log_untrustedstring(ab, a->u.kmod_name); 411 audit_log_untrustedstring(ab, a->u.kmod_name);
412 break; 412 break;
413 case LSM_AUDIT_DATA_IBPKEY: {
414 struct in6_addr sbn_pfx;
415
416 memset(&sbn_pfx.s6_addr, 0,
417 sizeof(sbn_pfx.s6_addr));
418 memcpy(&sbn_pfx.s6_addr, &a->u.ibpkey->subnet_prefix,
419 sizeof(a->u.ibpkey->subnet_prefix));
420 audit_log_format(ab, " pkey=0x%x subnet_prefix=%pI6c",
421 a->u.ibpkey->pkey, &sbn_pfx);
422 break;
423 }
424 case LSM_AUDIT_DATA_IBENDPORT:
425 audit_log_format(ab, " device=%s port_num=%u",
426 a->u.ibendport->dev_name,
427 a->u.ibendport->port);
428 break;
413 } /* switch (a->type) */ 429 } /* switch (a->type) */
414} 430}
415 431
diff --git a/security/security.c b/security/security.c
index b9fea3999cf8..30132378d103 100644
--- a/security/security.c
+++ b/security/security.c
@@ -4,6 +4,7 @@
4 * Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com> 4 * Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com>
5 * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com> 5 * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
6 * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com> 6 * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com>
7 * Copyright (C) 2016 Mellanox Technologies
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -25,6 +26,7 @@
25#include <linux/mount.h> 26#include <linux/mount.h>
26#include <linux/personality.h> 27#include <linux/personality.h>
27#include <linux/backing-dev.h> 28#include <linux/backing-dev.h>
29#include <linux/string.h>
28#include <net/flow.h> 30#include <net/flow.h>
29 31
30#define MAX_LSM_EVM_XATTR 2 32#define MAX_LSM_EVM_XATTR 2
@@ -33,6 +35,8 @@
33#define SECURITY_NAME_MAX 10 35#define SECURITY_NAME_MAX 10
34 36
35struct security_hook_heads security_hook_heads __lsm_ro_after_init; 37struct security_hook_heads security_hook_heads __lsm_ro_after_init;
38static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
39
36char *lsm_names; 40char *lsm_names;
37/* Boot-time LSM user choice */ 41/* Boot-time LSM user choice */
38static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = 42static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
@@ -86,6 +90,21 @@ static int __init choose_lsm(char *str)
86} 90}
87__setup("security=", choose_lsm); 91__setup("security=", choose_lsm);
88 92
93static bool match_last_lsm(const char *list, const char *lsm)
94{
95 const char *last;
96
97 if (WARN_ON(!list || !lsm))
98 return false;
99 last = strrchr(list, ',');
100 if (last)
101 /* Pass the comma, strcmp() will check for '\0' */
102 last++;
103 else
104 last = list;
105 return !strcmp(last, lsm);
106}
107
89static int lsm_append(char *new, char **result) 108static int lsm_append(char *new, char **result)
90{ 109{
91 char *cp; 110 char *cp;
@@ -93,6 +112,9 @@ static int lsm_append(char *new, char **result)
93 if (*result == NULL) { 112 if (*result == NULL) {
94 *result = kstrdup(new, GFP_KERNEL); 113 *result = kstrdup(new, GFP_KERNEL);
95 } else { 114 } else {
115 /* Check if it is the last registered name */
116 if (match_last_lsm(*result, new))
117 return 0;
96 cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new); 118 cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new);
97 if (cp == NULL) 119 if (cp == NULL)
98 return -ENOMEM; 120 return -ENOMEM;
@@ -146,6 +168,24 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
146 panic("%s - Cannot get early memory.\n", __func__); 168 panic("%s - Cannot get early memory.\n", __func__);
147} 169}
148 170
171int call_lsm_notifier(enum lsm_event event, void *data)
172{
173 return atomic_notifier_call_chain(&lsm_notifier_chain, event, data);
174}
175EXPORT_SYMBOL(call_lsm_notifier);
176
177int register_lsm_notifier(struct notifier_block *nb)
178{
179 return atomic_notifier_chain_register(&lsm_notifier_chain, nb);
180}
181EXPORT_SYMBOL(register_lsm_notifier);
182
183int unregister_lsm_notifier(struct notifier_block *nb)
184{
185 return atomic_notifier_chain_unregister(&lsm_notifier_chain, nb);
186}
187EXPORT_SYMBOL(unregister_lsm_notifier);
188
149/* 189/*
150 * Hook list operation macros. 190 * Hook list operation macros.
151 * 191 *
@@ -380,9 +420,12 @@ int security_sb_set_mnt_opts(struct super_block *sb,
380EXPORT_SYMBOL(security_sb_set_mnt_opts); 420EXPORT_SYMBOL(security_sb_set_mnt_opts);
381 421
382int security_sb_clone_mnt_opts(const struct super_block *oldsb, 422int security_sb_clone_mnt_opts(const struct super_block *oldsb,
383 struct super_block *newsb) 423 struct super_block *newsb,
424 unsigned long kern_flags,
425 unsigned long *set_kern_flags)
384{ 426{
385 return call_int_hook(sb_clone_mnt_opts, 0, oldsb, newsb); 427 return call_int_hook(sb_clone_mnt_opts, 0, oldsb, newsb,
428 kern_flags, set_kern_flags);
386} 429}
387EXPORT_SYMBOL(security_sb_clone_mnt_opts); 430EXPORT_SYMBOL(security_sb_clone_mnt_opts);
388 431
@@ -1496,6 +1539,33 @@ EXPORT_SYMBOL(security_tun_dev_open);
1496 1539
1497#endif /* CONFIG_SECURITY_NETWORK */ 1540#endif /* CONFIG_SECURITY_NETWORK */
1498 1541
1542#ifdef CONFIG_SECURITY_INFINIBAND
1543
1544int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey)
1545{
1546 return call_int_hook(ib_pkey_access, 0, sec, subnet_prefix, pkey);
1547}
1548EXPORT_SYMBOL(security_ib_pkey_access);
1549
1550int security_ib_endport_manage_subnet(void *sec, const char *dev_name, u8 port_num)
1551{
1552 return call_int_hook(ib_endport_manage_subnet, 0, sec, dev_name, port_num);
1553}
1554EXPORT_SYMBOL(security_ib_endport_manage_subnet);
1555
1556int security_ib_alloc_security(void **sec)
1557{
1558 return call_int_hook(ib_alloc_security, 0, sec);
1559}
1560EXPORT_SYMBOL(security_ib_alloc_security);
1561
1562void security_ib_free_security(void *sec)
1563{
1564 call_void_hook(ib_free_security, sec);
1565}
1566EXPORT_SYMBOL(security_ib_free_security);
1567#endif /* CONFIG_SECURITY_INFINIBAND */
1568
1499#ifdef CONFIG_SECURITY_NETWORK_XFRM 1569#ifdef CONFIG_SECURITY_NETWORK_XFRM
1500 1570
1501int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, 1571int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index 3411c33e2a44..ff5895ede96f 100644
--- a/security/selinux/Makefile
+++ b/security/selinux/Makefile
@@ -5,7 +5,7 @@
5obj-$(CONFIG_SECURITY_SELINUX) := selinux.o 5obj-$(CONFIG_SECURITY_SELINUX) := selinux.o
6 6
7selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \ 7selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \
8 netnode.o netport.o exports.o \ 8 netnode.o netport.o ibpkey.o exports.o \
9 ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \ 9 ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \
10 ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/status.o 10 ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/status.o
11 11
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 819fd6858b49..33fd061305c4 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -17,6 +17,7 @@
17 * Paul Moore <paul@paul-moore.com> 17 * Paul Moore <paul@paul-moore.com>
18 * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd. 18 * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
19 * Yuichi Nakamura <ynakam@hitachisoft.jp> 19 * Yuichi Nakamura <ynakam@hitachisoft.jp>
20 * Copyright (C) 2016 Mellanox Technologies
20 * 21 *
21 * This program is free software; you can redistribute it and/or modify 22 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License version 2, 23 * it under the terms of the GNU General Public License version 2,
@@ -90,6 +91,7 @@
90#include "netif.h" 91#include "netif.h"
91#include "netnode.h" 92#include "netnode.h"
92#include "netport.h" 93#include "netport.h"
94#include "ibpkey.h"
93#include "xfrm.h" 95#include "xfrm.h"
94#include "netlabel.h" 96#include "netlabel.h"
95#include "audit.h" 97#include "audit.h"
@@ -171,6 +173,16 @@ static int selinux_netcache_avc_callback(u32 event)
171 return 0; 173 return 0;
172} 174}
173 175
176static int selinux_lsm_notifier_avc_callback(u32 event)
177{
178 if (event == AVC_CALLBACK_RESET) {
179 sel_ib_pkey_flush();
180 call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
181 }
182
183 return 0;
184}
185
174/* 186/*
175 * initialise the security for the init task 187 * initialise the security for the init task
176 */ 188 */
@@ -398,18 +410,6 @@ static void superblock_free_security(struct super_block *sb)
398 kfree(sbsec); 410 kfree(sbsec);
399} 411}
400 412
401/* The file system's label must be initialized prior to use. */
402
403static const char *labeling_behaviors[7] = {
404 "uses xattr",
405 "uses transition SIDs",
406 "uses task SIDs",
407 "uses genfs_contexts",
408 "not configured for labeling",
409 "uses mountpoint labeling",
410 "uses native labeling",
411};
412
413static inline int inode_doinit(struct inode *inode) 413static inline int inode_doinit(struct inode *inode)
414{ 414{
415 return inode_doinit_with_dentry(inode, NULL); 415 return inode_doinit_with_dentry(inode, NULL);
@@ -524,13 +524,17 @@ static int sb_finish_set_opts(struct super_block *sb)
524 } 524 }
525 } 525 }
526 526
527 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
528 printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
529 sb->s_id, sb->s_type->name);
530
531 sbsec->flags |= SE_SBINITIALIZED; 527 sbsec->flags |= SE_SBINITIALIZED;
528
529 /*
530 * Explicitly set or clear SBLABEL_MNT. It's not sufficient to simply
531 * leave the flag untouched because sb_clone_mnt_opts might be handing
532 * us a superblock that needs the flag to be cleared.
533 */
532 if (selinux_is_sblabel_mnt(sb)) 534 if (selinux_is_sblabel_mnt(sb))
533 sbsec->flags |= SBLABEL_MNT; 535 sbsec->flags |= SBLABEL_MNT;
536 else
537 sbsec->flags &= ~SBLABEL_MNT;
534 538
535 /* Initialize the root inode. */ 539 /* Initialize the root inode. */
536 rc = inode_doinit_with_dentry(root_inode, root); 540 rc = inode_doinit_with_dentry(root_inode, root);
@@ -809,6 +813,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
809 sbsec->flags |= SE_SBPROC | SE_SBGENFS; 813 sbsec->flags |= SE_SBPROC | SE_SBGENFS;
810 814
811 if (!strcmp(sb->s_type->name, "debugfs") || 815 if (!strcmp(sb->s_type->name, "debugfs") ||
816 !strcmp(sb->s_type->name, "tracefs") ||
812 !strcmp(sb->s_type->name, "sysfs") || 817 !strcmp(sb->s_type->name, "sysfs") ||
813 !strcmp(sb->s_type->name, "pstore")) 818 !strcmp(sb->s_type->name, "pstore"))
814 sbsec->flags |= SE_SBGENFS; 819 sbsec->flags |= SE_SBGENFS;
@@ -963,8 +968,11 @@ mismatch:
963} 968}
964 969
965static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb, 970static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
966 struct super_block *newsb) 971 struct super_block *newsb,
972 unsigned long kern_flags,
973 unsigned long *set_kern_flags)
967{ 974{
975 int rc = 0;
968 const struct superblock_security_struct *oldsbsec = oldsb->s_security; 976 const struct superblock_security_struct *oldsbsec = oldsb->s_security;
969 struct superblock_security_struct *newsbsec = newsb->s_security; 977 struct superblock_security_struct *newsbsec = newsb->s_security;
970 978
@@ -979,6 +987,13 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
979 if (!ss_initialized) 987 if (!ss_initialized)
980 return 0; 988 return 0;
981 989
990 /*
991 * Specifying internal flags without providing a place to
992 * place the results is not allowed.
993 */
994 if (kern_flags && !set_kern_flags)
995 return -EINVAL;
996
982 /* how can we clone if the old one wasn't set up?? */ 997 /* how can we clone if the old one wasn't set up?? */
983 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED)); 998 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
984 999
@@ -994,6 +1009,18 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
994 newsbsec->def_sid = oldsbsec->def_sid; 1009 newsbsec->def_sid = oldsbsec->def_sid;
995 newsbsec->behavior = oldsbsec->behavior; 1010 newsbsec->behavior = oldsbsec->behavior;
996 1011
1012 if (newsbsec->behavior == SECURITY_FS_USE_NATIVE &&
1013 !(kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) {
1014 rc = security_fs_use(newsb);
1015 if (rc)
1016 goto out;
1017 }
1018
1019 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !set_context) {
1020 newsbsec->behavior = SECURITY_FS_USE_NATIVE;
1021 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
1022 }
1023
997 if (set_context) { 1024 if (set_context) {
998 u32 sid = oldsbsec->mntpoint_sid; 1025 u32 sid = oldsbsec->mntpoint_sid;
999 1026
@@ -1013,8 +1040,9 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
1013 } 1040 }
1014 1041
1015 sb_finish_set_opts(newsb); 1042 sb_finish_set_opts(newsb);
1043out:
1016 mutex_unlock(&newsbsec->lock); 1044 mutex_unlock(&newsbsec->lock);
1017 return 0; 1045 return rc;
1018} 1046}
1019 1047
1020static int selinux_parse_opts_str(char *options, 1048static int selinux_parse_opts_str(char *options,
@@ -2062,8 +2090,9 @@ static inline u32 file_to_av(struct file *file)
2062static inline u32 open_file_to_av(struct file *file) 2090static inline u32 open_file_to_av(struct file *file)
2063{ 2091{
2064 u32 av = file_to_av(file); 2092 u32 av = file_to_av(file);
2093 struct inode *inode = file_inode(file);
2065 2094
2066 if (selinux_policycap_openperm) 2095 if (selinux_policycap_openperm && inode->i_sb->s_magic != SOCKFS_MAGIC)
2067 av |= FILE__OPEN; 2096 av |= FILE__OPEN;
2068 2097
2069 return av; 2098 return av;
@@ -3058,6 +3087,7 @@ static int selinux_inode_permission(struct inode *inode, int mask)
3058static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 3087static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
3059{ 3088{
3060 const struct cred *cred = current_cred(); 3089 const struct cred *cred = current_cred();
3090 struct inode *inode = d_backing_inode(dentry);
3061 unsigned int ia_valid = iattr->ia_valid; 3091 unsigned int ia_valid = iattr->ia_valid;
3062 __u32 av = FILE__WRITE; 3092 __u32 av = FILE__WRITE;
3063 3093
@@ -3073,8 +3103,10 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
3073 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) 3103 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
3074 return dentry_has_perm(cred, dentry, FILE__SETATTR); 3104 return dentry_has_perm(cred, dentry, FILE__SETATTR);
3075 3105
3076 if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE) 3106 if (selinux_policycap_openperm &&
3077 && !(ia_valid & ATTR_FILE)) 3107 inode->i_sb->s_magic != SOCKFS_MAGIC &&
3108 (ia_valid & ATTR_SIZE) &&
3109 !(ia_valid & ATTR_FILE))
3078 av |= FILE__OPEN; 3110 av |= FILE__OPEN;
3079 3111
3080 return dentry_has_perm(cred, dentry, av); 3112 return dentry_has_perm(cred, dentry, av);
@@ -3106,6 +3138,18 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
3106 return dentry_has_perm(cred, dentry, FILE__SETATTR); 3138 return dentry_has_perm(cred, dentry, FILE__SETATTR);
3107} 3139}
3108 3140
3141static bool has_cap_mac_admin(bool audit)
3142{
3143 const struct cred *cred = current_cred();
3144 int cap_audit = audit ? SECURITY_CAP_AUDIT : SECURITY_CAP_NOAUDIT;
3145
3146 if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, cap_audit))
3147 return false;
3148 if (cred_has_capability(cred, CAP_MAC_ADMIN, cap_audit, true))
3149 return false;
3150 return true;
3151}
3152
3109static int selinux_inode_setxattr(struct dentry *dentry, const char *name, 3153static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3110 const void *value, size_t size, int flags) 3154 const void *value, size_t size, int flags)
3111{ 3155{
@@ -3137,7 +3181,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3137 3181
3138 rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL); 3182 rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL);
3139 if (rc == -EINVAL) { 3183 if (rc == -EINVAL) {
3140 if (!capable(CAP_MAC_ADMIN)) { 3184 if (!has_cap_mac_admin(true)) {
3141 struct audit_buffer *ab; 3185 struct audit_buffer *ab;
3142 size_t audit_size; 3186 size_t audit_size;
3143 const char *str; 3187 const char *str;
@@ -3263,13 +3307,8 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
3263 * and lack of permission just means that we fall back to the 3307 * and lack of permission just means that we fall back to the
3264 * in-core context value, not a denial. 3308 * in-core context value, not a denial.
3265 */ 3309 */
3266 error = cap_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN,
3267 SECURITY_CAP_NOAUDIT);
3268 if (!error)
3269 error = cred_has_capability(current_cred(), CAP_MAC_ADMIN,
3270 SECURITY_CAP_NOAUDIT, true);
3271 isec = inode_security(inode); 3310 isec = inode_security(inode);
3272 if (!error) 3311 if (has_cap_mac_admin(false))
3273 error = security_sid_to_context_force(isec->sid, &context, 3312 error = security_sid_to_context_force(isec->sid, &context,
3274 &size); 3313 &size);
3275 else 3314 else
@@ -3549,6 +3588,18 @@ static int selinux_mmap_addr(unsigned long addr)
3549static int selinux_mmap_file(struct file *file, unsigned long reqprot, 3588static int selinux_mmap_file(struct file *file, unsigned long reqprot,
3550 unsigned long prot, unsigned long flags) 3589 unsigned long prot, unsigned long flags)
3551{ 3590{
3591 struct common_audit_data ad;
3592 int rc;
3593
3594 if (file) {
3595 ad.type = LSM_AUDIT_DATA_FILE;
3596 ad.u.file = file;
3597 rc = inode_has_perm(current_cred(), file_inode(file),
3598 FILE__MAP, &ad);
3599 if (rc)
3600 return rc;
3601 }
3602
3552 if (selinux_checkreqprot) 3603 if (selinux_checkreqprot)
3553 prot = reqprot; 3604 prot = reqprot;
3554 3605
@@ -3709,7 +3760,8 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
3709 3760
3710/* task security operations */ 3761/* task security operations */
3711 3762
3712static int selinux_task_create(unsigned long clone_flags) 3763static int selinux_task_alloc(struct task_struct *task,
3764 unsigned long clone_flags)
3713{ 3765{
3714 u32 sid = current_sid(); 3766 u32 sid = current_sid();
3715 3767
@@ -5917,7 +5969,7 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
5917 } 5969 }
5918 error = security_context_to_sid(value, size, &sid, GFP_KERNEL); 5970 error = security_context_to_sid(value, size, &sid, GFP_KERNEL);
5919 if (error == -EINVAL && !strcmp(name, "fscreate")) { 5971 if (error == -EINVAL && !strcmp(name, "fscreate")) {
5920 if (!capable(CAP_MAC_ADMIN)) { 5972 if (!has_cap_mac_admin(true)) {
5921 struct audit_buffer *ab; 5973 struct audit_buffer *ab;
5922 size_t audit_size; 5974 size_t audit_size;
5923 5975
@@ -6127,7 +6179,70 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
6127 *_buffer = context; 6179 *_buffer = context;
6128 return rc; 6180 return rc;
6129} 6181}
6182#endif
6183
6184#ifdef CONFIG_SECURITY_INFINIBAND
6185static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val)
6186{
6187 struct common_audit_data ad;
6188 int err;
6189 u32 sid = 0;
6190 struct ib_security_struct *sec = ib_sec;
6191 struct lsm_ibpkey_audit ibpkey;
6192
6193 err = sel_ib_pkey_sid(subnet_prefix, pkey_val, &sid);
6194 if (err)
6195 return err;
6196
6197 ad.type = LSM_AUDIT_DATA_IBPKEY;
6198 ibpkey.subnet_prefix = subnet_prefix;
6199 ibpkey.pkey = pkey_val;
6200 ad.u.ibpkey = &ibpkey;
6201 return avc_has_perm(sec->sid, sid,
6202 SECCLASS_INFINIBAND_PKEY,
6203 INFINIBAND_PKEY__ACCESS, &ad);
6204}
6205
6206static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name,
6207 u8 port_num)
6208{
6209 struct common_audit_data ad;
6210 int err;
6211 u32 sid = 0;
6212 struct ib_security_struct *sec = ib_sec;
6213 struct lsm_ibendport_audit ibendport;
6214
6215 err = security_ib_endport_sid(dev_name, port_num, &sid);
6216
6217 if (err)
6218 return err;
6219
6220 ad.type = LSM_AUDIT_DATA_IBENDPORT;
6221 strncpy(ibendport.dev_name, dev_name, sizeof(ibendport.dev_name));
6222 ibendport.port = port_num;
6223 ad.u.ibendport = &ibendport;
6224 return avc_has_perm(sec->sid, sid,
6225 SECCLASS_INFINIBAND_ENDPORT,
6226 INFINIBAND_ENDPORT__MANAGE_SUBNET, &ad);
6227}
6228
6229static int selinux_ib_alloc_security(void **ib_sec)
6230{
6231 struct ib_security_struct *sec;
6130 6232
6233 sec = kzalloc(sizeof(*sec), GFP_KERNEL);
6234 if (!sec)
6235 return -ENOMEM;
6236 sec->sid = current_sid();
6237
6238 *ib_sec = sec;
6239 return 0;
6240}
6241
6242static void selinux_ib_free_security(void *ib_sec)
6243{
6244 kfree(ib_sec);
6245}
6131#endif 6246#endif
6132 6247
6133static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { 6248static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
@@ -6212,7 +6327,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
6212 6327
6213 LSM_HOOK_INIT(file_open, selinux_file_open), 6328 LSM_HOOK_INIT(file_open, selinux_file_open),
6214 6329
6215 LSM_HOOK_INIT(task_create, selinux_task_create), 6330 LSM_HOOK_INIT(task_alloc, selinux_task_alloc),
6216 LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank), 6331 LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank),
6217 LSM_HOOK_INIT(cred_free, selinux_cred_free), 6332 LSM_HOOK_INIT(cred_free, selinux_cred_free),
6218 LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare), 6333 LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare),
@@ -6314,7 +6429,13 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
6314 LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue), 6429 LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue),
6315 LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach), 6430 LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
6316 LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open), 6431 LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
6317 6432#ifdef CONFIG_SECURITY_INFINIBAND
6433 LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access),
6434 LSM_HOOK_INIT(ib_endport_manage_subnet,
6435 selinux_ib_endport_manage_subnet),
6436 LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security),
6437 LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
6438#endif
6318#ifdef CONFIG_SECURITY_NETWORK_XFRM 6439#ifdef CONFIG_SECURITY_NETWORK_XFRM
6319 LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc), 6440 LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
6320 LSM_HOOK_INIT(xfrm_policy_clone_security, selinux_xfrm_policy_clone), 6441 LSM_HOOK_INIT(xfrm_policy_clone_security, selinux_xfrm_policy_clone),
@@ -6378,6 +6499,9 @@ static __init int selinux_init(void)
6378 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) 6499 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
6379 panic("SELinux: Unable to register AVC netcache callback\n"); 6500 panic("SELinux: Unable to register AVC netcache callback\n");
6380 6501
6502 if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
6503 panic("SELinux: Unable to register AVC LSM notifier callback\n");
6504
6381 if (selinux_enforcing) 6505 if (selinux_enforcing)
6382 printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n"); 6506 printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n");
6383 else 6507 else
@@ -6447,6 +6571,23 @@ static struct nf_hook_ops selinux_nf_ops[] = {
6447#endif /* IPV6 */ 6571#endif /* IPV6 */
6448}; 6572};
6449 6573
6574static int __net_init selinux_nf_register(struct net *net)
6575{
6576 return nf_register_net_hooks(net, selinux_nf_ops,
6577 ARRAY_SIZE(selinux_nf_ops));
6578}
6579
6580static void __net_exit selinux_nf_unregister(struct net *net)
6581{
6582 nf_unregister_net_hooks(net, selinux_nf_ops,
6583 ARRAY_SIZE(selinux_nf_ops));
6584}
6585
6586static struct pernet_operations selinux_net_ops = {
6587 .init = selinux_nf_register,
6588 .exit = selinux_nf_unregister,
6589};
6590
6450static int __init selinux_nf_ip_init(void) 6591static int __init selinux_nf_ip_init(void)
6451{ 6592{
6452 int err; 6593 int err;
@@ -6456,13 +6597,12 @@ static int __init selinux_nf_ip_init(void)
6456 6597
6457 printk(KERN_DEBUG "SELinux: Registering netfilter hooks\n"); 6598 printk(KERN_DEBUG "SELinux: Registering netfilter hooks\n");
6458 6599
6459 err = nf_register_hooks(selinux_nf_ops, ARRAY_SIZE(selinux_nf_ops)); 6600 err = register_pernet_subsys(&selinux_net_ops);
6460 if (err) 6601 if (err)
6461 panic("SELinux: nf_register_hooks: error %d\n", err); 6602 panic("SELinux: register_pernet_subsys: error %d\n", err);
6462 6603
6463 return 0; 6604 return 0;
6464} 6605}
6465
6466__initcall(selinux_nf_ip_init); 6606__initcall(selinux_nf_ip_init);
6467 6607
6468#ifdef CONFIG_SECURITY_SELINUX_DISABLE 6608#ifdef CONFIG_SECURITY_SELINUX_DISABLE
@@ -6470,7 +6610,7 @@ static void selinux_nf_ip_exit(void)
6470{ 6610{
6471 printk(KERN_DEBUG "SELinux: Unregistering netfilter hooks\n"); 6611 printk(KERN_DEBUG "SELinux: Unregistering netfilter hooks\n");
6472 6612
6473 nf_unregister_hooks(selinux_nf_ops, ARRAY_SIZE(selinux_nf_ops)); 6613 unregister_pernet_subsys(&selinux_net_ops);
6474} 6614}
6475#endif 6615#endif
6476 6616
diff --git a/security/selinux/ibpkey.c b/security/selinux/ibpkey.c
new file mode 100644
index 000000000000..e3614ee5f1c0
--- /dev/null
+++ b/security/selinux/ibpkey.c
@@ -0,0 +1,245 @@
1/*
2 * Pkey table
3 *
4 * SELinux must keep a mapping of Infinband PKEYs to labels/SIDs. This
5 * mapping is maintained as part of the normal policy but a fast cache is
6 * needed to reduce the lookup overhead.
7 *
8 * This code is heavily based on the "netif" and "netport" concept originally
9 * developed by
10 * James Morris <jmorris@redhat.com> and
11 * Paul Moore <paul@paul-moore.com>
12 * (see security/selinux/netif.c and security/selinux/netport.c for more
13 * information)
14 *
15 */
16
17/*
18 * (c) Mellanox Technologies, 2016
19 *
20 * This program is free software: you can redistribute it and/or modify
21 * it under the terms of version 2 of the GNU General Public License as
22 * published by the Free Software Foundation.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 */
30
31#include <linux/types.h>
32#include <linux/rcupdate.h>
33#include <linux/list.h>
34#include <linux/spinlock.h>
35
36#include "ibpkey.h"
37#include "objsec.h"
38
39#define SEL_PKEY_HASH_SIZE 256
40#define SEL_PKEY_HASH_BKT_LIMIT 16
41
42struct sel_ib_pkey_bkt {
43 int size;
44 struct list_head list;
45};
46
47struct sel_ib_pkey {
48 struct pkey_security_struct psec;
49 struct list_head list;
50 struct rcu_head rcu;
51};
52
53static LIST_HEAD(sel_ib_pkey_list);
54static DEFINE_SPINLOCK(sel_ib_pkey_lock);
55static struct sel_ib_pkey_bkt sel_ib_pkey_hash[SEL_PKEY_HASH_SIZE];
56
57/**
58 * sel_ib_pkey_hashfn - Hashing function for the pkey table
59 * @pkey: pkey number
60 *
61 * Description:
62 * This is the hashing function for the pkey table, it returns the bucket
63 * number for the given pkey.
64 *
65 */
66static unsigned int sel_ib_pkey_hashfn(u16 pkey)
67{
68 return (pkey & (SEL_PKEY_HASH_SIZE - 1));
69}
70
71/**
72 * sel_ib_pkey_find - Search for a pkey record
73 * @subnet_prefix: subnet_prefix
74 * @pkey_num: pkey_num
75 *
76 * Description:
77 * Search the pkey table and return the matching record. If an entry
78 * can not be found in the table return NULL.
79 *
80 */
81static struct sel_ib_pkey *sel_ib_pkey_find(u64 subnet_prefix, u16 pkey_num)
82{
83 unsigned int idx;
84 struct sel_ib_pkey *pkey;
85
86 idx = sel_ib_pkey_hashfn(pkey_num);
87 list_for_each_entry_rcu(pkey, &sel_ib_pkey_hash[idx].list, list) {
88 if (pkey->psec.pkey == pkey_num &&
89 pkey->psec.subnet_prefix == subnet_prefix)
90 return pkey;
91 }
92
93 return NULL;
94}
95
96/**
97 * sel_ib_pkey_insert - Insert a new pkey into the table
98 * @pkey: the new pkey record
99 *
100 * Description:
101 * Add a new pkey record to the hash table.
102 *
103 */
104static void sel_ib_pkey_insert(struct sel_ib_pkey *pkey)
105{
106 unsigned int idx;
107
108 /* we need to impose a limit on the growth of the hash table so check
109 * this bucket to make sure it is within the specified bounds
110 */
111 idx = sel_ib_pkey_hashfn(pkey->psec.pkey);
112 list_add_rcu(&pkey->list, &sel_ib_pkey_hash[idx].list);
113 if (sel_ib_pkey_hash[idx].size == SEL_PKEY_HASH_BKT_LIMIT) {
114 struct sel_ib_pkey *tail;
115
116 tail = list_entry(
117 rcu_dereference_protected(
118 sel_ib_pkey_hash[idx].list.prev,
119 lockdep_is_held(&sel_ib_pkey_lock)),
120 struct sel_ib_pkey, list);
121 list_del_rcu(&tail->list);
122 kfree_rcu(tail, rcu);
123 } else {
124 sel_ib_pkey_hash[idx].size++;
125 }
126}
127
128/**
129 * sel_ib_pkey_sid_slow - Lookup the SID of a pkey using the policy
130 * @subnet_prefix: subnet prefix
131 * @pkey_num: pkey number
132 * @sid: pkey SID
133 *
134 * Description:
135 * This function determines the SID of a pkey by querying the security
136 * policy. The result is added to the pkey table to speedup future
137 * queries. Returns zero on success, negative values on failure.
138 *
139 */
140static int sel_ib_pkey_sid_slow(u64 subnet_prefix, u16 pkey_num, u32 *sid)
141{
142 int ret;
143 struct sel_ib_pkey *pkey;
144 struct sel_ib_pkey *new = NULL;
145 unsigned long flags;
146
147 spin_lock_irqsave(&sel_ib_pkey_lock, flags);
148 pkey = sel_ib_pkey_find(subnet_prefix, pkey_num);
149 if (pkey) {
150 *sid = pkey->psec.sid;
151 spin_unlock_irqrestore(&sel_ib_pkey_lock, flags);
152 return 0;
153 }
154
155 ret = security_ib_pkey_sid(subnet_prefix, pkey_num, sid);
156 if (ret)
157 goto out;
158
159 /* If this memory allocation fails still return 0. The SID
160 * is valid, it just won't be added to the cache.
161 */
162 new = kzalloc(sizeof(*new), GFP_ATOMIC);
163 if (!new)
164 goto out;
165
166 new->psec.subnet_prefix = subnet_prefix;
167 new->psec.pkey = pkey_num;
168 new->psec.sid = *sid;
169 sel_ib_pkey_insert(new);
170
171out:
172 spin_unlock_irqrestore(&sel_ib_pkey_lock, flags);
173 return ret;
174}
175
176/**
177 * sel_ib_pkey_sid - Lookup the SID of a PKEY
178 * @subnet_prefix: subnet_prefix
179 * @pkey_num: pkey number
180 * @sid: pkey SID
181 *
182 * Description:
183 * This function determines the SID of a PKEY using the fastest method
184 * possible. First the pkey table is queried, but if an entry can't be found
185 * then the policy is queried and the result is added to the table to speedup
186 * future queries. Returns zero on success, negative values on failure.
187 *
188 */
189int sel_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *sid)
190{
191 struct sel_ib_pkey *pkey;
192
193 rcu_read_lock();
194 pkey = sel_ib_pkey_find(subnet_prefix, pkey_num);
195 if (pkey) {
196 *sid = pkey->psec.sid;
197 rcu_read_unlock();
198 return 0;
199 }
200 rcu_read_unlock();
201
202 return sel_ib_pkey_sid_slow(subnet_prefix, pkey_num, sid);
203}
204
205/**
206 * sel_ib_pkey_flush - Flush the entire pkey table
207 *
208 * Description:
209 * Remove all entries from the pkey table
210 *
211 */
212void sel_ib_pkey_flush(void)
213{
214 unsigned int idx;
215 struct sel_ib_pkey *pkey, *pkey_tmp;
216 unsigned long flags;
217
218 spin_lock_irqsave(&sel_ib_pkey_lock, flags);
219 for (idx = 0; idx < SEL_PKEY_HASH_SIZE; idx++) {
220 list_for_each_entry_safe(pkey, pkey_tmp,
221 &sel_ib_pkey_hash[idx].list, list) {
222 list_del_rcu(&pkey->list);
223 kfree_rcu(pkey, rcu);
224 }
225 sel_ib_pkey_hash[idx].size = 0;
226 }
227 spin_unlock_irqrestore(&sel_ib_pkey_lock, flags);
228}
229
230static __init int sel_ib_pkey_init(void)
231{
232 int iter;
233
234 if (!selinux_enabled)
235 return 0;
236
237 for (iter = 0; iter < SEL_PKEY_HASH_SIZE; iter++) {
238 INIT_LIST_HEAD(&sel_ib_pkey_hash[iter].list);
239 sel_ib_pkey_hash[iter].size = 0;
240 }
241
242 return 0;
243}
244
245subsys_initcall(sel_ib_pkey_init);
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 1e0cc9b5de20..b9fe3434b036 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -1,7 +1,7 @@
1#include <linux/capability.h> 1#include <linux/capability.h>
2 2
3#define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \ 3#define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \
4 "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append" 4 "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append", "map"
5 5
6#define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \ 6#define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \
7 "rename", "execute", "quotaon", "mounton", "audit_access", \ 7 "rename", "execute", "quotaon", "mounton", "audit_access", \
@@ -231,6 +231,10 @@ struct security_class_mapping secclass_map[] = {
231 { COMMON_SOCK_PERMS, NULL } }, 231 { COMMON_SOCK_PERMS, NULL } },
232 { "smc_socket", 232 { "smc_socket",
233 { COMMON_SOCK_PERMS, NULL } }, 233 { COMMON_SOCK_PERMS, NULL } },
234 { "infiniband_pkey",
235 { "access", NULL } },
236 { "infiniband_endport",
237 { "manage_subnet", NULL } },
234 { NULL } 238 { NULL }
235 }; 239 };
236 240
diff --git a/security/selinux/include/ibpkey.h b/security/selinux/include/ibpkey.h
new file mode 100644
index 000000000000..b17a19e348e6
--- /dev/null
+++ b/security/selinux/include/ibpkey.h
@@ -0,0 +1,31 @@
1/*
2 * pkey table
3 *
4 * SELinux must keep a mapping of pkeys to labels/SIDs. This
5 * mapping is maintained as part of the normal policy but a fast cache is
6 * needed to reduce the lookup overhead.
7 *
8 */
9
10/*
11 * (c) Mellanox Technologies, 2016
12 *
13 * This program is free software: you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 */
23
24#ifndef _SELINUX_IB_PKEY_H
25#define _SELINUX_IB_PKEY_H
26
27void sel_ib_pkey_flush(void);
28
29int sel_ib_pkey_sid(u64 subnet_prefix, u16 pkey, u32 *sid);
30
31#endif
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index c03cdcd12a3b..6ebc61e370ff 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -10,6 +10,7 @@
10 * 10 *
11 * Copyright (C) 2001,2002 Networks Associates Technology, Inc. 11 * Copyright (C) 2001,2002 Networks Associates Technology, Inc.
12 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> 12 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
13 * Copyright (C) 2016 Mellanox Technologies
13 * 14 *
14 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2, 16 * it under the terms of the GNU General Public License version 2,
@@ -139,6 +140,16 @@ struct key_security_struct {
139 u32 sid; /* SID of key */ 140 u32 sid; /* SID of key */
140}; 141};
141 142
143struct ib_security_struct {
144 u32 sid; /* SID of the queue pair or MAD agent */
145};
146
147struct pkey_security_struct {
148 u64 subnet_prefix; /* Port subnet prefix */
149 u16 pkey; /* PKey number */
150 u32 sid; /* SID of pkey */
151};
152
142extern unsigned int selinux_checkreqprot; 153extern unsigned int selinux_checkreqprot;
143 154
144#endif /* _SELINUX_OBJSEC_H_ */ 155#endif /* _SELINUX_OBJSEC_H_ */
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index f979c35e037e..e91f08c16c0b 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -36,10 +36,11 @@
36#define POLICYDB_VERSION_DEFAULT_TYPE 28 36#define POLICYDB_VERSION_DEFAULT_TYPE 28
37#define POLICYDB_VERSION_CONSTRAINT_NAMES 29 37#define POLICYDB_VERSION_CONSTRAINT_NAMES 29
38#define POLICYDB_VERSION_XPERMS_IOCTL 30 38#define POLICYDB_VERSION_XPERMS_IOCTL 30
39#define POLICYDB_VERSION_INFINIBAND 31
39 40
40/* Range of policy versions we understand*/ 41/* Range of policy versions we understand*/
41#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE 42#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
42#define POLICYDB_VERSION_MAX POLICYDB_VERSION_XPERMS_IOCTL 43#define POLICYDB_VERSION_MAX POLICYDB_VERSION_INFINIBAND
43 44
44/* Mask for just the mount related flags */ 45/* Mask for just the mount related flags */
45#define SE_MNTMASK 0x0f 46#define SE_MNTMASK 0x0f
@@ -76,6 +77,8 @@ enum {
76}; 77};
77#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) 78#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
78 79
80extern char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX];
81
79extern int selinux_policycap_netpeer; 82extern int selinux_policycap_netpeer;
80extern int selinux_policycap_openperm; 83extern int selinux_policycap_openperm;
81extern int selinux_policycap_extsockclass; 84extern int selinux_policycap_extsockclass;
@@ -178,6 +181,10 @@ int security_get_user_sids(u32 callsid, char *username,
178 181
179int security_port_sid(u8 protocol, u16 port, u32 *out_sid); 182int security_port_sid(u8 protocol, u16 port, u32 *out_sid);
180 183
184int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid);
185
186int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid);
187
181int security_netif_sid(char *name, u32 *if_sid); 188int security_netif_sid(char *name, u32 *if_sid);
182 189
183int security_node_sid(u16 domain, void *addr, u32 addrlen, 190int security_node_sid(u16 domain, void *addr, u32 addrlen,
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 50062e70140d..9010a3632d6f 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -41,15 +41,6 @@
41#include "objsec.h" 41#include "objsec.h"
42#include "conditional.h" 42#include "conditional.h"
43 43
44/* Policy capability filenames */
45static char *policycap_names[] = {
46 "network_peer_controls",
47 "open_perms",
48 "extended_socket_class",
49 "always_check_network",
50 "cgroup_seclabel"
51};
52
53unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; 44unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
54 45
55static int __init checkreqprot_setup(char *str) 46static int __init checkreqprot_setup(char *str)
@@ -163,6 +154,8 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
163 avc_ss_reset(0); 154 avc_ss_reset(0);
164 selnl_notify_setenforce(selinux_enforcing); 155 selnl_notify_setenforce(selinux_enforcing);
165 selinux_status_update_setenforce(selinux_enforcing); 156 selinux_status_update_setenforce(selinux_enforcing);
157 if (!selinux_enforcing)
158 call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
166 } 159 }
167 length = count; 160 length = count;
168out: 161out:
@@ -1750,9 +1743,9 @@ static int sel_make_policycap(void)
1750 sel_remove_entries(policycap_dir); 1743 sel_remove_entries(policycap_dir);
1751 1744
1752 for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) { 1745 for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) {
1753 if (iter < ARRAY_SIZE(policycap_names)) 1746 if (iter < ARRAY_SIZE(selinux_policycap_names))
1754 dentry = d_alloc_name(policycap_dir, 1747 dentry = d_alloc_name(policycap_dir,
1755 policycap_names[iter]); 1748 selinux_policycap_names[iter]);
1756 else 1749 else
1757 dentry = d_alloc_name(policycap_dir, "unknown"); 1750 dentry = d_alloc_name(policycap_dir, "unknown");
1758 1751
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 9db4709a6877..ad38299164c3 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -24,6 +24,8 @@
24 24
25#define BITS_PER_U64 (sizeof(u64) * 8) 25#define BITS_PER_U64 (sizeof(u64) * 8)
26 26
27static struct kmem_cache *ebitmap_node_cachep;
28
27int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2) 29int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2)
28{ 30{
29 struct ebitmap_node *n1, *n2; 31 struct ebitmap_node *n1, *n2;
@@ -54,7 +56,7 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
54 n = src->node; 56 n = src->node;
55 prev = NULL; 57 prev = NULL;
56 while (n) { 58 while (n) {
57 new = kzalloc(sizeof(*new), GFP_ATOMIC); 59 new = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
58 if (!new) { 60 if (!new) {
59 ebitmap_destroy(dst); 61 ebitmap_destroy(dst);
60 return -ENOMEM; 62 return -ENOMEM;
@@ -162,7 +164,7 @@ int ebitmap_netlbl_import(struct ebitmap *ebmap,
162 if (e_iter == NULL || 164 if (e_iter == NULL ||
163 offset >= e_iter->startbit + EBITMAP_SIZE) { 165 offset >= e_iter->startbit + EBITMAP_SIZE) {
164 e_prev = e_iter; 166 e_prev = e_iter;
165 e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC); 167 e_iter = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
166 if (e_iter == NULL) 168 if (e_iter == NULL)
167 goto netlbl_import_failure; 169 goto netlbl_import_failure;
168 e_iter->startbit = offset - (offset % EBITMAP_SIZE); 170 e_iter->startbit = offset - (offset % EBITMAP_SIZE);
@@ -288,7 +290,7 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
288 prev->next = n->next; 290 prev->next = n->next;
289 else 291 else
290 e->node = n->next; 292 e->node = n->next;
291 kfree(n); 293 kmem_cache_free(ebitmap_node_cachep, n);
292 } 294 }
293 return 0; 295 return 0;
294 } 296 }
@@ -299,7 +301,7 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
299 if (!value) 301 if (!value)
300 return 0; 302 return 0;
301 303
302 new = kzalloc(sizeof(*new), GFP_ATOMIC); 304 new = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
303 if (!new) 305 if (!new)
304 return -ENOMEM; 306 return -ENOMEM;
305 307
@@ -332,7 +334,7 @@ void ebitmap_destroy(struct ebitmap *e)
332 while (n) { 334 while (n) {
333 temp = n; 335 temp = n;
334 n = n->next; 336 n = n->next;
335 kfree(temp); 337 kmem_cache_free(ebitmap_node_cachep, temp);
336 } 338 }
337 339
338 e->highbit = 0; 340 e->highbit = 0;
@@ -400,7 +402,7 @@ int ebitmap_read(struct ebitmap *e, void *fp)
400 402
401 if (!n || startbit >= n->startbit + EBITMAP_SIZE) { 403 if (!n || startbit >= n->startbit + EBITMAP_SIZE) {
402 struct ebitmap_node *tmp; 404 struct ebitmap_node *tmp;
403 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); 405 tmp = kmem_cache_zalloc(ebitmap_node_cachep, GFP_KERNEL);
404 if (!tmp) { 406 if (!tmp) {
405 printk(KERN_ERR 407 printk(KERN_ERR
406 "SELinux: ebitmap: out of memory\n"); 408 "SELinux: ebitmap: out of memory\n");
@@ -519,3 +521,15 @@ int ebitmap_write(struct ebitmap *e, void *fp)
519 } 521 }
520 return 0; 522 return 0;
521} 523}
524
525void ebitmap_cache_init(void)
526{
527 ebitmap_node_cachep = kmem_cache_create("ebitmap_node",
528 sizeof(struct ebitmap_node),
529 0, SLAB_PANIC, NULL);
530}
531
532void ebitmap_cache_destroy(void)
533{
534 kmem_cache_destroy(ebitmap_node_cachep);
535}
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 9637b8c71085..6d5a9ac4251f 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -130,6 +130,9 @@ void ebitmap_destroy(struct ebitmap *e);
130int ebitmap_read(struct ebitmap *e, void *fp); 130int ebitmap_read(struct ebitmap *e, void *fp);
131int ebitmap_write(struct ebitmap *e, void *fp); 131int ebitmap_write(struct ebitmap *e, void *fp);
132 132
133void ebitmap_cache_init(void);
134void ebitmap_cache_destroy(void);
135
133#ifdef CONFIG_NETLABEL 136#ifdef CONFIG_NETLABEL
134int ebitmap_netlbl_export(struct ebitmap *ebmap, 137int ebitmap_netlbl_export(struct ebitmap *ebmap,
135 struct netlbl_lsm_catmap **catmap); 138 struct netlbl_lsm_catmap **catmap);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 0080122760ad..aa6500abb178 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -17,6 +17,11 @@
17 * 17 *
18 * Added support for the policy capability bitmap 18 * Added support for the policy capability bitmap
19 * 19 *
20 * Update: Mellanox Techonologies
21 *
22 * Added Infiniband support
23 *
24 * Copyright (C) 2016 Mellanox Techonologies
20 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P. 25 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
21 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 26 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
22 * Copyright (C) 2003 - 2004 Tresys Technology, LLC 27 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
@@ -76,81 +81,86 @@ static struct policydb_compat_info policydb_compat[] = {
76 { 81 {
77 .version = POLICYDB_VERSION_BASE, 82 .version = POLICYDB_VERSION_BASE,
78 .sym_num = SYM_NUM - 3, 83 .sym_num = SYM_NUM - 3,
79 .ocon_num = OCON_NUM - 1, 84 .ocon_num = OCON_NUM - 3,
80 }, 85 },
81 { 86 {
82 .version = POLICYDB_VERSION_BOOL, 87 .version = POLICYDB_VERSION_BOOL,
83 .sym_num = SYM_NUM - 2, 88 .sym_num = SYM_NUM - 2,
84 .ocon_num = OCON_NUM - 1, 89 .ocon_num = OCON_NUM - 3,
85 }, 90 },
86 { 91 {
87 .version = POLICYDB_VERSION_IPV6, 92 .version = POLICYDB_VERSION_IPV6,
88 .sym_num = SYM_NUM - 2, 93 .sym_num = SYM_NUM - 2,
89 .ocon_num = OCON_NUM, 94 .ocon_num = OCON_NUM - 2,
90 }, 95 },
91 { 96 {
92 .version = POLICYDB_VERSION_NLCLASS, 97 .version = POLICYDB_VERSION_NLCLASS,
93 .sym_num = SYM_NUM - 2, 98 .sym_num = SYM_NUM - 2,
94 .ocon_num = OCON_NUM, 99 .ocon_num = OCON_NUM - 2,
95 }, 100 },
96 { 101 {
97 .version = POLICYDB_VERSION_MLS, 102 .version = POLICYDB_VERSION_MLS,
98 .sym_num = SYM_NUM, 103 .sym_num = SYM_NUM,
99 .ocon_num = OCON_NUM, 104 .ocon_num = OCON_NUM - 2,
100 }, 105 },
101 { 106 {
102 .version = POLICYDB_VERSION_AVTAB, 107 .version = POLICYDB_VERSION_AVTAB,
103 .sym_num = SYM_NUM, 108 .sym_num = SYM_NUM,
104 .ocon_num = OCON_NUM, 109 .ocon_num = OCON_NUM - 2,
105 }, 110 },
106 { 111 {
107 .version = POLICYDB_VERSION_RANGETRANS, 112 .version = POLICYDB_VERSION_RANGETRANS,
108 .sym_num = SYM_NUM, 113 .sym_num = SYM_NUM,
109 .ocon_num = OCON_NUM, 114 .ocon_num = OCON_NUM - 2,
110 }, 115 },
111 { 116 {
112 .version = POLICYDB_VERSION_POLCAP, 117 .version = POLICYDB_VERSION_POLCAP,
113 .sym_num = SYM_NUM, 118 .sym_num = SYM_NUM,
114 .ocon_num = OCON_NUM, 119 .ocon_num = OCON_NUM - 2,
115 }, 120 },
116 { 121 {
117 .version = POLICYDB_VERSION_PERMISSIVE, 122 .version = POLICYDB_VERSION_PERMISSIVE,
118 .sym_num = SYM_NUM, 123 .sym_num = SYM_NUM,
119 .ocon_num = OCON_NUM, 124 .ocon_num = OCON_NUM - 2,
120 }, 125 },
121 { 126 {
122 .version = POLICYDB_VERSION_BOUNDARY, 127 .version = POLICYDB_VERSION_BOUNDARY,
123 .sym_num = SYM_NUM, 128 .sym_num = SYM_NUM,
124 .ocon_num = OCON_NUM, 129 .ocon_num = OCON_NUM - 2,
125 }, 130 },
126 { 131 {
127 .version = POLICYDB_VERSION_FILENAME_TRANS, 132 .version = POLICYDB_VERSION_FILENAME_TRANS,
128 .sym_num = SYM_NUM, 133 .sym_num = SYM_NUM,
129 .ocon_num = OCON_NUM, 134 .ocon_num = OCON_NUM - 2,
130 }, 135 },
131 { 136 {
132 .version = POLICYDB_VERSION_ROLETRANS, 137 .version = POLICYDB_VERSION_ROLETRANS,
133 .sym_num = SYM_NUM, 138 .sym_num = SYM_NUM,
134 .ocon_num = OCON_NUM, 139 .ocon_num = OCON_NUM - 2,
135 }, 140 },
136 { 141 {
137 .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, 142 .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
138 .sym_num = SYM_NUM, 143 .sym_num = SYM_NUM,
139 .ocon_num = OCON_NUM, 144 .ocon_num = OCON_NUM - 2,
140 }, 145 },
141 { 146 {
142 .version = POLICYDB_VERSION_DEFAULT_TYPE, 147 .version = POLICYDB_VERSION_DEFAULT_TYPE,
143 .sym_num = SYM_NUM, 148 .sym_num = SYM_NUM,
144 .ocon_num = OCON_NUM, 149 .ocon_num = OCON_NUM - 2,
145 }, 150 },
146 { 151 {
147 .version = POLICYDB_VERSION_CONSTRAINT_NAMES, 152 .version = POLICYDB_VERSION_CONSTRAINT_NAMES,
148 .sym_num = SYM_NUM, 153 .sym_num = SYM_NUM,
149 .ocon_num = OCON_NUM, 154 .ocon_num = OCON_NUM - 2,
150 }, 155 },
151 { 156 {
152 .version = POLICYDB_VERSION_XPERMS_IOCTL, 157 .version = POLICYDB_VERSION_XPERMS_IOCTL,
153 .sym_num = SYM_NUM, 158 .sym_num = SYM_NUM,
159 .ocon_num = OCON_NUM - 2,
160 },
161 {
162 .version = POLICYDB_VERSION_INFINIBAND,
163 .sym_num = SYM_NUM,
154 .ocon_num = OCON_NUM, 164 .ocon_num = OCON_NUM,
155 }, 165 },
156}; 166};
@@ -538,34 +548,30 @@ static int policydb_index(struct policydb *p)
538 symtab_hash_eval(p->symtab); 548 symtab_hash_eval(p->symtab);
539#endif 549#endif
540 550
541 rc = -ENOMEM;
542 p->class_val_to_struct = kcalloc(p->p_classes.nprim, 551 p->class_val_to_struct = kcalloc(p->p_classes.nprim,
543 sizeof(*p->class_val_to_struct), 552 sizeof(*p->class_val_to_struct),
544 GFP_KERNEL); 553 GFP_KERNEL);
545 if (!p->class_val_to_struct) 554 if (!p->class_val_to_struct)
546 goto out; 555 return -ENOMEM;
547 556
548 rc = -ENOMEM;
549 p->role_val_to_struct = kcalloc(p->p_roles.nprim, 557 p->role_val_to_struct = kcalloc(p->p_roles.nprim,
550 sizeof(*p->role_val_to_struct), 558 sizeof(*p->role_val_to_struct),
551 GFP_KERNEL); 559 GFP_KERNEL);
552 if (!p->role_val_to_struct) 560 if (!p->role_val_to_struct)
553 goto out; 561 return -ENOMEM;
554 562
555 rc = -ENOMEM;
556 p->user_val_to_struct = kcalloc(p->p_users.nprim, 563 p->user_val_to_struct = kcalloc(p->p_users.nprim,
557 sizeof(*p->user_val_to_struct), 564 sizeof(*p->user_val_to_struct),
558 GFP_KERNEL); 565 GFP_KERNEL);
559 if (!p->user_val_to_struct) 566 if (!p->user_val_to_struct)
560 goto out; 567 return -ENOMEM;
561 568
562 /* Yes, I want the sizeof the pointer, not the structure */ 569 /* Yes, I want the sizeof the pointer, not the structure */
563 rc = -ENOMEM;
564 p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *), 570 p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *),
565 p->p_types.nprim, 571 p->p_types.nprim,
566 GFP_KERNEL | __GFP_ZERO); 572 GFP_KERNEL | __GFP_ZERO);
567 if (!p->type_val_to_struct_array) 573 if (!p->type_val_to_struct_array)
568 goto out; 574 return -ENOMEM;
569 575
570 rc = flex_array_prealloc(p->type_val_to_struct_array, 0, 576 rc = flex_array_prealloc(p->type_val_to_struct_array, 0,
571 p->p_types.nprim, GFP_KERNEL | __GFP_ZERO); 577 p->p_types.nprim, GFP_KERNEL | __GFP_ZERO);
@@ -577,12 +583,11 @@ static int policydb_index(struct policydb *p)
577 goto out; 583 goto out;
578 584
579 for (i = 0; i < SYM_NUM; i++) { 585 for (i = 0; i < SYM_NUM; i++) {
580 rc = -ENOMEM;
581 p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *), 586 p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *),
582 p->symtab[i].nprim, 587 p->symtab[i].nprim,
583 GFP_KERNEL | __GFP_ZERO); 588 GFP_KERNEL | __GFP_ZERO);
584 if (!p->sym_val_to_name[i]) 589 if (!p->sym_val_to_name[i])
585 goto out; 590 return -ENOMEM;
586 591
587 rc = flex_array_prealloc(p->sym_val_to_name[i], 592 rc = flex_array_prealloc(p->sym_val_to_name[i],
588 0, p->symtab[i].nprim, 593 0, p->symtab[i].nprim,
@@ -2211,6 +2216,51 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2211 goto out; 2216 goto out;
2212 break; 2217 break;
2213 } 2218 }
2219 case OCON_IBPKEY:
2220 rc = next_entry(nodebuf, fp, sizeof(u32) * 4);
2221 if (rc)
2222 goto out;
2223
2224 c->u.ibpkey.subnet_prefix = be64_to_cpu(*((__be64 *)nodebuf));
2225
2226 if (nodebuf[2] > 0xffff ||
2227 nodebuf[3] > 0xffff) {
2228 rc = -EINVAL;
2229 goto out;
2230 }
2231
2232 c->u.ibpkey.low_pkey = le32_to_cpu(nodebuf[2]);
2233 c->u.ibpkey.high_pkey = le32_to_cpu(nodebuf[3]);
2234
2235 rc = context_read_and_validate(&c->context[0],
2236 p,
2237 fp);
2238 if (rc)
2239 goto out;
2240 break;
2241 case OCON_IBENDPORT:
2242 rc = next_entry(buf, fp, sizeof(u32) * 2);
2243 if (rc)
2244 goto out;
2245 len = le32_to_cpu(buf[0]);
2246
2247 rc = str_read(&c->u.ibendport.dev_name, GFP_KERNEL, fp, len);
2248 if (rc)
2249 goto out;
2250
2251 if (buf[1] > 0xff || buf[1] == 0) {
2252 rc = -EINVAL;
2253 goto out;
2254 }
2255
2256 c->u.ibendport.port = le32_to_cpu(buf[1]);
2257
2258 rc = context_read_and_validate(&c->context[0],
2259 p,
2260 fp);
2261 if (rc)
2262 goto out;
2263 break;
2214 } 2264 }
2215 } 2265 }
2216 } 2266 }
@@ -3140,6 +3190,33 @@ static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
3140 if (rc) 3190 if (rc)
3141 return rc; 3191 return rc;
3142 break; 3192 break;
3193 case OCON_IBPKEY:
3194 *((__be64 *)nodebuf) = cpu_to_be64(c->u.ibpkey.subnet_prefix);
3195
3196 nodebuf[2] = cpu_to_le32(c->u.ibpkey.low_pkey);
3197 nodebuf[3] = cpu_to_le32(c->u.ibpkey.high_pkey);
3198
3199 rc = put_entry(nodebuf, sizeof(u32), 4, fp);
3200 if (rc)
3201 return rc;
3202 rc = context_write(p, &c->context[0], fp);
3203 if (rc)
3204 return rc;
3205 break;
3206 case OCON_IBENDPORT:
3207 len = strlen(c->u.ibendport.dev_name);
3208 buf[0] = cpu_to_le32(len);
3209 buf[1] = cpu_to_le32(c->u.ibendport.port);
3210 rc = put_entry(buf, sizeof(u32), 2, fp);
3211 if (rc)
3212 return rc;
3213 rc = put_entry(c->u.ibendport.dev_name, 1, len, fp);
3214 if (rc)
3215 return rc;
3216 rc = context_write(p, &c->context[0], fp);
3217 if (rc)
3218 return rc;
3219 break;
3143 } 3220 }
3144 } 3221 }
3145 } 3222 }
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 725d5945a97e..5d23eed35fa7 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -187,6 +187,15 @@ struct ocontext {
187 u32 addr[4]; 187 u32 addr[4];
188 u32 mask[4]; 188 u32 mask[4];
189 } node6; /* IPv6 node information */ 189 } node6; /* IPv6 node information */
190 struct {
191 u64 subnet_prefix;
192 u16 low_pkey;
193 u16 high_pkey;
194 } ibpkey;
195 struct {
196 char *dev_name;
197 u8 port;
198 } ibendport;
190 } u; 199 } u;
191 union { 200 union {
192 u32 sclass; /* security class for genfs */ 201 u32 sclass; /* security class for genfs */
@@ -215,14 +224,16 @@ struct genfs {
215#define SYM_NUM 8 224#define SYM_NUM 8
216 225
217/* object context array indices */ 226/* object context array indices */
218#define OCON_ISID 0 /* initial SIDs */ 227#define OCON_ISID 0 /* initial SIDs */
219#define OCON_FS 1 /* unlabeled file systems */ 228#define OCON_FS 1 /* unlabeled file systems */
220#define OCON_PORT 2 /* TCP and UDP port numbers */ 229#define OCON_PORT 2 /* TCP and UDP port numbers */
221#define OCON_NETIF 3 /* network interfaces */ 230#define OCON_NETIF 3 /* network interfaces */
222#define OCON_NODE 4 /* nodes */ 231#define OCON_NODE 4 /* nodes */
223#define OCON_FSUSE 5 /* fs_use */ 232#define OCON_FSUSE 5 /* fs_use */
224#define OCON_NODE6 6 /* IPv6 nodes */ 233#define OCON_NODE6 6 /* IPv6 nodes */
225#define OCON_NUM 7 234#define OCON_IBPKEY 7 /* Infiniband PKeys */
235#define OCON_IBENDPORT 8 /* Infiniband end ports */
236#define OCON_NUM 9
226 237
227/* The policy database */ 238/* The policy database */
228struct policydb { 239struct policydb {
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 60d9b0252321..2f02fa67ec2e 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -70,6 +70,15 @@
70#include "ebitmap.h" 70#include "ebitmap.h"
71#include "audit.h" 71#include "audit.h"
72 72
73/* Policy capability names */
74char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX] = {
75 "network_peer_controls",
76 "open_perms",
77 "extended_socket_class",
78 "always_check_network",
79 "cgroup_seclabel"
80};
81
73int selinux_policycap_netpeer; 82int selinux_policycap_netpeer;
74int selinux_policycap_openperm; 83int selinux_policycap_openperm;
75int selinux_policycap_extsockclass; 84int selinux_policycap_extsockclass;
@@ -1986,6 +1995,9 @@ bad:
1986 1995
1987static void security_load_policycaps(void) 1996static void security_load_policycaps(void)
1988{ 1997{
1998 unsigned int i;
1999 struct ebitmap_node *node;
2000
1989 selinux_policycap_netpeer = ebitmap_get_bit(&policydb.policycaps, 2001 selinux_policycap_netpeer = ebitmap_get_bit(&policydb.policycaps,
1990 POLICYDB_CAPABILITY_NETPEER); 2002 POLICYDB_CAPABILITY_NETPEER);
1991 selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, 2003 selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps,
@@ -1997,6 +2009,17 @@ static void security_load_policycaps(void)
1997 selinux_policycap_cgroupseclabel = 2009 selinux_policycap_cgroupseclabel =
1998 ebitmap_get_bit(&policydb.policycaps, 2010 ebitmap_get_bit(&policydb.policycaps,
1999 POLICYDB_CAPABILITY_CGROUPSECLABEL); 2011 POLICYDB_CAPABILITY_CGROUPSECLABEL);
2012
2013 for (i = 0; i < ARRAY_SIZE(selinux_policycap_names); i++)
2014 pr_info("SELinux: policy capability %s=%d\n",
2015 selinux_policycap_names[i],
2016 ebitmap_get_bit(&policydb.policycaps, i));
2017
2018 ebitmap_for_each_positive_bit(&policydb.policycaps, node, i) {
2019 if (i >= ARRAY_SIZE(selinux_policycap_names))
2020 pr_info("SELinux: unknown policy capability %u\n",
2021 i);
2022 }
2000} 2023}
2001 2024
2002static int security_preserve_bools(struct policydb *p); 2025static int security_preserve_bools(struct policydb *p);
@@ -2031,9 +2054,11 @@ int security_load_policy(void *data, size_t len)
2031 2054
2032 if (!ss_initialized) { 2055 if (!ss_initialized) {
2033 avtab_cache_init(); 2056 avtab_cache_init();
2057 ebitmap_cache_init();
2034 rc = policydb_read(&policydb, fp); 2058 rc = policydb_read(&policydb, fp);
2035 if (rc) { 2059 if (rc) {
2036 avtab_cache_destroy(); 2060 avtab_cache_destroy();
2061 ebitmap_cache_destroy();
2037 goto out; 2062 goto out;
2038 } 2063 }
2039 2064
@@ -2044,6 +2069,7 @@ int security_load_policy(void *data, size_t len)
2044 if (rc) { 2069 if (rc) {
2045 policydb_destroy(&policydb); 2070 policydb_destroy(&policydb);
2046 avtab_cache_destroy(); 2071 avtab_cache_destroy();
2072 ebitmap_cache_destroy();
2047 goto out; 2073 goto out;
2048 } 2074 }
2049 2075
@@ -2051,6 +2077,7 @@ int security_load_policy(void *data, size_t len)
2051 if (rc) { 2077 if (rc) {
2052 policydb_destroy(&policydb); 2078 policydb_destroy(&policydb);
2053 avtab_cache_destroy(); 2079 avtab_cache_destroy();
2080 ebitmap_cache_destroy();
2054 goto out; 2081 goto out;
2055 } 2082 }
2056 2083
@@ -2210,6 +2237,87 @@ out:
2210} 2237}
2211 2238
2212/** 2239/**
2240 * security_pkey_sid - Obtain the SID for a pkey.
2241 * @subnet_prefix: Subnet Prefix
2242 * @pkey_num: pkey number
2243 * @out_sid: security identifier
2244 */
2245int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid)
2246{
2247 struct ocontext *c;
2248 int rc = 0;
2249
2250 read_lock(&policy_rwlock);
2251
2252 c = policydb.ocontexts[OCON_IBPKEY];
2253 while (c) {
2254 if (c->u.ibpkey.low_pkey <= pkey_num &&
2255 c->u.ibpkey.high_pkey >= pkey_num &&
2256 c->u.ibpkey.subnet_prefix == subnet_prefix)
2257 break;
2258
2259 c = c->next;
2260 }
2261
2262 if (c) {
2263 if (!c->sid[0]) {
2264 rc = sidtab_context_to_sid(&sidtab,
2265 &c->context[0],
2266 &c->sid[0]);
2267 if (rc)
2268 goto out;
2269 }
2270 *out_sid = c->sid[0];
2271 } else
2272 *out_sid = SECINITSID_UNLABELED;
2273
2274out:
2275 read_unlock(&policy_rwlock);
2276 return rc;
2277}
2278
2279/**
2280 * security_ib_endport_sid - Obtain the SID for a subnet management interface.
2281 * @dev_name: device name
2282 * @port: port number
2283 * @out_sid: security identifier
2284 */
2285int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid)
2286{
2287 struct ocontext *c;
2288 int rc = 0;
2289
2290 read_lock(&policy_rwlock);
2291
2292 c = policydb.ocontexts[OCON_IBENDPORT];
2293 while (c) {
2294 if (c->u.ibendport.port == port_num &&
2295 !strncmp(c->u.ibendport.dev_name,
2296 dev_name,
2297 IB_DEVICE_NAME_MAX))
2298 break;
2299
2300 c = c->next;
2301 }
2302
2303 if (c) {
2304 if (!c->sid[0]) {
2305 rc = sidtab_context_to_sid(&sidtab,
2306 &c->context[0],
2307 &c->sid[0]);
2308 if (rc)
2309 goto out;
2310 }
2311 *out_sid = c->sid[0];
2312 } else
2313 *out_sid = SECINITSID_UNLABELED;
2314
2315out:
2316 read_unlock(&policy_rwlock);
2317 return rc;
2318}
2319
2320/**
2213 * security_netif_sid - Obtain the SID for a network interface. 2321 * security_netif_sid - Obtain the SID for a network interface.
2214 * @name: interface name 2322 * @name: interface name
2215 * @if_sid: interface SID 2323 * @if_sid: interface SID
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index f6915f257486..c5f436b15d19 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -32,13 +32,11 @@ int sidtab_init(struct sidtab *s)
32 32
33int sidtab_insert(struct sidtab *s, u32 sid, struct context *context) 33int sidtab_insert(struct sidtab *s, u32 sid, struct context *context)
34{ 34{
35 int hvalue, rc = 0; 35 int hvalue;
36 struct sidtab_node *prev, *cur, *newnode; 36 struct sidtab_node *prev, *cur, *newnode;
37 37
38 if (!s) { 38 if (!s)
39 rc = -ENOMEM; 39 return -ENOMEM;
40 goto out;
41 }
42 40
43 hvalue = SIDTAB_HASH(sid); 41 hvalue = SIDTAB_HASH(sid);
44 prev = NULL; 42 prev = NULL;
@@ -48,21 +46,17 @@ int sidtab_insert(struct sidtab *s, u32 sid, struct context *context)
48 cur = cur->next; 46 cur = cur->next;
49 } 47 }
50 48
51 if (cur && sid == cur->sid) { 49 if (cur && sid == cur->sid)
52 rc = -EEXIST; 50 return -EEXIST;
53 goto out;
54 }
55 51
56 newnode = kmalloc(sizeof(*newnode), GFP_ATOMIC); 52 newnode = kmalloc(sizeof(*newnode), GFP_ATOMIC);
57 if (!newnode) { 53 if (!newnode)
58 rc = -ENOMEM; 54 return -ENOMEM;
59 goto out; 55
60 }
61 newnode->sid = sid; 56 newnode->sid = sid;
62 if (context_cpy(&newnode->context, context)) { 57 if (context_cpy(&newnode->context, context)) {
63 kfree(newnode); 58 kfree(newnode);
64 rc = -ENOMEM; 59 return -ENOMEM;
65 goto out;
66 } 60 }
67 61
68 if (prev) { 62 if (prev) {
@@ -78,8 +72,7 @@ int sidtab_insert(struct sidtab *s, u32 sid, struct context *context)
78 s->nel++; 72 s->nel++;
79 if (sid >= s->next_sid) 73 if (sid >= s->next_sid)
80 s->next_sid = sid + 1; 74 s->next_sid = sid + 1;
81out: 75 return 0;
82 return rc;
83} 76}
84 77
85static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force) 78static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force)
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 612b810fbbc6..6a71fc7831ab 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -320,7 +320,7 @@ int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
320struct smack_known *smk_import_entry(const char *, int); 320struct smack_known *smk_import_entry(const char *, int);
321void smk_insert_entry(struct smack_known *skp); 321void smk_insert_entry(struct smack_known *skp);
322struct smack_known *smk_find_entry(const char *); 322struct smack_known *smk_find_entry(const char *);
323int smack_privileged(int cap); 323bool smack_privileged(int cap);
324void smk_destroy_label_list(struct list_head *list); 324void smk_destroy_label_list(struct list_head *list);
325 325
326/* 326/*
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index a4b2e6b94abd..1a3004189447 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -627,35 +627,38 @@ DEFINE_MUTEX(smack_onlycap_lock);
627 * Is the task privileged and allowed to be privileged 627 * Is the task privileged and allowed to be privileged
628 * by the onlycap rule. 628 * by the onlycap rule.
629 * 629 *
630 * Returns 1 if the task is allowed to be privileged, 0 if it's not. 630 * Returns true if the task is allowed to be privileged, false if it's not.
631 */ 631 */
632int smack_privileged(int cap) 632bool smack_privileged(int cap)
633{ 633{
634 struct smack_known *skp = smk_of_current(); 634 struct smack_known *skp = smk_of_current();
635 struct smack_known_list_elem *sklep; 635 struct smack_known_list_elem *sklep;
636 int rc;
636 637
637 /* 638 /*
638 * All kernel tasks are privileged 639 * All kernel tasks are privileged
639 */ 640 */
640 if (unlikely(current->flags & PF_KTHREAD)) 641 if (unlikely(current->flags & PF_KTHREAD))
641 return 1; 642 return true;
642 643
643 if (!capable(cap)) 644 rc = cap_capable(current_cred(), &init_user_ns, cap,
644 return 0; 645 SECURITY_CAP_AUDIT);
646 if (rc)
647 return false;
645 648
646 rcu_read_lock(); 649 rcu_read_lock();
647 if (list_empty(&smack_onlycap_list)) { 650 if (list_empty(&smack_onlycap_list)) {
648 rcu_read_unlock(); 651 rcu_read_unlock();
649 return 1; 652 return true;
650 } 653 }
651 654
652 list_for_each_entry_rcu(sklep, &smack_onlycap_list, list) { 655 list_for_each_entry_rcu(sklep, &smack_onlycap_list, list) {
653 if (sklep->smk_label == skp) { 656 if (sklep->smk_label == skp) {
654 rcu_read_unlock(); 657 rcu_read_unlock();
655 return 1; 658 return true;
656 } 659 }
657 } 660 }
658 rcu_read_unlock(); 661 rcu_read_unlock();
659 662
660 return 0; 663 return false;
661} 664}
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 658f5d8c7e76..463af86812c7 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1915,7 +1915,7 @@ static int smack_file_receive(struct file *file)
1915 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); 1915 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1916 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1916 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1917 1917
1918 if (S_ISSOCK(inode->i_mode)) { 1918 if (inode->i_sb->s_magic == SOCKFS_MAGIC) {
1919 sock = SOCKET_I(inode); 1919 sock = SOCKET_I(inode);
1920 ssp = sock->sk->sk_security; 1920 ssp = sock->sk->sk_security;
1921 tsp = current_security(); 1921 tsp = current_security();
diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c
index 205b785fb400..cdeb0f3243dd 100644
--- a/security/smack/smack_netfilter.c
+++ b/security/smack/smack_netfilter.c
@@ -18,6 +18,7 @@
18#include <linux/netfilter_ipv6.h> 18#include <linux/netfilter_ipv6.h>
19#include <linux/netdevice.h> 19#include <linux/netdevice.h>
20#include <net/inet_sock.h> 20#include <net/inet_sock.h>
21#include <net/net_namespace.h>
21#include "smack.h" 22#include "smack.h"
22 23
23#if IS_ENABLED(CONFIG_IPV6) 24#if IS_ENABLED(CONFIG_IPV6)
@@ -74,20 +75,29 @@ static struct nf_hook_ops smack_nf_ops[] = {
74#endif /* IPV6 */ 75#endif /* IPV6 */
75}; 76};
76 77
77static int __init smack_nf_ip_init(void) 78static int __net_init smack_nf_register(struct net *net)
79{
80 return nf_register_net_hooks(net, smack_nf_ops,
81 ARRAY_SIZE(smack_nf_ops));
82}
83
84static void __net_exit smack_nf_unregister(struct net *net)
78{ 85{
79 int err; 86 nf_unregister_net_hooks(net, smack_nf_ops, ARRAY_SIZE(smack_nf_ops));
87}
80 88
89static struct pernet_operations smack_net_ops = {
90 .init = smack_nf_register,
91 .exit = smack_nf_unregister,
92};
93
94static int __init smack_nf_ip_init(void)
95{
81 if (smack_enabled == 0) 96 if (smack_enabled == 0)
82 return 0; 97 return 0;
83 98
84 printk(KERN_DEBUG "Smack: Registering netfilter hooks\n"); 99 printk(KERN_DEBUG "Smack: Registering netfilter hooks\n");
85 100 return register_pernet_subsys(&smack_net_ops);
86 err = nf_register_hooks(smack_nf_ops, ARRAY_SIZE(smack_nf_ops));
87 if (err)
88 pr_info("Smack: nf_register_hooks: error %d\n", err);
89
90 return 0;
91} 101}
92 102
93__initcall(smack_nf_ip_init); 103__initcall(smack_nf_ip_init);