]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-apparmor-after-grsec_full.patch
- merged from LINUX_2_6
[packages/kernel.git] / kernel-apparmor-after-grsec_full.patch
CommitLineData
2380c486
JR
1diff -uprN a/fs/afs/dir.c b/fs/afs/dir.c
2--- a/fs/afs/dir.c 2008-12-24 23:26:37.000000000 +0000
3+++ b/fs/afs/dir.c 2009-02-08 13:26:38.882622899 +0000
4@@ -46,6 +46,7 @@ const struct file_operations afs_dir_fil
9f87b1bd 5 .readdir = afs_readdir,
6 .lock = afs_lock,
2380c486
JR
7 .llseek = generic_file_llseek,
8+ .fsetattr = afs_fsetattr,
9f87b1bd 9 };
10
11 const struct inode_operations afs_dir_inode_operations = {
2380c486
JR
12diff -uprN a/fs/afs/file.c b/fs/afs/file.c
13--- a/fs/afs/file.c 2008-12-24 23:26:37.000000000 +0000
14+++ b/fs/afs/file.c 2009-02-08 13:26:38.882622899 +0000
9f87b1bd 15@@ -36,6 +36,7 @@ const struct file_operations afs_file_op
16 .fsync = afs_fsync,
17 .lock = afs_lock,
18 .flock = afs_flock,
19+ .fsetattr = afs_fsetattr,
20 };
21
22 const struct inode_operations afs_file_inode_operations = {
2380c486
JR
23diff -uprN a/fs/afs/inode.c b/fs/afs/inode.c
24--- a/fs/afs/inode.c 2008-12-24 23:26:37.000000000 +0000
25+++ b/fs/afs/inode.c 2009-02-08 13:26:38.882622899 +0000
9f87b1bd 26@@ -358,7 +358,8 @@ void afs_clear_inode(struct inode *inode
27 /*
28 * set the attributes of an inode
29 */
30-int afs_setattr(struct dentry *dentry, struct iattr *attr)
31+static int afs_do_setattr(struct dentry *dentry, struct iattr *attr,
32+ struct file *file)
33 {
34 struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode);
35 struct key *key;
36@@ -380,8 +381,8 @@ int afs_setattr(struct dentry *dentry, s
37 afs_writeback_all(vnode);
38 }
39
40- if (attr->ia_valid & ATTR_FILE) {
41- key = attr->ia_file->private_data;
42+ if (file) {
43+ key = file->private_data;
44 } else {
45 key = afs_request_key(vnode->volume->cell);
46 if (IS_ERR(key)) {
47@@ -391,10 +392,20 @@ int afs_setattr(struct dentry *dentry, s
48 }
49
50 ret = afs_vnode_setattr(vnode, key, attr);
51- if (!(attr->ia_valid & ATTR_FILE))
52+ if (!file)
53 key_put(key);
54
55 error:
56 _leave(" = %d", ret);
57 return ret;
58 }
59+
60+int afs_setattr(struct dentry *dentry, struct iattr *attr)
61+{
62+ return afs_do_setattr(dentry, attr, NULL);
63+}
64+
65+int afs_fsetattr(struct file *file, struct iattr *attr)
66+{
67+ return afs_do_setattr(file->f_path.dentry, attr, file);
68+}
2380c486
JR
69diff -uprN a/fs/afs/internal.h b/fs/afs/internal.h
70--- a/fs/afs/internal.h 2008-12-24 23:26:37.000000000 +0000
71+++ b/fs/afs/internal.h 2009-02-08 13:26:38.882622899 +0000
9f87b1bd 72@@ -548,6 +548,7 @@ extern void afs_zap_data(struct afs_vnod
73 extern int afs_validate(struct afs_vnode *, struct key *);
74 extern int afs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
75 extern int afs_setattr(struct dentry *, struct iattr *);
76+extern int afs_fsetattr(struct file *, struct iattr *);
77 extern void afs_clear_inode(struct inode *);
78
79 /*
2380c486
JR
80diff -uprN a/fs/attr.c b/fs/attr.c
81--- a/fs/attr.c 2008-12-24 23:26:37.000000000 +0000
82+++ b/fs/attr.c 2009-02-08 13:26:38.889289652 +0000
9f87b1bd 83@@ -100,7 +100,8 @@ int inode_setattr(struct inode * inode,
84 }
85 EXPORT_SYMBOL(inode_setattr);
86
87-int notify_change(struct dentry * dentry, struct iattr * attr)
88+int fnotify_change(struct dentry *dentry, struct vfsmount *mnt,
89+ struct iattr *attr, struct file *file)
90 {
91 struct inode *inode = dentry->d_inode;
92 mode_t mode = inode->i_mode;
2380c486
JR
93@@ -159,7 +160,7 @@ int notify_change(struct dentry * dentry
94 if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID)))
95 return 0;
96
97- error = security_inode_setattr(dentry, attr);
98+ error = security_inode_setattr(dentry, mnt, attr);
99 if (error)
100 return error;
101
102@@ -167,7 +168,21 @@ int notify_change(struct dentry * dentry
9f87b1bd 103 down_write(&dentry->d_inode->i_alloc_sem);
104
105 if (inode->i_op && inode->i_op->setattr) {
2380c486
JR
106- error = inode->i_op->setattr(dentry, attr);
107+ if (file && file->f_op && file->f_op->fsetattr) {
108+ error = file->f_op->fsetattr(file, attr);
109+ } else {
110+ /* External file system still expect to be
111+ * passed a file pointer via ia_file and
112+ * have it announced via ATTR_FILE. This
113+ * just makes it so they don't need to
114+ * change their API just for us. External
115+ * callers will have set these themselves. */
116+ if (file) {
117+ attr->ia_valid |= ATTR_FILE;
118+ attr->ia_file = file;
9f87b1bd 119+ }
2380c486 120+ error = inode->i_op->setattr(dentry, attr);
9f87b1bd 121+ }
122 } else {
123 error = inode_change_ok(inode, attr);
9f87b1bd 124 if (!error) {
2380c486 125@@ -187,5 +202,12 @@ int notify_change(struct dentry * dentry
9f87b1bd 126
127 return error;
128 }
129+EXPORT_SYMBOL_GPL(fnotify_change);
130+
131+int notify_change(struct dentry *dentry, struct vfsmount *mnt,
132+ struct iattr *attr)
133+{
134+ return fnotify_change(dentry, mnt, attr, NULL);
135+}
136
137 EXPORT_SYMBOL(notify_change);
2380c486
JR
138diff -uprN a/fs/dcache.c b/fs/dcache.c
139--- a/fs/dcache.c 2009-02-08 13:22:56.398269260 +0000
140+++ b/fs/dcache.c 2009-02-08 13:26:38.879284319 +0000
141@@ -1908,45 +1908,46 @@ static int prepend_name(char **buffer, i
9f87b1bd 142 * @root: root vfsmnt/dentry (may be modified by this function)
143 * @buffer: buffer to return value in
144 * @buflen: buffer length
145+ * @flags: flags controling behavior of d_path
146 *
147- * Convert a dentry into an ASCII path name. If the entry has been deleted
148- * the string " (deleted)" is appended. Note that this is ambiguous.
149- *
2380c486
JR
150- * Returns a pointer into the buffer or an error code if the
151- * path was too long.
9f87b1bd 152- *
153- * "buflen" should be positive. Caller holds the dcache_lock.
154+ * Convert a dentry into an ASCII path name. If the entry has been deleted,
155+ * then if @flags has D_PATH_FAIL_DELETED set, ERR_PTR(-ENOENT) is returned.
156+ * Otherwise, the string " (deleted)" is appended. Note that this is ambiguous.
157 *
158 * If path is not reachable from the supplied root, then the value of
159- * root is changed (without modifying refcounts).
160+ * root is changed (without modifying refcounts). The path returned in this
161+ * case will be relative (i.e., it will not start with a slash).
162+ *
163+ * Returns the buffer or an error code if the path was too long.
164 */
165 char *__d_path(const struct path *path, struct path *root,
166- char *buffer, int buflen)
167+ char *buffer, int buflen, int flags)
168 {
169 struct dentry *dentry = path->dentry;
170 struct vfsmount *vfsmnt = path->mnt;
171- char *end = buffer + buflen;
172- char *retval;
173+ const unsigned char *name;
174+ int namelen;
175+
176+ buffer += buflen;
177+ prepend(&buffer, &buflen, "\0", 1);
178
179 spin_lock(&vfsmount_lock);
180- prepend(&end, &buflen, "\0", 1);
181- if (!IS_ROOT(dentry) && d_unhashed(dentry) &&
182- (prepend(&end, &buflen, " (deleted)", 10) != 0))
183+ spin_lock(&dcache_lock);
184+ if (!IS_ROOT(dentry) && d_unhashed(dentry)) {
185+ if (flags & D_PATH_FAIL_DELETED) {
186+ buffer = ERR_PTR(-ENOENT);
187+ goto out;
188+ }
189+ if (prepend(&buffer, &buflen, " (deleted)", 10) != 0)
190 goto Elong;
191-
192+ }
193 if (buflen < 1)
194 goto Elong;
195- /* Get '/' right */
196- retval = end-1;
197- *retval = '/';
198
199- for (;;) {
200+ while (dentry != root->dentry || vfsmnt != root->mnt) {
201 struct dentry * parent;
202
203- if (dentry == root->dentry && vfsmnt == root->mnt)
204- break;
205 if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
206- /* Global root? */
207 if (vfsmnt->mnt_parent == vfsmnt) {
208 goto global_root;
209 }
2380c486 210@@ -1955,27 +1957,51 @@ char *__d_path(const struct path *path,
9f87b1bd 211 }
212 parent = dentry->d_parent;
213 prefetch(parent);
214- if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) ||
215- (prepend(&end, &buflen, "/", 1) != 0))
216+ if ((prepend_name(&buffer, &buflen, &dentry->d_name) != 0) ||
217+ (prepend(&buffer, &buflen, "/", 1) != 0))
218 goto Elong;
219- retval = end;
220 dentry = parent;
221 }
222+ /* Get '/' right. */
223+ if (*buffer != '/' && prepend(&buffer, &buflen, "/", 1))
224+ goto Elong;
225
226 out:
227+ spin_unlock(&dcache_lock);
228 spin_unlock(&vfsmount_lock);
229- return retval;
230+ return buffer;
231
232 global_root:
233- retval += 1; /* hit the slash */
234- if (prepend_name(&retval, &buflen, &dentry->d_name) != 0)
235+ /*
236+ * We went past the (vfsmount, dentry) we were looking for and have
237+ * either hit a root dentry, a lazily unmounted dentry, an
238+ * unconnected dentry, or the file is on a pseudo filesystem.
239+ */
240+ namelen = dentry->d_name.len;
241+ name = dentry->d_name.name;
242+
243+ /*
244+ * If this is a root dentry, then overwrite the slash. This
245+ * will also DTRT with pseudo filesystems which have root
246+ * dentries named "foo:".
247+ */
248+ if (IS_ROOT(dentry) && *buffer == '/') {
249+ buffer++;
250+ buflen++;
251+ }
252+ if ((flags & D_PATH_DISCONNECT) && *name == '/') {
253+ /* Make sure we won't return a pathname starting with '/' */
254+ name++;
255+ namelen--;
256+ }
257+ if (prepend(&buffer, &buflen, name, namelen))
258 goto Elong;
259 root->mnt = vfsmnt;
260 root->dentry = dentry;
261 goto out;
262
263 Elong:
264- retval = ERR_PTR(-ENAMETOOLONG);
265+ buffer = ERR_PTR(-ENAMETOOLONG);
266 goto out;
267 }
268
2380c486 269@@ -2012,10 +2038,8 @@ char *d_path(const struct path *path, ch
9f87b1bd 270 root = current->fs->root;
271 path_get(&root);
272 read_unlock(&current->fs->lock);
273- spin_lock(&dcache_lock);
274 tmp = root;
275- res = __d_path(path, &tmp, buf, buflen);
276- spin_unlock(&dcache_lock);
277+ res = __d_path(path, &tmp, buf, buflen, 0);
278 path_put(&root);
279 return res;
280 }
2380c486 281@@ -2098,9 +2122,9 @@ Elong:
9f87b1bd 282 */
2380c486 283 SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
9f87b1bd 284 {
285- int error;
286- struct path pwd, root;
287- char *page = (char *) __get_free_page(GFP_USER);
288+ int error, len;
289+ struct path pwd, root, tmp;
290+ char *page = (char *) __get_free_page(GFP_USER), *cwd;
291
292 if (!page)
293 return -ENOMEM;
2380c486 294@@ -2112,30 +2136,20 @@ SYSCALL_DEFINE2(getcwd, char __user *, b
9f87b1bd 295 path_get(&root);
296 read_unlock(&current->fs->lock);
297
298- error = -ENOENT;
299- /* Has the current directory has been unlinked? */
300- spin_lock(&dcache_lock);
301- if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) {
302- unsigned long len;
303- struct path tmp = root;
304- char * cwd;
305-
306- cwd = __d_path(&pwd, &tmp, page, PAGE_SIZE);
307- spin_unlock(&dcache_lock);
308-
309+ tmp = root;
310+ cwd = __d_path(&pwd, &tmp, page, PAGE_SIZE, D_PATH_FAIL_DELETED);
311+ if (IS_ERR(cwd)) {
312 error = PTR_ERR(cwd);
313- if (IS_ERR(cwd))
314- goto out;
315+ goto out;
316+ }
317
318- error = -ERANGE;
319- len = PAGE_SIZE + page - cwd;
320- if (len <= size) {
321- error = len;
322- if (copy_to_user(buf, cwd, len))
323- error = -EFAULT;
324- }
325- } else
326- spin_unlock(&dcache_lock);
327+ error = -ERANGE;
328+ len = PAGE_SIZE + page - cwd;
329+ if (len <= size) {
330+ error = len;
331+ if (copy_to_user(buf, cwd, len))
332+ error = -EFAULT;
333+ }
334
335 out:
336 path_put(&pwd);
2380c486
JR
337diff -uprN a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
338--- a/fs/ecryptfs/inode.c 2009-02-08 13:22:56.398269260 +0000
339+++ b/fs/ecryptfs/inode.c 2009-02-08 13:26:38.839289678 +0000
9f87b1bd 340@@ -403,19 +403,24 @@ static int ecryptfs_link(struct dentry *
341 struct dentry *new_dentry)
342 {
343 struct dentry *lower_old_dentry;
344+ struct vfsmount *lower_old_mnt;
345 struct dentry *lower_new_dentry;
346+ struct vfsmount *lower_new_mnt;
347 struct dentry *lower_dir_dentry;
348 u64 file_size_save;
349 int rc;
350
351 file_size_save = i_size_read(old_dentry->d_inode);
352 lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
353+ lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry);
354 lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
355+ lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry);
356 dget(lower_old_dentry);
357 dget(lower_new_dentry);
358 lower_dir_dentry = lock_parent(lower_new_dentry);
359- rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
360- lower_new_dentry);
361+ rc = vfs_link(lower_old_dentry, lower_old_mnt,
362+ lower_dir_dentry->d_inode, lower_new_dentry,
363+ lower_new_mnt);
364 if (rc || !lower_new_dentry->d_inode)
365 goto out_lock;
366 rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
2380c486 367@@ -474,11 +474,12 @@
9f87b1bd 368 {
369 int rc = 0;
370 struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
371+ struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
372 struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
373 struct dentry *lower_dir_dentry;
374
375 lower_dir_dentry = lock_parent(lower_dentry);
376- rc = vfs_unlink(lower_dir_inode, lower_dentry);
377+ rc = vfs_unlink(lower_dir_inode, lower_dentry, lower_mnt);
378 if (rc) {
379 printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
380 goto out_unlock;
381@@ -464,6 +470,7 @@ static int ecryptfs_symlink(struct inode
382 {
383 int rc;
384 struct dentry *lower_dentry;
385+ struct vfsmount *lower_mnt;
386 struct dentry *lower_dir_dentry;
387 char *encoded_symname;
388 int encoded_symlen;
389@@ -471,6 +478,7 @@ static int ecryptfs_symlink(struct inode
390
391 lower_dentry = ecryptfs_dentry_to_lower(dentry);
392 dget(lower_dentry);
393+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
394 lower_dir_dentry = lock_parent(lower_dentry);
395 encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname,
396 strlen(symname),
2380c486
JR
397@@ -517,7 +518,7 @@
398 strlen(symname));
399 if (rc)
9f87b1bd 400 goto out_lock;
9f87b1bd 401- rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry,
2380c486 402+ rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, lower_mnt
9f87b1bd 403 encoded_symname);
404 kfree(encoded_symname);
405 if (rc || !lower_dentry->d_inode)
406@@ -501,11 +509,14 @@ static int ecryptfs_mkdir(struct inode *
407 {
408 int rc;
409 struct dentry *lower_dentry;
410+ struct vfsmount *lower_mnt;
411 struct dentry *lower_dir_dentry;
412
413 lower_dentry = ecryptfs_dentry_to_lower(dentry);
414+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
415 lower_dir_dentry = lock_parent(lower_dentry);
416- rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode);
417+ rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt,
418+ mode);
419 if (rc || !lower_dentry->d_inode)
420 goto out;
421 rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
422@@ -524,14 +535,16 @@ out:
423 static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
424 {
425 struct dentry *lower_dentry;
426+ struct vfsmount *lower_mnt;
427 struct dentry *lower_dir_dentry;
428 int rc;
429
430 lower_dentry = ecryptfs_dentry_to_lower(dentry);
431+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
432 dget(dentry);
433 lower_dir_dentry = lock_parent(lower_dentry);
434 dget(lower_dentry);
435- rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
436+ rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt);
437 dput(lower_dentry);
438 if (!rc)
439 d_delete(lower_dentry);
440@@ -549,11 +562,14 @@ ecryptfs_mknod(struct inode *dir, struct
441 {
442 int rc;
443 struct dentry *lower_dentry;
444+ struct vfsmount *lower_mnt;
445 struct dentry *lower_dir_dentry;
446
447 lower_dentry = ecryptfs_dentry_to_lower(dentry);
448+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
449 lower_dir_dentry = lock_parent(lower_dentry);
450- rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev);
451+ rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, mode,
452+ dev);
453 if (rc || !lower_dentry->d_inode)
454 goto out;
455 rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
456@@ -574,19 +590,24 @@ ecryptfs_rename(struct inode *old_dir, s
457 {
458 int rc;
459 struct dentry *lower_old_dentry;
460+ struct vfsmount *lower_old_mnt;
461 struct dentry *lower_new_dentry;
462+ struct vfsmount *lower_new_mnt;
463 struct dentry *lower_old_dir_dentry;
464 struct dentry *lower_new_dir_dentry;
465
466 lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
467+ lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry);
468 lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
469+ lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry);
470 dget(lower_old_dentry);
471 dget(lower_new_dentry);
472 lower_old_dir_dentry = dget_parent(lower_old_dentry);
473 lower_new_dir_dentry = dget_parent(lower_new_dentry);
474 lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
475 rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
476- lower_new_dir_dentry->d_inode, lower_new_dentry);
477+ lower_old_mnt, lower_new_dir_dentry->d_inode,
478+ lower_new_dentry, lower_new_mnt);
479 if (rc)
480 goto out_lock;
481 fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL);
2380c486 482@@ -850,6 +871,7 @@ static int ecryptfs_setattr(struct dentr
9f87b1bd 483 {
484 int rc = 0;
485 struct dentry *lower_dentry;
486+ struct vfsmount *lower_mnt;
487 struct inode *inode;
488 struct inode *lower_inode;
489 struct ecryptfs_crypt_stat *crypt_stat;
2380c486 490@@ -860,6 +882,7 @@ static int ecryptfs_setattr(struct dentr
9f87b1bd 491 inode = dentry->d_inode;
492 lower_inode = ecryptfs_inode_to_lower(inode);
493 lower_dentry = ecryptfs_dentry_to_lower(dentry);
494+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
495 mutex_lock(&crypt_stat->cs_mutex);
496 if (S_ISDIR(dentry->d_inode->i_mode))
497 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
2380c486 498@@ -911,7 +934,7 @@ static int ecryptfs_setattr(struct dentr
9f87b1bd 499 ia->ia_valid &= ~ATTR_MODE;
500
501 mutex_lock(&lower_dentry->d_inode->i_mutex);
502- rc = notify_change(lower_dentry, ia);
503+ rc = notify_change(lower_dentry, lower_mnt, ia);
504 mutex_unlock(&lower_dentry->d_inode->i_mutex);
505 out:
506 fsstack_copy_attr_all(inode, lower_inode, NULL);
2380c486
JR
507diff -uprN a/fs/exec.c b/fs/exec.c
508--- a/fs/exec.c 2009-02-08 13:22:56.401605319 +0000
509+++ b/fs/exec.c 2009-02-08 13:26:38.765741762 +0000
510@@ -1829,7 +1829,8 @@ int do_coredump(long signr, int exit_cod
9f87b1bd 511 goto close_fail;
512 if (!file->f_op->write)
513 goto close_fail;
514- if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0)
515+ if (!ispipe &&
516+ do_truncate(file->f_path.dentry, file->f_path.mnt, 0, 0, file) != 0)
517 goto close_fail;
518
519 retval = binfmt->core_dump(signr, regs, file, core_limit);
2380c486
JR
520diff -uprN a/fs/fat/file.c b/fs/fat/file.c
521--- a/fs/fat/file.c 2008-12-24 23:26:37.000000000 +0000
522+++ b/fs/fat/file.c 2009-02-08 13:26:38.769075001 +0000
523@@ -93,7 +93,7 @@ int fat_generic_ioctl(struct inode *inod
9f87b1bd 524 * out the RO attribute for checking by the security
525 * module, just because it maps to a file mode.
526 */
527- err = security_inode_setattr(filp->f_path.dentry, &ia);
528+ err = security_inode_setattr(filp->f_path.dentry, filp->f_path.mnt, &ia);
529 if (err)
530 goto up;
531
2380c486
JR
532diff -uprN a/fs/fuse/dir.c b/fs/fuse/dir.c
533--- a/fs/fuse/dir.c 2008-12-24 23:26:37.000000000 +0000
534+++ b/fs/fuse/dir.c 2009-02-08 13:26:38.882622899 +0000
9f87b1bd 535@@ -1105,21 +1105,22 @@ static int fuse_dir_fsync(struct file *f
536 return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
537 }
538
539-static bool update_mtime(unsigned ivalid)
540+static bool update_mtime(unsigned ivalid, bool have_file)
541 {
542 /* Always update if mtime is explicitly set */
543 if (ivalid & ATTR_MTIME_SET)
544 return true;
545
546 /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
547- if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
548+ if ((ivalid & ATTR_SIZE) && ((ivalid & ATTR_OPEN) || have_file))
549 return false;
550
551 /* In all other cases update */
552 return true;
553 }
554
555-static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
556+static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg,
557+ bool have_file)
558 {
559 unsigned ivalid = iattr->ia_valid;
560
561@@ -1138,7 +1139,7 @@ static void iattr_to_fattr(struct iattr
562 if (!(ivalid & ATTR_ATIME_SET))
563 arg->valid |= FATTR_ATIME_NOW;
564 }
565- if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) {
566+ if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, have_file)) {
567 arg->valid |= FATTR_MTIME;
568 arg->mtime = iattr->ia_mtime.tv_sec;
569 arg->mtimensec = iattr->ia_mtime.tv_nsec;
570@@ -1199,8 +1200,8 @@ void fuse_release_nowrite(struct inode *
571 * vmtruncate() doesn't allow for this case, so do the rlimit checking
572 * and the actual truncation by hand.
573 */
574-static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
575- struct file *file)
576+int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
577+ struct file *file)
578 {
579 struct inode *inode = entry->d_inode;
580 struct fuse_conn *fc = get_fuse_conn(inode);
581@@ -1244,7 +1245,7 @@ static int fuse_do_setattr(struct dentry
582
583 memset(&inarg, 0, sizeof(inarg));
584 memset(&outarg, 0, sizeof(outarg));
585- iattr_to_fattr(attr, &inarg);
586+ iattr_to_fattr(attr, &inarg, file != NULL);
587 if (file) {
588 struct fuse_file *ff = file->private_data;
589 inarg.valid |= FATTR_FH;
590@@ -1314,10 +1315,7 @@ error:
591
592 static int fuse_setattr(struct dentry *entry, struct iattr *attr)
593 {
594- if (attr->ia_valid & ATTR_FILE)
595- return fuse_do_setattr(entry, attr, attr->ia_file);
596- else
597- return fuse_do_setattr(entry, attr, NULL);
598+ return fuse_do_setattr(entry, attr, NULL);
599 }
600
601 static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
2380c486
JR
602diff -uprN a/fs/fuse/file.c b/fs/fuse/file.c
603--- a/fs/fuse/file.c 2009-02-08 13:22:56.404930729 +0000
604+++ b/fs/fuse/file.c 2009-02-08 13:26:38.882622899 +0000
605@@ -1470,6 +1470,11 @@ static loff_t fuse_file_llseek(struct fi
9f87b1bd 606 return retval;
607 }
608
609+static int fuse_fsetattr(struct file *file, struct iattr *attr)
610+{
611+ return fuse_do_setattr(file->f_path.dentry, attr, file);
612+}
613+
614 static const struct file_operations fuse_file_operations = {
615 .llseek = fuse_file_llseek,
616 .read = do_sync_read,
2380c486 617@@ -1483,6 +1488,7 @@ static const struct file_operations fuse
9f87b1bd 618 .fsync = fuse_fsync,
619 .lock = fuse_file_lock,
620 .flock = fuse_file_flock,
621+ .fsetattr = fuse_fsetattr,
622 .splice_read = generic_file_splice_read,
623 };
624
2380c486
JR
625@@ -1496,6 +1502,7 @@ static const struct file_operations fuse
626 .unlocked_ioctl = fuse_file_ioctl,
627 .compat_ioctl = fuse_file_compat_ioctl,
628 .poll = fuse_file_poll,
9f87b1bd 629+ .fsetattr = fuse_fsetattr,
630 /* no mmap and splice_read */
631 };
632
2380c486
JR
633diff -uprN a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
634--- a/fs/fuse/fuse_i.h 2008-12-24 23:26:37.000000000 +0000
635+++ b/fs/fuse/fuse_i.h 2009-02-08 13:26:38.882622899 +0000
636@@ -554,6 +554,10 @@ void fuse_truncate(struct address_space
9f87b1bd 637 */
638 int fuse_dev_init(void);
639
640+
641+int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
642+ struct file *file);
643+
644 /**
645 * Cleanup the client device
646 */
2380c486
JR
647diff -uprN a/fs/hpfs/namei.c b/fs/hpfs/namei.c
648--- a/fs/hpfs/namei.c 2008-12-24 23:26:37.000000000 +0000
649+++ b/fs/hpfs/namei.c 2009-02-08 13:26:38.765741762 +0000
9f87b1bd 650@@ -426,7 +426,7 @@ again:
651 /*printk("HPFS: truncating file before delete.\n");*/
652 newattrs.ia_size = 0;
653 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
654- err = notify_change(dentry, &newattrs);
655+ err = notify_change(dentry, NULL, &newattrs);
656 put_write_access(inode);
657 if (!err)
658 goto again;
2380c486
JR
659diff -uprN a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
660--- a/fs/notify/inotify/inotify_user.c 2009-02-08 13:22:56.408263679 +0000
661+++ b/fs/notify/inotify/inotify_user.c 2009-02-08 13:26:38.905951221 +0000
9f87b1bd 662@@ -372,7 +372,7 @@ static int find_inode(const char __user
663 if (error)
664 return error;
665 /* you can only watch an inode if you have read permissions on it */
666- error = inode_permission(path->dentry->d_inode, MAY_READ);
667+ error = path_permission(path, MAY_READ);
668 if (error)
669 path_put(path);
670 return error;
2380c486
JR
671diff -uprN a/fs/namei.c b/fs/namei.c
672--- a/fs/namei.c 2009-02-08 13:22:56.411597278 +0000
673+++ b/fs/namei.c 2009-02-08 13:26:38.909283473 +0000
674@@ -226,7 +226,7 @@ int generic_permission(struct inode *ino
9f87b1bd 675 return -EACCES;
676 }
677
678-int inode_permission(struct inode *inode, int mask)
679+static int __inode_permission(struct inode *inode, int mask)
680 {
681 int retval;
682
2380c486 683@@ -256,7 +256,12 @@ int inode_permission(struct inode *inode
9f87b1bd 684 if (retval)
685 return retval;
686
687- retval = devcgroup_inode_permission(inode, mask);
688+ return devcgroup_inode_permission(inode, mask);
689+}
690+
691+int inode_permission(struct inode *inode, int mask)
692+{
693+ int retval = __inode_permission(inode, mask);
694 if (retval)
695 return retval;
696
2380c486 697@@ -264,6 +269,15 @@ int inode_permission(struct inode *inode
9f87b1bd 698 mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND));
699 }
700
701+int path_permission(struct path *path, int mask)
702+{
703+ int retval = __inode_permission(path->dentry->d_inode, mask);
704+ if (retval)
705+ return retval;
706+ return security_path_permission(path,
707+ mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND));
708+}
709+
710 /**
711 * vfs_permission - check for access rights to a given path
712 * @nd: lookup result that describes the path
2380c486 713@@ -276,7 +290,7 @@ int inode_permission(struct inode *inode
9f87b1bd 714 */
715 int vfs_permission(struct nameidata *nd, int mask)
716 {
717- return inode_permission(nd->path.dentry->d_inode, mask);
718+ return path_permission(&nd->path, mask);
719 }
720
721 /**
2380c486 722@@ -293,7 +307,7 @@ int vfs_permission(struct nameidata *nd,
9f87b1bd 723 */
724 int file_permission(struct file *file, int mask)
725 {
726- return inode_permission(file->f_path.dentry->d_inode, mask);
727+ return path_permission(&file->f_path, mask);
728 }
729
730 /*
2380c486 731@@ -434,8 +448,9 @@ static struct dentry * cached_lookup(str
9f87b1bd 732 * short-cut DAC fails, then call permission() to do more
733 * complete permission check.
734 */
735-static int exec_permission_lite(struct inode *inode)
736+static int exec_permission_lite(struct path *path)
737 {
738+ struct inode *inode = path->dentry->d_inode;
739 umode_t mode = inode->i_mode;
740
741 if (inode->i_op && inode->i_op->permission)
2380c486 742@@ -460,7 +475,7 @@ static int exec_permission_lite(struct i
9f87b1bd 743
744 return -EACCES;
745 ok:
746- return security_inode_permission(inode, MAY_EXEC);
747+ return security_path_permission(path, MAY_EXEC);
748 }
749
750 /*
2380c486 751@@ -857,7 +872,7 @@ static int __link_path_walk(const char *
9f87b1bd 752 unsigned int c;
753
754 nd->flags |= LOOKUP_CONTINUE;
755- err = exec_permission_lite(inode);
756+ err = exec_permission_lite(&nd->path);
757 if (err == -EAGAIN)
758 err = vfs_permission(nd, MAY_EXEC);
759 if (err)
2380c486 760@@ -1052,24 +1067,21 @@ static int do_path_lookup(int dfd, const
9f87b1bd 761 path_get(&fs->pwd);
762 read_unlock(&fs->lock);
763 } else {
764- struct dentry *dentry;
765-
766 file = fget_light(dfd, &fput_needed);
767 retval = -EBADF;
768 if (!file)
769 goto out_fail;
770
771- dentry = file->f_path.dentry;
772+ nd->path = file->f_path;
773
774 retval = -ENOTDIR;
775- if (!S_ISDIR(dentry->d_inode->i_mode))
776+ if (!S_ISDIR(nd->path.dentry->d_inode->i_mode))
777 goto fput_fail;
778
779 retval = file_permission(file, MAY_EXEC);
780 if (retval)
781 goto fput_fail;
782
783- nd->path = file->f_path;
784 path_get(&file->f_path);
785
786 fput_light(file, fput_needed);
2380c486 787@@ -1216,7 +1228,7 @@ static struct dentry *lookup_hash(struct
9f87b1bd 788 {
789 int err;
790
791- err = inode_permission(nd->path.dentry->d_inode, MAY_EXEC);
792+ err = path_permission(&nd->path, MAY_EXEC);
793 if (err)
794 return ERR_PTR(err);
795 return __lookup_hash(&nd->last, nd->path.dentry, nd);
2380c486 796@@ -1481,7 +1493,7 @@ int vfs_create(struct inode *dir, struct
9f87b1bd 797 return -EACCES; /* shouldn't it be ENOSYS? */
798 mode &= S_IALLUGO;
799 mode |= S_IFREG;
800- error = security_inode_create(dir, dentry, mode);
801+ error = security_inode_create(dir, dentry, nd ? nd->path.mnt : NULL, mode);
802 if (error)
803 return error;
804 DQUOT_INIT(dir);
2380c486 805@@ -1557,7 +1569,7 @@ int may_open(struct nameidata *nd, int a
9f87b1bd 806 if (!error) {
807 DQUOT_INIT(inode);
808
809- error = do_truncate(dentry, 0,
810+ error = do_truncate(dentry, nd->path.mnt, 0,
811 ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
812 NULL);
813 }
2380c486 814@@ -1924,7 +1936,8 @@ fail:
9f87b1bd 815 }
816 EXPORT_SYMBOL_GPL(lookup_create);
817
818-int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
819+int vfs_mknod(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt,
820+ int mode, dev_t dev)
821 {
822 int error = may_create(dir, dentry);
823
2380c486 824@@ -1941,7 +1954,7 @@ int vfs_mknod(struct inode *dir, struct
9f87b1bd 825 if (error)
826 return error;
827
828- error = security_inode_mknod(dir, dentry, mode, dev);
829+ error = security_inode_mknod(dir, dentry, mnt, mode, dev);
830 if (error)
831 return error;
832
2380c486 833@@ -2002,11 +2015,12 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
9f87b1bd 834 error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
835 break;
836 case S_IFCHR: case S_IFBLK:
837- error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,
838- new_decode_dev(dev));
839+ error = vfs_mknod(nd.path.dentry->d_inode, dentry,
840+ nd.path.mnt, mode, new_decode_dev(dev));
841 break;
842 case S_IFIFO: case S_IFSOCK:
843- error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0);
844+ error = vfs_mknod(nd.path.dentry->d_inode, dentry,
845+ nd.path.mnt, mode, 0);
846 break;
847 }
848 mnt_drop_write(nd.path.mnt);
2380c486 849@@ -2025,7 +2039,8 @@ SYSCALL_DEFINE3(mknod, const char __user
9f87b1bd 850 return sys_mknodat(AT_FDCWD, filename, mode, dev);
851 }
852
853-int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
854+int vfs_mkdir(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt,
855+ int mode)
856 {
857 int error = may_create(dir, dentry);
858
2380c486 859@@ -2036,7 +2051,7 @@ int vfs_mkdir(struct inode *dir, struct
9f87b1bd 860 return -EPERM;
861
862 mode &= (S_IRWXUGO|S_ISVTX);
863- error = security_inode_mkdir(dir, dentry, mode);
864+ error = security_inode_mkdir(dir, dentry, mnt, mode);
865 if (error)
866 return error;
867
2380c486 868@@ -2068,7 +2083,7 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
9f87b1bd 869 error = mnt_want_write(nd.path.mnt);
870 if (error)
871 goto out_dput;
872- error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
873+ error = vfs_mkdir(nd.path.dentry->d_inode, dentry, nd.path.mnt, mode);
874 mnt_drop_write(nd.path.mnt);
2380c486
JR
875
876 if (!error)
877@@ -2112,7 +2127,7 @@ void dentry_unhash(struct dentry *dentry
9f87b1bd 878 spin_unlock(&dcache_lock);
879 }
880
881-int vfs_rmdir(struct inode *dir, struct dentry *dentry)
882+int vfs_rmdir(struct inode *dir, struct dentry *dentry,struct vfsmount *mnt)
883 {
884 int error = may_delete(dir, dentry, 1);
885
2380c486 886@@ -2122,6 +2137,10 @@ int vfs_rmdir(struct inode *dir, struct
9f87b1bd 887 if (!dir->i_op || !dir->i_op->rmdir)
888 return -EPERM;
889
890+ error = security_inode_rmdir(dir, dentry, mnt);
891+ if (error)
892+ return error;
893+
894 DQUOT_INIT(dir);
895
896 mutex_lock(&dentry->d_inode->i_mutex);
2380c486 897@@ -2129,12 +2148,9 @@ int vfs_rmdir(struct inode *dir, struct
9f87b1bd 898 if (d_mountpoint(dentry))
899 error = -EBUSY;
900 else {
901- error = security_inode_rmdir(dir, dentry);
902- if (!error) {
903- error = dir->i_op->rmdir(dir, dentry);
904- if (!error)
905- dentry->d_inode->i_flags |= S_DEAD;
906- }
907+ error = dir->i_op->rmdir(dir, dentry);
908+ if (!error)
909+ dentry->d_inode->i_flags |= S_DEAD;
910 }
911 mutex_unlock(&dentry->d_inode->i_mutex);
912 if (!error) {
2380c486 913@@ -2178,7 +2194,7 @@ static long do_rmdir(int dfd, const char
9f87b1bd 914 error = mnt_want_write(nd.path.mnt);
915 if (error)
916 goto exit3;
917- error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
918+ error = vfs_rmdir(nd.path.dentry->d_inode, dentry, nd.path.mnt);
919 mnt_drop_write(nd.path.mnt);
2380c486
JR
920 if (!error && (saved_dev || saved_ino))
921 gr_handle_delete(saved_ino, saved_dev);
922@@ -2195,7 +2211,7 @@ SYSCALL_DEFINE1(rmdir, const char __user
9f87b1bd 923 return do_rmdir(AT_FDCWD, pathname);
924 }
925
926-int vfs_unlink(struct inode *dir, struct dentry *dentry)
927+int vfs_unlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt)
928 {
929 int error = may_delete(dir, dentry, 0);
930
2380c486 931@@ -2211,7 +2227,7 @@ int vfs_unlink(struct inode *dir, struct
9f87b1bd 932 if (d_mountpoint(dentry))
933 error = -EBUSY;
934 else {
935- error = security_inode_unlink(dir, dentry);
936+ error = security_inode_unlink(dir, dentry, mnt);
937 if (!error)
938 error = dir->i_op->unlink(dir, dentry);
939 }
2380c486 940@@ -2263,7 +2279,7 @@ static long do_unlinkat(int dfd, const c
9f87b1bd 941 error = mnt_want_write(nd.path.mnt);
942 if (error)
943 goto exit2;
944- error = vfs_unlink(nd.path.dentry->d_inode, dentry);
945+ error = vfs_unlink(nd.path.dentry->d_inode, dentry, nd.path.mnt);
2380c486
JR
946 if (!error && (saved_ino || saved_dev))
947 gr_handle_delete(saved_ino, saved_dev);
9f87b1bd 948 mnt_drop_write(nd.path.mnt);
2380c486 949@@ -2298,7 +2314,8 @@ SYSCALL_DEFINE1(unlink, const char __use
9f87b1bd 950 return do_unlinkat(AT_FDCWD, pathname);
951 }
952
953-int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
954+int vfs_symlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt,
955+ const char *oldname)
956 {
957 int error = may_create(dir, dentry);
958
2380c486 959@@ -2308,7 +2325,7 @@ int vfs_symlink(struct inode *dir, struc
9f87b1bd 960 if (!dir->i_op || !dir->i_op->symlink)
961 return -EPERM;
962
963- error = security_inode_symlink(dir, dentry, oldname);
964+ error = security_inode_symlink(dir, dentry, mnt, oldname);
965 if (error)
966 return error;
967
2380c486 968@@ -2344,7 +2361,7 @@ SYSCALL_DEFINE3(symlinkat, const char __
9f87b1bd 969 error = mnt_want_write(nd.path.mnt);
970 if (error)
971 goto out_dput;
972- error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
973+ error = vfs_symlink(nd.path.dentry->d_inode, dentry, nd.path.mnt, from);
2380c486
JR
974 if (!error)
975 gr_handle_create(dentry, nd.path.mnt);
9f87b1bd 976 mnt_drop_write(nd.path.mnt);
2380c486 977@@ -2362,7 +2379,7 @@ SYSCALL_DEFINE2(symlink, const char __us
9f87b1bd 978 return sys_symlinkat(oldname, AT_FDCWD, newname);
979 }
980
981-int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
982+int vfs_link(struct dentry *old_dentry, struct vfsmount *old_mnt, struct inode *dir, struct dentry *new_dentry, struct vfsmount *new_mnt)
983 {
984 struct inode *inode = old_dentry->d_inode;
985 int error;
2380c486 986@@ -2387,7 +2404,8 @@ int vfs_link(struct dentry *old_dentry,
9f87b1bd 987 if (S_ISDIR(inode->i_mode))
988 return -EPERM;
989
990- error = security_inode_link(old_dentry, dir, new_dentry);
991+ error = security_inode_link(old_dentry, old_mnt, dir, new_dentry,
992+ new_mnt);
993 if (error)
994 return error;
995
2380c486 996@@ -2440,7 +2458,9 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
9f87b1bd 997 error = mnt_want_write(nd.path.mnt);
998 if (error)
999 goto out_dput;
1000- error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
1001+ error = vfs_link(old_path.dentry, old_path.mnt,
1002+ nd.path.dentry->d_inode,
1003+ new_dentry, nd.path.mnt);
2380c486
JR
1004 if (!error)
1005 gr_handle_create(new_dentry, nd.path.mnt);
9f87b1bd 1006 mnt_drop_write(nd.path.mnt);
2380c486 1007@@ -2493,7 +2513,8 @@ SYSCALL_DEFINE2(link, const char __user
9f87b1bd 1008 * locking].
1009 */
1010 static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
1011- struct inode *new_dir, struct dentry *new_dentry)
1012+ struct vfsmount *old_mnt, struct inode *new_dir,
1013+ struct dentry *new_dentry, struct vfsmount *new_mnt)
1014 {
1015 int error = 0;
1016 struct inode *target;
2380c486 1017@@ -2508,7 +2529,8 @@ static int vfs_rename_dir(struct inode *
9f87b1bd 1018 return error;
1019 }
1020
1021- error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
1022+ error = security_inode_rename(old_dir, old_dentry, old_mnt,
1023+ new_dir, new_dentry, new_mnt);
1024 if (error)
1025 return error;
1026
2380c486 1027@@ -2536,12 +2558,14 @@ static int vfs_rename_dir(struct inode *
9f87b1bd 1028 }
1029
1030 static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
1031- struct inode *new_dir, struct dentry *new_dentry)
1032+ struct vfsmount *old_mnt, struct inode *new_dir,
1033+ struct dentry *new_dentry, struct vfsmount *new_mnt)
1034 {
1035 struct inode *target;
1036 int error;
1037
1038- error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
1039+ error = security_inode_rename(old_dir, old_dentry, old_mnt,
1040+ new_dir, new_dentry, new_mnt);
1041 if (error)
1042 return error;
1043
2380c486 1044@@ -2564,7 +2588,8 @@ static int vfs_rename_other(struct inode
9f87b1bd 1045 }
1046
1047 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1048- struct inode *new_dir, struct dentry *new_dentry)
1049+ struct vfsmount *old_mnt, struct inode *new_dir,
1050+ struct dentry *new_dentry, struct vfsmount *new_mnt)
1051 {
1052 int error;
1053 int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
2380c486 1054@@ -2593,9 +2618,11 @@ int vfs_rename(struct inode *old_dir, st
9f87b1bd 1055 old_name = fsnotify_oldname_init(old_dentry->d_name.name);
1056
1057 if (is_dir)
1058- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
1059+ error = vfs_rename_dir(old_dir, old_dentry, old_mnt,
1060+ new_dir, new_dentry, new_mnt);
1061 else
1062- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
1063+ error = vfs_rename_other(old_dir, old_dentry, old_mnt,
1064+ new_dir, new_dentry, new_mnt);
2380c486 1065
9f87b1bd 1066 if (!error) {
1067 const char *new_name = old_dentry->d_name.name;
2380c486 1068@@ -2676,8 +2703,8 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
9f87b1bd 1069 error = mnt_want_write(oldnd.path.mnt);
1070 if (error)
1071 goto exit5;
1072- error = vfs_rename(old_dir->d_inode, old_dentry,
1073- new_dir->d_inode, new_dentry);
1074+ error = vfs_rename(old_dir->d_inode, old_dentry, oldnd.path.mnt,
1075+ new_dir->d_inode, new_dentry, newnd.path.mnt);
2380c486
JR
1076 if (!error)
1077 gr_handle_rename(old_dir->d_inode, new_dir->d_inode, old_dentry,
1078 new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
1079@@ -2851,6 +2878,7 @@ EXPORT_SYMBOL(path_lookup);
1080 EXPORT_SYMBOL(kern_path);
9f87b1bd 1081 EXPORT_SYMBOL(vfs_path_lookup);
1082 EXPORT_SYMBOL(inode_permission);
1083+EXPORT_SYMBOL(path_permission);
1084 EXPORT_SYMBOL(vfs_permission);
1085 EXPORT_SYMBOL(file_permission);
1086 EXPORT_SYMBOL(unlock_rename);
2380c486
JR
1087diff -uprN a/fs/namespace.c b/fs/namespace.c
1088--- a/fs/namespace.c 2009-02-08 13:22:56.411597278 +0000
1089+++ b/fs/namespace.c 2009-02-08 13:26:38.935950875 +0000
1090@@ -2348,3 +2348,33 @@ void __put_mnt_ns(struct mnt_namespace *
9f87b1bd 1091 release_mounts(&umount_list);
1092 kfree(ns);
1093 }
1094+
1095+char *d_namespace_path(struct dentry *dentry, struct vfsmount *vfsmnt,
1096+ char *buf, int buflen)
1097+{
1098+ struct path root, tmp, ns_root = { };
1099+ struct path path = { .mnt = vfsmnt, .dentry = dentry };
1100+ char *res;
1101+
1102+ read_lock(&current->fs->lock);
1103+ root = current->fs->root;
1104+ path_get(&current->fs->root);
1105+ read_unlock(&current->fs->lock);
1106+ spin_lock(&vfsmount_lock);
2380c486 1107+ if (root.mnt && root.mnt->mnt_ns)
9f87b1bd 1108+ ns_root.mnt = mntget(root.mnt->mnt_ns->root);
1109+ if (ns_root.mnt)
1110+ ns_root.dentry = dget(ns_root.mnt->mnt_root);
1111+ spin_unlock(&vfsmount_lock);
1112+ tmp = ns_root;
1113+ res = __d_path(&path, &tmp, buf, buflen,
1114+ D_PATH_FAIL_DELETED | D_PATH_DISCONNECT);
1115+ path_put(&root);
1116+ path_put(&ns_root);
1117+
1118+ /* Prevent empty path for lazily unmounted filesystems. */
1119+ if (!IS_ERR(res) && *res == '\0')
1120+ *--res = '.';
1121+ return res;
1122+}
1123+EXPORT_SYMBOL(d_namespace_path);
2380c486
JR
1124diff -uprN a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
1125--- a/fs/nfsd/nfs4recover.c 2008-12-24 23:26:37.000000000 +0000
1126+++ b/fs/nfsd/nfs4recover.c 2009-02-08 13:26:38.829075718 +0000
9f87b1bd 1127@@ -158,7 +158,8 @@ nfsd4_create_clid_dir(struct nfs4_client
2380c486 1128 status = mnt_want_write(rec_dir.mnt);
9f87b1bd 1129 if (status)
1130 goto out_put;
2380c486
JR
1131- status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
1132+ status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, rec_dir.mnt,
1133+ S_IRWXU);
1134 mnt_drop_write(rec_dir.mnt);
9f87b1bd 1135 out_put:
1136 dput(dentry);
1137@@ -263,7 +264,7 @@ nfsd4_remove_clid_file(struct dentry *di
1138 return -EINVAL;
1139 }
1140 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
1141- status = vfs_unlink(dir->d_inode, dentry);
2380c486 1142+ status = vfs_unlink(dir->d_inode, dentry, rec_dir.mnt);
9f87b1bd 1143 mutex_unlock(&dir->d_inode->i_mutex);
1144 return status;
1145 }
1146@@ -278,7 +279,7 @@ nfsd4_clear_clid_dir(struct dentry *dir,
1147 * a kernel from the future.... */
1148 nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
1149 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
1150- status = vfs_rmdir(dir->d_inode, dentry);
2380c486 1151+ status = vfs_rmdir(dir->d_inode, dentry, rec_dir.mnt);
9f87b1bd 1152 mutex_unlock(&dir->d_inode->i_mutex);
1153 return status;
1154 }
2380c486
JR
1155diff -uprN a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
1156--- a/fs/nfsd/nfs4xdr.c 2008-12-24 23:26:37.000000000 +0000
1157+++ b/fs/nfsd/nfs4xdr.c 2009-02-08 13:26:38.855950336 +0000
1158@@ -1458,7 +1458,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s
9f87b1bd 1159 }
1160 if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT
1161 | FATTR4_WORD0_SUPPORTED_ATTRS)) {
1162- err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
1163+ err = nfsd4_get_nfs4_acl(rqstp, dentry, exp->ex_path.mnt, &acl);
1164 aclsupport = (err == 0);
1165 if (bmval0 & FATTR4_WORD0_ACL) {
1166 if (err == -EOPNOTSUPP)
2380c486
JR
1167diff -uprN a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
1168--- a/fs/nfsd/vfs.c 2008-12-24 23:26:37.000000000 +0000
1169+++ b/fs/nfsd/vfs.c 2009-02-08 13:26:38.892617808 +0000
1170@@ -387,7 +387,7 @@ nfsd_setattr(struct svc_rqst *rqstp, str
9f87b1bd 1171 err = nfserr_notsync;
1172 if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
1173 fh_lock(fhp);
1174- host_err = notify_change(dentry, iap);
1175+ host_err = notify_change(dentry, fhp->fh_export->ex_path.mnt, iap);
1176 err = nfserrno(host_err);
1177 fh_unlock(fhp);
1178 }
2380c486 1179@@ -407,12 +407,13 @@ out_nfserr:
9f87b1bd 1180 #if defined(CONFIG_NFSD_V2_ACL) || \
1181 defined(CONFIG_NFSD_V3_ACL) || \
1182 defined(CONFIG_NFSD_V4)
1183-static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf)
1184+static ssize_t nfsd_getxattr(struct dentry *dentry, struct vfsmount *mnt,
1185+ char *key, void **buf)
1186 {
1187 ssize_t buflen;
2380c486 1188 ssize_t ret;
9f87b1bd 1189
1190- buflen = vfs_getxattr(dentry, key, NULL, 0);
1191+ buflen = vfs_getxattr(dentry, mnt, key, NULL, 0, NULL);
1192 if (buflen <= 0)
1193 return buflen;
1194
2380c486 1195@@ -420,7 +421,7 @@ static ssize_t nfsd_getxattr(struct dent
9f87b1bd 1196 if (!*buf)
1197 return -ENOMEM;
1198
2380c486
JR
1199- ret = vfs_getxattr(dentry, key, *buf, buflen);
1200+ ret = vfs_getxattr(dentry, mnt, key, *buf, buflen, NULL);
1201 if (ret < 0)
1202 kfree(*buf);
1203 return ret;
1204@@ -429,7 +430,8 @@ static ssize_t nfsd_getxattr(struct dent
9f87b1bd 1205
1206 #if defined(CONFIG_NFSD_V4)
1207 static int
1208-set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
1209+set_nfsv4_acl_one(struct dentry *dentry, struct vfsmount *mnt,
1210+ struct posix_acl *pacl, char *key)
1211 {
1212 int len;
1213 size_t buflen;
2380c486 1214@@ -448,7 +450,7 @@ set_nfsv4_acl_one(struct dentry *dentry,
9f87b1bd 1215 goto out;
1216 }
1217
1218- error = vfs_setxattr(dentry, key, buf, len, 0);
1219+ error = vfs_setxattr(dentry, mnt, key, buf, len, 0, NULL);
1220 out:
1221 kfree(buf);
1222 return error;
2380c486 1223@@ -461,6 +463,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
9f87b1bd 1224 __be32 error;
1225 int host_error;
1226 struct dentry *dentry;
1227+ struct vfsmount *mnt;
1228 struct inode *inode;
1229 struct posix_acl *pacl = NULL, *dpacl = NULL;
1230 unsigned int flags = 0;
2380c486 1231@@ -471,6 +474,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
9f87b1bd 1232 return error;
1233
1234 dentry = fhp->fh_dentry;
1235+ mnt = fhp->fh_export->ex_path.mnt;
1236 inode = dentry->d_inode;
1237 if (S_ISDIR(inode->i_mode))
1238 flags = NFS4_ACL_DIR;
2380c486 1239@@ -481,12 +485,14 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
9f87b1bd 1240 } else if (host_error < 0)
1241 goto out_nfserr;
1242
1243- host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
1244+ host_error = set_nfsv4_acl_one(dentry, mnt, pacl,
1245+ POSIX_ACL_XATTR_ACCESS);
1246 if (host_error < 0)
1247 goto out_release;
1248
1249 if (S_ISDIR(inode->i_mode))
1250- host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
1251+ host_error = set_nfsv4_acl_one(dentry, mnt, dpacl,
1252+ POSIX_ACL_XATTR_DEFAULT);
1253
1254 out_release:
1255 posix_acl_release(pacl);
2380c486 1256@@ -499,13 +505,13 @@ out_nfserr:
9f87b1bd 1257 }
1258
1259 static struct posix_acl *
1260-_get_posix_acl(struct dentry *dentry, char *key)
1261+_get_posix_acl(struct dentry *dentry, struct vfsmount *mnt, char *key)
1262 {
1263 void *buf = NULL;
1264 struct posix_acl *pacl = NULL;
1265 int buflen;
1266
1267- buflen = nfsd_getxattr(dentry, key, &buf);
1268+ buflen = nfsd_getxattr(dentry, mnt, key, &buf);
1269 if (!buflen)
1270 buflen = -ENODATA;
1271 if (buflen <= 0)
2380c486 1272@@ -517,14 +523,15 @@ _get_posix_acl(struct dentry *dentry, ch
9f87b1bd 1273 }
1274
1275 int
1276-nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_acl **acl)
1277+nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry,
1278+ struct vfsmount *mnt, struct nfs4_acl **acl)
1279 {
1280 struct inode *inode = dentry->d_inode;
1281 int error = 0;
1282 struct posix_acl *pacl = NULL, *dpacl = NULL;
1283 unsigned int flags = 0;
1284
1285- pacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_ACCESS);
1286+ pacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_ACCESS);
1287 if (IS_ERR(pacl) && PTR_ERR(pacl) == -ENODATA)
1288 pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
1289 if (IS_ERR(pacl)) {
2380c486 1290@@ -534,7 +541,7 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqst
9f87b1bd 1291 }
1292
1293 if (S_ISDIR(inode->i_mode)) {
1294- dpacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_DEFAULT);
1295+ dpacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_DEFAULT);
1296 if (IS_ERR(dpacl) && PTR_ERR(dpacl) == -ENODATA)
1297 dpacl = NULL;
1298 else if (IS_ERR(dpacl)) {
2380c486 1299@@ -947,13 +954,13 @@ out:
9f87b1bd 1300 return err;
1301 }
1302
1303-static void kill_suid(struct dentry *dentry)
1304+static void kill_suid(struct dentry *dentry, struct vfsmount *mnt)
1305 {
1306 struct iattr ia;
1307 ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
1308
1309 mutex_lock(&dentry->d_inode->i_mutex);
1310- notify_change(dentry, &ia);
1311+ notify_change(dentry, mnt, &ia);
1312 mutex_unlock(&dentry->d_inode->i_mutex);
1313 }
1314
2380c486 1315@@ -1012,7 +1019,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s
9f87b1bd 1316
1317 /* clear setuid/setgid flag after write */
1318 if (host_err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID)))
1319- kill_suid(dentry);
1320+ kill_suid(dentry, exp->ex_path.mnt);
1321
1322 if (host_err >= 0 && stable) {
1323 static ino_t last_ino;
2380c486 1324@@ -1190,6 +1197,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
9f87b1bd 1325 int type, dev_t rdev, struct svc_fh *resfhp)
1326 {
1327 struct dentry *dentry, *dchild = NULL;
1328+ struct svc_export *exp;
1329 struct inode *dirp;
1330 __be32 err;
1331 __be32 err2;
2380c486 1332@@ -1207,6 +1215,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
9f87b1bd 1333 goto out;
1334
1335 dentry = fhp->fh_dentry;
1336+ exp = fhp->fh_export;
1337 dirp = dentry->d_inode;
1338
1339 err = nfserr_notdir;
2380c486 1340@@ -1223,7 +1232,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
9f87b1bd 1341 host_err = PTR_ERR(dchild);
1342 if (IS_ERR(dchild))
1343 goto out_nfserr;
1344- err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
1345+ err = fh_compose(resfhp, exp, dchild, fhp);
1346 if (err)
1347 goto out;
1348 } else {
2380c486 1349@@ -1273,13 +1282,14 @@ nfsd_create(struct svc_rqst *rqstp, stru
9f87b1bd 1350 host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
1351 break;
1352 case S_IFDIR:
1353- host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
1354+ host_err = vfs_mkdir(dirp, dchild, exp->ex_path.mnt, iap->ia_mode);
1355 break;
1356 case S_IFCHR:
1357 case S_IFBLK:
1358 case S_IFIFO:
1359 case S_IFSOCK:
1360- host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
1361+ host_err = vfs_mknod(dirp, dchild, exp->ex_path.mnt,
1362+ iap->ia_mode, rdev);
1363 break;
1364 }
1365 if (host_err < 0) {
2380c486 1366@@ -1287,7 +1297,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
9f87b1bd 1367 goto out_nfserr;
1368 }
1369
1370- if (EX_ISSYNC(fhp->fh_export)) {
1371+ if (EX_ISSYNC(exp)) {
1372 err = nfserrno(nfsd_sync_dir(dentry));
1373 write_inode_now(dchild->d_inode, 1);
1374 }
2380c486 1375@@ -1517,6 +1527,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
9f87b1bd 1376 struct iattr *iap)
1377 {
1378 struct dentry *dentry, *dnew;
1379+ struct svc_export *exp;
1380 __be32 err, cerr;
1381 int host_err;
1382
2380c486 1383@@ -1541,6 +1552,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
9f87b1bd 1384 if (host_err)
1385 goto out_nfserr;
1386
1387+ exp = fhp->fh_export;
1388 if (unlikely(path[plen] != 0)) {
1389 char *path_alloced = kmalloc(plen+1, GFP_KERNEL);
1390 if (path_alloced == NULL)
2380c486 1391@@ -1548,14 +1560,16 @@ nfsd_symlink(struct svc_rqst *rqstp, str
9f87b1bd 1392 else {
1393 strncpy(path_alloced, path, plen);
1394 path_alloced[plen] = 0;
1395- host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced);
1396+ host_err = vfs_symlink(dentry->d_inode, dnew,
1397+ exp->ex_path.mnt, path_alloced);
1398 kfree(path_alloced);
1399 }
1400 } else
1401- host_err = vfs_symlink(dentry->d_inode, dnew, path);
1402+ host_err = vfs_symlink(dentry->d_inode, dnew, exp->ex_path.mnt,
1403+ path);
1404
1405 if (!host_err) {
1406- if (EX_ISSYNC(fhp->fh_export))
1407+ if (EX_ISSYNC(exp))
1408 host_err = nfsd_sync_dir(dentry);
1409 }
1410 err = nfserrno(host_err);
2380c486 1411@@ -1563,7 +1577,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
9f87b1bd 1412
1413 mnt_drop_write(fhp->fh_export->ex_path.mnt);
1414
1415- cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp);
1416+ cerr = fh_compose(resfhp, exp, dnew, fhp);
1417 dput(dnew);
1418 if (err==0) err = cerr;
1419 out:
2380c486 1420@@ -1618,7 +1632,8 @@ nfsd_link(struct svc_rqst *rqstp, struct
9f87b1bd 1421 err = nfserrno(host_err);
1422 goto out_dput;
1423 }
1424- host_err = vfs_link(dold, dirp, dnew);
1425+ host_err = vfs_link(dold, tfhp->fh_export->ex_path.mnt, dirp,
1426+ dnew, ffhp->fh_export->ex_path.mnt);
1427 if (!host_err) {
1428 if (EX_ISSYNC(ffhp->fh_export)) {
1429 err = nfserrno(nfsd_sync_dir(ddir));
2380c486 1430@@ -1719,7 +1734,8 @@ nfsd_rename(struct svc_rqst *rqstp, stru
9f87b1bd 1431 if (host_err)
1432 goto out_dput_new;
1433
1434- host_err = vfs_rename(fdir, odentry, tdir, ndentry);
1435+ host_err = vfs_rename(fdir, odentry, ffhp->fh_export->ex_path.mnt,
1436+ tdir, ndentry, tfhp->fh_export->ex_path.mnt);
1437 if (!host_err && EX_ISSYNC(tfhp->fh_export)) {
1438 host_err = nfsd_sync_dir(tdentry);
1439 if (!host_err)
2380c486 1440@@ -1757,6 +1773,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
9f87b1bd 1441 char *fname, int flen)
1442 {
1443 struct dentry *dentry, *rdentry;
1444+ struct svc_export *exp;
1445 struct inode *dirp;
1446 __be32 err;
1447 int host_err;
2380c486 1448@@ -1771,6 +1788,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
9f87b1bd 1449 fh_lock_nested(fhp, I_MUTEX_PARENT);
1450 dentry = fhp->fh_dentry;
1451 dirp = dentry->d_inode;
1452+ exp = fhp->fh_export;
1453
1454 rdentry = lookup_one_len(fname, dentry, flen);
1455 host_err = PTR_ERR(rdentry);
2380c486 1456@@ -1792,21 +1810,21 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
9f87b1bd 1457
1458 if (type != S_IFDIR) { /* It's UNLINK */
1459 #ifdef MSNFS
1460- if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
1461+ if ((exp->ex_flags & NFSEXP_MSNFS) &&
1462 (atomic_read(&rdentry->d_count) > 1)) {
1463 host_err = -EPERM;
1464 } else
1465 #endif
1466- host_err = vfs_unlink(dirp, rdentry);
1467+ host_err = vfs_unlink(dirp, rdentry, exp->ex_path.mnt);
1468 } else { /* It's RMDIR */
1469- host_err = vfs_rmdir(dirp, rdentry);
1470+ host_err = vfs_rmdir(dirp, rdentry, exp->ex_path.mnt);
1471 }
1472
1473 dput(rdentry);
1474
1475 if (host_err)
1476 goto out_drop;
1477- if (EX_ISSYNC(fhp->fh_export))
1478+ if (EX_ISSYNC(exp))
1479 host_err = nfsd_sync_dir(dentry);
1480
1481 out_drop:
2380c486 1482@@ -2143,7 +2161,8 @@ nfsd_get_posix_acl(struct svc_fh *fhp, i
9f87b1bd 1483 return ERR_PTR(-EOPNOTSUPP);
1484 }
1485
1486- size = nfsd_getxattr(fhp->fh_dentry, name, &value);
1487+ size = nfsd_getxattr(fhp->fh_dentry, fhp->fh_export->ex_path.mnt, name,
1488+ &value);
1489 if (size < 0)
1490 return ERR_PTR(size);
1491
2380c486 1492@@ -2155,6 +2174,7 @@ nfsd_get_posix_acl(struct svc_fh *fhp, i
9f87b1bd 1493 int
1494 nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
1495 {
1496+ struct vfsmount *mnt;
1497 struct inode *inode = fhp->fh_dentry->d_inode;
1498 char *name;
1499 void *value = NULL;
2380c486 1500@@ -2187,21 +2207,24 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i
9f87b1bd 1501 } else
1502 size = 0;
1503
1504- error = mnt_want_write(fhp->fh_export->ex_path.mnt);
1505+ mnt = fhp->fh_export->ex_path.mnt;
1506+ error = mnt_want_write(mnt);
1507 if (error)
1508 goto getout;
1509 if (size)
1510- error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0);
1511+ error = vfs_setxattr(fhp->fh_dentry, mnt, name, value, size, 0,
1512+ NULL);
1513 else {
1514 if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
1515 error = 0;
1516 else {
1517- error = vfs_removexattr(fhp->fh_dentry, name);
1518+ error = vfs_removexattr(fhp->fh_dentry, mnt, name,
1519+ NULL);
1520 if (error == -ENODATA)
1521 error = 0;
1522 }
1523 }
1524- mnt_drop_write(fhp->fh_export->ex_path.mnt);
1525+ mnt_drop_write(mnt);
1526
1527 getout:
1528 kfree(value);
2380c486
JR
1529diff -uprN a/fs/open.c b/fs/open.c
1530--- a/fs/open.c 2009-02-08 13:22:56.414930486 +0000
1531+++ b/fs/open.c 2009-02-08 13:26:38.905951221 +0000
1532@@ -195,8 +195,8 @@ out:
9f87b1bd 1533 return error;
1534 }
1535
1536-int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
1537- struct file *filp)
1538+int do_truncate(struct dentry *dentry, struct vfsmount *mnt, loff_t length,
1539+ unsigned int time_attrs, struct file *filp)
1540 {
1541 int err;
1542 struct iattr newattrs;
2380c486 1543@@ -207,16 +207,15 @@ int do_truncate(struct dentry *dentry, l
9f87b1bd 1544
1545 newattrs.ia_size = length;
1546 newattrs.ia_valid = ATTR_SIZE | time_attrs;
1547- if (filp) {
1548- newattrs.ia_file = filp;
1549+
1550+ if (filp)
1551 newattrs.ia_valid |= ATTR_FILE;
1552- }
1553
1554 /* Remove suid/sgid on truncate too */
1555 newattrs.ia_valid |= should_remove_suid(dentry);
1556
1557 mutex_lock(&dentry->d_inode->i_mutex);
1558- err = notify_change(dentry, &newattrs);
1559+ err = fnotify_change(dentry, mnt, &newattrs, filp);
1560 mutex_unlock(&dentry->d_inode->i_mutex);
1561 return err;
1562 }
2380c486 1563@@ -249,7 +248,7 @@ static long do_sys_truncate(const char _
9f87b1bd 1564 if (error)
1565 goto dput_and_out;
1566
1567- error = inode_permission(inode, MAY_WRITE);
1568+ error = path_permission(&path, MAY_WRITE);
1569 if (error)
1570 goto mnt_drop_write_and_out;
1571
2380c486 1572@@ -272,7 +271,7 @@ static long do_sys_truncate(const char _
9f87b1bd 1573 error = locks_verify_truncate(inode, NULL, length);
1574 if (!error) {
1575 DQUOT_INIT(inode);
1576- error = do_truncate(path.dentry, length, 0, NULL);
1577+ error = do_truncate(path.dentry, path.mnt, length, 0, NULL);
1578 }
1579
1580 put_write_and_out:
2380c486 1581@@ -327,7 +326,8 @@ static long do_sys_ftruncate(unsigned in
9f87b1bd 1582
1583 error = locks_verify_truncate(inode, file, length);
1584 if (!error)
1585- error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file);
1586+ error = do_truncate(dentry, file->f_path.mnt, length,
1587+ ATTR_MTIME|ATTR_CTIME, file);
1588 out_putf:
1589 fput(file);
1590 out:
2380c486 1591@@ -493,7 +493,7 @@ SYSCALL_DEFINE3(faccessat, int, dfd, con
9f87b1bd 1592 goto out_path_release;
1593 }
1594
1595- res = inode_permission(inode, mode | MAY_ACCESS);
1596+ res = path_permission(&path, mode | MAY_ACCESS);
1597 /* SuS v2 requires we report a read only fs too */
1598 if (res || !(mode & S_IWOTH) || special_file(inode->i_mode))
1599 goto out_path_release;
2380c486 1600@@ -536,7 +536,7 @@ SYSCALL_DEFINE1(chdir, const char __user
9f87b1bd 1601 if (error)
1602 goto out;
1603
1604- error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
1605+ error = path_permission(&path, MAY_EXEC | MAY_ACCESS);
1606 if (error)
1607 goto dput_and_out;
1608
2380c486 1609@@ -565,7 +565,7 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd
9f87b1bd 1610 if (!S_ISDIR(inode->i_mode))
1611 goto out_putf;
1612
1613- error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
1614+ error = path_permission(&file->f_path, MAY_EXEC | MAY_ACCESS);
2380c486
JR
1615
1616 if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
1617 error = -EPERM;
1618@@ -583,7 +583,7 @@ SYSCALL_DEFINE1(chroot, const char __use
9f87b1bd 1619 if (error)
1620 goto out;
1621
1622- error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
1623+ error = path_permission(&path, MAY_EXEC | MAY_ACCESS);
1624 if (error)
1625 goto dput_and_out;
1626
2380c486
JR
1627@@ -623,8 +623,8 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd
1628 }
1629
9f87b1bd 1630 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
1631- newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
1632- err = notify_change(dentry, &newattrs);
1633+ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME | ATTR_FILE;
1634+ err = fnotify_change(dentry, file->f_path.mnt, &newattrs, file);
1635 mutex_unlock(&inode->i_mutex);
2380c486
JR
1636
1637 out_drop_write:
1638@@ -653,7 +653,7 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
1639
9f87b1bd 1640 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
1641 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
1642- error = notify_change(path.dentry, &newattrs);
1643+ error = notify_change(path.dentry, path.mnt, &newattrs);
1644 mutex_unlock(&inode->i_mutex);
2380c486
JR
1645
1646 out_drop_write:
1647@@ -667,7 +667,8 @@ SYSCALL_DEFINE2(chmod, const char __user
9f87b1bd 1648 return sys_fchmodat(AT_FDCWD, filename, mode);
1649 }
1650
2380c486 1651-static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
9f87b1bd 1652+static int chown_common(struct dentry * dentry, struct vfsmount *mnt,
1653+ uid_t user, gid_t group, struct file *file)
1654 {
1655 struct inode *inode = dentry->d_inode;
1656 int error;
2380c486 1657@@ -685,8 +686,11 @@ static int chown_common(struct dentry *
9f87b1bd 1658 if (!S_ISDIR(inode->i_mode))
1659 newattrs.ia_valid |=
1660 ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
1661+ if (file)
1662+ newattrs.ia_valid |= ATTR_FILE;
1663+
1664 mutex_lock(&inode->i_mutex);
1665- error = notify_change(dentry, &newattrs);
1666+ error = fnotify_change(dentry, mnt, &newattrs, file);
1667 mutex_unlock(&inode->i_mutex);
1668
1669 return error;
2380c486
JR
1670@@ -703,7 +707,7 @@ SYSCALL_DEFINE3(chown, const char __user
1671 error = cow_check_and_break(&path);
1672 if (!error)
1673 #endif
1674- error = chown_common(path.dentry, user, group, path.mnt);
1675+ error = chown_common(path.dentry, path.mnt, user, group, NULL);
9f87b1bd 1676 mnt_drop_write(path.mnt);
1677 out_release:
1678 path_put(&path);
2380c486
JR
1679@@ -728,7 +732,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, cons
1680 error = cow_check_and_break(&path);
1681 if (!error)
1682 #endif
1683- error = chown_common(path.dentry, user, group, path.mnt);
1684+ error = chown_common(path.dentry, path.mnt, user, group, NULL);
9f87b1bd 1685 mnt_drop_write(path.mnt);
1686 out_release:
1687 path_put(&path);
2380c486
JR
1688@@ -747,7 +751,7 @@ SYSCALL_DEFINE3(lchown, const char __use
1689 error = cow_check_and_break(&path);
1690 if (!error)
1691 #endif
1692- error = chown_common(path.dentry, user, group, path.mnt);
1693+ error = chown_common(path.dentry, path.mnt, user, group, NULL);
9f87b1bd 1694 mnt_drop_write(path.mnt);
1695 out_release:
1696 path_put(&path);
2380c486 1697@@ -770,7 +774,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd
9f87b1bd 1698 goto out_fput;
1699 dentry = file->f_path.dentry;
1700 audit_inode(NULL, dentry);
2380c486 1701- error = chown_common(dentry, user, group, file->f_path.mnt);
9f87b1bd 1702+ error = chown_common(dentry, file->f_path.mnt, user, group, file);
1703 mnt_drop_write(file->f_path.mnt);
1704 out_fput:
1705 fput(file);
2380c486
JR
1706diff -uprN a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
1707--- a/fs/reiserfs/xattr.c 2008-12-24 23:26:37.000000000 +0000
1708+++ b/fs/reiserfs/xattr.c 2009-02-08 13:26:38.819075170 +0000
9f87b1bd 1709@@ -459,7 +459,7 @@ reiserfs_xattr_set(struct inode *inode,
1710 newattrs.ia_size = buffer_size;
1711 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
1712 mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR);
1713- err = notify_change(dentry, &newattrs);
1714+ err = notify_change(dentry, NULL, &newattrs);
1715 if (err)
1716 goto out_filp;
1717
1718@@ -746,7 +746,7 @@ int reiserfs_delete_xattrs(struct inode
1719 if (dir->d_inode->i_nlink <= 2) {
1720 root = get_xa_root(inode->i_sb, XATTR_REPLACE);
1721 reiserfs_write_lock_xattrs(inode->i_sb);
1722- err = vfs_rmdir(root->d_inode, dir);
1723+ err = vfs_rmdir(root->d_inode, dir, NULL);
1724 reiserfs_write_unlock_xattrs(inode->i_sb);
1725 dput(root);
1726 } else {
1727@@ -790,7 +790,7 @@ reiserfs_chown_xattrs_filler(void *buf,
1728 }
1729
1730 if (!S_ISDIR(xafile->d_inode->i_mode))
1731- err = notify_change(xafile, attrs);
1732+ err = notify_change(xafile, NULL, attrs);
1733 dput(xafile);
1734
1735 return err;
1736@@ -834,7 +834,7 @@ int reiserfs_chown_xattrs(struct inode *
1737 goto out_dir;
1738 }
1739
1740- err = notify_change(dir, attrs);
1741+ err = notify_change(dir, NULL, attrs);
1742 unlock_kernel();
1743
1744 out_dir:
2380c486
JR
1745diff -uprN a/fs/seq_file.c b/fs/seq_file.c
1746--- a/fs/seq_file.c 2008-12-24 23:26:37.000000000 +0000
1747+++ b/fs/seq_file.c 2009-02-08 13:26:38.879284319 +0000
9f87b1bd 1748@@ -412,9 +412,7 @@ int seq_path_root(struct seq_file *m, st
1749 char *s = m->buf + m->count;
1750 char *p;
1751
1752- spin_lock(&dcache_lock);
1753- p = __d_path(path, root, s, m->size - m->count);
1754- spin_unlock(&dcache_lock);
1755+ p = __d_path(path, root, s, m->size - m->count, 0);
1756 err = PTR_ERR(p);
1757 if (!IS_ERR(p)) {
1758 s = mangle_path(s, p, esc);
2380c486
JR
1759diff -uprN a/fs/stat.c b/fs/stat.c
1760--- a/fs/stat.c 2009-02-08 13:22:56.418263704 +0000
1761+++ b/fs/stat.c 2009-02-08 13:26:38.801576209 +0000
1762@@ -308,7 +308,7 @@ SYSCALL_DEFINE4(readlinkat, int, dfd, co
9f87b1bd 1763
1764 error = -EINVAL;
1765 if (inode->i_op && inode->i_op->readlink) {
1766- error = security_inode_readlink(path.dentry);
1767+ error = security_inode_readlink(path.dentry, path.mnt);
1768 if (!error) {
1769 touch_atime(path.mnt, path.dentry);
1770 error = inode->i_op->readlink(path.dentry,
2380c486
JR
1771diff -uprN a/fs/utimes.c b/fs/utimes.c
1772--- a/fs/utimes.c 2009-02-08 13:22:56.421602476 +0000
1773+++ b/fs/utimes.c 2009-02-08 13:26:38.885950086 +0000
9f87b1bd 1774@@ -48,7 +48,8 @@ static bool nsec_valid(long nsec)
1775 return nsec >= 0 && nsec <= 999999999;
1776 }
1777
1778-static int utimes_common(struct path *path, struct timespec *times)
1779+static int utimes_common(struct path *path, struct timespec *times,
1780+ struct file *f)
1781 {
1782 int error;
1783 struct iattr newattrs;
1784@@ -102,7 +103,7 @@ static int utimes_common(struct path *pa
9f87b1bd 1785 }
2380c486 1786
9f87b1bd 1787 mutex_lock(&inode->i_mutex);
1788- error = notify_change(path->dentry, &newattrs);
1789+ error = fnotify_change(path->dentry, path->mnt, &newattrs, f);
1790 mutex_unlock(&inode->i_mutex);
1791
1792 mnt_drop_write_and_out:
1793@@ -149,7 +150,7 @@ long do_utimes(int dfd, char __user *fil
1794 if (!file)
1795 goto out;
1796
1797- error = utimes_common(&file->f_path, times);
1798+ error = utimes_common(&file->f_path, times, file);
1799 fput(file);
1800 } else {
1801 struct path path;
1802@@ -162,7 +163,7 @@ long do_utimes(int dfd, char __user *fil
1803 if (error)
1804 goto out;
1805
1806- error = utimes_common(&path, times);
1807+ error = utimes_common(&path, times, NULL);
1808 path_put(&path);
1809 }
1810
2380c486
JR
1811diff -uprN a/fs/xattr.c b/fs/xattr.c
1812--- a/fs/xattr.c 2009-02-08 13:22:56.421602476 +0000
1813+++ b/fs/xattr.c 2009-02-08 13:26:38.892617808 +0000
9f87b1bd 1814@@ -67,8 +67,8 @@ xattr_permission(struct inode *inode, co
1815 }
1816
1817 int
1818-vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
1819- size_t size, int flags)
1820+vfs_setxattr(struct dentry *dentry, struct vfsmount *mnt, const char *name,
1821+ const void *value, size_t size, int flags, struct file *file)
1822 {
1823 struct inode *inode = dentry->d_inode;
1824 int error;
1825@@ -78,7 +78,7 @@ vfs_setxattr(struct dentry *dentry, cons
1826 return error;
1827
1828 mutex_lock(&inode->i_mutex);
1829- error = security_inode_setxattr(dentry, name, value, size, flags);
1830+ error = security_inode_setxattr(dentry, mnt, name, value, size, flags, file);
1831 if (error)
1832 goto out;
1833 error = -EOPNOTSUPP;
1834@@ -86,7 +86,7 @@ vfs_setxattr(struct dentry *dentry, cons
1835 error = inode->i_op->setxattr(dentry, name, value, size, flags);
1836 if (!error) {
1837 fsnotify_xattr(dentry);
1838- security_inode_post_setxattr(dentry, name, value,
1839+ security_inode_post_setxattr(dentry, mnt, name, value,
1840 size, flags);
1841 }
1842 } else if (!strncmp(name, XATTR_SECURITY_PREFIX,
1843@@ -131,7 +131,8 @@ out_noalloc:
1844 EXPORT_SYMBOL_GPL(xattr_getsecurity);
1845
1846 ssize_t
1847-vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
1848+vfs_getxattr(struct dentry *dentry, struct vfsmount *mnt, const char *name,
1849+ void *value, size_t size, struct file *file)
1850 {
1851 struct inode *inode = dentry->d_inode;
1852 int error;
1853@@ -140,7 +141,7 @@ vfs_getxattr(struct dentry *dentry, cons
1854 if (error)
1855 return error;
1856
1857- error = security_inode_getxattr(dentry, name);
1858+ error = security_inode_getxattr(dentry, mnt, name, file);
1859 if (error)
1860 return error;
1861
1862@@ -167,18 +168,20 @@ nolsm:
1863 EXPORT_SYMBOL_GPL(vfs_getxattr);
1864
1865 ssize_t
1866-vfs_listxattr(struct dentry *d, char *list, size_t size)
1867+vfs_listxattr(struct dentry *dentry, struct vfsmount *mnt, char *list,
1868+ size_t size, struct file *file)
1869 {
1870+ struct inode *inode = dentry->d_inode;
1871 ssize_t error;
1872
1873- error = security_inode_listxattr(d);
1874+ error = security_inode_listxattr(dentry, mnt, file);
1875 if (error)
1876 return error;
1877 error = -EOPNOTSUPP;
1878- if (d->d_inode->i_op && d->d_inode->i_op->listxattr) {
1879- error = d->d_inode->i_op->listxattr(d, list, size);
1880- } else {
1881- error = security_inode_listsecurity(d->d_inode, list, size);
1882+ if (inode->i_op && inode->i_op->listxattr)
1883+ error = inode->i_op->listxattr(dentry, list, size);
1884+ else {
1885+ error = security_inode_listsecurity(inode, list, size);
1886 if (size && error > size)
1887 error = -ERANGE;
1888 }
1889@@ -187,7 +190,8 @@ vfs_listxattr(struct dentry *d, char *li
1890 EXPORT_SYMBOL_GPL(vfs_listxattr);
1891
1892 int
1893-vfs_removexattr(struct dentry *dentry, const char *name)
1894+vfs_removexattr(struct dentry *dentry, struct vfsmount *mnt, const char *name,
1895+ struct file *file)
1896 {
1897 struct inode *inode = dentry->d_inode;
1898 int error;
1899@@ -199,7 +203,7 @@ vfs_removexattr(struct dentry *dentry, c
1900 if (error)
1901 return error;
1902
1903- error = security_inode_removexattr(dentry, name);
1904+ error = security_inode_removexattr(dentry, mnt, name, file);
1905 if (error)
1906 return error;
1907
1908@@ -218,8 +222,8 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
1909 * Extended attribute SET operations
1910 */
1911 static long
1912-setxattr(struct dentry *d, const char __user *name, const void __user *value,
1913- size_t size, int flags)
1914+setxattr(struct dentry *dentry, struct vfsmount *mnt, const char __user *name,
1915+ const void __user *value, size_t size, int flags, struct file *file)
1916 {
1917 int error;
1918 void *kvalue = NULL;
1919@@ -246,7 +250,7 @@ setxattr(struct dentry *d, const char __
1920 }
1921 }
1922
1923- error = vfs_setxattr(d, kname, kvalue, size, flags);
1924+ error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags, file);
1925 kfree(kvalue);
1926 return error;
1927 }
2380c486 1928@@ -263,7 +267,7 @@ SYSCALL_DEFINE5(setxattr, const char __u
9f87b1bd 1929 return error;
1930 error = mnt_want_write(path.mnt);
1931 if (!error) {
1932- error = setxattr(path.dentry, name, value, size, flags);
1933+ error = setxattr(path.dentry, path.mnt, name, value, size, flags, NULL);
1934 mnt_drop_write(path.mnt);
1935 }
1936 path_put(&path);
2380c486 1937@@ -282,7 +286,7 @@ SYSCALL_DEFINE5(lsetxattr, const char __
9f87b1bd 1938 return error;
1939 error = mnt_want_write(path.mnt);
1940 if (!error) {
1941- error = setxattr(path.dentry, name, value, size, flags);
1942+ error = setxattr(path.dentry, path.mnt, name, value, size, flags, NULL);
1943 mnt_drop_write(path.mnt);
1944 }
1945 path_put(&path);
2380c486 1946@@ -303,7 +307,8 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, cons
9f87b1bd 1947 audit_inode(NULL, dentry);
1948 error = mnt_want_write(f->f_path.mnt);
1949 if (!error) {
1950- error = setxattr(dentry, name, value, size, flags);
1951+ error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags,
1952+ f);
1953 mnt_drop_write(f->f_path.mnt);
1954 }
1955 fput(f);
2380c486 1956@@ -314,8 +319,8 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, cons
9f87b1bd 1957 * Extended attribute GET operations
1958 */
1959 static ssize_t
1960-getxattr(struct dentry *d, const char __user *name, void __user *value,
1961- size_t size)
1962+getxattr(struct dentry *dentry, struct vfsmount *mnt, const char __user *name,
1963+ void __user *value, size_t size, struct file *file)
1964 {
1965 ssize_t error;
1966 void *kvalue = NULL;
2380c486 1967@@ -335,7 +340,7 @@ getxattr(struct dentry *d, const char __
9f87b1bd 1968 return -ENOMEM;
1969 }
1970
1971- error = vfs_getxattr(d, kname, kvalue, size);
1972+ error = vfs_getxattr(dentry, mnt, kname, kvalue, size, file);
1973 if (error > 0) {
1974 if (size && copy_to_user(value, kvalue, error))
1975 error = -EFAULT;
2380c486 1976@@ -357,7 +362,7 @@ SYSCALL_DEFINE4(getxattr, const char __u
9f87b1bd 1977 error = user_path(pathname, &path);
1978 if (error)
1979 return error;
1980- error = getxattr(path.dentry, name, value, size);
1981+ error = getxattr(path.dentry, path.mnt, name, value, size, NULL);
1982 path_put(&path);
1983 return error;
1984 }
2380c486 1985@@ -371,7 +376,7 @@ SYSCALL_DEFINE4(lgetxattr, const char __
9f87b1bd 1986 error = user_lpath(pathname, &path);
1987 if (error)
1988 return error;
1989- error = getxattr(path.dentry, name, value, size);
1990+ error = getxattr(path.dentry, path.mnt, name, value, size, NULL);
1991 path_put(&path);
1992 return error;
1993 }
2380c486 1994@@ -386,7 +391,7 @@ SYSCALL_DEFINE4(fgetxattr, int, fd, cons
9f87b1bd 1995 if (!f)
1996 return error;
1997 audit_inode(NULL, f->f_path.dentry);
1998- error = getxattr(f->f_path.dentry, name, value, size);
1999+ error = getxattr(f->f_path.dentry, f->f_path.mnt, name, value, size, f);
2000 fput(f);
2001 return error;
2002 }
2380c486 2003@@ -395,7 +400,8 @@ SYSCALL_DEFINE4(fgetxattr, int, fd, cons
9f87b1bd 2004 * Extended attribute LIST operations
2005 */
2006 static ssize_t
2007-listxattr(struct dentry *d, char __user *list, size_t size)
2008+listxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *list,
2009+ size_t size, struct file *file)
2010 {
2011 ssize_t error;
2012 char *klist = NULL;
2380c486 2013@@ -408,7 +414,7 @@ listxattr(struct dentry *d, char __user
9f87b1bd 2014 return -ENOMEM;
2015 }
2016
2017- error = vfs_listxattr(d, klist, size);
2018+ error = vfs_listxattr(dentry, mnt, klist, size, file);
2019 if (error > 0) {
2020 if (size && copy_to_user(list, klist, error))
2021 error = -EFAULT;
2380c486 2022@@ -430,7 +436,7 @@ SYSCALL_DEFINE3(listxattr, const char __
9f87b1bd 2023 error = user_path(pathname, &path);
2024 if (error)
2025 return error;
2026- error = listxattr(path.dentry, list, size);
2027+ error = listxattr(path.dentry, path.mnt, list, size, NULL);
2028 path_put(&path);
2029 return error;
2030 }
2380c486 2031@@ -444,7 +450,7 @@ SYSCALL_DEFINE3(llistxattr, const char _
9f87b1bd 2032 error = user_lpath(pathname, &path);
2033 if (error)
2034 return error;
2035- error = listxattr(path.dentry, list, size);
2036+ error = listxattr(path.dentry, path.mnt, list, size, NULL);
2037 path_put(&path);
2038 return error;
2039 }
2380c486 2040@@ -458,7 +464,7 @@ SYSCALL_DEFINE3(flistxattr, int, fd, cha
9f87b1bd 2041 if (!f)
2042 return error;
2043 audit_inode(NULL, f->f_path.dentry);
2044- error = listxattr(f->f_path.dentry, list, size);
2045+ error = listxattr(f->f_path.dentry, f->f_path.mnt, list, size, f);
2046 fput(f);
2047 return error;
2048 }
2380c486 2049@@ -467,7 +473,8 @@ SYSCALL_DEFINE3(flistxattr, int, fd, cha
9f87b1bd 2050 * Extended attribute REMOVE operations
2051 */
2052 static long
2053-removexattr(struct dentry *d, const char __user *name)
2054+removexattr(struct dentry *dentry, struct vfsmount *mnt,
2055+ const char __user *name, struct file *file)
2056 {
2057 int error;
2058 char kname[XATTR_NAME_MAX + 1];
2380c486 2059@@ -478,7 +485,7 @@ removexattr(struct dentry *d, const char
9f87b1bd 2060 if (error < 0)
2061 return error;
2062
2063- return vfs_removexattr(d, kname);
2064+ return vfs_removexattr(dentry, mnt, kname, file);
2065 }
2066
2380c486
JR
2067 SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
2068@@ -492,7 +499,7 @@ SYSCALL_DEFINE2(removexattr, const char
9f87b1bd 2069 return error;
2070 error = mnt_want_write(path.mnt);
2071 if (!error) {
2072- error = removexattr(path.dentry, name);
2073+ error = removexattr(path.dentry, path.mnt, name, NULL);
2074 mnt_drop_write(path.mnt);
2075 }
2076 path_put(&path);
2380c486 2077@@ -510,7 +517,7 @@ SYSCALL_DEFINE2(lremovexattr, const char
9f87b1bd 2078 return error;
2079 error = mnt_want_write(path.mnt);
2080 if (!error) {
2081- error = removexattr(path.dentry, name);
2082+ error = removexattr(path.dentry, path.mnt, name, NULL);
2083 mnt_drop_write(path.mnt);
2084 }
2085 path_put(&path);
2380c486 2086@@ -530,7 +537,7 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, c
9f87b1bd 2087 audit_inode(NULL, dentry);
2088 error = mnt_want_write(f->f_path.mnt);
2089 if (!error) {
2090- error = removexattr(dentry, name);
2091+ error = removexattr(dentry, f->f_path.mnt, name, f);
2092 mnt_drop_write(f->f_path.mnt);
2093 }
2094 fput(f);
2380c486
JR
2095diff -uprN a/include/linux/audit.h b/include/linux/audit.h
2096--- a/include/linux/audit.h 2008-12-24 23:26:37.000000000 +0000
2097+++ b/include/linux/audit.h 2009-02-08 13:26:38.912617629 +0000
9f87b1bd 2098@@ -33,7 +33,7 @@
2099 * 1200 - 1299 messages internal to the audit daemon
2100 * 1300 - 1399 audit event messages
2101 * 1400 - 1499 SE Linux use
2102- * 1500 - 1599 kernel LSPP events
2103+ * 1500 - 1599 AppArmor use
2104 * 1600 - 1699 kernel crypto events
2105 * 1700 - 1799 kernel anomaly records
2106 * 1800 - 1999 future kernel use (maybe integrity labels and related events)
2107@@ -119,6 +119,13 @@
2108 #define AUDIT_MAC_UNLBL_STCADD 1416 /* NetLabel: add a static label */
2109 #define AUDIT_MAC_UNLBL_STCDEL 1417 /* NetLabel: del a static label */
2110
2111+#define AUDIT_APPARMOR_AUDIT 1501 /* AppArmor audited grants */
2112+#define AUDIT_APPARMOR_ALLOWED 1502 /* Allowed Access for learning */
2113+#define AUDIT_APPARMOR_DENIED 1503
2114+#define AUDIT_APPARMOR_HINT 1504 /* Process Tracking information */
2115+#define AUDIT_APPARMOR_STATUS 1505 /* Changes in config */
2116+#define AUDIT_APPARMOR_ERROR 1506 /* Internal AppArmor Errors */
2117+
2118 #define AUDIT_FIRST_KERN_ANOM_MSG 1700
2119 #define AUDIT_LAST_KERN_ANOM_MSG 1799
2120 #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
2380c486 2121@@ -547,6 +554,9 @@ extern void audit_log(struct audit_
9f87b1bd 2122 __attribute__((format(printf,4,5)));
2123
2124 extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
2125+extern void audit_log_vformat(struct audit_buffer *ab,
2126+ const char *fmt, va_list args)
2127+ __attribute__((format(printf,2,0)));
2128 extern void audit_log_format(struct audit_buffer *ab,
2129 const char *fmt, ...)
2130 __attribute__((format(printf,2,3)));
2380c486
JR
2131diff -uprN a/include/linux/dcache.h b/include/linux/dcache.h
2132--- a/include/linux/dcache.h 2008-12-24 23:26:37.000000000 +0000
2133+++ b/include/linux/dcache.h 2009-02-08 13:26:38.879284319 +0000
2134@@ -300,9 +300,12 @@ extern int d_validate(struct dentry *, s
9f87b1bd 2135 /*
2136 * helper function for dentry_operations.d_dname() members
2137 */
2138+#define D_PATH_FAIL_DELETED 1
2139+#define D_PATH_DISCONNECT 2
2140 extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
2141
2142-extern char *__d_path(const struct path *path, struct path *root, char *, int);
2143+extern char *__d_path(const struct path *path, struct path *root, char *, int,
2144+ int);
2145 extern char *d_path(const struct path *, char *, int);
2146 extern char *dentry_path(struct dentry *, char *, int);
2147
2380c486
JR
2148diff -uprN a/include/linux/fs.h b/include/linux/fs.h
2149--- a/include/linux/fs.h 2009-02-08 13:22:56.424935829 +0000
2150+++ b/include/linux/fs.h 2009-02-08 13:26:38.909283473 +0000
2151@@ -372,6 +372,10 @@ struct iattr {
9f87b1bd 2152 * Not an attribute, but an auxilary info for filesystems wanting to
2153 * implement an ftruncate() like method. NOTE: filesystem should
2154 * check for (ia_valid & ATTR_FILE), and not for (ia_file != NULL).
2155+ *
2156+ * NOTE: With patches.apparmor/fsetattr.diff applied, this is
2157+ * for compatibility with external file system modules only. There
2158+ * should not be any in-kernel users left.
2159 */
2160 struct file *ia_file;
2161 };
2380c486 2162@@ -1207,13 +1211,13 @@ extern void unlock_super(struct super_bl
9f87b1bd 2163 */
2164 extern int vfs_permission(struct nameidata *, int);
2165 extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
2166-extern int vfs_mkdir(struct inode *, struct dentry *, int);
2167-extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
2168-extern int vfs_symlink(struct inode *, struct dentry *, const char *);
2169-extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
2170-extern int vfs_rmdir(struct inode *, struct dentry *);
2171-extern int vfs_unlink(struct inode *, struct dentry *);
2172-extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
2173+extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int);
2174+extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t);
2175+extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *);
2176+extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *);
2177+extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *);
2178+extern int vfs_unlink(struct inode *, struct dentry *, struct vfsmount *);
2179+extern int vfs_rename(struct inode *, struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *);
2180
2181 /*
2182 * VFS dentry helper functions.
2380c486
JR
2183@@ -1240,6 +1244,11 @@ int fiemap_fill_next_extent(struct fiema
2184 int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
9f87b1bd 2185
2186 /*
2187+ * VFS path helper functions.
2188+ */
2189+extern int path_permission(struct path *, int);
2190+
2191+/*
2192 * File types
2193 *
2194 * NOTE! These match bits 12..15 of stat.st_mode
2380c486 2195@@ -1308,6 +1317,7 @@ struct file_operations {
9f87b1bd 2196 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
2197 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
2198 int (*setlease)(struct file *, long, struct file_lock **);
2199+ int (*fsetattr)(struct file *, struct iattr *);
2200 };
2201
2202 struct inode_operations {
2380c486 2203@@ -1671,8 +1681,8 @@ static inline int break_lease(struct ino
9f87b1bd 2204
2205 /* fs/open.c */
2206
2207-extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
2208- struct file *filp);
2209+extern int do_truncate(struct dentry *, struct vfsmount *, loff_t start,
2210+ unsigned int time_attrs, struct file *filp);
2211 extern long do_sys_open(int dfd, const char __user *filename, int flags,
2212 int mode);
2213 extern struct file *filp_open(const char *, int, int);
2380c486 2214@@ -1832,7 +1842,8 @@ extern int do_remount_sb(struct super_bl
9f87b1bd 2215 #ifdef CONFIG_BLOCK
2216 extern sector_t bmap(struct inode *, sector_t);
2217 #endif
2218-extern int notify_change(struct dentry *, struct iattr *);
2219+extern int notify_change(struct dentry *, struct vfsmount *, struct iattr *);
2220+extern int fnotify_change(struct dentry *, struct vfsmount *, struct iattr *, struct file *);
2221 extern int inode_permission(struct inode *, int);
2222 extern int generic_permission(struct inode *, int,
2223 int (*check_acl)(struct inode *, int));
2380c486
JR
2224diff -uprN a/include/linux/mount.h b/include/linux/mount.h
2225--- a/include/linux/mount.h 2008-12-24 23:26:37.000000000 +0000
2226+++ b/include/linux/mount.h 2009-02-08 13:26:38.879284319 +0000
2227@@ -112,4 +112,6 @@ extern void mark_mounts_for_expiry(struc
9f87b1bd 2228 extern spinlock_t vfsmount_lock;
2229 extern dev_t name_to_dev_t(char *name);
2230
2231+extern char *d_namespace_path(struct dentry *, struct vfsmount *, char *, int);
2232+
2233 #endif /* _LINUX_MOUNT_H */
2380c486
JR
2234diff -uprN a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
2235--- a/include/linux/nfsd/nfsd.h 2008-12-24 23:26:37.000000000 +0000
2236+++ b/include/linux/nfsd/nfsd.h 2009-02-08 13:26:38.855950336 +0000
2237@@ -86,7 +86,8 @@ __be32 nfsd_setattr(struct svc_rqst *,
9f87b1bd 2238 #ifdef CONFIG_NFSD_V4
2239 __be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *,
2240 struct nfs4_acl *);
2241-int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **);
2242+int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *,
2243+ struct vfsmount *mnt, struct nfs4_acl **);
2244 #endif /* CONFIG_NFSD_V4 */
2245 __be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
2246 char *name, int len, struct iattr *attrs,
2380c486
JR
2247diff -uprN a/include/linux/security.h b/include/linux/security.h
2248--- a/include/linux/security.h 2008-12-24 23:26:37.000000000 +0000
2249+++ b/include/linux/security.h 2009-02-08 13:26:38.902622774 +0000
9f87b1bd 2250@@ -54,9 +54,11 @@ extern void cap_capset_set(struct task_s
2251 extern int cap_bprm_set_security(struct linux_binprm *bprm);
2252 extern void cap_bprm_apply_creds(struct linux_binprm *bprm, int unsafe);
2253 extern int cap_bprm_secureexec(struct linux_binprm *bprm);
2254-extern int cap_inode_setxattr(struct dentry *dentry, const char *name,
2255- const void *value, size_t size, int flags);
2256-extern int cap_inode_removexattr(struct dentry *dentry, const char *name);
2257+extern int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
2258+ const char *name, const void *value, size_t size,
2259+ int flags, struct file *file);
2260+extern int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt,
2261+ const char *name, struct file *file);
2262 extern int cap_inode_need_killpriv(struct dentry *dentry);
2263 extern int cap_inode_killpriv(struct dentry *dentry);
2264 extern int cap_task_post_setuid(uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
2265@@ -337,23 +339,28 @@ static inline void security_free_mnt_opt
2266 * Check permission to create a regular file.
2267 * @dir contains inode structure of the parent of the new file.
2268 * @dentry contains the dentry structure for the file to be created.
2269+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
2270 * @mode contains the file mode of the file to be created.
2271 * Return 0 if permission is granted.
2272 * @inode_link:
2273 * Check permission before creating a new hard link to a file.
2274 * @old_dentry contains the dentry structure for an existing link to the file.
2275+ * @old_mnt is the vfsmount corresponding to @old_dentry (may be NULL).
2276 * @dir contains the inode structure of the parent directory of the new link.
2277 * @new_dentry contains the dentry structure for the new link.
2278+ * @new_mnt is the vfsmount corresponding to @new_dentry (may be NULL).
2279 * Return 0 if permission is granted.
2280 * @inode_unlink:
2281 * Check the permission to remove a hard link to a file.
2282 * @dir contains the inode structure of parent directory of the file.
2283 * @dentry contains the dentry structure for file to be unlinked.
2284+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
2285 * Return 0 if permission is granted.
2286 * @inode_symlink:
2287 * Check the permission to create a symbolic link to a file.
2288 * @dir contains the inode structure of parent directory of the symbolic link.
2289 * @dentry contains the dentry structure of the symbolic link.
2290+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
2291 * @old_name contains the pathname of file.
2292 * Return 0 if permission is granted.
2293 * @inode_mkdir:
2294@@ -361,12 +368,14 @@ static inline void security_free_mnt_opt
2295 * associated with inode strcture @dir.
2296 * @dir containst the inode structure of parent of the directory to be created.
2297 * @dentry contains the dentry structure of new directory.
2298+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
2299 * @mode contains the mode of new directory.
2300 * Return 0 if permission is granted.
2301 * @inode_rmdir:
2302 * Check the permission to remove a directory.
2303 * @dir contains the inode structure of parent of the directory to be removed.
2304 * @dentry contains the dentry structure of directory to be removed.
2305+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
2306 * Return 0 if permission is granted.
2307 * @inode_mknod:
2308 * Check permissions when creating a special file (or a socket or a fifo
2309@@ -375,6 +384,7 @@ static inline void security_free_mnt_opt
2310 * and not this hook.
2311 * @dir contains the inode structure of parent of the new file.
2312 * @dentry contains the dentry structure of the new file.
2313+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
2314 * @mode contains the mode of the new file.
2315 * @dev contains the device number.
2316 * Return 0 if permission is granted.
2317@@ -382,12 +392,15 @@ static inline void security_free_mnt_opt
2318 * Check for permission to rename a file or directory.
2319 * @old_dir contains the inode structure for parent of the old link.
2320 * @old_dentry contains the dentry structure of the old link.
2321+ * @old_mnt is the vfsmount corresponding to @old_dentry (may be NULL).
2322 * @new_dir contains the inode structure for parent of the new link.
2323 * @new_dentry contains the dentry structure of the new link.
2324+ * @new_mnt is the vfsmount corresponding to @new_dentry (may be NULL).
2325 * Return 0 if permission is granted.
2326 * @inode_readlink:
2327 * Check the permission to read the symbolic link.
2328 * @dentry contains the dentry structure for the file link.
2329+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
2330 * Return 0 if permission is granted.
2331 * @inode_follow_link:
2332 * Check permission to follow a symbolic link when looking up a pathname.
2333@@ -411,6 +424,7 @@ static inline void security_free_mnt_opt
2334 * file attributes change (such as when a file is truncated, chown/chmod
2335 * operations, transferring disk quotas, etc).
2336 * @dentry contains the dentry structure for the file.
2337+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
2338 * @attr is the iattr structure containing the new file attributes.
2339 * Return 0 if permission is granted.
2340 * @inode_getattr:
2341@@ -426,18 +440,18 @@ static inline void security_free_mnt_opt
2342 * inode.
2343 * @inode_setxattr:
2344 * Check permission before setting the extended attributes
2345- * @value identified by @name for @dentry.
2346+ * @value identified by @name for @dentry and @mnt.
2347 * Return 0 if permission is granted.
2348 * @inode_post_setxattr:
2349 * Update inode security field after successful setxattr operation.
2350- * @value identified by @name for @dentry.
2351+ * @value identified by @name for @dentry and @mnt.
2352 * @inode_getxattr:
2353 * Check permission before obtaining the extended attributes
2354- * identified by @name for @dentry.
2355+ * identified by @name for @dentry and @mnt.
2356 * Return 0 if permission is granted.
2357 * @inode_listxattr:
2358 * Check permission before obtaining the list of extended attribute
2359- * names for @dentry.
2360+ * names for @dentry and @mnt.
2361 * Return 0 if permission is granted.
2362 * @inode_removexattr:
2363 * Check permission before removing the extended attribute
2364@@ -578,6 +592,20 @@ static inline void security_free_mnt_opt
2365 * file_permission, and recheck access if anything has changed
2366 * since inode_permission.
2367 *
2368+ * Security hook for path
2369+ *
2370+ * @path_permission:
2371+ * Check permission before accessing a path. This hook is called by the
2372+ * existing Linux permission function, so a security module can use it to
2373+ * provide additional checking for existing Linux permission checks.
2374+ * Notice that this hook is called when a file is opened (as well as many
2375+ * other operations), whereas the file_security_ops permission hook is
2376+ * called when the actual read/write operations are performed. This
2377+ * hook is optional and if absent, inode_permission will be substituted.
2378+ * @path contains the path structure to check.
2379+ * @mask contains the permission mask.
2380+ * Return 0 if permission is granted.
2381+
2382 * Security hooks for task operations.
2383 *
2384 * @task_create:
2385@@ -1354,32 +1382,45 @@ struct security_operations {
2386 void (*inode_free_security) (struct inode *inode);
2387 int (*inode_init_security) (struct inode *inode, struct inode *dir,
2388 char **name, void **value, size_t *len);
2389- int (*inode_create) (struct inode *dir,
2390- struct dentry *dentry, int mode);
2391- int (*inode_link) (struct dentry *old_dentry,
2392- struct inode *dir, struct dentry *new_dentry);
2393- int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
2394- int (*inode_symlink) (struct inode *dir,
2395- struct dentry *dentry, const char *old_name);
2396- int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, int mode);
2397- int (*inode_rmdir) (struct inode *dir, struct dentry *dentry);
2398+ int (*inode_create) (struct inode *dir, struct dentry *dentry,
2399+ struct vfsmount *mnt, int mode);
2400+ int (*inode_link) (struct dentry *old_dentry, struct vfsmount *old_mnt,
2401+ struct inode *dir, struct dentry *new_dentry,
2402+ struct vfsmount *new_mnt);
2403+ int (*inode_unlink) (struct inode *dir, struct dentry *dentry,
2404+ struct vfsmount *mnt);
2405+ int (*inode_symlink) (struct inode *dir, struct dentry *dentry,
2406+ struct vfsmount *mnt, const char *old_name);
2407+ int (*inode_mkdir) (struct inode *dir, struct dentry *dentry,
2408+ struct vfsmount *mnt, int mode);
2409+ int (*inode_rmdir) (struct inode *dir, struct dentry *dentry,
2410+ struct vfsmount *mnt);
2411 int (*inode_mknod) (struct inode *dir, struct dentry *dentry,
2412- int mode, dev_t dev);
2413+ struct vfsmount *mnt, int mode, dev_t dev);
2414 int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
2415- struct inode *new_dir, struct dentry *new_dentry);
2416- int (*inode_readlink) (struct dentry *dentry);
2417+ struct vfsmount *old_mnt,
2418+ struct inode *new_dir, struct dentry *new_dentry,
2419+ struct vfsmount *new_mnt);
2420+ int (*inode_readlink) (struct dentry *dentry, struct vfsmount *mnt);
2421 int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
2422 int (*inode_permission) (struct inode *inode, int mask);
2423- int (*inode_setattr) (struct dentry *dentry, struct iattr *attr);
2424+ int (*inode_setattr) (struct dentry *dentry, struct vfsmount *,
2425+ struct iattr *attr);
2426 int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
2427 void (*inode_delete) (struct inode *inode);
2428- int (*inode_setxattr) (struct dentry *dentry, const char *name,
2429- const void *value, size_t size, int flags);
2430- void (*inode_post_setxattr) (struct dentry *dentry, const char *name,
2431- const void *value, size_t size, int flags);
2432- int (*inode_getxattr) (struct dentry *dentry, const char *name);
2433- int (*inode_listxattr) (struct dentry *dentry);
2434- int (*inode_removexattr) (struct dentry *dentry, const char *name);
2435+ int (*inode_setxattr) (struct dentry *dentry, struct vfsmount *mnt,
2436+ const char *name, const void *value, size_t size,
2437+ int flags, struct file *file);
2438+ void (*inode_post_setxattr) (struct dentry *dentry,
2439+ struct vfsmount *mnt,
2440+ const char *name, const void *value,
2441+ size_t size, int flags);
2442+ int (*inode_getxattr) (struct dentry *dentry, struct vfsmount *mnt,
2443+ const char *name, struct file *file);
2444+ int (*inode_listxattr) (struct dentry *dentry, struct vfsmount *mnt,
2445+ struct file *file);
2446+ int (*inode_removexattr) (struct dentry *dentry, struct vfsmount *mnt,
2447+ const char *name, struct file *file);
2448 int (*inode_need_killpriv) (struct dentry *dentry);
2449 int (*inode_killpriv) (struct dentry *dentry);
2450 int (*inode_getsecurity) (const struct inode *inode, const char *name, void **buffer, bool alloc);
2451@@ -1407,6 +1448,7 @@ struct security_operations {
2452 struct fown_struct *fown, int sig);
2453 int (*file_receive) (struct file *file);
2454 int (*dentry_open) (struct file *file);
2455+ int (*path_permission) (struct path *path, int mask);
2456
2457 int (*task_create) (unsigned long clone_flags);
2458 int (*task_alloc_security) (struct task_struct *p);
2380c486 2459@@ -1618,30 +1660,43 @@ int security_inode_alloc(struct inode *i
9f87b1bd 2460 void security_inode_free(struct inode *inode);
2461 int security_inode_init_security(struct inode *inode, struct inode *dir,
2462 char **name, void **value, size_t *len);
2463-int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);
2464-int security_inode_link(struct dentry *old_dentry, struct inode *dir,
2465- struct dentry *new_dentry);
2466-int security_inode_unlink(struct inode *dir, struct dentry *dentry);
2467+int security_inode_create(struct inode *dir, struct dentry *dentry,
2468+ struct vfsmount *mnt, int mode);
2469+int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt,
2470+ struct inode *dir, struct dentry *new_dentry,
2471+ struct vfsmount *new_mnt);
2472+int security_inode_unlink(struct inode *dir, struct dentry *dentry,
2473+ struct vfsmount *mnt);
2474 int security_inode_symlink(struct inode *dir, struct dentry *dentry,
2475- const char *old_name);
2476-int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode);
2477-int security_inode_rmdir(struct inode *dir, struct dentry *dentry);
2478-int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev);
2479+ struct vfsmount *mnt, const char *old_name);
2480+int security_inode_mkdir(struct inode *dir, struct dentry *dentry,
2481+ struct vfsmount *mnt, int mode);
2482+int security_inode_rmdir(struct inode *dir, struct dentry *dentry,
2483+ struct vfsmount *mnt);
2484+int security_inode_mknod(struct inode *dir, struct dentry *dentry,
2485+ struct vfsmount *mnt, int mode, dev_t dev);
2486 int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
2487- struct inode *new_dir, struct dentry *new_dentry);
2488-int security_inode_readlink(struct dentry *dentry);
2489+ struct vfsmount *old_mnt, struct inode *new_dir,
2490+ struct dentry *new_dentry, struct vfsmount *new_mnt);
2491+int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt);
2492 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
2493 int security_inode_permission(struct inode *inode, int mask);
2494-int security_inode_setattr(struct dentry *dentry, struct iattr *attr);
2495+int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
2496+ struct iattr *attr);
2497 int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry);
2498 void security_inode_delete(struct inode *inode);
2499-int security_inode_setxattr(struct dentry *dentry, const char *name,
2500- const void *value, size_t size, int flags);
2501-void security_inode_post_setxattr(struct dentry *dentry, const char *name,
2502- const void *value, size_t size, int flags);
2503-int security_inode_getxattr(struct dentry *dentry, const char *name);
2504-int security_inode_listxattr(struct dentry *dentry);
2505-int security_inode_removexattr(struct dentry *dentry, const char *name);
2506+int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
2507+ const char *name, const void *value,
2508+ size_t size, int flags, struct file *file);
2509+void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt,
2510+ const char *name, const void *value,
2511+ size_t size, int flags);
2512+int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
2513+ const char *name, struct file *file);
2514+int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt,
2515+ struct file *file);
2516+int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt,
2517+ const char *name, struct file *file);
2518 int security_inode_need_killpriv(struct dentry *dentry);
2519 int security_inode_killpriv(struct dentry *dentry);
2520 int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc);
2380c486 2521@@ -1664,6 +1719,7 @@ int security_file_send_sigiotask(struct
9f87b1bd 2522 struct fown_struct *fown, int sig);
2523 int security_file_receive(struct file *file);
2524 int security_dentry_open(struct file *file);
2525+int security_path_permission(struct path *path, int mask);
2526 int security_task_create(unsigned long clone_flags);
2527 int security_task_alloc(struct task_struct *p);
2528 void security_task_free(struct task_struct *p);
2380c486 2529@@ -1973,26 +2029,31 @@ static inline int security_inode_init_se
9f87b1bd 2530
2531 static inline int security_inode_create(struct inode *dir,
2532 struct dentry *dentry,
2533+ struct vfsmount *mnt,
2534 int mode)
2535 {
2536 return 0;
2537 }
2538
2539 static inline int security_inode_link(struct dentry *old_dentry,
2540- struct inode *dir,
2541- struct dentry *new_dentry)
2542+ struct vfsmount *old_mnt,
2543+ struct inode *dir,
2544+ struct dentry *new_dentry,
2545+ struct vfsmount *new_mnt)
2546 {
2547 return 0;
2548 }
2549
2550 static inline int security_inode_unlink(struct inode *dir,
2551- struct dentry *dentry)
2552+ struct dentry *dentry,
2553+ struct vfsmount *mnt)
2554 {
2555 return 0;
2556 }
2557
2558 static inline int security_inode_symlink(struct inode *dir,
2559 struct dentry *dentry,
2560+ struct vfsmount *mnt,
2561 const char *old_name)
2562 {
2563 return 0;
2380c486 2564@@ -2000,19 +2061,22 @@ static inline int security_inode_symlink
9f87b1bd 2565
2566 static inline int security_inode_mkdir(struct inode *dir,
2567 struct dentry *dentry,
2568+ struct vfsmount *mnt,
2569 int mode)
2570 {
2571 return 0;
2572 }
2573
2574 static inline int security_inode_rmdir(struct inode *dir,
2575- struct dentry *dentry)
2576+ struct dentry *dentry,
2577+ struct vfsmount *mnt)
2578 {
2579 return 0;
2580 }
2581
2582 static inline int security_inode_mknod(struct inode *dir,
2583 struct dentry *dentry,
2584+ struct vfsmount *mnt,
2585 int mode, dev_t dev)
2586 {
2587 return 0;
2380c486 2588@@ -2020,13 +2084,16 @@ static inline int security_inode_mknod(s
9f87b1bd 2589
2590 static inline int security_inode_rename(struct inode *old_dir,
2591 struct dentry *old_dentry,
2592+ struct vfsmount *old_mnt,
2593 struct inode *new_dir,
2594- struct dentry *new_dentry)
2595+ struct dentry *new_dentry,
2596+ struct vfsmount *new_mnt)
2597 {
2598 return 0;
2599 }
2600
2601-static inline int security_inode_readlink(struct dentry *dentry)
2602+static inline int security_inode_readlink(struct dentry *dentry,
2603+ struct vfsmount *mnt)
2604 {
2605 return 0;
2606 }
2380c486 2607@@ -2043,7 +2110,8 @@ static inline int security_inode_permiss
9f87b1bd 2608 }
2609
2610 static inline int security_inode_setattr(struct dentry *dentry,
2611- struct iattr *attr)
2612+ struct vfsmount *mnt,
2613+ struct iattr *attr)
2614 {
2615 return 0;
2616 }
2380c486 2617@@ -2058,30 +2126,42 @@ static inline void security_inode_delete
9f87b1bd 2618 { }
2619
2620 static inline int security_inode_setxattr(struct dentry *dentry,
2621- const char *name, const void *value, size_t size, int flags)
2622+ struct vfsmount *mnt,
2623+ const char *name, const void *value,
2624+ size_t size, int flags,
2625+ struct file *file)
2626 {
2627- return cap_inode_setxattr(dentry, name, value, size, flags);
2628+ return cap_inode_setxattr(dentry, mnt, name, value, size, flags, file);
2629 }
2630
2631 static inline void security_inode_post_setxattr(struct dentry *dentry,
2632- const char *name, const void *value, size_t size, int flags)
2633+ struct vfsmount *mnt,
2634+ const char *name,
2635+ const void *value,
2636+ size_t size, int flags)
2637 { }
2638
2639 static inline int security_inode_getxattr(struct dentry *dentry,
2640- const char *name)
2641+ struct vfsmount *mnt,
2642+ const char *name,
2643+ struct file *file)
2644 {
2645 return 0;
2646 }
2647
2648-static inline int security_inode_listxattr(struct dentry *dentry)
2649+static inline int security_inode_listxattr(struct dentry *dentry,
2650+ struct vfsmount *mnt,
2651+ struct file *file)
2652 {
2653 return 0;
2654 }
2655
2656 static inline int security_inode_removexattr(struct dentry *dentry,
2657- const char *name)
2658+ struct vfsmount *mnt,
2659+ const char *name,
2660+ struct file *file)
2661 {
2662- return cap_inode_removexattr(dentry, name);
2663+ return cap_inode_removexattr(dentry, mnt, name, file);
2664 }
2665
2666 static inline int security_inode_need_killpriv(struct dentry *dentry)
2380c486 2667@@ -2182,6 +2262,11 @@ static inline int security_dentry_open(s
9f87b1bd 2668 return 0;
2669 }
2670
2671+static inline int security_path_permission(struct path *path, int mask)
2672+{
2673+ return 0;
2674+}
2675+
2676 static inline int security_task_create(unsigned long clone_flags)
2677 {
2678 return 0;
2380c486
JR
2679diff -uprN a/include/linux/sysctl.h b/include/linux/sysctl.h
2680--- a/include/linux/sysctl.h 2008-12-24 23:26:37.000000000 +0000
2681+++ b/include/linux/sysctl.h 2009-02-08 13:26:38.899283105 +0000
9f87b1bd 2682@@ -996,6 +996,8 @@ extern int proc_doulongvec_minmax(struct
2683 extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int,
2684 struct file *, void __user *, size_t *, loff_t *);
2685
2686+extern char *sysctl_pathname(ctl_table *, char *, int);
2687+
2688 extern int do_sysctl (int __user *name, int nlen,
2689 void __user *oldval, size_t __user *oldlenp,
2690 void __user *newval, size_t newlen);
2380c486
JR
2691diff -uprN a/include/linux/xattr.h b/include/linux/xattr.h
2692--- a/include/linux/xattr.h 2008-12-24 23:26:37.000000000 +0000
2693+++ b/include/linux/xattr.h 2009-02-08 13:26:38.895950162 +0000
9f87b1bd 2694@@ -16,6 +16,8 @@
2695 #ifdef __KERNEL__
2696
2697 #include <linux/types.h>
2698+#include <linux/mount.h>
2699+#include <linux/fs.h>
2700
2701 /* Namespaces */
2702 #define XATTR_OS2_PREFIX "os2."
2703@@ -47,10 +49,10 @@ struct xattr_handler {
2704 };
2705
2706 ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
2707-ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
2708-ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
2709-int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int);
2710-int vfs_removexattr(struct dentry *, const char *);
2711+ssize_t vfs_getxattr(struct dentry *, struct vfsmount *, const char *, void *, size_t, struct file *file);
2712+ssize_t vfs_listxattr(struct dentry *d, struct vfsmount *, char *list, size_t size, struct file *file);
2713+int vfs_setxattr(struct dentry *, struct vfsmount *, const char *, const void *, size_t, int, struct file *file);
2714+int vfs_removexattr(struct dentry *, struct vfsmount *mnt, const char *, struct file *file);
2715
2716 ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size);
2717 ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
2380c486
JR
2718diff -uprN a/ipc/mqueue.c b/ipc/mqueue.c
2719--- a/ipc/mqueue.c 2009-02-08 13:22:56.428264020 +0000
2720+++ b/ipc/mqueue.c 2009-02-08 13:26:38.832414683 +0000
2721@@ -753,7 +753,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __
9f87b1bd 2722 err = mnt_want_write(mqueue_mnt);
2723 if (err)
2724 goto out_err;
2725- err = vfs_unlink(dentry->d_parent->d_inode, dentry);
2726+ err = vfs_unlink(dentry->d_parent->d_inode, dentry, mqueue_mnt);
2727 mnt_drop_write(mqueue_mnt);
2728 out_err:
2729 dput(dentry);
2380c486
JR
2730diff -uprN a/kernel/audit.c b/kernel/audit.c
2731--- a/kernel/audit.c 2008-12-24 23:26:37.000000000 +0000
2732+++ b/kernel/audit.c 2009-02-08 13:26:38.912617629 +0000
2733@@ -1243,8 +1243,7 @@ static inline int audit_expand(struct au
9f87b1bd 2734 * will be called a second time. Currently, we assume that a printk
2735 * can't format message larger than 1024 bytes, so we don't either.
2736 */
2737-static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
2738- va_list args)
2739+void audit_log_vformat(struct audit_buffer *ab, const char *fmt, va_list args)
2740 {
2741 int len, avail;
2742 struct sk_buff *skb;
2380c486 2743@@ -1518,3 +1517,6 @@ EXPORT_SYMBOL(audit_log_start);
9f87b1bd 2744 EXPORT_SYMBOL(audit_log_end);
2745 EXPORT_SYMBOL(audit_log_format);
2746 EXPORT_SYMBOL(audit_log);
2747+EXPORT_SYMBOL_GPL(audit_log_vformat);
2748+EXPORT_SYMBOL_GPL(audit_log_untrustedstring);
2749+EXPORT_SYMBOL_GPL(audit_log_d_path);
2380c486
JR
2750diff -uprN a/kernel/cgroup.c b/kernel/cgroup.c
2751--- a/kernel/cgroup.c 2009-02-08 13:22:56.431602672 +0000
2752+++ b/kernel/cgroup.c 2009-02-08 13:26:38.778246972 +0000
2753@@ -2968,7 +2968,7 @@ int cgroup_clone(struct task_struct *tsk
9f87b1bd 2754 }
2755
2756 /* Create the cgroup directory, which also creates the cgroup */
2757- ret = vfs_mkdir(inode, dentry, S_IFDIR | 0755);
2758+ ret = vfs_mkdir(inode, dentry, NULL, S_IFDIR | 0755);
2759 child = __d_cgrp(dentry);
2760 dput(dentry);
2761 if (ret) {
2380c486
JR
2762diff -uprN a/kernel/sysctl.c b/kernel/sysctl.c
2763--- a/kernel/sysctl.c 2009-02-08 13:22:56.454931677 +0000
2764+++ b/kernel/sysctl.c 2009-02-08 13:26:38.899283105 +0000
2765@@ -1528,6 +1528,33 @@ void register_sysctl_root(struct ctl_tab
9f87b1bd 2766 spin_unlock(&sysctl_lock);
2767 }
2768
2769+char *sysctl_pathname(struct ctl_table *table, char *buffer, int buflen)
2770+{
2771+ if (buflen < 1)
2772+ return NULL;
2773+ buffer += --buflen;
2774+ *buffer = '\0';
2775+
2776+ while (table) {
2777+ int namelen = strlen(table->procname);
2778+
2779+ if (buflen < namelen + 1)
2780+ return NULL;
2781+ buflen -= namelen + 1;
2782+ buffer -= namelen;
2783+ memcpy(buffer, table->procname, namelen);
2784+ *--buffer = '/';
2785+ table = table->parent;
2786+ }
2787+ if (buflen < 4)
2788+ return NULL;
2789+ buffer -= 4;
2790+ memcpy(buffer, "/sys", 4);
2791+
2792+ return buffer;
2793+}
2794+EXPORT_SYMBOL_GPL(sysctl_pathname);
2795+
2796 #ifdef CONFIG_SYSCTL_SYSCALL
2797 /* Perform the actual read/write of a sysctl table entry. */
2798 static int do_sysctl_strategy(struct ctl_table_root *root,
2380c486
JR
2799diff -uprN a/mm/filemap.c b/mm/filemap.c
2800--- a/mm/filemap.c 2009-02-08 13:22:56.478269615 +0000
2801+++ b/mm/filemap.c 2009-02-08 13:26:38.769075001 +0000
2802@@ -1781,12 +1781,12 @@ int should_remove_suid(struct dentry *de
9f87b1bd 2803 }
2804 EXPORT_SYMBOL(should_remove_suid);
2805
2806-static int __remove_suid(struct dentry *dentry, int kill)
2807+static int __remove_suid(struct path *path, int kill)
2808 {
2809 struct iattr newattrs;
2810
2811 newattrs.ia_valid = ATTR_FORCE | kill;
2812- return notify_change(dentry, &newattrs);
2813+ return notify_change(path->dentry, path->mnt, &newattrs);
2814 }
2815
2816 int file_remove_suid(struct file *file)
2380c486 2817@@ -1801,7 +1801,7 @@ int file_remove_suid(struct file *file)
9f87b1bd 2818 if (killpriv)
2819 error = security_inode_killpriv(dentry);
2820 if (!error && killsuid)
2821- error = __remove_suid(dentry, killsuid);
2822+ error = __remove_suid(&file->f_path, killsuid);
2823
2824 return error;
2825 }
2380c486
JR
2826diff -uprN a/net/unix/af_unix.c b/net/unix/af_unix.c
2827--- a/net/unix/af_unix.c 2008-12-24 23:26:37.000000000 +0000
2828+++ b/net/unix/af_unix.c 2009-02-08 13:26:38.789081510 +0000
2829@@ -829,7 +829,8 @@ static int unix_bind(struct socket *sock
9f87b1bd 2830 goto out_mknod_dput;
2380c486
JR
2831 }
2832
9f87b1bd 2833- err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
2834+ err = vfs_mknod(nd.path.dentry->d_inode, dentry, nd.path.mnt,
2835+ mode, 0);
2836 mnt_drop_write(nd.path.mnt);
2837 if (err)
2838 goto out_mknod_dput;
2380c486
JR
2839diff -uprN a/security/Kconfig b/security/Kconfig
2840--- a/security/Kconfig 2008-12-24 23:26:37.000000000 +0000
2841+++ b/security/Kconfig 2009-02-08 13:26:38.922616652 +0000
2842@@ -59,6 +59,15 @@ config SECURITYFS
2843
2844 If you are unsure how to answer this question, answer N.
2845
2846+config SECURITY_DEFAULT
2847+ string "Default security module"
2848+ depends on SECURITY
2849+ default ""
2850+ help
2851+ This determines the security module used if the security=
2852+ boot parmater is not provided. If a security module is not
2853+ specified the first module to register will be used.
2854+
2855 config SECURITY_NETWORK
2856 bool "Socket and Networking Security Hooks"
2857 depends on SECURITY
2858@@ -125,6 +134,7 @@ config SECURITY_DEFAULT_MMAP_MIN_ADDR
9f87b1bd 2859
2860 source security/selinux/Kconfig
2861 source security/smack/Kconfig
2862+source security/apparmor/Kconfig
2863
2864 endmenu
2865
2380c486
JR
2866diff -uprN a/security/Makefile b/security/Makefile
2867--- a/security/Makefile 2008-12-24 23:26:37.000000000 +0000
2868+++ b/security/Makefile 2009-02-08 13:26:38.949289615 +0000
2869@@ -5,6 +5,7 @@
2870 obj-$(CONFIG_KEYS) += keys/
2871 subdir-$(CONFIG_SECURITY_SELINUX) += selinux
2872 subdir-$(CONFIG_SECURITY_SMACK) += smack
2873+subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
2874
2875 # always enable default capabilities
2876 obj-y += commoncap.o
2877@@ -15,5 +16,6 @@ obj-$(CONFIG_SECURITYFS) += inode.o
9f87b1bd 2878 # Must precede capability.o in order to stack properly.
2879 obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
2880 obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
2380c486
JR
2881+obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o
2882 obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o
9f87b1bd 2883 obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
2380c486
JR
2884diff -uprN a/security/apparmor/Kconfig b/security/apparmor/Kconfig
2885--- a/security/apparmor/Kconfig 1970-01-01 00:00:00.000000000 +0000
2886+++ b/security/apparmor/Kconfig 2009-02-08 13:26:38.945950214 +0000
2887@@ -0,0 +1,44 @@
9f87b1bd 2888+config SECURITY_APPARMOR
2889+ bool "AppArmor support"
2890+ depends on SECURITY
2380c486 2891+ depends on SECURITY_NETWORK
9f87b1bd 2892+ select AUDIT
2380c486 2893+ default n
9f87b1bd 2894+ help
2895+ This enables the AppArmor security module.
2896+ Required userspace tools (if they are not included in your
2897+ distribution) and further information may be found at
2898+ <http://forge.novell.com/modules/xfmod/project/?apparmor>
2899+
2900+ If you are unsure how to answer this question, answer N.
2901+
2902+config SECURITY_APPARMOR_BOOTPARAM_VALUE
2903+ int "AppArmor boot parameter default value"
2904+ depends on SECURITY_APPARMOR
2905+ range 0 1
2906+ default 1
2907+ help
2908+ This option sets the default value for the kernel parameter
2909+ 'apparmor', which allows AppArmor to be enabled or disabled
2910+ at boot. If this option is set to 0 (zero), the AppArmor
2911+ kernel parameter will default to 0, disabling AppArmor at
2912+ bootup. If this option is set to 1 (one), the AppArmor
2913+ kernel parameter will default to 1, enabling AppArmor at
2914+ bootup.
2915+
2916+ If you are unsure how to answer this question, answer 1.
2917+
2918+config SECURITY_APPARMOR_DISABLE
2919+ bool "AppArmor runtime disable"
2920+ depends on SECURITY_APPARMOR
2921+ default n
2922+ help
2923+ This option enables writing to a apparmorfs node 'disable', which
2924+ allows AppArmor to be disabled at runtime prior to the policy load.
2925+ AppArmor will then remain disabled until the next boot.
2926+ This option is similar to the apparmor.enabled=0 boot parameter,
2927+ but is to support runtime disabling of AppArmor, e.g. from
2928+ /sbin/init, for portability across platforms where boot
2929+ parameters are difficult to employ.
2930+
2931+ If you are unsure how to answer this question, answer N.
2380c486
JR
2932diff -uprN a/security/apparmor/Makefile b/security/apparmor/Makefile
2933--- a/security/apparmor/Makefile 1970-01-01 00:00:00.000000000 +0000
2934+++ b/security/apparmor/Makefile 2009-02-08 13:26:38.925956402 +0000
9f87b1bd 2935@@ -0,0 +1,18 @@
2936+# Makefile for AppArmor Linux Security Module
2937+#
2938+obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
2939+
2940+apparmor-y := main.o list.o procattr.o lsm.o apparmorfs.o \
2941+ module_interface.o match.o
2942+
2943+quiet_cmd_make-caps = GEN $@
2944+cmd_make-caps = sed -n -e "/CAP_FS_MASK/d" -e "s/^\#define[ \\t]\\+CAP_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\$$/[\\2] = \"\\1\",/p" $< | tr A-Z a-z > $@
2945+
2946+quiet_cmd_make-af = GEN $@
2947+cmd_make-af = sed -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "s/^\#define[ \\t]\\+AF_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/[\\2] = \"\\1\",/p" $< | tr A-Z a-z > $@
2948+
2949+$(obj)/main.o : $(obj)/capability_names.h $(obj)/af_names.h
2950+$(obj)/capability_names.h : $(srctree)/include/linux/capability.h
2951+ $(call cmd,make-caps)
2952+$(obj)/af_names.h : $(srctree)/include/linux/socket.h
2953+ $(call cmd,make-af)
2380c486
JR
2954diff -uprN a/security/apparmor/apparmor.h b/security/apparmor/apparmor.h
2955--- a/security/apparmor/apparmor.h 1970-01-01 00:00:00.000000000 +0000
2956+++ b/security/apparmor/apparmor.h 2009-02-08 13:26:38.945950214 +0000
2957@@ -0,0 +1,405 @@
9f87b1bd 2958+/*
2959+ * Copyright (C) 1998-2007 Novell/SUSE
2960+ *
2961+ * This program is free software; you can redistribute it and/or
2962+ * modify it under the terms of the GNU General Public License as
2963+ * published by the Free Software Foundation, version 2 of the
2964+ * License.
2965+ *
2966+ * AppArmor internal prototypes
2967+ */
2968+
2969+#ifndef __APPARMOR_H
2970+#define __APPARMOR_H
2971+
2972+#include <linux/sched.h>
2973+#include <linux/fs.h>
2974+#include <linux/binfmts.h>
2975+#include <linux/rcupdate.h>
2976+#include <linux/resource.h>
2977+#include <linux/socket.h>
2978+#include <net/sock.h>
2979+
2980+/*
2981+ * We use MAY_READ, MAY_WRITE, MAY_EXEC, MAY_APPEND and the following flags
2982+ * for profile permissions
2983+ */
2984+#define AA_MAY_LINK 0x0010
2985+#define AA_MAY_LOCK 0x0020
2986+#define AA_EXEC_MMAP 0x0040
2987+#define AA_MAY_MOUNT 0x0080 /* no direct audit mapping */
2988+#define AA_EXEC_UNSAFE 0x0100
2989+#define AA_EXEC_INHERIT 0x0200
2990+#define AA_EXEC_MOD_0 0x0400
2991+#define AA_EXEC_MOD_1 0x0800
2992+#define AA_EXEC_MOD_2 0x1000
2993+#define AA_EXEC_MOD_3 0x2000
2994+
2995+#define AA_BASE_PERMS (MAY_READ | MAY_WRITE | MAY_EXEC | \
2996+ MAY_APPEND | AA_MAY_LINK | \
2997+ AA_MAY_LOCK | AA_EXEC_MMAP | \
2998+ AA_MAY_MOUNT | AA_EXEC_UNSAFE | \
2999+ AA_EXEC_INHERIT | AA_EXEC_MOD_0 | \
3000+ AA_EXEC_MOD_1 | AA_EXEC_MOD_2 | \
3001+ AA_EXEC_MOD_3)
3002+
3003+#define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \
3004+ AA_EXEC_MOD_2 | AA_EXEC_MOD_3)
3005+
3006+#define AA_EXEC_TYPE (AA_EXEC_UNSAFE | AA_EXEC_INHERIT | \
3007+ AA_EXEC_MODIFIERS)
3008+
3009+#define AA_EXEC_UNCONFINED AA_EXEC_MOD_0
3010+#define AA_EXEC_PROFILE AA_EXEC_MOD_1
3011+#define AA_EXEC_CHILD (AA_EXEC_MOD_0 | AA_EXEC_MOD_1)
3012+/* remaining exec modes are index into profile name table */
3013+#define AA_EXEC_INDEX(mode) ((mode & AA_EXEC_MODIFIERS) >> 10)
3014+
3015+#define AA_USER_SHIFT 0
3016+#define AA_OTHER_SHIFT 14
3017+
3018+#define AA_USER_PERMS (AA_BASE_PERMS << AA_USER_SHIFT)
3019+#define AA_OTHER_PERMS (AA_BASE_PERMS << AA_OTHER_SHIFT)
3020+
3021+#define AA_FILE_PERMS (AA_USER_PERMS | AA_OTHER_PERMS)
3022+
3023+#define AA_LINK_BITS ((AA_MAY_LINK << AA_USER_SHIFT) | \
3024+ (AA_MAY_LINK << AA_OTHER_SHIFT))
3025+
3026+#define AA_USER_EXEC (MAY_EXEC << AA_USER_SHIFT)
3027+#define AA_OTHER_EXEC (MAY_EXEC << AA_OTHER_SHIFT)
3028+
3029+#define AA_USER_EXEC_TYPE (AA_EXEC_TYPE << AA_USER_SHIFT)
3030+#define AA_OTHER_EXEC_TYPE (AA_EXEC_TYPE << AA_OTHER_SHIFT)
3031+
3032+#define AA_EXEC_BITS (AA_USER_EXEC | AA_OTHER_EXEC)
3033+
3034+#define ALL_AA_EXEC_UNSAFE ((AA_EXEC_UNSAFE << AA_USER_SHIFT) | \
3035+ (AA_EXEC_UNSAFE << AA_OTHER_SHIFT))
3036+
3037+#define ALL_AA_EXEC_TYPE (AA_USER_EXEC_TYPE | AA_OTHER_EXEC_TYPE)
3038+
3039+/* overloaded permissions for link pairs */
3040+#define AA_LINK_SUBSET_TEST 0x0020
3041+
3042+#define AA_USER_PTRACE 0x10000000
3043+#define AA_OTHER_PTRACE 0x20000000
3044+#define AA_PTRACE_PERMS (AA_USER_PTRACE | AA_OTHER_PTRACE)
3045+
3046+/* shared permissions that are not duplicated in user::other */
3047+#define AA_CHANGE_HAT 0x40000000
3048+#define AA_CHANGE_PROFILE 0x80000000
3049+
3050+#define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE)
3051+
3052+#define AA_VALID_PERM_MASK (AA_FILE_PERMS | AA_PTRACE_PERMS | \
3053+ AA_SHARED_PERMS)
3054+
3055+/* audit bits for the second accept field */
3056+#define AUDIT_FILE_MASK 0x1fc07f
3057+#define AUDIT_QUIET_MASK(mask) ((mask >> 7) & AUDIT_FILE_MASK)
3058+#define AA_VALID_PERM2_MASK 0x0fffffff
3059+
3060+#define AA_SECURE_EXEC_NEEDED 1
3061+
3062+/* Control parameters (0 or 1), settable thru module/boot flags or
3063+ * via /sys/kernel/security/apparmor/control */
3064+extern int apparmor_complain;
3065+extern int apparmor_debug;
3066+extern int apparmor_audit;
3067+extern int apparmor_logsyscall;
3068+extern unsigned int apparmor_path_max;
3069+
3070+#define PROFILE_COMPLAIN(_profile) \
3071+ (apparmor_complain == 1 || ((_profile) && (_profile)->flags.complain))
3072+
3073+#define APPARMOR_COMPLAIN(_cxt) \
3074+ (apparmor_complain == 1 || \
3075+ ((_cxt) && (_cxt)->profile && (_cxt)->profile->flags.complain))
3076+
3077+#define PROFILE_AUDIT(_profile) \
3078+ (apparmor_audit == 1 || ((_profile) && (_profile)->flags.audit))
3079+
3080+#define APPARMOR_AUDIT(_cxt) \
3081+ (apparmor_audit == 1 || \
3082+ ((_cxt) && (_cxt)->profile && (_cxt)->profile->flags.audit))
3083+
3084+#define PROFILE_IS_HAT(_profile) \
3085+ ((_profile) && (_profile)->flags.hat)
3086+
3087+/*
3088+ * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
3089+ * which is not related to profile accesses.
3090+ */
3091+
3092+#define AA_DEBUG(fmt, args...) \
3093+ do { \
3094+ if (apparmor_debug) \
3095+ printk(KERN_DEBUG "AppArmor: " fmt, ##args); \
3096+ } while (0)
3097+
2380c486 3098+#define AA_ERROR(fmt, args...) do { if (printk_ratelimit()) printk(KERN_ERR "AppArmor: " fmt, ##args); } while (0)
9f87b1bd 3099+
3100+/* struct aa_rlimit - rlimits settings for the profile
3101+ * @mask: which hard limits to set
3102+ * @limits: rlimit values that override task limits
3103+ *
3104+ * AppArmor rlimits are used to set confined task rlimits. Only the
3105+ * limits specified in @mask will be controlled by apparmor.
3106+ */
3107+struct aa_rlimit {
3108+ unsigned int mask;
3109+ struct rlimit limits[RLIM_NLIMITS];
3110+};
3111+
3112+struct aa_profile;
3113+
3114+/* struct aa_namespace - namespace for a set of profiles
3115+ * @name: the name of the namespace
3116+ * @list: list the namespace is on
3117+ * @profiles: list of profile in the namespace
3118+ * @profile_count: the number of profiles in the namespace
3119+ * @null_complain_profile: special profile used for learning in this namespace
3120+ * @count: reference count on the namespace
3121+ * @lock: lock for adding/removing profile to the namespace
3122+ */
3123+struct aa_namespace {
3124+ char *name;
3125+ struct list_head list;
3126+ struct list_head profiles;
3127+ int profile_count;
3128+ struct aa_profile *null_complain_profile;
3129+
3130+ struct kref count;
3131+ rwlock_t lock;
3132+};
3133+
3134+/* struct aa_profile - basic confinement data
3135+ * @name: the profiles name
3136+ * @list: list this profile is on
3137+ * @ns: namespace the profile is in
3138+ * @file_rules: dfa containing the profiles file rules
3139+ * @flags: flags controlling profile behavior
3140+ * @isstale: flag indicating if profile is stale
3141+ * @set_caps: capabilities that are being set
3142+ * @capabilities: capabilities mask
3143+ * @audit_caps: caps that are to be audited
3144+ * @quiet_caps: caps that should not be audited
3145+ * @capabilities: capabilities granted by the process
3146+ * @rlimits: rlimits for the profile
3147+ * @task_count: how many tasks the profile is attached to
3148+ * @count: reference count of the profile
3149+ * @task_contexts: list of tasks confined by profile
3150+ * @lock: lock for the task_contexts list
3151+ * @network_families: basic network permissions
3152+ * @audit_network: which network permissions to force audit
3153+ * @quiet_network: which network permissions to quiet rejects
3154+ *
3155+ * The AppArmor profile contains the basic confinement data. Each profile
3156+ * has a name, and all nonstale profile are in a profile namespace.
3157+ *
3158+ * The task_contexts list and the isstale flag are protected by the
3159+ * profile lock.
3160+ *
3161+ * If a task context is moved between two profiles, we first need to grab
3162+ * both profile locks. lock_both_profiles() does that in a deadlock-safe
3163+ * way.
3164+ */
3165+struct aa_profile {
3166+ char *name;
3167+ struct list_head list;
3168+ struct aa_namespace *ns;
3169+
3170+ int exec_table_size;
3171+ char **exec_table;
3172+ struct aa_dfa *file_rules;
3173+ struct {
2380c486
JR
3174+ u32 hat;
3175+ u32 complain;
3176+ u32 audit;
9f87b1bd 3177+ } flags;
3178+ int isstale;
3179+
3180+ kernel_cap_t set_caps;
3181+ kernel_cap_t capabilities;
3182+ kernel_cap_t audit_caps;
3183+ kernel_cap_t quiet_caps;
3184+
3185+ struct aa_rlimit rlimits;
3186+ unsigned int task_count;
3187+
3188+ struct kref count;
3189+ struct list_head task_contexts;
3190+ spinlock_t lock;
3191+ unsigned long int_flags;
3192+ u16 network_families[AF_MAX];
3193+ u16 audit_network[AF_MAX];
3194+ u16 quiet_network[AF_MAX];
3195+};
3196+
3197+extern struct list_head profile_ns_list;
3198+extern rwlock_t profile_ns_list_lock;
3199+extern struct mutex aa_interface_lock;
3200+
3201+/**
3202+ * struct aa_task_context - primary label for confined tasks
3203+ * @profile: the current profile
3204+ * @previous_profile: profile the task may return to
3205+ * @cookie: magic value the task must know for returning to @previous_profile
3206+ * @list: list this aa_task_context is on
3207+ * @task: task that the aa_task_context confines
3208+ * @rcu: rcu head used when freeing the aa_task_context
3209+ * @caps_logged: caps that have previously generated log entries
3210+ *
3211+ * Contains the task's current profile (which could change due to
3212+ * change_hat). Plus the hat_magic needed during change_hat.
3213+ */
3214+struct aa_task_context {
3215+ struct aa_profile *profile;
3216+ struct aa_profile *previous_profile;
3217+ u64 cookie;
3218+ struct list_head list;
3219+ struct task_struct *task;
3220+ struct rcu_head rcu;
3221+ kernel_cap_t caps_logged;
3222+};
3223+
3224+extern struct aa_namespace *default_namespace;
3225+
3226+/* aa_audit - AppArmor auditing structure
3227+ * Structure is populated by access control code and passed to aa_audit which
3228+ * provides for a single point of logging.
3229+ */
3230+
3231+struct aa_audit {
3232+ const char *operation;
3233+ gfp_t gfp_mask;
3234+ const char *info;
3235+ const char *name;
3236+ const char *name2;
3237+ const char *name3;
3238+ int request_mask, denied_mask, audit_mask;
3239+ int rlimit;
3240+ struct iattr *iattr;
3241+ pid_t task, parent;
3242+ int family, type, protocol;
3243+ int error_code;
3244+};
3245+
3246+/* Flags for the permission check functions */
3247+#define AA_CHECK_FD 1 /* coming from a file descriptor */
3248+#define AA_CHECK_DIR 2 /* file type is directory */
3249+
3250+/* lock subtypes so lockdep does not raise false dependencies */
3251+enum aa_lock_class {
3252+ aa_lock_normal,
3253+ aa_lock_nested,
3254+ aa_lock_task_release
3255+};
3256+
2380c486
JR
3257+/* apparmor/profiles */
3258+extern struct seq_operations apparmorfs_profiles_op;
3259+
9f87b1bd 3260+/* main.c */
3261+extern int alloc_default_namespace(void);
3262+extern void free_default_namespace(void);
3263+extern int aa_audit_message(struct aa_profile *profile, struct aa_audit *sa,
3264+ int type);
3265+void aa_audit_hint(struct aa_profile *profile, struct aa_audit *sa);
3266+void aa_audit_status(struct aa_profile *profile, struct aa_audit *sa);
3267+int aa_audit_reject(struct aa_profile *profile, struct aa_audit *sa);
3268+extern int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp,
3269+ const char *);
9f87b1bd 3270+
3271+extern int aa_attr(struct aa_profile *profile, struct dentry *dentry,
3272+ struct vfsmount *mnt, struct iattr *iattr);
3273+extern int aa_perm_xattr(struct aa_profile *profile, const char *operation,
3274+ struct dentry *dentry, struct vfsmount *mnt,
3275+ int mask, int check);
3276+extern int aa_capability(struct aa_task_context *cxt, int cap);
3277+extern int aa_perm(struct aa_profile *profile, const char *operation,
3278+ struct dentry *dentry, struct vfsmount *mnt, int mask,
3279+ int check);
3280+extern int aa_perm_dir(struct aa_profile *profile, const char *operation,
3281+ struct dentry *dentry, struct vfsmount *mnt,
3282+ int mask);
3283+extern int aa_perm_path(struct aa_profile *, const char *operation,
3284+ const char *name, int mask, uid_t uid);
3285+extern int aa_link(struct aa_profile *profile,
3286+ struct dentry *link, struct vfsmount *link_mnt,
3287+ struct dentry *target, struct vfsmount *target_mnt);
3288+extern int aa_clone(struct task_struct *task);
3289+extern int aa_register(struct linux_binprm *bprm);
3290+extern void aa_release(struct task_struct *task);
3291+extern int aa_change_hat(const char *id, u64 hat_magic);
3292+extern int aa_change_profile(const char *ns_name, const char *name);
3293+extern struct aa_profile *__aa_replace_profile(struct task_struct *task,
3294+ struct aa_profile *profile);
3295+extern struct aa_task_context *lock_task_and_profiles(struct task_struct *task,
2380c486 3296+ struct aa_profile *profile);
9f87b1bd 3297+extern void unlock_task_and_profiles(struct task_struct *task,
3298+ struct aa_task_context *cxt,
3299+ struct aa_profile *profile);
3300+extern void aa_change_task_context(struct task_struct *task,
3301+ struct aa_task_context *new_cxt,
3302+ struct aa_profile *profile, u64 cookie,
3303+ struct aa_profile *previous_profile);
3304+extern int aa_may_ptrace(struct aa_task_context *cxt,
3305+ struct aa_profile *tracee);
3306+extern int aa_net_perm(struct aa_profile *profile, char *operation,
3307+ int family, int type, int protocol);
3308+extern int aa_revalidate_sk(struct sock *sk, char *operation);
3309+extern int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource,
3310+ struct rlimit *new_rlim);
3311+extern void aa_set_rlimits(struct task_struct *task, struct aa_profile *profile);
3312+
3313+
3314+/* lsm.c */
3315+extern int apparmor_initialized;
3316+extern void info_message(const char *str);
3317+extern void apparmor_disable(void);
3318+
3319+/* list.c */
3320+extern struct aa_namespace *__aa_find_namespace(const char *name,
3321+ struct list_head *list);
3322+extern struct aa_profile *__aa_find_profile(const char *name,
3323+ struct list_head *list);
3324+extern void aa_profile_ns_list_release(void);
3325+
3326+/* module_interface.c */
3327+extern ssize_t aa_add_profile(void *, size_t);
3328+extern ssize_t aa_replace_profile(void *, size_t);
3329+extern ssize_t aa_remove_profile(char *, size_t);
3330+extern struct aa_namespace *alloc_aa_namespace(char *name);
3331+extern void free_aa_namespace(struct aa_namespace *ns);
3332+extern void free_aa_namespace_kref(struct kref *kref);
3333+extern struct aa_profile *alloc_aa_profile(void);
3334+extern void free_aa_profile(struct aa_profile *profile);
3335+extern void free_aa_profile_kref(struct kref *kref);
3336+extern void aa_unconfine_tasks(struct aa_profile *profile);
3337+
3338+/* procattr.c */
3339+extern int aa_getprocattr(struct aa_profile *profile, char **string,
3340+ unsigned *len);
3341+extern int aa_setprocattr_changehat(char *args);
3342+extern int aa_setprocattr_changeprofile(char *args);
3343+extern int aa_setprocattr_setprofile(struct task_struct *task, char *args);
3344+
3345+/* apparmorfs.c */
3346+extern int create_apparmorfs(void);
3347+extern void destroy_apparmorfs(void);
3348+
3349+/* match.c */
3350+extern struct aa_dfa *aa_match_alloc(void);
3351+extern void aa_match_free(struct aa_dfa *dfa);
3352+extern int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size);
3353+extern int verify_dfa(struct aa_dfa *dfa);
3354+extern unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str, int *);
3355+extern unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start,
3356+ const char *str);
3357+extern unsigned int aa_match_state(struct aa_dfa *dfa, unsigned int start,
3358+ const char *str, unsigned int *final);
3359+extern unsigned int aa_dfa_null_transition(struct aa_dfa *dfa,
3360+ unsigned int start);
3361+
3362+#endif /* __APPARMOR_H */
2380c486
JR
3363diff -uprN a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
3364--- a/security/apparmor/apparmorfs.c 1970-01-01 00:00:00.000000000 +0000
3365+++ b/security/apparmor/apparmorfs.c 2009-02-08 13:26:38.942622976 +0000
3366@@ -0,0 +1,277 @@
9f87b1bd 3367+/*
3368+ * Copyright (C) 1998-2007 Novell/SUSE
3369+ *
3370+ * This program is free software; you can redistribute it and/or
3371+ * modify it under the terms of the GNU General Public License as
3372+ * published by the Free Software Foundation, version 2 of the
3373+ * License.
3374+ *
3375+ * AppArmor filesystem (part of securityfs)
3376+ */
3377+
3378+#include <linux/security.h>
3379+#include <linux/vmalloc.h>
3380+#include <linux/module.h>
3381+#include <linux/seq_file.h>
2380c486 3382+#include <linux/uaccess.h>
9f87b1bd 3383+#include <linux/namei.h>
3384+
3385+#include "apparmor.h"
3386+#include "inline.h"
3387+
3388+static char *aa_simple_write_to_buffer(const char __user *userbuf,
3389+ size_t alloc_size, size_t copy_size,
3390+ loff_t *pos, const char *operation)
3391+{
3392+ struct aa_profile *profile;
3393+ char *data;
3394+
3395+ if (*pos != 0) {
3396+ /* only writes from pos 0, that is complete writes */
3397+ data = ERR_PTR(-ESPIPE);
3398+ goto out;
3399+ }
3400+
3401+ /*
3402+ * Don't allow confined processes to load/replace/remove profiles.
3403+ * No sane person would add rules allowing this to a profile
3404+ * but we enforce the restriction anyways.
3405+ */
3406+ profile = aa_get_profile(current);
3407+ if (profile) {
3408+ struct aa_audit sa;
3409+ memset(&sa, 0, sizeof(sa));
3410+ sa.operation = operation;
3411+ sa.gfp_mask = GFP_KERNEL;
3412+ sa.error_code = -EACCES;
3413+ data = ERR_PTR(aa_audit_reject(profile, &sa));
3414+ aa_put_profile(profile);
3415+ goto out;
3416+ }
3417+
3418+ data = vmalloc(alloc_size);
3419+ if (data == NULL) {
3420+ data = ERR_PTR(-ENOMEM);
3421+ goto out;
3422+ }
3423+
3424+ if (copy_from_user(data, userbuf, copy_size)) {
3425+ vfree(data);
3426+ data = ERR_PTR(-EFAULT);
3427+ goto out;
3428+ }
3429+
3430+out:
3431+ return data;
3432+}
3433+
9f87b1bd 3434+static int aa_profiles_open(struct inode *inode, struct file *file)
3435+{
3436+ return seq_open(file, &apparmorfs_profiles_op);
3437+}
3438+
3439+
3440+static int aa_profiles_release(struct inode *inode, struct file *file)
3441+{
3442+ return seq_release(inode, file);
3443+}
3444+
3445+static struct file_operations apparmorfs_profiles_fops = {
3446+ .open = aa_profiles_open,
3447+ .read = seq_read,
3448+ .llseek = seq_lseek,
3449+ .release = aa_profiles_release,
3450+};
3451+
3452+/* apparmor/matching */
3453+static ssize_t aa_matching_read(struct file *file, char __user *buf,
3454+ size_t size, loff_t *ppos)
3455+{
3456+ const char *matching = "pattern=aadfa audit perms=rwxamlk/ user::other";
3457+
3458+ return simple_read_from_buffer(buf, size, ppos, matching,
3459+ strlen(matching));
3460+}
3461+
3462+static struct file_operations apparmorfs_matching_fops = {
3463+ .read = aa_matching_read,
3464+};
3465+
3466+/* apparmor/features */
3467+static ssize_t aa_features_read(struct file *file, char __user *buf,
3468+ size_t size, loff_t *ppos)
3469+{
3470+ const char *features = "file=3.0 capability=2.0 network=1.0 "
3471+ "change_hat=1.5 change_profile=1.0 "
3472+ "aanamespaces=1.0 rlimit=1.0";
3473+
3474+ return simple_read_from_buffer(buf, size, ppos, features,
3475+ strlen(features));
3476+}
3477+
3478+static struct file_operations apparmorfs_features_fops = {
3479+ .read = aa_features_read,
3480+};
3481+
3482+/* apparmor/.load */
3483+static ssize_t aa_profile_load(struct file *f, const char __user *buf,
3484+ size_t size, loff_t *pos)
3485+{
3486+ char *data;
3487+ ssize_t error;
3488+
3489+ data = aa_simple_write_to_buffer(buf, size, size, pos, "profile_load");
3490+
3491+ error = PTR_ERR(data);
3492+ if (!IS_ERR(data)) {
3493+ error = aa_add_profile(data, size);
3494+ vfree(data);
3495+ }
3496+
3497+ return error;
3498+}
3499+
3500+
3501+static struct file_operations apparmorfs_profile_load = {
3502+ .write = aa_profile_load
3503+};
3504+
3505+/* apparmor/.replace */
3506+static ssize_t aa_profile_replace(struct file *f, const char __user *buf,
3507+ size_t size, loff_t *pos)
3508+{
3509+ char *data;
3510+ ssize_t error;
3511+
3512+ data = aa_simple_write_to_buffer(buf, size, size, pos,
3513+ "profile_replace");
3514+
3515+ error = PTR_ERR(data);
3516+ if (!IS_ERR(data)) {
3517+ error = aa_replace_profile(data, size);
3518+ vfree(data);
3519+ }
3520+
3521+ return error;
3522+}
3523+
3524+
3525+static struct file_operations apparmorfs_profile_replace = {
3526+ .write = aa_profile_replace
3527+};
3528+
3529+/* apparmor/.remove */
3530+static ssize_t aa_profile_remove(struct file *f, const char __user *buf,
3531+ size_t size, loff_t *pos)
3532+{
3533+ char *data;
3534+ ssize_t error;
3535+
3536+ /*
3537+ * aa_remove_profile needs a null terminated string so 1 extra
3538+ * byte is allocated and the copied data is null terminated.
3539+ */
3540+ data = aa_simple_write_to_buffer(buf, size + 1, size, pos,
3541+ "profile_remove");
3542+
3543+ error = PTR_ERR(data);
3544+ if (!IS_ERR(data)) {
3545+ data[size] = 0;
3546+ error = aa_remove_profile(data, size);
3547+ vfree(data);
3548+ }
3549+
3550+ return error;
3551+}
3552+
3553+static struct file_operations apparmorfs_profile_remove = {
3554+ .write = aa_profile_remove
3555+};
3556+
3557+static struct dentry *apparmor_dentry;
3558+
3559+static void aafs_remove(const char *name)
3560+{
3561+ struct dentry *dentry;
3562+
3563+ dentry = lookup_one_len(name, apparmor_dentry, strlen(name));
3564+ if (!IS_ERR(dentry)) {
3565+ securityfs_remove(dentry);
3566+ dput(dentry);
3567+ }
3568+}
3569+
3570+static int aafs_create(const char *name, int mask, struct file_operations *fops)
3571+{
3572+ struct dentry *dentry;
3573+
3574+ dentry = securityfs_create_file(name, S_IFREG | mask, apparmor_dentry,
3575+ NULL, fops);
3576+
3577+ return IS_ERR(dentry) ? PTR_ERR(dentry) : 0;
3578+}
3579+
3580+void destroy_apparmorfs(void)
3581+{
3582+ if (apparmor_dentry) {
3583+ aafs_remove(".remove");
3584+ aafs_remove(".replace");
3585+ aafs_remove(".load");
3586+ aafs_remove("matching");
3587+ aafs_remove("features");
3588+ aafs_remove("profiles");
3589+ securityfs_remove(apparmor_dentry);
3590+ apparmor_dentry = NULL;
3591+ }
3592+}
3593+
3594+int create_apparmorfs(void)
3595+{
3596+ int error;
3597+
3598+ if (!apparmor_initialized)
3599+ return 0;
3600+
3601+ if (apparmor_dentry) {
2380c486 3602+ AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
9f87b1bd 3603+ return -EEXIST;
3604+ }
3605+
3606+ apparmor_dentry = securityfs_create_dir("apparmor", NULL);
3607+ if (IS_ERR(apparmor_dentry)) {
3608+ error = PTR_ERR(apparmor_dentry);
3609+ apparmor_dentry = NULL;
2380c486 3610+ goto error;
9f87b1bd 3611+ }
3612+ error = aafs_create("profiles", 0440, &apparmorfs_profiles_fops);
3613+ if (error)
3614+ goto error;
3615+ error = aafs_create("matching", 0444, &apparmorfs_matching_fops);
3616+ if (error)
3617+ goto error;
3618+ error = aafs_create("features", 0444, &apparmorfs_features_fops);
3619+ if (error)
3620+ goto error;
3621+ error = aafs_create(".load", 0640, &apparmorfs_profile_load);
3622+ if (error)
3623+ goto error;
3624+ error = aafs_create(".replace", 0640, &apparmorfs_profile_replace);
3625+ if (error)
3626+ goto error;
3627+ error = aafs_create(".remove", 0640, &apparmorfs_profile_remove);
3628+ if (error)
3629+ goto error;
3630+
3631+ /* Report that AppArmor fs is enabled */
3632+ info_message("AppArmor Filesystem Enabled");
3633+ return 0;
3634+
3635+error:
3636+ destroy_apparmorfs();
3637+ AA_ERROR("Error creating AppArmor securityfs\n");
3638+ apparmor_disable();
3639+ return error;
3640+}
3641+
3642+fs_initcall(create_apparmorfs);
3643+
2380c486
JR
3644diff -uprN a/security/apparmor/inline.h b/security/apparmor/inline.h
3645--- a/security/apparmor/inline.h 1970-01-01 00:00:00.000000000 +0000
3646+++ b/security/apparmor/inline.h 2009-02-08 13:26:38.945950214 +0000
9f87b1bd 3647@@ -0,0 +1,250 @@
3648+/*
3649+ * Copyright (C) 1998-2007 Novell/SUSE
3650+ *
3651+ * This program is free software; you can redistribute it and/or
3652+ * modify it under the terms of the GNU General Public License as
3653+ * published by the Free Software Foundation, version 2 of the
3654+ * License.
3655+ */
3656+
3657+#ifndef __INLINE_H
3658+#define __INLINE_H
3659+
3660+#include <linux/sched.h>
3661+
3662+#include "match.h"
3663+
3664+static inline int mediated_filesystem(struct inode *inode)
3665+{
3666+ return !(inode->i_sb->s_flags & MS_NOUSER);
3667+}
3668+
3669+static inline struct aa_task_context *aa_task_context(struct task_struct *task)
3670+{
2380c486 3671+ return rcu_dereference(task->security);
9f87b1bd 3672+}
3673+
3674+static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns)
3675+{
3676+ if (ns)
3677+ kref_get(&(ns->count));
3678+
3679+ return ns;
3680+}
3681+
3682+static inline void aa_put_namespace(struct aa_namespace *ns)
3683+{
3684+ if (ns)
3685+ kref_put(&ns->count, free_aa_namespace_kref);
3686+}
3687+
3688+
3689+static inline struct aa_namespace *aa_find_namespace(const char *name)
3690+{
3691+ struct aa_namespace *ns = NULL;
3692+
3693+ read_lock(&profile_ns_list_lock);
3694+ ns = aa_get_namespace(__aa_find_namespace(name, &profile_ns_list));
3695+ read_unlock(&profile_ns_list_lock);
3696+
3697+ return ns;
3698+}
3699+
3700+/**
3701+ * aa_dup_profile - increment refcount on profile @p
3702+ * @p: profile
3703+ */
3704+static inline struct aa_profile *aa_dup_profile(struct aa_profile *p)
3705+{
3706+ if (p)
3707+ kref_get(&(p->count));
3708+
3709+ return p;
3710+}
3711+
3712+/**
3713+ * aa_put_profile - decrement refcount on profile @p
3714+ * @p: profile
3715+ */
3716+static inline void aa_put_profile(struct aa_profile *p)
3717+{
3718+ if (p)
3719+ kref_put(&p->count, free_aa_profile_kref);
3720+}
3721+
3722+static inline struct aa_profile *aa_get_profile(struct task_struct *task)
3723+{
3724+ struct aa_task_context *cxt;
3725+ struct aa_profile *profile = NULL;
3726+
3727+ rcu_read_lock();
3728+ cxt = aa_task_context(task);
3729+ if (cxt) {
3730+ profile = cxt->profile;
3731+ aa_dup_profile(profile);
3732+ }
3733+ rcu_read_unlock();
3734+
3735+ return profile;
3736+}
3737+
3738+static inline struct aa_profile *aa_find_profile(struct aa_namespace *ns,
3739+ const char *name)
3740+{
2380c486 3741+ struct aa_profile *profile;
9f87b1bd 3742+
3743+ read_lock(&ns->lock);
3744+ profile = aa_dup_profile(__aa_find_profile(name, &ns->profiles));
3745+ read_unlock(&ns->lock);
3746+
3747+ return profile;
3748+}
3749+
3750+static inline struct aa_task_context *aa_alloc_task_context(gfp_t flags)
3751+{
3752+ struct aa_task_context *cxt;
3753+
3754+ cxt = kzalloc(sizeof(*cxt), flags);
3755+ if (cxt) {
3756+ INIT_LIST_HEAD(&cxt->list);
3757+ INIT_RCU_HEAD(&cxt->rcu);
3758+ }
3759+
3760+ return cxt;
3761+}
3762+
3763+static inline void aa_free_task_context(struct aa_task_context *cxt)
3764+{
3765+ if (cxt) {
3766+ aa_put_profile(cxt->profile);
3767+ aa_put_profile(cxt->previous_profile);
3768+ kfree(cxt);
3769+ }
3770+}
3771+
3772+/**
3773+ * lock_profile - lock a profile
3774+ * @profile: the profile to lock
3775+ *
3776+ * While the profile is locked, local interrupts are disabled. This also
3777+ * gives us RCU reader safety.
3778+ */
3779+static inline void lock_profile_nested(struct aa_profile *profile,
3780+ enum aa_lock_class lock_class)
3781+{
3782+ /*
3783+ * Lock the profile.
3784+ *
3785+ * Need to disable interrupts here because this lock is used in
3786+ * the task_free_security hook, which may run in RCU context.
3787+ */
3788+ if (profile)
3789+ spin_lock_irqsave_nested(&profile->lock, profile->int_flags,
3790+ lock_class);
3791+}
3792+
3793+static inline void lock_profile(struct aa_profile *profile)
3794+{
3795+ lock_profile_nested(profile, aa_lock_normal);
3796+}
3797+
3798+/**
3799+ * unlock_profile - unlock a profile
3800+ * @profile: the profile to unlock
3801+ */
3802+static inline void unlock_profile(struct aa_profile *profile)
3803+{
3804+ /* Unlock the profile. */
3805+ if (profile)
3806+ spin_unlock_irqrestore(&profile->lock, profile->int_flags);
3807+}
3808+
3809+/**
3810+ * lock_both_profiles - lock two profiles in a deadlock-free way
3811+ * @profile1: profile to lock (may be NULL)
3812+ * @profile2: profile to lock (may be NULL)
3813+ *
3814+ * The order in which profiles are passed into lock_both_profiles() /
3815+ * unlock_both_profiles() does not matter.
3816+ * While the profile is locked, local interrupts are disabled. This also
3817+ * gives us RCU reader safety.
3818+ */
3819+static inline void lock_both_profiles(struct aa_profile *profile1,
3820+ struct aa_profile *profile2)
3821+{
3822+ /*
3823+ * Lock the two profiles.
3824+ *
3825+ * We need to disable interrupts because the profile locks are
3826+ * used in the task_free_security hook, which may run in RCU
3827+ * context.
3828+ *
3829+ * Do not nest spin_lock_irqsave()/spin_unlock_irqresore():
3830+ * interrupts only need to be turned off once.
3831+ */
3832+ if (!profile1 || profile1 == profile2) {
3833+ if (profile2)
3834+ spin_lock_irqsave_nested(&profile2->lock,
3835+ profile2->int_flags,
3836+ aa_lock_normal);
3837+ } else if (profile1 > profile2) {
3838+ /* profile1 cannot be NULL here. */
3839+ spin_lock_irqsave_nested(&profile1->lock, profile1->int_flags,
3840+ aa_lock_normal);
3841+ if (profile2)
3842+ spin_lock_nested(&profile2->lock, aa_lock_nested);
3843+
3844+ } else {
3845+ /* profile2 cannot be NULL here. */
3846+ spin_lock_irqsave_nested(&profile2->lock, profile2->int_flags,
3847+ aa_lock_normal);
3848+ spin_lock_nested(&profile1->lock, aa_lock_nested);
3849+ }
3850+}
3851+
3852+/**
3853+ * unlock_both_profiles - unlock two profiles in a deadlock-free way
3854+ * @profile1: profile to unlock (may be NULL)
3855+ * @profile2: profile to unlock (may be NULL)
3856+ *
3857+ * The order in which profiles are passed into lock_both_profiles() /
3858+ * unlock_both_profiles() does not matter.
3859+ * While the profile is locked, local interrupts are disabled. This also
3860+ * gives us RCU reader safety.
3861+ */
3862+static inline void unlock_both_profiles(struct aa_profile *profile1,
2380c486 3863+ struct aa_profile *profile2)
9f87b1bd 3864+{
3865+ /* Unlock the two profiles. */
3866+ if (!profile1 || profile1 == profile2) {
3867+ if (profile2)
3868+ spin_unlock_irqrestore(&profile2->lock,
3869+ profile2->int_flags);
3870+ } else if (profile1 > profile2) {
3871+ /* profile1 cannot be NULL here. */
3872+ if (profile2)
3873+ spin_unlock(&profile2->lock);
3874+ spin_unlock_irqrestore(&profile1->lock, profile1->int_flags);
3875+ } else {
3876+ /* profile2 cannot be NULL here. */
3877+ spin_unlock(&profile1->lock);
3878+ spin_unlock_irqrestore(&profile2->lock, profile2->int_flags);
3879+ }
3880+}
3881+
3882+static inline unsigned int aa_match(struct aa_dfa *dfa, const char *pathname,
3883+ int *audit_mask)
3884+{
3885+ if (dfa)
3886+ return aa_dfa_match(dfa, pathname, audit_mask);
3887+ if (audit_mask)
3888+ *audit_mask = 0;
3889+ return 0;
3890+}
3891+
3892+static inline int dfa_audit_mask(struct aa_dfa *dfa, unsigned int state)
3893+{
3894+ return ACCEPT_TABLE2(dfa)[state];
3895+}
3896+
3897+#endif /* __INLINE_H__ */
2380c486
JR
3898diff -uprN a/security/apparmor/list.c b/security/apparmor/list.c
3899--- a/security/apparmor/list.c 1970-01-01 00:00:00.000000000 +0000
3900+++ b/security/apparmor/list.c 2009-02-08 13:26:38.945950214 +0000
3901@@ -0,0 +1,176 @@
9f87b1bd 3902+/*
3903+ * Copyright (C) 1998-2007 Novell/SUSE
3904+ *
3905+ * This program is free software; you can redistribute it and/or
3906+ * modify it under the terms of the GNU General Public License as
3907+ * published by the Free Software Foundation, version 2 of the
3908+ * License.
3909+ *
3910+ * AppArmor Profile List Management
3911+ */
3912+
3913+#include <linux/seq_file.h>
3914+#include "apparmor.h"
3915+#include "inline.h"
3916+
3917+/* list of profile namespaces and lock */
3918+LIST_HEAD(profile_ns_list);
2380c486 3919+DEFINE_RWLOCK(profile_ns_list_lock);
9f87b1bd 3920+
3921+/**
3922+ * __aa_find_namespace - look up a profile namespace on the namespace list
3923+ * @name: name of namespace to find
3924+ * @head: list to search
3925+ *
3926+ * Returns a pointer to the namespace on the list, or NULL if no namespace
3927+ * called @name exists. The caller must hold the profile_ns_list_lock.
3928+ */
3929+struct aa_namespace *__aa_find_namespace(const char *name,
3930+ struct list_head *head)
3931+{
3932+ struct aa_namespace *ns;
3933+
3934+ list_for_each_entry(ns, head, list) {
3935+ if (!strcmp(ns->name, name))
3936+ return ns;
3937+ }
3938+
3939+ return NULL;
3940+}
3941+
3942+/**
3943+ * __aa_find_profile - look up a profile on the profile list
3944+ * @name: name of profile to find
3945+ * @head: list to search
3946+ *
3947+ * Returns a pointer to the profile on the list, or NULL if no profile
3948+ * called @name exists. The caller must hold the profile_list_lock.
3949+ */
3950+struct aa_profile *__aa_find_profile(const char *name, struct list_head *head)
3951+{
3952+ struct aa_profile *profile;
3953+
3954+ list_for_each_entry(profile, head, list) {
3955+ if (!strcmp(profile->name, name))
3956+ return profile;
3957+ }
3958+
3959+ return NULL;
3960+}
3961+
3962+static void aa_profile_list_release(struct list_head *head)
3963+{
3964+ struct aa_profile *profile, *tmp;
3965+ list_for_each_entry_safe(profile, tmp, head, list) {
3966+ /* Remove the profile from each task context it is on. */
3967+ lock_profile(profile);
3968+ profile->isstale = 1;
3969+ aa_unconfine_tasks(profile);
3970+ list_del_init(&profile->list);
3971+ unlock_profile(profile);
3972+ aa_put_profile(profile);
3973+ }
3974+}
3975+
3976+/**
3977+ * aa_profilelist_release - Remove all profiles from profile_list
3978+ */
3979+void aa_profile_ns_list_release(void)
3980+{
3981+ struct aa_namespace *ns, *tmp;
3982+
3983+ /* Remove and release all the profiles on namespace profile lists. */
3984+ write_lock(&profile_ns_list_lock);
3985+ list_for_each_entry_safe(ns, tmp, &profile_ns_list, list) {
3986+ write_lock(&ns->lock);
3987+ aa_profile_list_release(&ns->profiles);
3988+ list_del_init(&ns->list);
3989+ write_unlock(&ns->lock);
3990+ aa_put_namespace(ns);
3991+ }
3992+ write_unlock(&profile_ns_list_lock);
3993+}
3994+
3995+
3996+static struct aa_profile *next_profile(struct aa_profile *profile)
3997+{
3998+ struct aa_profile *next = profile;
3999+ struct aa_namespace *ns;
4000+
4001+ list_for_each_entry_continue(next, &profile->ns->profiles, list)
4002+ return next;
4003+
4004+ ns = profile->ns;
4005+ read_unlock(&ns->lock);
4006+ list_for_each_entry_continue(ns, &profile_ns_list, list) {
4007+ read_lock(&ns->lock);
4008+ list_for_each_entry(profile, &ns->profiles, list)
4009+ return profile;
4010+ read_unlock(&ns->lock);
4011+ }
4012+ return NULL;
4013+}
4014+
4015+static void *p_start(struct seq_file *f, loff_t *pos)
2380c486 4016+ __acquires(profile_ns_list_lock)
9f87b1bd 4017+{
4018+ struct aa_namespace *ns;
4019+ loff_t l = *pos;
4020+
4021+ read_lock(&profile_ns_list_lock);
4022+ if (!list_empty(&profile_ns_list)) {
4023+ struct aa_profile *profile = NULL;
4024+ ns = list_first_entry(&profile_ns_list, typeof(*ns), list);
4025+ read_lock(&ns->lock);
4026+ if (!list_empty(&ns->profiles))
4027+ profile = list_first_entry(&ns->profiles,
4028+ typeof(*profile), list);
4029+ else
4030+ read_unlock(&ns->lock);
4031+ for ( ; profile && l > 0; l--)
4032+ profile = next_profile(profile);
4033+ return profile;
4034+ }
4035+ return NULL;
4036+}
4037+
4038+static void *p_next(struct seq_file *f, void *p, loff_t *pos)
4039+{
4040+ struct aa_profile *profile = (struct aa_profile *) p;
4041+
4042+ (*pos)++;
4043+ profile = next_profile(profile);
4044+
4045+ return profile;
4046+}
4047+
4048+static void p_stop(struct seq_file *f, void *p)
2380c486 4049+ __releases(profile_ns_list_lock)
9f87b1bd 4050+{
4051+ struct aa_profile *profile = (struct aa_profile *) p;
4052+
4053+ if (profile)
4054+ read_unlock(&profile->ns->lock);
4055+ read_unlock(&profile_ns_list_lock);
4056+}
4057+
4058+static int seq_show_profile(struct seq_file *f, void *p)
4059+{
4060+ struct aa_profile *profile = (struct aa_profile *)p;
4061+
4062+ if (profile->ns == default_namespace)
4063+ seq_printf(f, "%s (%s)\n", profile->name,
4064+ PROFILE_COMPLAIN(profile) ? "complain" : "enforce");
4065+ else
4066+ seq_printf(f, ":%s:%s (%s)\n", profile->ns->name, profile->name,
4067+ PROFILE_COMPLAIN(profile) ? "complain" : "enforce");
4068+ return 0;
4069+}
4070+
4071+/* Used in apparmorfs.c */
4072+struct seq_operations apparmorfs_profiles_op = {
4073+ .start = p_start,
4074+ .next = p_next,
4075+ .stop = p_stop,
4076+ .show = seq_show_profile,
4077+};
2380c486
JR
4078diff -uprN a/security/apparmor/locking.txt b/security/apparmor/locking.txt
4079--- a/security/apparmor/locking.txt 1970-01-01 00:00:00.000000000 +0000
4080+++ b/security/apparmor/locking.txt 2009-02-08 13:26:38.922616652 +0000
9f87b1bd 4081@@ -0,0 +1,68 @@
4082+Locking in AppArmor
4083+===================
4084+
4085+Lock hierarchy:
4086+
4087+ aa_interface_lock
4088+ profile_list_lock
4089+ aa_profile->lock
4090+ task_lock()
4091+
4092+
4093+Which lock protects what?
4094+
4095+ /-----------------------+-------------------------------\
4096+ | Variable | Lock |
4097+ >-----------------------+-------------------------------<
4098+ | profile_list | profile_list_lock |
4099+ +-----------------------+-------------------------------+
4100+ | aa_profile | (reference count) |
4101+ +-----------------------+-------------------------------+
4102+ | aa_profile-> | aa_profile->lock |
4103+ | isstale, | |
4104+ | task_contexts | |
4105+ +-----------------------+-------------------------------+
4106+ | task_struct->security | read: RCU |
4107+ | | write: task_lock() |
4108+ +-----------------------+-------------------------------+
4109+ | aa_profile->sub | handle on the profile (list |
4110+ | | is never modified) |
4111+ \-----------------------+-------------------------------/
4112+
4113+(Obviously, the list_heads embedded in data structures are always
4114+protected with the lock that also protects the list.)
4115+
4116+When moving a task context from one profile to another, we grab both
4117+profile locks with lock_both_profiles(). This ensures that both locks
4118+are always taken in the same order, and so we won't deadlock.
4119+
4120+Since task_struct->security is RCU protected the aa_task_struct it
4121+references is only guarenteed to exist for the rcu cycle. Where
4122+aa_task_context->profile is needed in blocking operations the
4123+profile's reference count is incremented and the profile reference
4124+is used.
4125+
4126+Profiles on profile_list are never stale: when a profile becomes stale,
4127+it is removed from profile_list at the same time (under profile_list_lock
4128+and aa_profile->lock).
4129+
4130+The aa_interface_lock is taken whenever user-space modifies the profile
4131+list, and can sleep. This ensures that profile loading/replacement/removal
4132+won't race with itself. We release the profile_list_lock as soon as
4133+possible to avoid stalling exec during profile loading/replacement/removal.
4134+
4135+AppArmor uses lock subtyping to avoid false positives from lockdep. The
4136+profile lock is often taken nested, but it is guaranteed to be in a lock
4137+safe order and not the same lock when done, so it is safe.
4138+
4139+A third lock type (aa_lock_task_release) is given to the profile lock
4140+when it is taken in soft irq context during task release (aa_release).
4141+This is to avoid a false positive between the task lock and the profile
4142+lock. In task context the profile lock wraps the task lock with irqs
4143+off, but the kernel takes the task lock with irqs enabled. This won't
4144+result in a deadlock because for a deadlock to occur the kernel must
4145+take dead task A's lock (irqs on), the rcu callback hook freeing
4146+dead task A must be run and AppArmor must be changing the profile on
4147+dead task A. The kernel should not be taking a dead task's task_lock
4148+at the same time the task is being freed by task rcu cleanup other wise
4149+the task would not be out of its quiescent period.
2380c486
JR
4150diff -uprN a/security/apparmor/lsm.c b/security/apparmor/lsm.c
4151--- a/security/apparmor/lsm.c 1970-01-01 00:00:00.000000000 +0000
4152+++ b/security/apparmor/lsm.c 2009-02-08 13:26:38.949289615 +0000
4153@@ -0,0 +1,1024 @@
9f87b1bd 4154+/*
4155+ * Copyright (C) 1998-2007 Novell/SUSE
4156+ *
4157+ * This program is free software; you can redistribute it and/or
4158+ * modify it under the terms of the GNU General Public License as
4159+ * published by the Free Software Foundation, version 2 of the
4160+ * License.
4161+ *
4162+ * AppArmor LSM interface
4163+ */
4164+
4165+#include <linux/security.h>
2380c486 4166+#include <linux/moduleparam.h>
9f87b1bd 4167+#include <linux/mm.h>
4168+#include <linux/mman.h>
4169+#include <linux/mount.h>
4170+#include <linux/namei.h>
4171+#include <linux/ctype.h>
4172+#include <linux/sysctl.h>
4173+#include <linux/audit.h>
4174+#include <net/sock.h>
4175+
4176+#include "apparmor.h"
4177+#include "inline.h"
4178+
4179+/* Flag indicating whether initialization completed */
2380c486 4180+int apparmor_initialized;
9f87b1bd 4181+
4182+static int param_set_aabool(const char *val, struct kernel_param *kp);
4183+static int param_get_aabool(char *buffer, struct kernel_param *kp);
4184+#define param_check_aabool(name, p) __param_check(name, p, int)
4185+
4186+static int param_set_aauint(const char *val, struct kernel_param *kp);
4187+static int param_get_aauint(char *buffer, struct kernel_param *kp);
4188+#define param_check_aauint(name, p) __param_check(name, p, int)
4189+
4190+/* Flag values, also controllable via /sys/module/apparmor/parameters
4191+ * We define special types as we want to do additional mediation.
4192+ *
4193+ * Complain mode -- in complain mode access failures result in auditing only
4194+ * and task is allowed access. audit events are processed by userspace to
4195+ * generate policy. Default is 'enforce' (0).
4196+ * Value is also togglable per profile and referenced when global value is
4197+ * enforce.
4198+ */
2380c486 4199+int apparmor_complain;
9f87b1bd 4200+module_param_named(complain, apparmor_complain, aabool, S_IRUSR | S_IWUSR);
9f87b1bd 4201+
4202+/* Debug mode */
2380c486 4203+int apparmor_debug;
9f87b1bd 4204+module_param_named(debug, apparmor_debug, aabool, S_IRUSR | S_IWUSR);
9f87b1bd 4205+
4206+/* Audit mode */
2380c486 4207+int apparmor_audit;
9f87b1bd 4208+module_param_named(audit, apparmor_audit, aabool, S_IRUSR | S_IWUSR);
9f87b1bd 4209+/* Syscall logging mode */
2380c486 4210+int apparmor_logsyscall;
9f87b1bd 4211+module_param_named(logsyscall, apparmor_logsyscall, aabool, S_IRUSR | S_IWUSR);
9f87b1bd 4212+
4213+/* Maximum pathname length before accesses will start getting rejected */
4214+unsigned int apparmor_path_max = 2 * PATH_MAX;
4215+module_param_named(path_max, apparmor_path_max, aauint, S_IRUSR | S_IWUSR);
9f87b1bd 4216+
4217+/* Boot time disable flag */
4218+#ifdef CONFIG_SECURITY_APPARMOR_DISABLE
4219+#define AA_ENABLED_PERMS 0600
4220+#else
4221+#define AA_ENABLED_PERMS 0400
4222+#endif
4223+static int param_set_aa_enabled(const char *val, struct kernel_param *kp);
2380c486 4224+static unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
9f87b1bd 4225+module_param_call(enabled, param_set_aa_enabled, param_get_aauint,
4226+ &apparmor_enabled, AA_ENABLED_PERMS);
9f87b1bd 4227+
4228+static int __init apparmor_enabled_setup(char *str)
4229+{
4230+ apparmor_enabled = simple_strtol(str, NULL, 0);
4231+ return 1;
4232+}
4233+__setup("apparmor=", apparmor_enabled_setup);
4234+
4235+static int param_set_aabool(const char *val, struct kernel_param *kp)
4236+{
4237+ if (aa_task_context(current))
4238+ return -EPERM;
4239+ return param_set_bool(val, kp);
4240+}
4241+
4242+static int param_get_aabool(char *buffer, struct kernel_param *kp)
4243+{
4244+ if (aa_task_context(current))
4245+ return -EPERM;
4246+ return param_get_bool(buffer, kp);
4247+}
4248+
4249+static int param_set_aauint(const char *val, struct kernel_param *kp)
4250+{
4251+ if (aa_task_context(current))
4252+ return -EPERM;
4253+ return param_set_uint(val, kp);
4254+}
4255+
4256+static int param_get_aauint(char *buffer, struct kernel_param *kp)
4257+{
4258+ if (aa_task_context(current))
4259+ return -EPERM;
4260+ return param_get_uint(buffer, kp);
4261+}
4262+
4263+/* allow run time disabling of apparmor */
4264+static int param_set_aa_enabled(const char *val, struct kernel_param *kp)
4265+{
9f87b1bd 4266+ unsigned long l;
4267+
4268+ if (!apparmor_initialized) {
4269+ apparmor_enabled = 0;
4270+ return 0;
4271+ }
4272+
4273+ if (aa_task_context(current))
4274+ return -EPERM;
4275+
4276+ if (!apparmor_enabled)
4277+ return -EINVAL;
4278+
4279+ if (!val)
4280+ return -EINVAL;
4281+
2380c486 4282+ if (strict_strtoul(val, 0, &l) || l != 0)
9f87b1bd 4283+ return -EINVAL;
4284+
4285+ apparmor_enabled = 0;
4286+ apparmor_disable();
4287+ return 0;
4288+}
4289+
9f87b1bd 4290+static int apparmor_ptrace(struct task_struct *tracer,
4291+ struct task_struct *tracee)
4292+{
4293+ struct aa_task_context *cxt;
4294+ int error = 0;
4295+
4296+ /*
4297+ * tracer can ptrace tracee when
4298+ * - tracer is unconfined
4299+ * - tracer & tracee are in the same namespace &&
4300+ * - tracer is in complain mode
4301+ * - tracer and tracee are confined by the same profile
4302+ * - tracer profile has CAP_SYS_PTRACE
4303+ */
4304+
4305+ rcu_read_lock();
4306+ cxt = aa_task_context(tracer);
4307+ if (cxt) {
4308+ if (tracer->nsproxy != tracee->nsproxy) {
4309+ struct aa_audit sa;
4310+ memset(&sa, 0, sizeof(sa));
4311+ sa.operation = "ptrace";
4312+ sa.gfp_mask = GFP_ATOMIC;
4313+ sa.parent = tracer->pid;
4314+ sa.task = tracee->pid;
4315+ sa.info = "different namespaces";
4316+ aa_audit_reject(cxt->profile, &sa);
4317+ error = -EPERM;
4318+ } else {
4319+ struct aa_task_context *tracee_cxt =
4320+ aa_task_context(tracee);
4321+
4322+ error = aa_may_ptrace(cxt, tracee_cxt ?
4323+ tracee_cxt->profile : NULL);
4324+ if (error && PROFILE_COMPLAIN(cxt->profile)) {
4325+ struct aa_audit sa;
4326+ memset(&sa, 0, sizeof(sa));
4327+ sa.operation = "ptrace";
4328+ sa.gfp_mask = GFP_ATOMIC;
4329+ sa.parent = tracer->pid;
4330+ sa.task = tracee->pid;
4331+ aa_audit_hint(cxt->profile, &sa);
4332+ }
4333+ }
4334+ }
4335+ rcu_read_unlock();
4336+
4337+ return error;
4338+}
4339+
4340+static int apparmor_ptrace_may_access(struct task_struct *child,
4341+ unsigned int mode)
4342+{
4343+ return apparmor_ptrace(current, child);
4344+}
4345+
4346+
4347+static int apparmor_ptrace_traceme(struct task_struct *parent)
4348+{
4349+ return apparmor_ptrace(parent, current);
4350+}
4351+
4352+static int apparmor_capable(struct task_struct *task, int cap)
4353+{
4354+ int error;
4355+ struct aa_task_context *cxt;
4356+
4357+ /* cap_capable returns 0 on success, else -EPERM */
4358+ error = cap_capable(task, cap);
4359+
4360+ rcu_read_lock();
4361+ cxt = aa_task_context(task);
4362+ if (cxt && (!error || cap_raised(cxt->profile->set_caps, cap)))
4363+ error = aa_capability(cxt, cap);
4364+ rcu_read_unlock();
4365+
4366+ return error;
4367+}
4368+
4369+static int apparmor_sysctl(struct ctl_table *table, int op)
4370+{
4371+ struct aa_profile *profile = aa_get_profile(current);
4372+ int error = 0;
4373+
4374+ if (profile) {
4375+ char *buffer, *name;
4376+ int mask;
4377+
4378+ mask = 0;
4379+ if (op & 4)
4380+ mask |= MAY_READ;
4381+ if (op & 2)
4382+ mask |= MAY_WRITE;
4383+
4384+ error = -ENOMEM;
2380c486 4385+ buffer = (char *)__get_free_page(GFP_KERNEL);
9f87b1bd 4386+ if (!buffer)
4387+ goto out;
4388+ name = sysctl_pathname(table, buffer, PAGE_SIZE);
4389+ if (name && name - buffer >= 5) {
4390+ name -= 5;
4391+ memcpy(name, "/proc", 5);
4392+ error = aa_perm_path(profile, "sysctl", name, mask, 0);
4393+ }
4394+ free_page((unsigned long)buffer);
4395+ }
4396+
4397+out:
4398+ aa_put_profile(profile);
4399+ return error;
4400+}
4401+
4402+static int apparmor_bprm_set_security(struct linux_binprm *bprm)
4403+{
4404+ /* handle capability bits with setuid, etc */
4405+ cap_bprm_set_security(bprm);
4406+ /* already set based on script name */
4407+ if (bprm->sh_bang)
4408+ return 0;
4409+ return aa_register(bprm);
4410+}
4411+
4412+static int apparmor_bprm_secureexec(struct linux_binprm *bprm)
4413+{
4414+ int ret = cap_bprm_secureexec(bprm);
4415+
4416+ if (!ret && (unsigned long)bprm->security & AA_SECURE_EXEC_NEEDED) {
4417+ AA_DEBUG("%s: secureexec required for %s\n",
2380c486 4418+ __func__, bprm->filename);
9f87b1bd 4419+ ret = 1;
4420+ }
4421+
4422+ return ret;
4423+}
4424+
9f87b1bd 4425+static int apparmor_inode_mkdir(struct inode *dir, struct dentry *dentry,
4426+ struct vfsmount *mnt, int mask)
4427+{
4428+ struct aa_profile *profile;
4429+ int error = 0;
4430+
4431+ if (!mnt || !mediated_filesystem(dir))
4432+ goto out;
4433+
4434+ profile = aa_get_profile(current);
4435+
4436+ if (profile)
4437+ error = aa_perm_dir(profile, "inode_mkdir", dentry, mnt,
4438+ MAY_WRITE);
4439+
4440+ aa_put_profile(profile);
4441+
4442+out:
4443+ return error;
4444+}
4445+
4446+static int apparmor_inode_rmdir(struct inode *dir, struct dentry *dentry,
4447+ struct vfsmount *mnt)
4448+{
4449+ struct aa_profile *profile;
4450+ int error = 0;
4451+
4452+ if (!mnt || !mediated_filesystem(dir))
4453+ goto out;
4454+
4455+ profile = aa_get_profile(current);
4456+
4457+ if (profile)
4458+ error = aa_perm_dir(profile, "inode_rmdir", dentry, mnt,
4459+ MAY_WRITE);
4460+
4461+ aa_put_profile(profile);
4462+
4463+out:
4464+ return error;
4465+}
4466+
4467+static int aa_permission(const char *operation, struct inode *inode,
4468+ struct dentry *dentry, struct vfsmount *mnt,
4469+ int mask, int check)
4470+{
4471+ int error = 0;
4472+
4473+ if (mnt && mediated_filesystem(inode)) {
4474+ struct aa_profile *profile;
4475+
4476+ profile = aa_get_profile(current);
4477+ if (profile)
4478+ error = aa_perm(profile, operation, dentry, mnt, mask,
4479+ check);
4480+ aa_put_profile(profile);
4481+ }
4482+ return error;
4483+}
4484+
4485+static inline int aa_mask_permissions(int mask)
4486+{
4487+ if (mask & MAY_APPEND)
4488+ mask &= (MAY_READ | MAY_APPEND | MAY_EXEC);
4489+ else
4490+ mask &= (MAY_READ | MAY_WRITE | MAY_EXEC);
4491+ return mask;
4492+}
4493+
4494+static int apparmor_inode_create(struct inode *dir, struct dentry *dentry,
4495+ struct vfsmount *mnt, int mask)
4496+{
4497+ return aa_permission("inode_create", dir, dentry, mnt, MAY_APPEND, 0);
4498+}
4499+
4500+static int apparmor_inode_link(struct dentry *old_dentry,
4501+ struct vfsmount *old_mnt, struct inode *dir,
4502+ struct dentry *new_dentry,
4503+ struct vfsmount *new_mnt)
4504+{
4505+ int error = 0;
4506+ struct aa_profile *profile;
4507+
4508+ if (!old_mnt || !new_mnt || !mediated_filesystem(dir))
4509+ goto out;
4510+
4511+ profile = aa_get_profile(current);
4512+
4513+ if (profile)
4514+ error = aa_link(profile, new_dentry, new_mnt,
4515+ old_dentry, old_mnt);
4516+
4517+ aa_put_profile(profile);
4518+
4519+out:
4520+ return error;
4521+}
4522+
4523+static int apparmor_inode_unlink(struct inode *dir, struct dentry *dentry,
4524+ struct vfsmount *mnt)
4525+{
4526+ int check = 0;
4527+
4528+ if (S_ISDIR(dentry->d_inode->i_mode))
4529+ check |= AA_CHECK_DIR;
4530+ return aa_permission("inode_unlink", dir, dentry, mnt, MAY_WRITE,
4531+ check);
4532+}
4533+
4534+static int apparmor_inode_symlink(struct inode *dir, struct dentry *dentry,
4535+ struct vfsmount *mnt, const char *old_name)
4536+{
4537+ return aa_permission("inode_symlink", dir, dentry, mnt, MAY_WRITE, 0);
4538+}
4539+
4540+static int apparmor_inode_mknod(struct inode *dir, struct dentry *dentry,
4541+ struct vfsmount *mnt, int mode, dev_t dev)
4542+{
4543+ return aa_permission("inode_mknod", dir, dentry, mnt, MAY_WRITE, 0);
4544+}
4545+
4546+static int apparmor_inode_rename(struct inode *old_dir,
4547+ struct dentry *old_dentry,
4548+ struct vfsmount *old_mnt,
4549+ struct inode *new_dir,
4550+ struct dentry *new_dentry,
4551+ struct vfsmount *new_mnt)
4552+{
4553+ struct aa_profile *profile;
4554+ int error = 0;
4555+
4556+ if ((!old_mnt && !new_mnt) || !mediated_filesystem(old_dir))
4557+ goto out;
4558+
4559+ profile = aa_get_profile(current);
4560+
4561+ if (profile) {
4562+ struct inode *inode = old_dentry->d_inode;
4563+ int check = 0;
4564+
4565+ if (inode && S_ISDIR(inode->i_mode))
4566+ check |= AA_CHECK_DIR;
4567+ if (old_mnt)
4568+ error = aa_perm(profile, "inode_rename", old_dentry,
4569+ old_mnt, MAY_READ | MAY_WRITE, check);
4570+
4571+ if (!error && new_mnt) {
4572+ error = aa_perm(profile, "inode_rename", new_dentry,
4573+ new_mnt, MAY_WRITE, check);
4574+ }
4575+ }
4576+
4577+ aa_put_profile(profile);
4578+
4579+out:
4580+ return error;
4581+}
4582+
4583+static int apparmor_inode_permission(struct inode *inode, int mask)
4584+{
4585+ return 0;
4586+}
4587+
4588+static int apparmor_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
4589+ struct iattr *iattr)
4590+{
4591+ int error = 0;
4592+
4593+ if (!mnt)
4594+ goto out;
4595+
4596+ if (mediated_filesystem(dentry->d_inode)) {
4597+ struct aa_profile *profile;
4598+
4599+ profile = aa_get_profile(current);
4600+ /*
4601+ * Mediate any attempt to change attributes of a file
4602+ * (chmod, chown, chgrp, etc)
4603+ */
4604+ if (profile)
4605+ error = aa_attr(profile, dentry, mnt, iattr);
4606+
4607+ aa_put_profile(profile);
4608+ }
4609+
4610+out:
4611+ return error;
4612+}
4613+
4614+static int aa_xattr_permission(struct dentry *dentry, struct vfsmount *mnt,
4615+ const char *operation, int mask,
4616+ struct file *file)
4617+{
4618+ int error = 0;
4619+
4620+ if (mnt && mediated_filesystem(dentry->d_inode)) {
4621+ struct aa_profile *profile = aa_get_profile(current);
4622+ int check = file ? AA_CHECK_FD : 0;
4623+
4624+ if (profile)
4625+ error = aa_perm_xattr(profile, operation, dentry, mnt,
4626+ mask, check);
4627+ aa_put_profile(profile);
4628+ }
4629+
4630+ return error;
4631+}
4632+
4633+static int apparmor_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
4634+ const char *name, const void *value,
4635+ size_t size, int flags, struct file *file)
4636+{
4637+ int error = cap_inode_setxattr(dentry, mnt, name, value, size, flags,
4638+ file);
4639+
4640+ if (!error)
4641+ error = aa_xattr_permission(dentry, mnt, "xattr set",
4642+ MAY_WRITE, file);
4643+ return error;
4644+}
4645+
4646+static int apparmor_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
4647+ const char *name, struct file *file)
4648+{
4649+ return aa_xattr_permission(dentry, mnt, "xattr get", MAY_READ, file);
4650+}
4651+
4652+static int apparmor_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt,
4653+ struct file *file)
4654+{
4655+ return aa_xattr_permission(dentry, mnt, "xattr list", MAY_READ, file);
4656+}
4657+
4658+static int apparmor_inode_removexattr(struct dentry *dentry,
4659+ struct vfsmount *mnt, const char *name,
4660+ struct file *file)
4661+{
4662+ return aa_xattr_permission(dentry, mnt, "xattr remove", MAY_WRITE,
4663+ file);
4664+}
4665+
4666+static int aa_file_permission(const char *op, struct file *file, int mask)
4667+{
4668+ struct aa_profile *profile;
2380c486 4669+ struct aa_profile *file_profile = file->f_security;
9f87b1bd 4670+ int error = 0;
4671+
4672+ if (!file_profile)
4673+ goto out;
4674+
4675+ /*
4676+ * If this file was opened under a different profile, we
4677+ * revalidate the access against the current profile.
4678+ */
4679+ profile = aa_get_profile(current);
4680+ if (profile && (file_profile != profile || mask & AA_MAY_LOCK)) {
4681+ struct dentry *dentry = file->f_dentry;
4682+ struct vfsmount *mnt = file->f_vfsmnt;
4683+ struct inode *inode = dentry->d_inode;
4684+ int check = AA_CHECK_FD;
4685+
4686+ /*
4687+ * FIXME: We should remember which profiles we revalidated
4688+ * against.
4689+ */
4690+ if (S_ISDIR(inode->i_mode))
4691+ check |= AA_CHECK_DIR;
4692+ error = aa_permission(op, inode, dentry, mnt, mask, check);
4693+ }
4694+ aa_put_profile(profile);
4695+
4696+out:
4697+ return error;
4698+}
4699+
4700+static int apparmor_file_permission(struct file *file, int mask)
4701+{
4702+ return aa_file_permission("file_permission", file,
4703+ aa_mask_permissions(mask));
4704+}
4705+
2380c486 4706+static int apparmor_file_lock(struct file *file, unsigned int cmd)
9f87b1bd 4707+{
4708+ int mask = AA_MAY_LOCK;
4709+ if (cmd == F_WRLCK)
4710+ mask |= MAY_WRITE;
4711+ return aa_file_permission("file_lock", file, mask);
4712+}
4713+
4714+static int apparmor_file_alloc_security(struct file *file)
4715+{
4716+ struct aa_profile *profile;
4717+
4718+ profile = aa_get_profile(current);
4719+ if (profile)
4720+ file->f_security = profile;
4721+
4722+ return 0;
4723+}
4724+
4725+static void apparmor_file_free_security(struct file *file)
4726+{
2380c486 4727+ struct aa_profile *file_profile = file->f_security;
9f87b1bd 4728+
4729+ aa_put_profile(file_profile);
4730+}
4731+
2380c486
JR
4732+static int aa_mmap(struct file *file, const char *operation,
4733+ unsigned long prot, unsigned long flags)
9f87b1bd 4734+{
4735+ struct dentry *dentry;
4736+ int mask = 0;
4737+
4738+ if (!file || !file->f_security)
4739+ return 0;
4740+
4741+ if (prot & PROT_READ)
4742+ mask |= MAY_READ;
4743+ /* Private mappings don't require write perms since they don't
4744+ * write back to the files */
4745+ if ((prot & PROT_WRITE) && !(flags & MAP_PRIVATE))
4746+ mask |= MAY_WRITE;
4747+ if (prot & PROT_EXEC)
4748+ mask |= AA_EXEC_MMAP;
4749+
4750+ dentry = file->f_dentry;
4751+ return aa_permission(operation, dentry->d_inode, dentry,
4752+ file->f_vfsmnt, mask, AA_CHECK_FD);
4753+}
4754+
4755+static int apparmor_file_mmap(struct file *file, unsigned long reqprot,
4756+ unsigned long prot, unsigned long flags,
4757+ unsigned long addr, unsigned long addr_only)
4758+{
4759+ if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) {
4760+ struct aa_profile *profile = aa_get_profile(current);
4761+ if (profile)
4762+ /* future control check here */
4763+ return -EACCES;
4764+ else
4765+ return -EACCES;
4766+ aa_put_profile(profile);
4767+ }
4768+
4769+ return aa_mmap(file, "file_mmap", prot, flags);
4770+}
4771+
4772+static int apparmor_file_mprotect(struct vm_area_struct *vma,
4773+ unsigned long reqprot, unsigned long prot)
4774+{
4775+ return aa_mmap(vma->vm_file, "file_mprotect", prot,
4776+ !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
4777+}
4778+
4779+static int apparmor_path_permission(struct path *path, int mask)
4780+{
4781+ struct inode *inode;
4782+ int check = 0;
4783+
4784+ if (!path)
4785+ return 0;
4786+
4787+ inode = path->dentry->d_inode;
4788+
4789+ mask = aa_mask_permissions(mask);
4790+ if (S_ISDIR(inode->i_mode)) {
4791+ check |= AA_CHECK_DIR;
4792+ /* allow traverse accesses to directories */
4793+ mask &= ~MAY_EXEC;
4794+ if (!mask)
4795+ return 0;
4796+ }
4797+
4798+ return aa_permission("inode_permission", inode, path->dentry,
4799+ path->mnt, mask, check);
4800+}
4801+
4802+static int apparmor_task_alloc_security(struct task_struct *task)
4803+{
4804+ return aa_clone(task);
4805+}
4806+
4807+/*
4808+ * Called from IRQ context from RCU callback.
4809+ */
4810+static void apparmor_task_free_security(struct task_struct *task)
4811+{
4812+ aa_release(task);
4813+}
4814+
4815+static int apparmor_socket_create(int family, int type, int protocol, int kern)
4816+{
4817+ struct aa_profile *profile;
4818+ int error = 0;
4819+
4820+ if (kern)
4821+ return 0;
4822+
4823+ profile = aa_get_profile(current);
4824+ if (profile)
4825+ error = aa_net_perm(profile, "socket_create", family,
4826+ type, protocol);
4827+ aa_put_profile(profile);
4828+
4829+ return error;
4830+}
4831+
4832+static int apparmor_socket_post_create(struct socket *sock, int family,
4833+ int type, int protocol, int kern)
4834+{
4835+ struct sock *sk = sock->sk;
4836+
4837+ if (kern)
4838+ return 0;
4839+
4840+ return aa_revalidate_sk(sk, "socket_post_create");
4841+}
4842+
4843+static int apparmor_socket_bind(struct socket *sock,
4844+ struct sockaddr *address, int addrlen)
4845+{
4846+ struct sock *sk = sock->sk;
4847+
4848+ return aa_revalidate_sk(sk, "socket_bind");
4849+}
4850+
4851+static int apparmor_socket_connect(struct socket *sock,
4852+ struct sockaddr *address, int addrlen)
4853+{
4854+ struct sock *sk = sock->sk;
4855+
4856+ return aa_revalidate_sk(sk, "socket_connect");
4857+}
4858+
4859+static int apparmor_socket_listen(struct socket *sock, int backlog)
4860+{
4861+ struct sock *sk = sock->sk;
4862+
4863+ return aa_revalidate_sk(sk, "socket_listen");
4864+}
4865+
4866+static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
4867+{
4868+ struct sock *sk = sock->sk;
4869+
4870+ return aa_revalidate_sk(sk, "socket_accept");
4871+}
4872+
4873+static int apparmor_socket_sendmsg(struct socket *sock,
4874+ struct msghdr *msg, int size)
4875+{
4876+ struct sock *sk = sock->sk;
4877+
4878+ return aa_revalidate_sk(sk, "socket_sendmsg");
4879+}
4880+
4881+static int apparmor_socket_recvmsg(struct socket *sock,
4882+ struct msghdr *msg, int size, int flags)
4883+{
4884+ struct sock *sk = sock->sk;
4885+
4886+ return aa_revalidate_sk(sk, "socket_recvmsg");
4887+}
4888+
4889+static int apparmor_socket_getsockname(struct socket *sock)
4890+{
4891+ struct sock *sk = sock->sk;
4892+
4893+ return aa_revalidate_sk(sk, "socket_getsockname");
4894+}
4895+
4896+static int apparmor_socket_getpeername(struct socket *sock)
4897+{
4898+ struct sock *sk = sock->sk;
4899+
4900+ return aa_revalidate_sk(sk, "socket_getpeername");
4901+}
4902+
4903+static int apparmor_socket_getsockopt(struct socket *sock, int level,
4904+ int optname)
4905+{
4906+ struct sock *sk = sock->sk;
4907+
4908+ return aa_revalidate_sk(sk, "socket_getsockopt");
4909+}
4910+
4911+static int apparmor_socket_setsockopt(struct socket *sock, int level,
4912+ int optname)
4913+{
4914+ struct sock *sk = sock->sk;
4915+
4916+ return aa_revalidate_sk(sk, "socket_setsockopt");
4917+}
4918+
4919+static int apparmor_socket_shutdown(struct socket *sock, int how)
4920+{
4921+ struct sock *sk = sock->sk;
4922+
4923+ return aa_revalidate_sk(sk, "socket_shutdown");
4924+}
4925+
4926+static int apparmor_getprocattr(struct task_struct *task, char *name,
4927+ char **value)
4928+{
4929+ unsigned len;
4930+ int error;
4931+ struct aa_profile *profile;
4932+
4933+ /* AppArmor only supports the "current" process attribute */
4934+ if (strcmp(name, "current") != 0)
4935+ return -EINVAL;
4936+
4937+ /* must be task querying itself or admin */
4938+ if (current != task && !capable(CAP_SYS_ADMIN))
4939+ return -EPERM;
4940+
4941+ profile = aa_get_profile(task);
4942+ error = aa_getprocattr(profile, value, &len);
4943+ aa_put_profile(profile);
4944+ if (!error)
4945+ error = len;
4946+
4947+ return error;
4948+}
4949+
4950+static int apparmor_setprocattr(struct task_struct *task, char *name,
4951+ void *value, size_t size)
4952+{
4953+ char *command, *args;
4954+ int error;
4955+
4956+ if (strcmp(name, "current") != 0 || size == 0 || size >= PAGE_SIZE)
4957+ return -EINVAL;
4958+ args = value;
4959+ args[size] = '\0';
4960+ args = strstrip(args);
4961+ command = strsep(&args, " ");
4962+ if (!args)
4963+ return -EINVAL;
4964+ while (isspace(*args))
4965+ args++;
4966+ if (!*args)
4967+ return -EINVAL;
4968+
4969+ if (strcmp(command, "changehat") == 0) {
4970+ if (current != task)
4971+ return -EACCES;
4972+ error = aa_setprocattr_changehat(args);
4973+ } else if (strcmp(command, "changeprofile") == 0) {
4974+ if (current != task)
4975+ return -EACCES;
4976+ error = aa_setprocattr_changeprofile(args);
4977+ } else if (strcmp(command, "setprofile") == 0) {
4978+ struct aa_profile *profile;
4979+
4980+ /* Only an unconfined process with admin capabilities
4981+ * may change the profile of another task.
4982+ */
4983+
4984+ if (!capable(CAP_SYS_ADMIN))
4985+ return -EACCES;
4986+
4987+ profile = aa_get_profile(current);
4988+ if (profile) {
4989+ struct aa_audit sa;
4990+ memset(&sa, 0, sizeof(sa));
4991+ sa.operation = "profile_set";
4992+ sa.gfp_mask = GFP_KERNEL;
4993+ sa.task = task->pid;
4994+ sa.info = "from confined process";
4995+ aa_audit_reject(profile, &sa);
4996+ aa_put_profile(profile);
4997+ return -EACCES;
4998+ }
4999+ error = aa_setprocattr_setprofile(task, args);
5000+ } else {
5001+ struct aa_audit sa;
5002+ memset(&sa, 0, sizeof(sa));
5003+ sa.operation = "setprocattr";
5004+ sa.gfp_mask = GFP_KERNEL;
5005+ sa.info = "invalid command";
5006+ sa.name = command;
5007+ sa.task = task->pid;
5008+ aa_audit_reject(NULL, &sa);
5009+ return -EINVAL;
5010+ }
5011+
5012+ if (!error)
5013+ error = size;
5014+ return error;
5015+}
5016+
5017+static int apparmor_task_setrlimit(unsigned int resource,
5018+ struct rlimit *new_rlim)
5019+{
5020+ struct aa_profile *profile;
5021+ int error = 0;
5022+
5023+ profile = aa_get_profile(current);
5024+ if (profile) {
5025+ error = aa_task_setrlimit(profile, resource, new_rlim);
5026+ }
5027+ aa_put_profile(profile);
5028+
5029+ return error;
5030+}
5031+
2380c486
JR
5032+static struct security_operations apparmor_ops = {
5033+ .name = "apparmor",
9f87b1bd 5034+ .ptrace_may_access = apparmor_ptrace_may_access,
5035+ .ptrace_traceme = apparmor_ptrace_traceme,
5036+ .capget = cap_capget,
5037+ .capset_check = cap_capset_check,
5038+ .capset_set = cap_capset_set,
5039+ .sysctl = apparmor_sysctl,
5040+ .capable = apparmor_capable,
5041+ .syslog = cap_syslog,
5042+
5043+ .bprm_apply_creds = cap_bprm_apply_creds,
5044+ .bprm_set_security = apparmor_bprm_set_security,
5045+ .bprm_secureexec = apparmor_bprm_secureexec,
5046+
9f87b1bd 5047+ .inode_mkdir = apparmor_inode_mkdir,
5048+ .inode_rmdir = apparmor_inode_rmdir,
5049+ .inode_create = apparmor_inode_create,
5050+ .inode_link = apparmor_inode_link,
5051+ .inode_unlink = apparmor_inode_unlink,
5052+ .inode_symlink = apparmor_inode_symlink,
5053+ .inode_mknod = apparmor_inode_mknod,
5054+ .inode_rename = apparmor_inode_rename,
5055+ .inode_permission = apparmor_inode_permission,
5056+ .inode_setattr = apparmor_inode_setattr,
5057+ .inode_setxattr = apparmor_inode_setxattr,
5058+ .inode_getxattr = apparmor_inode_getxattr,
5059+ .inode_listxattr = apparmor_inode_listxattr,
5060+ .inode_removexattr = apparmor_inode_removexattr,
5061+ .file_permission = apparmor_file_permission,
5062+ .file_alloc_security = apparmor_file_alloc_security,
5063+ .file_free_security = apparmor_file_free_security,
5064+ .file_mmap = apparmor_file_mmap,
5065+ .file_mprotect = apparmor_file_mprotect,
5066+ .file_lock = apparmor_file_lock,
5067+
5068+ .path_permission = apparmor_path_permission,
5069+
5070+ .task_alloc_security = apparmor_task_alloc_security,
5071+ .task_free_security = apparmor_task_free_security,
5072+ .task_post_setuid = cap_task_post_setuid,
5073+ .task_reparent_to_init = cap_task_reparent_to_init,
5074+ .task_setrlimit = apparmor_task_setrlimit,
5075+
5076+ .getprocattr = apparmor_getprocattr,
5077+ .setprocattr = apparmor_setprocattr,
5078+
5079+ .socket_create = apparmor_socket_create,
5080+ .socket_post_create = apparmor_socket_post_create,
5081+ .socket_bind = apparmor_socket_bind,
5082+ .socket_connect = apparmor_socket_connect,
5083+ .socket_listen = apparmor_socket_listen,
5084+ .socket_accept = apparmor_socket_accept,
5085+ .socket_sendmsg = apparmor_socket_sendmsg,
5086+ .socket_recvmsg = apparmor_socket_recvmsg,
5087+ .socket_getsockname = apparmor_socket_getsockname,
5088+ .socket_getpeername = apparmor_socket_getpeername,
5089+ .socket_getsockopt = apparmor_socket_getsockopt,
5090+ .socket_setsockopt = apparmor_socket_setsockopt,
5091+ .socket_shutdown = apparmor_socket_shutdown,
5092+};
5093+
5094+void info_message(const char *str)
5095+{
5096+ struct aa_audit sa;
5097+ memset(&sa, 0, sizeof(sa));
5098+ sa.gfp_mask = GFP_KERNEL;
5099+ sa.info = str;
5100+ printk(KERN_INFO "AppArmor: %s\n", str);
5101+ if (audit_enabled)
5102+ aa_audit_message(NULL, &sa, AUDIT_APPARMOR_STATUS);
5103+}
5104+
5105+static int __init apparmor_init(void)
5106+{
5107+ int error;
5108+
2380c486
JR
5109+ if (!apparmor_enabled || !security_module_enable(&apparmor_ops)) {
5110+ info_message("AppArmor disabled by boot time parameter\n");
9f87b1bd 5111+ return 0;
5112+ }
5113+
2380c486
JR
5114+ error = create_apparmorfs();
5115+ if (error) {
9f87b1bd 5116+ AA_ERROR("Unable to activate AppArmor filesystem\n");
5117+ goto createfs_out;
5118+ }
5119+
2380c486
JR
5120+ error = alloc_default_namespace();
5121+ if (error) {
9f87b1bd 5122+ AA_ERROR("Unable to allocate default profile namespace\n");
5123+ goto alloc_out;
5124+ }
5125+
2380c486
JR
5126+ error = register_security(&apparmor_ops);
5127+ if (error) {
9f87b1bd 5128+ AA_ERROR("Unable to register AppArmor\n");
5129+ goto register_security_out;
5130+ }
5131+
5132+ /* Report that AppArmor successfully initialized */
5133+ apparmor_initialized = 1;
5134+ if (apparmor_complain)
5135+ info_message("AppArmor initialized: complainmode enabled");
5136+ else
5137+ info_message("AppArmor initialized");
5138+
5139+ return error;
5140+
5141+register_security_out:
5142+ free_default_namespace();
5143+
5144+alloc_out:
2380c486 5145+ destroy_apparmorfs();
9f87b1bd 5146+
5147+createfs_out:
5148+ return error;
5149+
5150+}
5151+
5152+security_initcall(apparmor_init);
5153+
5154+void apparmor_disable(void)
5155+{
5156+ /* Remove and release all the profiles on the profile list. */
5157+ mutex_lock(&aa_interface_lock);
5158+ aa_profile_ns_list_release();
5159+
5160+ /* FIXME: cleanup profiles references on files */
5161+ free_default_namespace();
5162+
5163+ /*
5164+ * Delay for an rcu cycle to make sure that all active task
5165+ * context readers have finished, and all profiles have been
5166+ * freed by their rcu callbacks.
5167+ */
5168+ synchronize_rcu();
5169+
5170+ destroy_apparmorfs();
5171+ mutex_unlock(&aa_interface_lock);
5172+
5173+ apparmor_initialized = 0;
5174+
5175+ info_message("AppArmor protection removed");
5176+}
5177+
2380c486
JR
5178diff -uprN a/security/apparmor/main.c b/security/apparmor/main.c
5179--- a/security/apparmor/main.c 1970-01-01 00:00:00.000000000 +0000
5180+++ b/security/apparmor/main.c 2009-02-08 13:26:38.949289615 +0000
5181@@ -0,0 +1,1692 @@
9f87b1bd 5182+/*
5183+ * Copyright (C) 2002-2007 Novell/SUSE
5184+ *
5185+ * This program is free software; you can redistribute it and/or
5186+ * modify it under the terms of the GNU General Public License as
5187+ * published by the Free Software Foundation, version 2 of the
5188+ * License.
5189+ *
5190+ * AppArmor Core
5191+ */
5192+
5193+#include <linux/security.h>
5194+#include <linux/namei.h>
5195+#include <linux/audit.h>
5196+#include <linux/mount.h>
5197+#include <linux/ptrace.h>
5198+#include <linux/socket.h>
5199+#include <linux/net.h>
5200+#include <net/sock.h>
5201+
5202+#include "apparmor.h"
5203+
5204+#include "inline.h"
5205+
5206+/*
5207+ * Table of capability names: we generate it from capabilities.h.
5208+ */
5209+static const char *capability_names[] = {
5210+#include "capability_names.h"
5211+};
5212+
5213+struct aa_namespace *default_namespace;
5214+
5215+static int aa_inode_mode(struct inode *inode)
5216+{
5217+ /* if the inode doesn't exist the user is creating it */
5218+ if (!inode || current->fsuid == inode->i_uid)
5219+ return AA_USER_SHIFT;
5220+ return AA_OTHER_SHIFT;
5221+}
5222+
5223+int alloc_default_namespace(void)
5224+{
5225+ struct aa_namespace *ns;
5226+ char *name = kstrdup("default", GFP_KERNEL);
5227+ if (!name)
5228+ return -ENOMEM;
5229+ ns = alloc_aa_namespace(name);
5230+ if (!ns) {
5231+ kfree(name);
5232+ return -ENOMEM;
5233+ }
5234+
5235+ write_lock(&profile_ns_list_lock);
5236+ default_namespace = ns;
5237+ aa_get_namespace(ns);
5238+ list_add(&ns->list, &profile_ns_list);
5239+ write_unlock(&profile_ns_list_lock);
5240+
5241+ return 0;
5242+}
5243+
5244+void free_default_namespace(void)
5245+{
5246+ write_lock(&profile_ns_list_lock);
5247+ list_del_init(&default_namespace->list);
5248+ write_unlock(&profile_ns_list_lock);
5249+ aa_put_namespace(default_namespace);
5250+ default_namespace = NULL;
5251+}
5252+
5253+static void aa_audit_file_sub_mask(struct audit_buffer *ab, char *buffer,
5254+ int mask)
5255+{
5256+ const char unsafex[] = "upcn";
5257+ const char safex[] = "UPCN";
5258+ char *m = buffer;
5259+
5260+ if (mask & AA_EXEC_MMAP)
5261+ *m++ = 'm';
5262+ if (mask & MAY_READ)
5263+ *m++ = 'r';
5264+ if (mask & MAY_WRITE)
5265+ *m++ = 'w';
5266+ else if (mask & MAY_APPEND)
5267+ *m++ = 'a';
5268+ if (mask & MAY_EXEC) {
5269+ int index = AA_EXEC_INDEX(mask);
5270+ /* all indexes > 4 are also named transitions */
5271+ if (index > 4)
5272+ index = 4;
5273+ if (index > 0) {
5274+ if (mask & AA_EXEC_UNSAFE)
5275+ *m++ = unsafex[index - 1];
5276+ else
5277+ *m++ = safex[index - 1];
5278+ }
5279+ if (mask & AA_EXEC_INHERIT)
5280+ *m++ = 'i';
5281+ *m++ = 'x';
5282+ }
5283+ if (mask & AA_MAY_LINK)
5284+ *m++ = 'l';
5285+ if (mask & AA_MAY_LOCK)
5286+ *m++ = 'k';
5287+ *m++ = '\0';
5288+}
5289+
5290+static void aa_audit_file_mask(struct audit_buffer *ab, const char *name,
5291+ int mask)
5292+{
5293+ char user[10], other[10];
5294+
5295+ aa_audit_file_sub_mask(ab, user,
5296+ (mask & AA_USER_PERMS) >> AA_USER_SHIFT);
5297+ aa_audit_file_sub_mask(ab, other,
5298+ (mask & AA_OTHER_PERMS) >> AA_OTHER_SHIFT);
5299+
5300+ audit_log_format(ab, " %s=\"%s::%s\"", name, user, other);
5301+}
5302+
5303+static const char *address_families[] = {
5304+#include "af_names.h"
5305+};
5306+
5307+static const char *sock_types[] = {
5308+ "unknown(0)",
5309+ "stream",
5310+ "dgram",
5311+ "raw",
5312+ "rdm",
5313+ "seqpacket",
5314+ "dccp",
5315+ "unknown(7)",
5316+ "unknown(8)",
5317+ "unknown(9)",
5318+ "packet",
5319+};
5320+
5321+/**
5322+ * aa_audit - Log an audit event to the audit subsystem
5323+ * @profile: profile to check against
5324+ * @sa: audit event
5325+ * @audit_cxt: audit context to log message to
5326+ * @type: audit event number
5327+ */
5328+static int aa_audit_base(struct aa_profile *profile, struct aa_audit *sa,
5329+ struct audit_context *audit_cxt, int type)
5330+{
5331+ struct audit_buffer *ab = NULL;
5332+
5333+ ab = audit_log_start(audit_cxt, sa->gfp_mask, type);
5334+
5335+ if (!ab) {
5336+ AA_ERROR("Unable to log event (%d) to audit subsys\n",
5337+ type);
5338+ /* don't fail operations in complain mode even if logging
5339+ * fails */
5340+ return type == AUDIT_APPARMOR_ALLOWED ? 0 : -ENOMEM;
5341+ }
5342+
5343+ if (sa->operation)
5344+ audit_log_format(ab, "operation=\"%s\"", sa->operation);
5345+
5346+ if (sa->info) {
5347+ audit_log_format(ab, " info=\"%s\"", sa->info);
5348+ if (sa->error_code)
5349+ audit_log_format(ab, " error=%d", sa->error_code);
5350+ }
5351+
5352+ if (sa->request_mask)
5353+ aa_audit_file_mask(ab, "requested_mask", sa->request_mask);
5354+
5355+ if (sa->denied_mask)
5356+ aa_audit_file_mask(ab, "denied_mask", sa->denied_mask);
5357+
5358+ if (sa->request_mask)
5359+ audit_log_format(ab, " fsuid=%d", current->fsuid);
5360+
5361+ if (sa->rlimit)
5362+ audit_log_format(ab, " rlimit=%d", sa->rlimit - 1);
5363+
5364+ if (sa->iattr) {
5365+ struct iattr *iattr = sa->iattr;
5366+
5367+ audit_log_format(ab, " attribute=\"%s%s%s%s%s%s%s\"",
5368+ iattr->ia_valid & ATTR_MODE ? "mode," : "",
5369+ iattr->ia_valid & ATTR_UID ? "uid," : "",
5370+ iattr->ia_valid & ATTR_GID ? "gid," : "",
5371+ iattr->ia_valid & ATTR_SIZE ? "size," : "",
5372+ iattr->ia_valid & (ATTR_ATIME | ATTR_ATIME_SET) ?
5373+ "atime," : "",
5374+ iattr->ia_valid & (ATTR_MTIME | ATTR_MTIME_SET) ?
5375+ "mtime," : "",
5376+ iattr->ia_valid & ATTR_CTIME ? "ctime," : "");
5377+ }
5378+
5379+ if (sa->task)
5380+ audit_log_format(ab, " task=%d", sa->task);
5381+
5382+ if (sa->parent)
5383+ audit_log_format(ab, " parent=%d", sa->parent);
5384+
5385+ if (sa->name) {
5386+ audit_log_format(ab, " name=");
5387+ audit_log_untrustedstring(ab, sa->name);
5388+ }
5389+
5390+ if (sa->name2) {
5391+ audit_log_format(ab, " name2=");
5392+ audit_log_untrustedstring(ab, sa->name2);
5393+ }
5394+
5395+ if (sa->family || sa->type) {
5396+ if (address_families[sa->family])
5397+ audit_log_format(ab, " family=\"%s\"",
5398+ address_families[sa->family]);
5399+ else
5400+ audit_log_format(ab, " family=\"unknown(%d)\"",
5401+ sa->family);
5402+
5403+ if (sock_types[sa->type])
5404+ audit_log_format(ab, " sock_type=\"%s\"",
5405+ sock_types[sa->type]);
5406+ else
5407+ audit_log_format(ab, " sock_type=\"unknown(%d)\"",
5408+ sa->type);
5409+
5410+ audit_log_format(ab, " protocol=%d", sa->protocol);
5411+ }
5412+
2380c486 5413+ audit_log_format(ab, " pid=%d", current->pid);
9f87b1bd 5414+
5415+ if (profile) {
2380c486
JR
5416+ if (!sa->parent)
5417+ audit_log_format(ab, " parent=%d",
5418+ current->real_parent->pid);
5419+
9f87b1bd 5420+ audit_log_format(ab, " profile=");
5421+ audit_log_untrustedstring(ab, profile->name);
5422+
5423+ if (profile->ns != default_namespace) {
5424+ audit_log_format(ab, " namespace=");
5425+ audit_log_untrustedstring(ab, profile->ns->name);
5426+ }
5427+ }
5428+
5429+ audit_log_end(ab);
5430+
5431+ return type == AUDIT_APPARMOR_ALLOWED ? 0 : sa->error_code;
5432+}
5433+
5434+/**
5435+ * aa_audit_syscallreject - Log a syscall rejection to the audit subsystem
5436+ * @profile: profile to check against
5437+ * @gfp: memory allocation flags
5438+ * @msg: string describing syscall being rejected
5439+ */
5440+int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp,
5441+ const char *msg)
5442+{
5443+ struct aa_audit sa;
5444+ memset(&sa, 0, sizeof(sa));
5445+ sa.operation = "syscall";
5446+ sa.name = msg;
5447+ sa.gfp_mask = gfp;
5448+ sa.error_code = -EPERM;
5449+
5450+ return aa_audit_base(profile, &sa, current->audit_context,
5451+ AUDIT_APPARMOR_DENIED);
5452+}
5453+
5454+int aa_audit_message(struct aa_profile *profile, struct aa_audit *sa,
5455+ int type)
5456+{
5457+ struct audit_context *audit_cxt;
5458+
5459+ audit_cxt = apparmor_logsyscall ? current->audit_context : NULL;
5460+ return aa_audit_base(profile, sa, audit_cxt, type);
5461+}
5462+
5463+void aa_audit_hint(struct aa_profile *profile, struct aa_audit *sa)
5464+{
5465+ aa_audit_message(profile, sa, AUDIT_APPARMOR_HINT);
5466+}
5467+
5468+void aa_audit_status(struct aa_profile *profile, struct aa_audit *sa)
5469+{
5470+ aa_audit_message(profile, sa, AUDIT_APPARMOR_STATUS);
5471+}
5472+
5473+int aa_audit_reject(struct aa_profile *profile, struct aa_audit *sa)
5474+{
5475+ return aa_audit_message(profile, sa, AUDIT_APPARMOR_DENIED);
5476+}
5477+
5478+/**
5479+ * aa_audit - Log an audit event to the audit subsystem
5480+ * @profile: profile to check against
5481+ * @sa: audit event
5482+ */
2380c486 5483+static int aa_audit(struct aa_profile *profile, struct aa_audit *sa)
9f87b1bd 5484+{
5485+ int type = AUDIT_APPARMOR_DENIED;
5486+ struct audit_context *audit_cxt;
5487+
5488+ if (likely(!sa->error_code))
5489+ type = AUDIT_APPARMOR_AUDIT;
5490+ else if (PROFILE_COMPLAIN(profile))
5491+ type = AUDIT_APPARMOR_ALLOWED;
5492+
5493+ audit_cxt = apparmor_logsyscall ? current->audit_context : NULL;
5494+ return aa_audit_base(profile, sa, audit_cxt, type);
5495+}
5496+
5497+static int aa_audit_file(struct aa_profile *profile, struct aa_audit *sa)
5498+{
5499+ if (likely(!sa->error_code)) {
5500+ int mask = sa->audit_mask & AUDIT_FILE_MASK;
5501+
5502+ if (unlikely(PROFILE_AUDIT(profile)))
5503+ mask |= AUDIT_FILE_MASK;
5504+
5505+ if (likely(!(sa->request_mask & mask)))
5506+ return 0;
5507+
5508+ /* mask off perms that are not being force audited */
5509+ sa->request_mask &= mask | ALL_AA_EXEC_TYPE;
5510+ } else {
5511+ int mask = AUDIT_QUIET_MASK(sa->audit_mask);
5512+
2380c486 5513+ if (!(sa->denied_mask & ~mask) && !PROFILE_COMPLAIN(profile))
9f87b1bd 5514+ return sa->error_code;
5515+
5516+ /* mask off perms whose denial is being silenced */
5517+ if (!PROFILE_COMPLAIN(profile))
5518+ sa->denied_mask &= (~mask) | ALL_AA_EXEC_TYPE;
5519+ }
5520+
5521+ return aa_audit(profile, sa);
5522+}
5523+
5524+static int aa_audit_caps(struct aa_profile *profile, struct aa_audit *sa,
5525+ int cap)
5526+{
5527+ if (likely(!sa->error_code)) {
5528+ if (likely(!PROFILE_AUDIT(profile) &&
5529+ !cap_raised(profile->audit_caps, cap)))
5530+ return 0;
5531+ }
5532+
5533+ /* quieting of capabilities is handled the caps_logged cache */
5534+ return aa_audit(profile, sa);
5535+}
5536+
5537+/**
5538+ * aa_file_denied - check for @mask access on a file
5539+ * @profile: profile to check against
5540+ * @name: pathname of file
5541+ * @mask: permission mask requested for file
5542+ * @audit_mask: return audit mask for the match
5543+ *
5544+ * Return %0 on success, or else the permissions in @mask that the
5545+ * profile denies.
5546+ */
5547+static int aa_file_denied(struct aa_profile *profile, const char *name,
5548+ int mask, int *audit_mask)
5549+{
5550+ return (mask & ~aa_match(profile->file_rules, name, audit_mask));
5551+}
5552+
5553+/**
5554+ * aa_link_denied - check for permission to link a file
5555+ * @profile: profile to check against
5556+ * @link: pathname of link being created
5557+ * @target: pathname of target to be linked to
5558+ * @target_mode: UGO shift for target inode
5559+ * @request_mask: the permissions subset valid only if link succeeds
5560+ * @audit_mask: return the audit_mask for the link permission
5561+ * Return %0 on success, or else the permissions that the profile denies.
5562+ */
5563+static int aa_link_denied(struct aa_profile *profile, const char *link,
5564+ const char *target, int target_mode,
5565+ int *request_mask, int *audit_mask)
5566+{
5567+ unsigned int state;
5568+ int l_mode, t_mode, l_x, t_x, denied_mask = 0;
5569+ int link_mask = AA_MAY_LINK << target_mode;
5570+
5571+ *request_mask = link_mask;
5572+
5573+ l_mode = aa_match_state(profile->file_rules, DFA_START, link, &state);
5574+
5575+ if (l_mode & link_mask) {
5576+ int mode;
5577+ /* test to see if target can be paired with link */
5578+ state = aa_dfa_null_transition(profile->file_rules, state);
5579+ mode = aa_match_state(profile->file_rules, state, target,
5580+ &state);
5581+
5582+ if (!(mode & link_mask))
5583+ denied_mask |= link_mask;
5584+
5585+ *audit_mask = dfa_audit_mask(profile->file_rules, state);
5586+
5587+ /* return if link subset test is not required */
5588+ if (!(mode & (AA_LINK_SUBSET_TEST << target_mode)))
5589+ return denied_mask;
5590+ }
5591+
5592+ /* Do link perm subset test requiring permission on link are a
5593+ * subset of the permissions on target.
5594+ * If a subset test is required a permission subset test of the
5595+ * perms for the link are done against the user::other of the
5596+ * target's 'r', 'w', 'x', 'a', 'k', and 'm' permissions.
5597+ *
5598+ * If the link has 'x', an exact match of all the execute flags
5599+ * must match.
2380c486 5600+ */
9f87b1bd 5601+ denied_mask |= ~l_mode & link_mask;
5602+
5603+ t_mode = aa_match(profile->file_rules, target, NULL);
5604+
5605+ l_x = l_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS);
5606+ t_x = t_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS);
5607+
5608+ /* For actual subset test ignore valid-profile-transition flags,
5609+ * and link bits
5610+ */
5611+ l_mode &= AA_FILE_PERMS & ~AA_LINK_BITS;
5612+ t_mode &= AA_FILE_PERMS & ~AA_LINK_BITS;
5613+
5614+ *request_mask = l_mode | link_mask;
5615+
5616+ if (l_mode) {
5617+ int x = l_x | (t_x & ALL_AA_EXEC_UNSAFE);
5618+ denied_mask |= l_mode & ~t_mode;
5619+ /* mask off x modes not used by link */
5620+
5621+ /* handle exec subset
5622+ * - link safe exec issubset of unsafe exec
5623+ * - no link x perm is subset of target having x perm
5624+ */
5625+ if ((l_mode & AA_USER_EXEC) &&
5626+ (x & AA_USER_EXEC_TYPE) != (t_x & AA_USER_EXEC_TYPE))
5627+ denied_mask = AA_USER_EXEC | (l_x & AA_USER_EXEC_TYPE);
5628+ if ((l_mode & AA_OTHER_EXEC) &&
2380c486
JR
5629+ (x & AA_OTHER_EXEC_TYPE) != (t_x & AA_OTHER_EXEC_TYPE)) {
5630+ denied_mask =
5631+ AA_OTHER_EXEC | (l_x & AA_OTHER_EXEC_TYPE);
5632+ }
9f87b1bd 5633+ }
5634+
5635+ return denied_mask;
5636+}
5637+
5638+/**
5639+ * aa_get_name - compute the pathname of a file
5640+ * @dentry: dentry of the file
5641+ * @mnt: vfsmount of the file
5642+ * @buffer: buffer that aa_get_name() allocated
5643+ * @check: AA_CHECK_DIR is set if the file is a directory
5644+ *
5645+ * Returns a pointer to the beginning of the pathname (which usually differs
5646+ * from the beginning of the buffer), or an error code.
5647+ *
5648+ * We need @check to indicate whether the file is a directory or not because
5649+ * the file may not yet exist, and so we cannot check the inode's file type.
5650+ */
5651+static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt,
5652+ char **buffer, int check)
5653+{
5654+ char *name;
5655+ int is_dir, size = 256;
5656+
5657+ is_dir = (check & AA_CHECK_DIR) ? 1 : 0;
5658+
5659+ for (;;) {
5660+ char *buf = kmalloc(size, GFP_KERNEL);
5661+ if (!buf)
5662+ return ERR_PTR(-ENOMEM);
5663+
5664+ name = d_namespace_path(dentry, mnt, buf, size - is_dir);
5665+ if (!IS_ERR(name)) {
5666+ if (name[0] != '/') {
5667+ /*
5668+ * This dentry is not connected to the
5669+ * namespace root -- reject access.
5670+ */
5671+ kfree(buf);
5672+ return ERR_PTR(-ENOENT);
5673+ }
5674+ if (is_dir && name[1] != '\0') {
5675+ /*
5676+ * Append "/" to the pathname. The root
5677+ * directory is a special case; it already
5678+ * ends in slash.
5679+ */
5680+ buf[size - 2] = '/';
5681+ buf[size - 1] = '\0';
5682+ }
5683+
5684+ *buffer = buf;
5685+ return name;
5686+ }
5687+ if (PTR_ERR(name) != -ENAMETOOLONG)
5688+ return name;
5689+
5690+ kfree(buf);
5691+ size <<= 1;
5692+ if (size > apparmor_path_max)
5693+ return ERR_PTR(-ENAMETOOLONG);
5694+ }
5695+}
5696+
5697+static char *new_compound_name(const char *n1, const char *n2)
5698+{
5699+ char *name = kmalloc(strlen(n1) + strlen(n2) + 3, GFP_KERNEL);
5700+ if (name)
5701+ sprintf(name, "%s//%s", n1, n2);
5702+ return name;
5703+}
2380c486
JR
5704+
5705+static void aa_put_name_buffer(char *buffer)
9f87b1bd 5706+{
5707+ kfree(buffer);
5708+}
5709+
5710+/**
5711+ * aa_perm_dentry - check if @profile allows @mask for a file
5712+ * @profile: profile to check against
5713+ * @dentry: dentry of the file
5714+ * @mnt: vfsmount o the file
5715+ * @sa: audit context
5716+ * @mask: requested profile permissions
5717+ * @check: kind of check to perform
5718+ *
5719+ * Returns 0 upon success, or else an error code.
5720+ *
5721+ * @check indicates the file type, and whether the file was accessed through
5722+ * an open file descriptor (AA_CHECK_FD) or not.
5723+ */
5724+static int aa_perm_dentry(struct aa_profile *profile, struct dentry *dentry,
5725+ struct vfsmount *mnt, struct aa_audit *sa, int check)
5726+{
5727+ int error;
5728+ char *buffer = NULL;
5729+
5730+ sa->name = aa_get_name(dentry, mnt, &buffer, check);
5731+ sa->request_mask <<= aa_inode_mode(dentry->d_inode);
5732+ if (IS_ERR(sa->name)) {
5733+ /*
5734+ * deleted files are given a pass on permission checks when
5735+ * accessed through a file descriptor.
5736+ */
5737+ if (PTR_ERR(sa->name) == -ENOENT && (check & AA_CHECK_FD))
5738+ sa->denied_mask = 0;
5739+ else {
5740+ sa->denied_mask = sa->request_mask;
5741+ sa->error_code = PTR_ERR(sa->name);
5742+ if (sa->error_code == -ENOENT)
5743+ sa->info = "Failed name resolution - object not a valid entry";
5744+ else if (sa->error_code == -ENAMETOOLONG)
5745+ sa->info = "Failed name resolution - name too long";
5746+ else
5747+ sa->info = "Failed name resolution";
5748+ }
5749+ sa->name = NULL;
5750+ } else
5751+ sa->denied_mask = aa_file_denied(profile, sa->name,
5752+ sa->request_mask,
5753+ &sa->audit_mask);
5754+
5755+ if (!sa->denied_mask)
5756+ sa->error_code = 0;
5757+
5758+ error = aa_audit_file(profile, sa);
5759+ aa_put_name_buffer(buffer);
5760+
5761+ return error;
5762+}
5763+
5764+/**
5765+ * aa_attr - check if attribute change is allowed
5766+ * @profile: profile to check against
5767+ * @dentry: dentry of the file to check
5768+ * @mnt: vfsmount of the file to check
5769+ * @iattr: attribute changes requested
5770+ */
5771+int aa_attr(struct aa_profile *profile, struct dentry *dentry,
5772+ struct vfsmount *mnt, struct iattr *iattr)
5773+{
5774+ struct inode *inode = dentry->d_inode;
5775+ int error, check;
5776+ struct aa_audit sa;
5777+
5778+ memset(&sa, 0, sizeof(sa));
5779+ sa.operation = "setattr";
5780+ sa.gfp_mask = GFP_KERNEL;
5781+ sa.iattr = iattr;
5782+ sa.request_mask = MAY_WRITE;
5783+ sa.error_code = -EACCES;
5784+
5785+ check = 0;
5786+ if (inode && S_ISDIR(inode->i_mode))
5787+ check |= AA_CHECK_DIR;
5788+ if (iattr->ia_valid & ATTR_FILE)
5789+ check |= AA_CHECK_FD;
5790+
5791+ error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
5792+
5793+ return error;
5794+}
5795+
5796+/**
5797+ * aa_perm_xattr - check if xattr attribute change is allowed
5798+ * @profile: profile to check against
5799+ * @dentry: dentry of the file to check
5800+ * @mnt: vfsmount of the file to check
5801+ * @operation: xattr operation being done
5802+ * @mask: access mode requested
5803+ * @check: kind of check to perform
5804+ */
5805+int aa_perm_xattr(struct aa_profile *profile, const char *operation,
5806+ struct dentry *dentry, struct vfsmount *mnt, int mask,
5807+ int check)
5808+{
5809+ struct inode *inode = dentry->d_inode;
5810+ int error;
5811+ struct aa_audit sa;
5812+
5813+ memset(&sa, 0, sizeof(sa));
5814+ sa.operation = operation;
5815+ sa.gfp_mask = GFP_KERNEL;
5816+ sa.request_mask = mask;
5817+ sa.error_code = -EACCES;
5818+
5819+ if (inode && S_ISDIR(inode->i_mode))
5820+ check |= AA_CHECK_DIR;
5821+
5822+ error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
5823+
5824+ return error;
5825+}
5826+
5827+/**
5828+ * aa_perm - basic apparmor permissions check
5829+ * @profile: profile to check against
5830+ * @dentry: dentry of the file to check
5831+ * @mnt: vfsmount of the file to check
5832+ * @mask: access mode requested
5833+ * @check: kind of check to perform
5834+ *
5835+ * Determine if access @mask for the file is authorized by @profile.
5836+ * Returns 0 on success, or else an error code.
5837+ */
5838+int aa_perm(struct aa_profile *profile, const char *operation,
5839+ struct dentry *dentry, struct vfsmount *mnt, int mask, int check)
5840+{
5841+ struct aa_audit sa;
5842+ int error = 0;
5843+
5844+ if (mask == 0)
5845+ goto out;
5846+
5847+ memset(&sa, 0, sizeof(sa));
5848+ sa.operation = operation;
5849+ sa.gfp_mask = GFP_KERNEL;
5850+ sa.request_mask = mask;
5851+ sa.error_code = -EACCES;
5852+
5853+ error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
5854+
5855+out:
5856+ return error;
5857+}
5858+
5859+/**
5860+ * aa_perm_dir
5861+ * @profile: profile to check against
5862+ * @dentry: dentry of directory to check
5863+ * @mnt: vfsmount of directory to check
5864+ * @operation: directory operation being performed
5865+ * @mask: access mode requested
5866+ *
5867+ * Determine if directory operation (make/remove) for dentry is authorized
5868+ * by @profile.
5869+ * Returns 0 on success, or else an error code.
5870+ */
5871+int aa_perm_dir(struct aa_profile *profile, const char *operation,
5872+ struct dentry *dentry, struct vfsmount *mnt, int mask)
5873+{
5874+ struct aa_audit sa;
5875+
5876+ memset(&sa, 0, sizeof(sa));
5877+ sa.operation = operation;
5878+ sa.gfp_mask = GFP_KERNEL;
5879+ sa.request_mask = mask;
5880+ sa.error_code = -EACCES;
5881+
5882+ return aa_perm_dentry(profile, dentry, mnt, &sa, AA_CHECK_DIR);
5883+}
5884+
5885+int aa_perm_path(struct aa_profile *profile, const char *operation,
5886+ const char *name, int mask, uid_t uid)
5887+{
5888+ struct aa_audit sa;
5889+
5890+ memset(&sa, 0, sizeof(sa));
5891+ sa.operation = operation;
5892+ sa.gfp_mask = GFP_KERNEL;
5893+ sa.request_mask = mask;
5894+ sa.name = name;
5895+ if (current->fsuid == uid)
5896+ sa.request_mask = mask << AA_USER_SHIFT;
5897+ else
5898+ sa.request_mask = mask << AA_OTHER_SHIFT;
5899+
5900+ sa.denied_mask = aa_file_denied(profile, name, sa.request_mask,
5901+ &sa.audit_mask) ;
5902+ sa.error_code = sa.denied_mask ? -EACCES : 0;
5903+
5904+ return aa_audit_file(profile, &sa);
5905+}
5906+
5907+/**
5908+ * aa_capability - test permission to use capability
5909+ * @cxt: aa_task_context with profile to check against
5910+ * @cap: capability to be tested
5911+ *
5912+ * Look up capability in profile capability set.
5913+ * Returns 0 on success, or else an error code.
5914+ */
5915+int aa_capability(struct aa_task_context *cxt, int cap)
5916+{
5917+ int error = cap_raised(cxt->profile->capabilities, cap) ? 0 : -EPERM;
5918+ struct aa_audit sa;
5919+
5920+ /* test if cap has alread been logged */
5921+ if (cap_raised(cxt->caps_logged, cap)) {
5922+ if (PROFILE_COMPLAIN(cxt->profile))
5923+ error = 0;
5924+ return error;
5925+ } else
5926+ /* don't worry about rcu replacement of the cxt here.
5927+ * caps_logged is a cache to reduce the occurence of
5928+ * duplicate messages in the log. The worst that can
5929+ * happen is duplicate capability messages shows up in
5930+ * the audit log
5931+ */
5932+ cap_raise(cxt->caps_logged, cap);
5933+
5934+ memset(&sa, 0, sizeof(sa));
5935+ sa.operation = "capable";
5936+ sa.gfp_mask = GFP_ATOMIC;
5937+ sa.name = capability_names[cap];
5938+ sa.error_code = error;
5939+
5940+ error = aa_audit_caps(cxt->profile, &sa, cap);
5941+
5942+ return error;
5943+}
5944+
5945+/* must be used inside rcu_read_lock or task_lock */
5946+int aa_may_ptrace(struct aa_task_context *cxt, struct aa_profile *tracee)
5947+{
5948+ if (!cxt || cxt->profile == tracee)
5949+ return 0;
5950+ return aa_capability(cxt, CAP_SYS_PTRACE);
5951+}
5952+
5953+/**
5954+ * aa_link - hard link check
5955+ * @profile: profile to check against
5956+ * @link: dentry of link being created
5957+ * @link_mnt: vfsmount of link being created
5958+ * @target: dentry of link target
5959+ * @target_mnt: vfsmunt of link target
5960+ *
5961+ * Returns 0 on success, or else an error code.
5962+ */
5963+int aa_link(struct aa_profile *profile,
5964+ struct dentry *link, struct vfsmount *link_mnt,
5965+ struct dentry *target, struct vfsmount *target_mnt)
5966+{
5967+ int error;
5968+ struct aa_audit sa;
5969+ char *buffer = NULL, *buffer2 = NULL;
5970+
5971+ memset(&sa, 0, sizeof(sa));
5972+ sa.operation = "inode_link";
5973+ sa.gfp_mask = GFP_KERNEL;
5974+ sa.name = aa_get_name(link, link_mnt, &buffer, 0);
5975+ sa.name2 = aa_get_name(target, target_mnt, &buffer2, 0);
5976+
5977+ if (IS_ERR(sa.name)) {
5978+ sa.error_code = PTR_ERR(sa.name);
5979+ sa.name = NULL;
5980+ }
5981+ if (IS_ERR(sa.name2)) {
5982+ sa.error_code = PTR_ERR(sa.name2);
5983+ sa.name2 = NULL;
5984+ }
5985+
5986+ if (sa.name && sa.name2) {
5987+ sa.denied_mask = aa_link_denied(profile, sa.name, sa.name2,
5988+ aa_inode_mode(target->d_inode),
5989+ &sa.request_mask,
5990+ &sa.audit_mask);
5991+ sa.error_code = sa.denied_mask ? -EACCES : 0;
5992+ }
5993+
5994+ error = aa_audit_file(profile, &sa);
5995+
5996+ aa_put_name_buffer(buffer);
5997+ aa_put_name_buffer(buffer2);
5998+
5999+ return error;
6000+}
6001+
6002+int aa_net_perm(struct aa_profile *profile, char *operation,
6003+ int family, int type, int protocol)
6004+{
6005+ struct aa_audit sa;
6006+ int error = 0;
6007+ u16 family_mask, audit_mask, quiet_mask;
6008+
6009+ if ((family < 0) || (family >= AF_MAX))
6010+ return -EINVAL;
6011+
6012+ if ((type < 0) || (type >= SOCK_MAX))
6013+ return -EINVAL;
6014+
6015+ /* unix domain and netlink sockets are handled by ipc */
6016+ if (family == AF_UNIX || family == AF_NETLINK)
6017+ return 0;
6018+
6019+ family_mask = profile->network_families[family];
6020+ audit_mask = profile->audit_network[family];
6021+ quiet_mask = profile->quiet_network[family];
6022+
6023+ error = (family_mask & (1 << type)) ? 0 : -EACCES;
6024+
6025+ memset(&sa, 0, sizeof(sa));
6026+ sa.operation = operation;
6027+ sa.gfp_mask = GFP_KERNEL;
6028+ sa.family = family;
6029+ sa.type = type;
6030+ sa.protocol = protocol;
6031+ sa.error_code = error;
6032+
6033+ if (likely(!error)) {
6034+ if (!PROFILE_AUDIT(profile) && !(family_mask & audit_mask))
6035+ return 0;
6036+ } else if (!((1 << type) & ~quiet_mask)) {
6037+ return error;
6038+ }
6039+
6040+ error = aa_audit(profile, &sa);
6041+
6042+ return error;
6043+}
6044+
6045+int aa_revalidate_sk(struct sock *sk, char *operation)
6046+{
6047+ struct aa_profile *profile;
6048+ int error = 0;
6049+
6050+ /* this is some debugging code to flush out the network hooks that
6051+ that are called in interrupt context */
6052+ if (in_interrupt()) {
2380c486 6053+ printk(KERN_WARNING "AppArmor Debug: Hook being called from interrupt context\n");
9f87b1bd 6054+ dump_stack();
6055+ return 0;
6056+ }
6057+
6058+ profile = aa_get_profile(current);
6059+ if (profile)
6060+ error = aa_net_perm(profile, operation,
6061+ sk->sk_family, sk->sk_type,
6062+ sk->sk_protocol);
6063+ aa_put_profile(profile);
6064+
6065+ return error;
6066+}
6067+/**
6068+ * aa_task_setrlimit - test permission to set an rlimit
6069+ * @profile - profile confining the task
6070+ * @resource - the resource being set
6071+ * @new_rlim - the new resource limit
6072+ *
6073+ * Control raising the processes hard limit.
6074+ */
6075+int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource,
6076+ struct rlimit *new_rlim)
6077+{
6078+ struct aa_audit sa;
6079+ int error = 0;
6080+
6081+ memset(&sa, 0, sizeof(sa));
6082+ sa.operation = "setrlimit";
6083+ sa.gfp_mask = GFP_KERNEL;
6084+ sa.rlimit = resource + 1;
6085+
6086+ if (profile->rlimits.mask & (1 << resource) &&
6087+ new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max) {
6088+ sa.error_code = -EACCES;
6089+
6090+ error = aa_audit(profile, &sa);
6091+ }
6092+
6093+ return error;
6094+}
6095+
6096+static int aa_rlimit_nproc(struct aa_profile *profile) {
6097+ if (profile && (profile->rlimits.mask & (1 << RLIMIT_NPROC)) &&
6098+ profile->task_count >= profile->rlimits.limits[RLIMIT_NPROC].rlim_max)
6099+ return -EAGAIN;
6100+ return 0;
6101+}
6102+
6103+void aa_set_rlimits(struct task_struct *task, struct aa_profile *profile)
6104+{
6105+ int i, mask;
6106+
6107+ if (!profile)
6108+ return;
6109+
6110+ if (!profile->rlimits.mask)
6111+ return;
6112+
6113+ task_lock(task->group_leader);
6114+ mask = 1;
6115+ for (i = 0; i < RLIM_NLIMITS; i++, mask <<= 1) {
6116+ struct rlimit new_rlim, *old_rlim;
6117+
6118+ /* check to see if NPROC which is per profile and handled
6119+ * in clone/exec or whether this is a limit to be set
6120+ * can't set cpu limit either right now
6121+ */
6122+ if (i == RLIMIT_NPROC || i == RLIMIT_CPU)
6123+ continue;
6124+
6125+ old_rlim = task->signal->rlim + i;
6126+ new_rlim = *old_rlim;
6127+
6128+ if (mask & profile->rlimits.mask &&
6129+ profile->rlimits.limits[i].rlim_max < new_rlim.rlim_max) {
6130+ new_rlim.rlim_max = profile->rlimits.limits[i].rlim_max;
6131+ /* soft limit should not exceed hard limit */
6132+ if (new_rlim.rlim_cur > new_rlim.rlim_max)
6133+ new_rlim.rlim_cur = new_rlim.rlim_max;
6134+ }
6135+
6136+ *old_rlim = new_rlim;
6137+ }
6138+ task_unlock(task->group_leader);
6139+}
6140+
6141+/*******************************
6142+ * Global task related functions
6143+ *******************************/
6144+
6145+/**
6146+ * aa_clone - initialize the task context for a new task
6147+ * @child: task that is being created
6148+ *
6149+ * Returns 0 on success, or else an error code.
6150+ */
6151+int aa_clone(struct task_struct *child)
6152+{
6153+ struct aa_audit sa;
6154+ struct aa_task_context *cxt, *child_cxt;
6155+ struct aa_profile *profile;
6156+
6157+ if (!aa_task_context(current))
6158+ return 0;
6159+ child_cxt = aa_alloc_task_context(GFP_KERNEL);
6160+ if (!child_cxt)
6161+ return -ENOMEM;
6162+
6163+ memset(&sa, 0, sizeof(sa));
6164+ sa.operation = "clone";
6165+ sa.task = child->pid;
6166+ sa.gfp_mask = GFP_KERNEL;
6167+
6168+repeat:
6169+ profile = aa_get_profile(current);
6170+ if (profile) {
6171+ lock_profile(profile);
6172+ cxt = aa_task_context(current);
6173+ if (unlikely(profile->isstale || !cxt ||
6174+ cxt->profile != profile)) {
6175+ /**
6176+ * Race with profile replacement or removal, or with
6177+ * task context removal.
6178+ */
6179+ unlock_profile(profile);
6180+ aa_put_profile(profile);
6181+ goto repeat;
6182+ }
6183+
6184+ if (aa_rlimit_nproc(profile)) {
6185+ sa.info = "rlimit nproc limit exceeded";
6186+ unlock_profile(profile);
6187+ aa_audit_reject(profile, &sa);
6188+ aa_put_profile(profile);
6189+ return -EAGAIN;
6190+ }
6191+
6192+ /* No need to grab the child's task lock here. */
6193+ aa_change_task_context(child, child_cxt, profile,
6194+ cxt->cookie, cxt->previous_profile);
6195+
6196+ unlock_profile(profile);
6197+
9f87b1bd 6198+ aa_put_profile(profile);
6199+ } else
6200+ aa_free_task_context(child_cxt);
6201+
6202+ return 0;
6203+}
6204+
6205+static struct aa_profile *
2380c486 6206+aa_register_find(struct aa_profile *profile, const char *ns_name,
9f87b1bd 6207+ const char *name, int mandatory, int complain,
6208+ struct aa_audit *sa)
6209+{
6210+ struct aa_namespace *ns;
6211+ struct aa_profile *new_profile;
6212+ int ns_ref = 0;
6213+
6214+ if (profile)
6215+ ns = profile->ns;
6216+ else
6217+ ns = default_namespace;
6218+
6219+ if (ns_name) {
6220+ /* locate the profile namespace */
6221+ ns = aa_find_namespace(ns_name);
6222+ if (!ns) {
6223+ if (mandatory) {
6224+ sa->info = "profile namespace not found";
6225+ sa->denied_mask = sa->request_mask;
6226+ sa->error_code = -ENOENT;
6227+ return ERR_PTR(-ENOENT);
6228+ } else {
6229+ return NULL;
6230+ }
6231+ }
6232+ ns_ref++;
6233+ }
6234+
6235+ /* Locate new profile */
6236+ new_profile = aa_find_profile(ns, name);
6237+
6238+ if (new_profile) {
6239+ AA_DEBUG("%s: setting profile %s\n",
2380c486 6240+ __func__, new_profile->name);
9f87b1bd 6241+ } else if (mandatory && profile) {
6242+ sa->info = "mandatory profile missing";
6243+ sa->denied_mask = sa->request_mask; /* shifted MAY_EXEC */
6244+ if (complain) {
6245+ aa_audit_hint(profile, sa);
6246+ new_profile =
6247+ aa_dup_profile(profile->ns->null_complain_profile);
6248+ } else {
6249+ sa->error_code = -EACCES;
6250+ if (ns_ref)
6251+ aa_put_namespace(ns);
6252+ return ERR_PTR(-EACCES);
6253+ }
6254+ } else {
6255+ /* Only way we can get into this code is if task
6256+ * is unconfined, pix, nix.
6257+ */
6258+ AA_DEBUG("%s: No profile found for exec image '%s'\n",
2380c486 6259+ __func__, name);
9f87b1bd 6260+ }
6261+ if (ns_ref)
6262+ aa_put_namespace(ns);
6263+ return new_profile;
6264+}
6265+
6266+static struct aa_profile *
6267+aa_x_to_profile(struct aa_profile *profile, const char *filename, int xmode,
6268+ struct aa_audit *sa, char **child)
6269+{
6270+ struct aa_profile *new_profile = NULL;
6271+ int ix = xmode & AA_EXEC_INHERIT;
6272+ int complain = PROFILE_COMPLAIN(profile);
6273+ int index;
6274+
6275+ *child = NULL;
6276+ switch (xmode & AA_EXEC_MODIFIERS) {
6277+ case 0:
6278+ /* only valid with ix flag */
6279+ ix = 1;
6280+ break;
6281+ case AA_EXEC_UNCONFINED:
6282+ /* only valid without ix flag */
6283+ ix = 0;
6284+ break;
6285+ case AA_EXEC_PROFILE:
6286+ new_profile = aa_register_find(profile, NULL, filename, !ix,
6287+ complain, sa);
6288+ break;
6289+ case AA_EXEC_CHILD:
6290+ *child = new_compound_name(profile->name, filename);
6291+ sa->name2 = *child;
6292+ if (!*child) {
6293+ sa->info = "Failed name resolution - exec failed";
6294+ sa->error_code = -ENOMEM;
6295+ new_profile = ERR_PTR(-ENOMEM);
6296+ } else {
6297+ new_profile = aa_register_find(profile, NULL, *child,
6298+ !ix, complain, sa);
6299+ }
6300+ break;
6301+ default:
6302+ /* all other indexes are named transitions */
6303+ index = AA_EXEC_INDEX(xmode);
6304+ if (index - 4 > profile->exec_table_size) {
6305+ sa->info = "invalid named transition - exec failed";
6306+ sa->error_code = -EACCES;
6307+ new_profile = ERR_PTR(-EACCES);
6308+ } else {
6309+ char *ns_name = NULL;
6310+ char *name = profile->exec_table[index - 4];
6311+ if (*name == ':') {
6312+ ns_name = name + 1;
6313+ name = ns_name + strlen(ns_name) + 1;
6314+ }
6315+ sa->name2 = name;
6316+ sa->name3 = ns_name;
6317+ new_profile =
6318+ aa_register_find(profile, ns_name, name,
6319+ !ix, complain, sa);
6320+ }
6321+ }
6322+ if (IS_ERR(new_profile))
6323+ /* all these failures must be audited - no quieting */
6324+ return ERR_PTR(aa_audit_reject(profile, sa));
6325+ return new_profile;
6326+}
6327+
6328+/**
6329+ * aa_register - register a new program
6330+ * @bprm: binprm of program being registered
6331+ *
6332+ * Try to register a new program during execve(). This should give the
6333+ * new program a valid aa_task_context if confined.
6334+ */
6335+int aa_register(struct linux_binprm *bprm)
6336+{
6337+ const char *filename;
6338+ char *buffer = NULL, *child = NULL;
6339+ struct file *filp = bprm->file;
6340+ struct aa_profile *profile, *old_profile, *new_profile = NULL;
6341+ int exec_mode, complain = 0, shift;
6342+ struct aa_audit sa;
6343+
2380c486 6344+ AA_DEBUG("%s\n", __func__);
9f87b1bd 6345+
6346+ profile = aa_get_profile(current);
6347+
6348+ shift = aa_inode_mode(filp->f_dentry->d_inode);
6349+ memset(&sa, 0, sizeof(sa));
6350+ sa.operation = "exec";
6351+ sa.gfp_mask = GFP_KERNEL;
6352+ sa.request_mask = MAY_EXEC << shift;
6353+
6354+ filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer, 0);
6355+ if (IS_ERR(filename)) {
6356+ if (profile) {
6357+ sa.info = "Failed name resolution - exec failed";
6358+ sa.error_code = PTR_ERR(filename);
6359+ aa_audit_file(profile, &sa);
6360+ return sa.error_code;
6361+ } else
6362+ return 0;
6363+ }
6364+ sa.name = filename;
6365+
6366+ exec_mode = AA_EXEC_UNSAFE << shift;
6367+
6368+repeat:
6369+ if (profile) {
6370+ complain = PROFILE_COMPLAIN(profile);
6371+
6372+ /* Confined task, determine what mode inherit, unconfined or
6373+ * mandatory to load new profile
6374+ */
6375+ exec_mode = aa_match(profile->file_rules, filename,
6376+ &sa.audit_mask);
6377+
6378+
6379+ if (exec_mode & sa.request_mask) {
6380+ int xm = exec_mode >> shift;
6381+ new_profile = aa_x_to_profile(profile, filename,
6382+ xm, &sa, &child);
6383+
6384+ if (!new_profile && (xm & AA_EXEC_INHERIT))
6385+ /* (p|c|n|)ix - don't change profile */
6386+ goto cleanup;
6387+ /* error case caught below */
6388+
6389+ } else if (sa.request_mask & AUDIT_QUIET_MASK(sa.audit_mask)) {
6390+ /* quiet failed exit */
6391+ new_profile = ERR_PTR(-EACCES);
6392+ } else if (complain) {
6393+ /* There was no entry in calling profile
6394+ * describing mode to execute image in.
6395+ * Drop into null-profile (disabling secure exec).
6396+ */
6397+ new_profile =
6398+ aa_dup_profile(profile->ns->null_complain_profile);
6399+ exec_mode |= AA_EXEC_UNSAFE << shift;
6400+ } else {
6401+ sa.denied_mask = sa.request_mask;
6402+ sa.error_code = -EACCES;
6403+ new_profile = ERR_PTR(aa_audit_file(profile, &sa));
6404+ }
6405+ } else {
6406+ /* Unconfined task, load profile if it exists */
6407+ new_profile = aa_register_find(NULL, NULL, filename, 0, 0, &sa);
6408+ if (new_profile == NULL)
6409+ goto cleanup;
6410+ }
6411+
6412+ if (IS_ERR(new_profile))
6413+ goto cleanup;
6414+
6415+ old_profile = __aa_replace_profile(current, new_profile);
6416+ if (IS_ERR(old_profile)) {
6417+ aa_put_profile(new_profile);
6418+ aa_put_profile(profile);
6419+ if (PTR_ERR(old_profile) == -ESTALE) {
6420+ profile = aa_get_profile(current);
6421+ goto repeat;
6422+ }
6423+ if (PTR_ERR(old_profile) == -EPERM) {
6424+ sa.denied_mask = sa.request_mask;
6425+ sa.info = "unable to set profile due to ptrace";
6426+ sa.task = current->parent->pid;
6427+ aa_audit_reject(profile, &sa);
6428+ }
6429+ if (PTR_ERR(old_profile) == -EAGAIN) {
6430+ sa.info = "rlimit nproc limit exceeded";
6431+ aa_audit_reject(profile, &sa);
6432+ }
6433+ new_profile = old_profile;
6434+ goto cleanup;
6435+ }
6436+ aa_put_profile(old_profile);
6437+ aa_put_profile(profile);
6438+
6439+ /* Handle confined exec.
6440+ * Can be at this point for the following reasons:
6441+ * 1. unconfined switching to confined
6442+ * 2. confined switching to different confinement
6443+ * 3. confined switching to unconfined
6444+ *
6445+ * Cases 2 and 3 are marked as requiring secure exec
6446+ * (unless policy specified "unsafe exec")
6447+ */
6448+ if (!(exec_mode & (AA_EXEC_UNSAFE << shift))) {
6449+ unsigned long bprm_flags;
6450+
6451+ bprm_flags = AA_SECURE_EXEC_NEEDED;
2380c486 6452+ bprm->security = (void *)
9f87b1bd 6453+ ((unsigned long)bprm->security | bprm_flags);
6454+ }
6455+
6456+ if (complain && new_profile &&
6457+ new_profile == new_profile->ns->null_complain_profile) {
6458+ sa.request_mask = 0;
6459+ sa.name = NULL;
6460+ sa.info = "set profile";
6461+ aa_audit_hint(new_profile, &sa);
6462+ }
6463+
6464+cleanup:
6465+ aa_put_name_buffer(child);
6466+ aa_put_name_buffer(buffer);
6467+ if (IS_ERR(new_profile))
6468+ return PTR_ERR(new_profile);
6469+ aa_put_profile(new_profile);
6470+ return 0;
6471+}
6472+
6473+/**
6474+ * aa_release - release a task context
6475+ * @task: task being released
6476+ *
6477+ * This is called after a task has exited and the parent has reaped it.
6478+ */
6479+void aa_release(struct task_struct *task)
6480+{
6481+ struct aa_task_context *cxt;
6482+ struct aa_profile *profile;
6483+ /*
6484+ * While the task context is still on a profile's task context
6485+ * list, another process could replace the profile under us,
6486+ * leaving us with a locked profile that is no longer attached
6487+ * to this task. So after locking the profile, we check that
6488+ * the profile is still attached. The profile lock is
6489+ * sufficient to prevent the replacement race so we do not lock
6490+ * the task.
6491+ *
6492+ * Use lock subtyping to avoid lockdep reporting a false irq
6493+ * possible inversion between the task_lock and profile_lock
6494+ *
6495+ * We also avoid taking the task_lock here because lock_dep
6496+ * would report another false {softirq-on-W} potential irq_lock
6497+ * inversion.
6498+ *
6499+ * If the task does not have a profile attached we are safe;
6500+ * nothing can race with us at this point.
6501+ */
6502+
6503+repeat:
6504+ profile = aa_get_profile(task);
6505+ if (profile) {
6506+ lock_profile_nested(profile, aa_lock_task_release);
6507+ cxt = aa_task_context(task);
6508+ if (unlikely(!cxt || cxt->profile != profile)) {
6509+ unlock_profile(profile);
6510+ aa_put_profile(profile);
6511+ goto repeat;
6512+ }
6513+ aa_change_task_context(task, NULL, NULL, 0, NULL);
6514+ unlock_profile(profile);
6515+ aa_put_profile(profile);
6516+ }
6517+}
6518+
6519+static int do_change_profile(struct aa_profile *expected,
6520+ struct aa_namespace *ns, const char *name,
6521+ u64 cookie, int restore, int hat,
6522+ struct aa_audit *sa)
6523+{
6524+ struct aa_profile *new_profile = NULL, *old_profile = NULL,
6525+ *previous_profile = NULL;
6526+ struct aa_task_context *new_cxt, *cxt;
6527+ int error = 0;
6528+
6529+ sa->name = name;
6530+
6531+ new_cxt = aa_alloc_task_context(GFP_KERNEL);
6532+ if (!new_cxt)
6533+ return -ENOMEM;
6534+
6535+ new_profile = aa_find_profile(ns, name);
6536+ if (!new_profile && !restore) {
6537+ if (!PROFILE_COMPLAIN(expected)) {
6538+ aa_free_task_context(new_cxt);
6539+ return -ENOENT;
6540+ }
6541+ new_profile = aa_dup_profile(ns->null_complain_profile);
6542+ } else if (new_profile && hat && !PROFILE_IS_HAT(new_profile)) {
6543+ aa_free_task_context(new_cxt);
6544+ aa_put_profile(new_profile);
6545+ return error;
6546+ }
6547+
6548+ cxt = lock_task_and_profiles(current, new_profile);
6549+ if (!cxt) {
6550+ error = -EPERM;
6551+ goto out;
6552+ }
6553+ old_profile = cxt->profile;
6554+
6555+ if (cxt->profile != expected || (new_profile && new_profile->isstale)) {
6556+ error = -ESTALE;
6557+ goto out;
6558+ }
6559+
6560+ if (cxt->previous_profile) {
6561+ if (cxt->cookie != cookie) {
6562+ error = -EACCES;
6563+ sa->info = "killing process";
6564+ aa_audit_reject(cxt->profile, sa);
6565+ /* terminate process */
6566+ (void)send_sig_info(SIGKILL, NULL, current);
6567+ goto out;
6568+ }
6569+
6570+ if (!restore)
6571+ previous_profile = cxt->previous_profile;
6572+ } else
6573+ previous_profile = cxt->profile;
6574+
6575+ if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, new_profile)) {
6576+ error = -EACCES;
6577+ goto out;
6578+ }
6579+
6580+ if ((error = aa_rlimit_nproc(new_profile))) {
6581+ sa->info = "rlimit nproc limit exceeded";
6582+ aa_audit_reject(cxt->profile, sa);
6583+ goto out;
6584+ }
6585+
6586+ if (new_profile == ns->null_complain_profile)
6587+ aa_audit_hint(cxt->profile, sa);
6588+
6589+ if (APPARMOR_AUDIT(cxt))
6590+ aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT);
6591+
6592+ if (!restore && cookie)
6593+ aa_change_task_context(current, new_cxt, new_profile, cookie,
6594+ previous_profile);
6595+ else
6596+ /* either return to previous_profile, or a permanent change */
6597+ aa_change_task_context(current, new_cxt, new_profile, 0, NULL);
6598+
6599+out:
6600+ if (aa_task_context(current) != new_cxt)
6601+ aa_free_task_context(new_cxt);
6602+ task_unlock(current);
6603+ unlock_both_profiles(old_profile, new_profile);
6604+ aa_put_profile(new_profile);
6605+ return error;
6606+}
6607+
6608+/**
6609+ * aa_change_profile - perform a one-way profile transition
6610+ * @ns_name: name of the profile namespace to change to
6611+ * @name: name of profile to change to
6612+ * Change to new profile @name. Unlike with hats, there is no way
6613+ * to change back.
6614+ *
6615+ * Returns %0 on success, error otherwise.
6616+ */
6617+int aa_change_profile(const char *ns_name, const char *name)
6618+{
6619+ struct aa_task_context *cxt;
6620+ struct aa_profile *profile = NULL;
6621+ struct aa_namespace *ns = NULL;
6622+ struct aa_audit sa;
6623+ unsigned int state;
6624+ int error = -EINVAL;
6625+
6626+ if (!name)
6627+ return -EINVAL;
6628+
6629+ memset(&sa, 0, sizeof(sa));
6630+ sa.gfp_mask = GFP_ATOMIC;
6631+ sa.operation = "change_profile";
6632+
6633+repeat:
6634+ task_lock(current);
6635+ cxt = aa_task_context(current);
6636+ if (cxt)
6637+ profile = aa_dup_profile(cxt->profile);
6638+ task_unlock(current);
6639+
6640+ if (ns_name)
6641+ ns = aa_find_namespace(ns_name);
6642+ else if (profile)
6643+ ns = aa_get_namespace(profile->ns);
6644+ else
6645+ ns = aa_get_namespace(default_namespace);
6646+
6647+ if (!ns) {
6648+ aa_put_profile(profile);
6649+ return -ENOENT;
6650+ }
6651+
6652+ if (!profile || PROFILE_COMPLAIN(profile) ||
6653+ (ns == profile->ns &&
6654+ (aa_match(profile->file_rules, name, NULL) & AA_CHANGE_PROFILE)))
6655+ error = do_change_profile(profile, ns, name, 0, 0, 0, &sa);
6656+ else {
6657+ /* check for a rule with a namespace prepended */
6658+ aa_match_state(profile->file_rules, DFA_START, ns->name,
6659+ &state);
6660+ state = aa_dfa_null_transition(profile->file_rules, state);
6661+ if ((aa_match_state(profile->file_rules, state, name, NULL) &
6662+ AA_CHANGE_PROFILE))
6663+ error = do_change_profile(profile, ns, name, 0, 0, 0,
6664+ &sa);
6665+ else
6666+ /* no permission to transition to profile @name */
6667+ error = -EACCES;
6668+ }
6669+
6670+ aa_put_namespace(ns);
6671+ aa_put_profile(profile);
6672+ if (error == -ESTALE)
6673+ goto repeat;
6674+
6675+ return error;
6676+}
6677+
6678+/**
6679+ * aa_change_hat - change hat to/from subprofile
6680+ * @hat_name: hat to change to
6681+ * @cookie: magic value to validate the hat change
6682+ *
6683+ * Change to new @hat_name, and store the @hat_magic in the current task
6684+ * context. If the new @hat_name is %NULL and the @cookie matches that
6685+ * stored in the current task context and is not 0, return to the top level
6686+ * profile.
6687+ * Returns %0 on success, error otherwise.
6688+ */
6689+int aa_change_hat(const char *hat_name, u64 cookie)
6690+{
6691+ struct aa_task_context *cxt;
6692+ struct aa_profile *profile, *previous_profile;
6693+ struct aa_audit sa;
6694+ int error = 0;
6695+
6696+ memset(&sa, 0, sizeof(sa));
6697+ sa.gfp_mask = GFP_ATOMIC;
6698+ sa.operation = "change_hat";
6699+
6700+repeat:
6701+ task_lock(current);
6702+ cxt = aa_task_context(current);
6703+ if (!cxt) {
6704+ task_unlock(current);
6705+ return -EPERM;
6706+ }
6707+ profile = aa_dup_profile(cxt->profile);
6708+ previous_profile = aa_dup_profile(cxt->previous_profile);
6709+ task_unlock(current);
6710+
6711+ if (hat_name) {
6712+ char *name, *profile_name;
6713+
6714+ if (previous_profile)
6715+ profile_name = previous_profile->name;
6716+ else
6717+ profile_name = profile->name;
6718+
6719+ name = new_compound_name(profile_name, hat_name);
6720+ if (!name) {
6721+ error = -ENOMEM;
6722+ goto out;
6723+ }
6724+ error = do_change_profile(profile, profile->ns, name, cookie,
6725+ 0, 1, &sa);
6726+ aa_put_name_buffer(name);
6727+ } else if (previous_profile)
6728+ error = do_change_profile(profile, profile->ns,
6729+ previous_profile->name, cookie, 1, 0,
6730+ &sa);
6731+ /* else ignore restores when there is no saved profile */
6732+
6733+out:
6734+ aa_put_profile(previous_profile);
6735+ aa_put_profile(profile);
6736+ if (error == -ESTALE)
6737+ goto repeat;
6738+
6739+ return error;
6740+}
6741+
6742+/**
6743+ * __aa_replace_profile - replace a task's profile
6744+ * @task: task to switch the profile of
6745+ * @profile: profile to switch to
6746+ *
6747+ * Returns a handle to the previous profile upon success, or else an
6748+ * error code.
6749+ */
6750+struct aa_profile *__aa_replace_profile(struct task_struct *task,
6751+ struct aa_profile *profile)
6752+{
6753+ struct aa_task_context *cxt, *new_cxt = NULL;
6754+ struct aa_profile *old_profile = NULL;
6755+
6756+ if (profile) {
6757+ new_cxt = aa_alloc_task_context(GFP_KERNEL);
6758+ if (!new_cxt)
6759+ return ERR_PTR(-ENOMEM);
6760+ }
6761+
6762+ cxt = lock_task_and_profiles(task, profile);
6763+ if (unlikely(profile && profile->isstale)) {
6764+ old_profile = ERR_PTR(-ESTALE);
6765+ goto error;
6766+ }
6767+
6768+ if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) {
6769+ old_profile = ERR_PTR(-EPERM);
6770+ goto error;
6771+ }
6772+
6773+ if (aa_rlimit_nproc(profile)) {
6774+ old_profile = ERR_PTR(-EAGAIN);
6775+ goto error;
6776+ }
6777+
6778+ if (cxt)
6779+ old_profile = aa_dup_profile(cxt->profile);
6780+ aa_change_task_context(task, new_cxt, profile, 0, NULL);
6781+
6782+ task_unlock(task);
6783+ aa_set_rlimits(task, profile);
6784+ unlock_both_profiles(profile, old_profile);
6785+ return old_profile;
6786+
6787+error:
6788+ task_unlock(task);
6789+ unlock_both_profiles(profile, cxt ? cxt->profile : NULL);
6790+ aa_free_task_context(new_cxt);
6791+ return old_profile;
6792+}
6793+
6794+/**
6795+ * lock_task_and_profiles - lock the task and confining profiles and @profile
6796+ * @task: task to lock
6797+ * @profile: extra profile to lock in addition to the current profile
6798+ *
6799+ * Handle the spinning on locking to make sure the task context and
6800+ * profile are consistent once all locks are aquired.
6801+ *
6802+ * return the aa_task_context currently confining the task. The task lock
6803+ * will be held whether or not the task is confined.
6804+ */
6805+struct aa_task_context *
6806+lock_task_and_profiles(struct task_struct *task, struct aa_profile *profile)
6807+{
6808+ struct aa_task_context *cxt;
6809+ struct aa_profile *old_profile = NULL;
6810+
6811+ rcu_read_lock();
6812+repeat:
6813+ cxt = aa_task_context(task);
6814+ if (cxt)
6815+ old_profile = cxt->profile;
6816+
6817+ lock_both_profiles(profile, old_profile);
6818+ task_lock(task);
6819+
6820+ /* check for race with profile transition, replacement or removal */
6821+ if (unlikely(cxt != aa_task_context(task))) {
6822+ task_unlock(task);
6823+ unlock_both_profiles(profile, old_profile);
6824+ old_profile = NULL;
6825+ goto repeat;
6826+ }
6827+ rcu_read_unlock();
6828+ return cxt;
6829+}
6830+
6831+static void free_aa_task_context_rcu_callback(struct rcu_head *head)
6832+{
6833+ struct aa_task_context *cxt;
6834+
6835+ cxt = container_of(head, struct aa_task_context, rcu);
6836+ aa_free_task_context(cxt);
6837+}
6838+
6839+/**
6840+ * aa_change_task_context - switch a task to use a new context and profile
6841+ * @task: task that is having its task context changed
6842+ * @new_cxt: new task context to use after the switch
6843+ * @profile: new profile to use after the switch
6844+ * @cookie: magic value to switch to
6845+ * @previous_profile: profile the task can return to
6846+ */
6847+void aa_change_task_context(struct task_struct *task,
6848+ struct aa_task_context *new_cxt,
6849+ struct aa_profile *profile, u64 cookie,
6850+ struct aa_profile *previous_profile)
6851+{
6852+ struct aa_task_context *old_cxt = aa_task_context(task);
6853+
6854+ if (old_cxt) {
6855+ list_del_init(&old_cxt->list);
6856+ old_cxt->profile->task_count--;
6857+ call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback);
6858+ }
6859+ if (new_cxt) {
6860+ /* set the caps_logged cache to the quiet_caps mask
6861+ * this has the effect of quieting caps that are not
6862+ * supposed to be logged
6863+ */
6864+ new_cxt->caps_logged = profile->quiet_caps;
6865+ new_cxt->cookie = cookie;
6866+ new_cxt->task = task;
6867+ new_cxt->profile = aa_dup_profile(profile);
6868+ profile->task_count++;
6869+ new_cxt->previous_profile = aa_dup_profile(previous_profile);
6870+ list_move(&new_cxt->list, &profile->task_contexts);
6871+ }
6872+ rcu_assign_pointer(task->security, new_cxt);
6873+}
2380c486
JR
6874diff -uprN a/security/apparmor/match.c b/security/apparmor/match.c
6875--- a/security/apparmor/match.c 1970-01-01 00:00:00.000000000 +0000
6876+++ b/security/apparmor/match.c 2009-02-08 13:26:38.949289615 +0000
6877@@ -0,0 +1,363 @@
9f87b1bd 6878+/*
6879+ * Copyright (C) 2007 Novell/SUSE
6880+ *
6881+ * This program is free software; you can redistribute it and/or
6882+ * modify it under the terms of the GNU General Public License as
6883+ * published by the Free Software Foundation, version 2 of the
6884+ * License.
6885+ *
6886+ * Regular expression transition table matching
6887+ */
6888+
6889+#include <linux/kernel.h>
6890+#include <linux/slab.h>
6891+#include <linux/errno.h>
6892+#include "apparmor.h"
6893+#include "match.h"
6894+#include "inline.h"
6895+
6896+static struct table_header *unpack_table(void *blob, size_t bsize)
6897+{
6898+ struct table_header *table = NULL;
6899+ struct table_header th;
6900+ size_t tsize;
6901+
6902+ if (bsize < sizeof(struct table_header))
6903+ goto out;
6904+
6905+ th.td_id = be16_to_cpu(*(u16 *) (blob));
6906+ th.td_flags = be16_to_cpu(*(u16 *) (blob + 2));
6907+ th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8));
6908+ blob += sizeof(struct table_header);
6909+
6910+ if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
6911+ th.td_flags == YYTD_DATA8))
6912+ goto out;
6913+
6914+ tsize = table_size(th.td_lolen, th.td_flags);
6915+ if (bsize < tsize)
6916+ goto out;
6917+
6918+ table = kmalloc(tsize, GFP_KERNEL);
6919+ if (table) {
6920+ *table = th;
6921+ if (th.td_flags == YYTD_DATA8)
6922+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
6923+ u8, byte_to_byte);
6924+ else if (th.td_flags == YYTD_DATA16)
6925+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
6926+ u16, be16_to_cpu);
6927+ else
6928+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
6929+ u32, be32_to_cpu);
6930+ }
6931+
6932+out:
6933+ return table;
6934+}
6935+
6936+int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size)
6937+{
6938+ int hsize, i;
6939+ int error = -ENOMEM;
6940+
6941+ /* get dfa table set header */
6942+ if (size < sizeof(struct table_set_header))
6943+ goto fail;
6944+
6945+ if (ntohl(*(u32 *)blob) != YYTH_MAGIC)
6946+ goto fail;
6947+
6948+ hsize = ntohl(*(u32 *)(blob + 4));
6949+ if (size < hsize)
6950+ goto fail;
6951+
6952+ blob += hsize;
6953+ size -= hsize;
6954+
6955+ error = -EPROTO;
6956+ while (size > 0) {
6957+ struct table_header *table;
6958+ table = unpack_table(blob, size);
6959+ if (!table)
6960+ goto fail;
6961+
2380c486 6962+ switch (table->td_id) {
9f87b1bd 6963+ case YYTD_ID_ACCEPT:
6964+ case YYTD_ID_ACCEPT2:
6965+ case YYTD_ID_BASE:
6966+ dfa->tables[table->td_id - 1] = table;
6967+ if (table->td_flags != YYTD_DATA32)
6968+ goto fail;
6969+ break;
6970+ case YYTD_ID_DEF:
6971+ case YYTD_ID_NXT:
6972+ case YYTD_ID_CHK:
6973+ dfa->tables[table->td_id - 1] = table;
6974+ if (table->td_flags != YYTD_DATA16)
6975+ goto fail;
6976+ break;
6977+ case YYTD_ID_EC:
6978+ dfa->tables[table->td_id - 1] = table;
6979+ if (table->td_flags != YYTD_DATA8)
6980+ goto fail;
6981+ break;
6982+ default:
6983+ kfree(table);
6984+ goto fail;
6985+ }
6986+
6987+ blob += table_size(table->td_lolen, table->td_flags);
6988+ size -= table_size(table->td_lolen, table->td_flags);
6989+ }
6990+
6991+ return 0;
6992+
6993+fail:
6994+ for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) {
2380c486
JR
6995+ kfree(dfa->tables[i]);
6996+ dfa->tables[i] = NULL;
9f87b1bd 6997+ }
6998+ return error;
6999+}
7000+
7001+/**
7002+ * verify_dfa - verify that all the transitions and states in the dfa tables
7003+ * are in bounds.
7004+ * @dfa: dfa to test
7005+ *
7006+ * assumes dfa has gone through the verification done by unpacking
7007+ */
7008+int verify_dfa(struct aa_dfa *dfa)
7009+{
7010+ size_t i, state_count, trans_count;
7011+ int error = -EPROTO;
7012+
7013+ /* check that required tables exist */
7014+ if (!(dfa->tables[YYTD_ID_ACCEPT - 1] &&
7015+ dfa->tables[YYTD_ID_ACCEPT2 - 1] &&
7016+ dfa->tables[YYTD_ID_DEF - 1] &&
7017+ dfa->tables[YYTD_ID_BASE - 1] &&
7018+ dfa->tables[YYTD_ID_NXT - 1] &&
7019+ dfa->tables[YYTD_ID_CHK - 1]))
7020+ goto out;
7021+
7022+ /* accept.size == default.size == base.size */
7023+ state_count = dfa->tables[YYTD_ID_BASE - 1]->td_lolen;
7024+ if (!(state_count == dfa->tables[YYTD_ID_DEF - 1]->td_lolen &&
7025+ state_count == dfa->tables[YYTD_ID_ACCEPT - 1]->td_lolen &&
7026+ state_count == dfa->tables[YYTD_ID_ACCEPT2 - 1]->td_lolen))
7027+ goto out;
7028+
7029+ /* next.size == chk.size */
7030+ trans_count = dfa->tables[YYTD_ID_NXT - 1]->td_lolen;
7031+ if (trans_count != dfa->tables[YYTD_ID_CHK - 1]->td_lolen)
7032+ goto out;
7033+
7034+ /* if equivalence classes then its table size must be 256 */
7035+ if (dfa->tables[YYTD_ID_EC - 1] &&
7036+ dfa->tables[YYTD_ID_EC - 1]->td_lolen != 256)
7037+ goto out;
7038+
7039+ for (i = 0; i < state_count; i++) {
7040+ if (DEFAULT_TABLE(dfa)[i] >= state_count)
7041+ goto out;
7042+ if (BASE_TABLE(dfa)[i] >= trans_count + 256)
7043+ goto out;
7044+ }
7045+
7046+ for (i = 0; i < trans_count ; i++) {
7047+ if (NEXT_TABLE(dfa)[i] >= state_count)
7048+ goto out;
7049+ if (CHECK_TABLE(dfa)[i] >= state_count)
7050+ goto out;
7051+ }
7052+
7053+ /* verify accept permissions */
7054+ for (i = 0; i < state_count; i++) {
7055+ int mode = ACCEPT_TABLE(dfa)[i];
7056+
7057+ if (mode & ~AA_VALID_PERM_MASK)
7058+ goto out;
7059+ if (ACCEPT_TABLE2(dfa)[i] & ~AA_VALID_PERM2_MASK)
7060+ goto out;
7061+
7062+ /* if any exec modifier is set MAY_EXEC must be set */
7063+ if ((mode & AA_USER_EXEC_TYPE) && !(mode & AA_USER_EXEC))
7064+ goto out;
7065+ if ((mode & AA_OTHER_EXEC_TYPE) && !(mode & AA_OTHER_EXEC))
7066+ goto out;
7067+ }
7068+
7069+ error = 0;
7070+out:
7071+ return error;
7072+}
7073+
7074+struct aa_dfa *aa_match_alloc(void)
7075+{
7076+ return kzalloc(sizeof(struct aa_dfa), GFP_KERNEL);
7077+}
7078+
7079+void aa_match_free(struct aa_dfa *dfa)
7080+{
7081+ if (dfa) {
7082+ int i;
7083+
7084+ for (i = 0; i < ARRAY_SIZE(dfa->tables); i++)
7085+ kfree(dfa->tables[i]);
7086+ }
7087+ kfree(dfa);
7088+}
7089+
7090+/**
7091+ * aa_dfa_next_state_len - traverse @dfa to find state @str stops at
7092+ * @dfa: the dfa to match @str against
7093+ * @start: the state of the dfa to start matching in
7094+ * @str: the string of bytes to match against the dfa
7095+ * @len: length of the string of bytes to match
7096+ *
7097+ * aa_dfa_next_state will match @str against the dfa and return the state it
7098+ * finished matching in. The final state can be used to look up the accepting
7099+ * label, or as the start state of a continuing match.
7100+ *
7101+ * aa_dfa_next_state could be implement using this function by doing
7102+ * return aa_dfa_next_state_len(dfa, start, str, strlen(str));
7103+ * but that would require traversing the string twice and be slightly
7104+ * slower.
7105+ */
2380c486
JR
7106+static unsigned int aa_dfa_next_state_len(struct aa_dfa *dfa,
7107+ unsigned int start,
7108+ const char *str, int len)
9f87b1bd 7109+{
7110+ u16 *def = DEFAULT_TABLE(dfa);
7111+ u32 *base = BASE_TABLE(dfa);
7112+ u16 *next = NEXT_TABLE(dfa);
7113+ u16 *check = CHECK_TABLE(dfa);
7114+ unsigned int state = start, pos;
7115+
7116+ if (state == 0)
7117+ return 0;
7118+
7119+ /* current state is <state>, matching character *str */
7120+ if (dfa->tables[YYTD_ID_EC - 1]) {
7121+ u8 *equiv = EQUIV_TABLE(dfa);
7122+ for (; len; len--) {
7123+ pos = base[state] + equiv[(u8)*str++];
7124+ if (check[pos] == state)
7125+ state = next[pos];
7126+ else
7127+ state = def[state];
7128+ }
7129+ } else {
7130+ for (; len; len--) {
7131+ pos = base[state] + (u8)*str++;
7132+ if (check[pos] == state)
7133+ state = next[pos];
7134+ else
7135+ state = def[state];
7136+ }
7137+ }
7138+ return state;
7139+}
7140+
7141+/**
7142+ * aa_dfa_next_state - traverse @dfa to find state @str stops at
7143+ * @dfa: the dfa to match @str against
7144+ * @start: the state of the dfa to start matching in
7145+ * @str: the null terminated string of bytes to match against the dfa
7146+ *
7147+ * aa_dfa_next_state will match @str against the dfa and return the state it
7148+ * finished matching in. The final state can be used to look up the accepting
7149+ * label, or as the start state of a continuing match.
7150+ */
7151+unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start,
7152+ const char *str)
7153+{
7154+ u16 *def = DEFAULT_TABLE(dfa);
7155+ u32 *base = BASE_TABLE(dfa);
7156+ u16 *next = NEXT_TABLE(dfa);
7157+ u16 *check = CHECK_TABLE(dfa);
7158+ unsigned int state = start, pos;
7159+
7160+ if (state == 0)
7161+ return 0;
7162+
7163+ /* current state is <state>, matching character *str */
7164+ if (dfa->tables[YYTD_ID_EC - 1]) {
7165+ u8 *equiv = EQUIV_TABLE(dfa);
7166+ while (*str) {
7167+ pos = base[state] + equiv[(u8)*str++];
7168+ if (check[pos] == state)
7169+ state = next[pos];
7170+ else
7171+ state = def[state];
7172+ }
7173+ } else {
7174+ while (*str) {
7175+ pos = base[state] + (u8)*str++;
7176+ if (check[pos] == state)
7177+ state = next[pos];
7178+ else
7179+ state = def[state];
7180+ }
7181+ }
7182+ return state;
7183+}
7184+
7185+/**
7186+ * aa_dfa_null_transition - step to next state after null character
7187+ * @dfa: the dfa to match against
7188+ * @start: the state of the dfa to start matching in
7189+ *
7190+ * aa_dfa_null_transition transitions to the next state after a null
7191+ * character which is not used in standard matching and is only
7192+ * used to seperate pairs.
7193+ */
7194+unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start)
7195+{
7196+ return aa_dfa_next_state_len(dfa, start, "", 1);
7197+}
7198+
7199+/**
7200+ * aa_dfa_match - find accept perm for @str in @dfa
7201+ * @dfa: the dfa to match @str against
7202+ * @str: the string to match against the dfa
7203+ * @audit_mask: the audit_mask for the final state
7204+ *
7205+ * aa_dfa_match will match @str and return the accept perms for the
7206+ * final state.
7207+ */
7208+unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str, int *audit_mask)
7209+{
7210+ int state = aa_dfa_next_state(dfa, DFA_START, str);
7211+ if (audit_mask)
7212+ *audit_mask = dfa_audit_mask(dfa, state);
7213+ return ACCEPT_TABLE(dfa)[state];
7214+}
7215+
7216+/**
7217+ * aa_match_state - find accept perm and state for @str in @dfa
7218+ * @dfa: the dfa to match @str against
7219+ * @start: the state to start the match from
7220+ * @str: the string to match against the dfa
7221+ * @final: the state that the match finished in
7222+ *
7223+ * aa_match_state will match @str and return the accept perms, and @final
7224+ * state, the match occured in.
7225+ */
7226+unsigned int aa_match_state(struct aa_dfa *dfa, unsigned int start,
7227+ const char *str, unsigned int *final)
7228+{
7229+ unsigned int state;
7230+ if (dfa) {
7231+ state = aa_dfa_next_state(dfa, start, str);
7232+ if (final)
7233+ *final = state;
7234+ return ACCEPT_TABLE(dfa)[state];
7235+ }
7236+ if (final)
7237+ *final = 0;
7238+ return 0;
7239+}
7240+
2380c486
JR
7241diff -uprN a/security/apparmor/match.h b/security/apparmor/match.h
7242--- a/security/apparmor/match.h 1970-01-01 00:00:00.000000000 +0000
7243+++ b/security/apparmor/match.h 2009-02-08 13:26:38.945950214 +0000
9f87b1bd 7244@@ -0,0 +1,87 @@
7245+/*
7246+ * Copyright (C) 2007 Novell/SUSE
7247+ *
7248+ * This program is free software; you can redistribute it and/or
7249+ * modify it under the terms of the GNU General Public License as
7250+ * published by the Free Software Foundation, version 2 of the
7251+ * License.
7252+ *
7253+ * AppArmor submodule (match) prototypes
7254+ */
7255+
7256+#ifndef __MATCH_H
7257+#define __MATCH_H
7258+
7259+#define DFA_START 1
7260+
7261+/**
7262+ * The format used for transition tables is based on the GNU flex table
7263+ * file format (--tables-file option; see Table File Format in the flex
7264+ * info pages and the flex sources for documentation). The magic number
7265+ * used in the header is 0x1B5E783D insted of 0xF13C57B1 though, because
7266+ * the YY_ID_CHK (check) and YY_ID_DEF (default) tables are used
7267+ * slightly differently (see the apparmor-parser package).
7268+ */
7269+
7270+#define YYTH_MAGIC 0x1B5E783D
7271+
7272+struct table_set_header {
7273+ u32 th_magic; /* YYTH_MAGIC */
7274+ u32 th_hsize;
7275+ u32 th_ssize;
7276+ u16 th_flags;
7277+ char th_version[];
7278+};
7279+
7280+#define YYTD_ID_ACCEPT 1
7281+#define YYTD_ID_BASE 2
7282+#define YYTD_ID_CHK 3
7283+#define YYTD_ID_DEF 4
7284+#define YYTD_ID_EC 5
7285+#define YYTD_ID_META 6
7286+#define YYTD_ID_ACCEPT2 7
7287+#define YYTD_ID_NXT 8
7288+
7289+
7290+#define YYTD_DATA8 1
7291+#define YYTD_DATA16 2
7292+#define YYTD_DATA32 4
7293+
7294+struct table_header {
7295+ u16 td_id;
7296+ u16 td_flags;
7297+ u32 td_hilen;
7298+ u32 td_lolen;
7299+ char td_data[];
7300+};
7301+
7302+#define DEFAULT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_DEF - 1]->td_data))
7303+#define BASE_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_BASE - 1]->td_data))
7304+#define NEXT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_NXT - 1]->td_data))
7305+#define CHECK_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_CHK - 1]->td_data))
7306+#define EQUIV_TABLE(DFA) ((u8 *)((DFA)->tables[YYTD_ID_EC - 1]->td_data))
7307+#define ACCEPT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT - 1]->td_data))
2380c486 7308+#define ACCEPT_TABLE2(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT2 - 1]->td_data))
9f87b1bd 7309+
7310+struct aa_dfa {
7311+ struct table_header *tables[YYTD_ID_NXT];
7312+};
7313+
7314+#define byte_to_byte(X) (X)
7315+
7316+#define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \
7317+ do { \
7318+ typeof(LEN) __i; \
7319+ TYPE *__t = (TYPE *) TABLE; \
7320+ TYPE *__b = (TYPE *) BLOB; \
7321+ for (__i = 0; __i < LEN; __i++) { \
7322+ __t[__i] = NTOHX(__b[__i]); \
7323+ } \
7324+ } while (0)
7325+
7326+static inline size_t table_size(size_t len, size_t el_size)
7327+{
7328+ return ALIGN(sizeof(struct table_header) + len * el_size, 8);
7329+}
7330+
7331+#endif /* __MATCH_H */
2380c486
JR
7332diff -uprN a/security/apparmor/module_interface.c b/security/apparmor/module_interface.c
7333--- a/security/apparmor/module_interface.c 1970-01-01 00:00:00.000000000 +0000
7334+++ b/security/apparmor/module_interface.c 2009-02-08 13:26:38.949289615 +0000
7335@@ -0,0 +1,956 @@
9f87b1bd 7336+/*
7337+ * Copyright (C) 1998-2007 Novell/SUSE
7338+ *
7339+ * This program is free software; you can redistribute it and/or
7340+ * modify it under the terms of the GNU General Public License as
7341+ * published by the Free Software Foundation, version 2 of the
7342+ * License.
7343+ *
7344+ * AppArmor userspace policy interface
7345+ */
7346+
7347+#include <asm/unaligned.h>
7348+
7349+#include "apparmor.h"
7350+#include "inline.h"
7351+
7352+/*
7353+ * This mutex is used to synchronize profile adds, replacements, and
7354+ * removals: we only allow one of these operations at a time.
7355+ * We do not use the profile list lock here in order to avoid blocking
7356+ * exec during those operations. (Exec involves a profile list lookup
7357+ * for named-profile transitions.)
7358+ */
7359+DEFINE_MUTEX(aa_interface_lock);
7360+
7361+/*
7362+ * The AppArmor interface treats data as a type byte followed by the
7363+ * actual data. The interface has the notion of a a named entry
7364+ * which has a name (AA_NAME typecode followed by name string) followed by
7365+ * the entries typecode and data. Named types allow for optional
7366+ * elements and extensions to be added and tested for without breaking
7367+ * backwards compatability.
7368+ */
7369+
7370+enum aa_code {
7371+ AA_U8,
7372+ AA_U16,
7373+ AA_U32,
7374+ AA_U64,
7375+ AA_NAME, /* same as string except it is items name */
7376+ AA_STRING,
7377+ AA_BLOB,
7378+ AA_STRUCT,
7379+ AA_STRUCTEND,
7380+ AA_LIST,
7381+ AA_LISTEND,
7382+ AA_ARRAY,
7383+ AA_ARRAYEND,
7384+};
7385+
7386+/*
7387+ * aa_ext is the read of the buffer containing the serialized profile. The
7388+ * data is copied into a kernel buffer in apparmorfs and then handed off to
7389+ * the unpack routines.
7390+ */
7391+struct aa_ext {
7392+ void *start;
7393+ void *end;
7394+ void *pos; /* pointer to current position in the buffer */
7395+ u32 version;
7396+ char *ns_name;
7397+};
7398+
2380c486 7399+static int aa_inbounds(struct aa_ext *e, size_t size)
9f87b1bd 7400+{
7401+ return (size <= e->end - e->pos);
7402+}
7403+
7404+/**
7405+ * aa_u16_chunck - test and do bounds checking for a u16 size based chunk
7406+ * @e: serialized data read head
7407+ * @chunk: start address for chunk of data
7408+ *
7409+ * return the size of chunk found with the read head at the end of
7410+ * the chunk.
7411+ */
7412+static size_t aa_is_u16_chunk(struct aa_ext *e, char **chunk)
7413+{
7414+ void *pos = e->pos;
7415+ size_t size = 0;
7416+
7417+ if (!aa_inbounds(e, sizeof(u16)))
7418+ goto fail;
7419+ size = le16_to_cpu(get_unaligned((u16 *)e->pos));
7420+ e->pos += sizeof(u16);
7421+ if (!aa_inbounds(e, size))
7422+ goto fail;
7423+ *chunk = e->pos;
7424+ e->pos += size;
7425+ return size;
7426+
7427+fail:
7428+ e->pos = pos;
7429+ return 0;
7430+}
7431+
2380c486 7432+static int aa_is_X(struct aa_ext *e, enum aa_code code)
9f87b1bd 7433+{
7434+ if (!aa_inbounds(e, 1))
7435+ return 0;
7436+ if (*(u8 *) e->pos != code)
7437+ return 0;
7438+ e->pos++;
7439+ return 1;
7440+}
7441+
7442+/**
7443+ * aa_is_nameX - check is the next element is of type X with a name of @name
7444+ * @e: serialized data extent information
7445+ * @code: type code
7446+ * @name: name to match to the serialized element.
7447+ *
7448+ * check that the next serialized data element is of type X and has a tag
7449+ * name @name. If @name is specified then there must be a matching
7450+ * name element in the stream. If @name is NULL any name element will be
7451+ * skipped and only the typecode will be tested.
7452+ * returns 1 on success (both type code and name tests match) and the read
7453+ * head is advanced past the headers
7454+ * returns %0 if either match failes, the read head does not move
7455+ */
7456+static int aa_is_nameX(struct aa_ext *e, enum aa_code code, const char *name)
7457+{
7458+ void *pos = e->pos;
7459+ /*
7460+ * Check for presence of a tagname, and if present name size
7461+ * AA_NAME tag value is a u16.
7462+ */
7463+ if (aa_is_X(e, AA_NAME)) {
2380c486 7464+ char *tag = NULL;
9f87b1bd 7465+ size_t size = aa_is_u16_chunk(e, &tag);
7466+ /* if a name is specified it must match. otherwise skip tag */
7467+ if (name && (!size || strcmp(name, tag)))
7468+ goto fail;
7469+ } else if (name) {
7470+ /* if a name is specified and there is no name tag fail */
7471+ goto fail;
7472+ }
7473+
7474+ /* now check if type code matches */
7475+ if (aa_is_X(e, code))
7476+ return 1;
7477+
7478+fail:
7479+ e->pos = pos;
7480+ return 0;
7481+}
7482+
7483+static int aa_is_u16(struct aa_ext *e, u16 *data, const char *name)
7484+{
7485+ void *pos = e->pos;
7486+ if (aa_is_nameX(e, AA_U16, name)) {
7487+ if (!aa_inbounds(e, sizeof(u16)))
7488+ goto fail;
7489+ if (data)
7490+ *data = le16_to_cpu(get_unaligned((u16 *)e->pos));
7491+ e->pos += sizeof(u16);
7492+ return 1;
7493+ }
7494+fail:
7495+ e->pos = pos;
7496+ return 0;
7497+}
7498+
7499+static int aa_is_u32(struct aa_ext *e, u32 *data, const char *name)
7500+{
7501+ void *pos = e->pos;
7502+ if (aa_is_nameX(e, AA_U32, name)) {
7503+ if (!aa_inbounds(e, sizeof(u32)))
7504+ goto fail;
7505+ if (data)
7506+ *data = le32_to_cpu(get_unaligned((u32 *)e->pos));
7507+ e->pos += sizeof(u32);
7508+ return 1;
7509+ }
7510+fail:
7511+ e->pos = pos;
7512+ return 0;
7513+}
7514+
7515+static int aa_is_u64(struct aa_ext *e, u64 *data, const char *name)
7516+{
7517+ void *pos = e->pos;
7518+ if (aa_is_nameX(e, AA_U64, name)) {
7519+ if (!aa_inbounds(e, sizeof(u64)))
7520+ goto fail;
7521+ if (data)
7522+ *data = le64_to_cpu(get_unaligned((u64 *)e->pos));
7523+ e->pos += sizeof(u64);
7524+ return 1;
7525+ }
7526+fail:
7527+ e->pos = pos;
7528+ return 0;
7529+}
7530+
7531+static size_t aa_is_array(struct aa_ext *e, const char *name)
7532+{
7533+ void *pos = e->pos;
7534+ if (aa_is_nameX(e, AA_ARRAY, name)) {
7535+ int size;
7536+ if (!aa_inbounds(e, sizeof(u16)))
7537+ goto fail;
7538+ size = (int) le16_to_cpu(get_unaligned((u16 *)e->pos));
7539+ e->pos += sizeof(u16);
7540+ return size;
7541+ }
7542+fail:
7543+ e->pos = pos;
7544+ return 0;
7545+}
7546+
7547+static size_t aa_is_blob(struct aa_ext *e, char **blob, const char *name)
7548+{
7549+ void *pos = e->pos;
7550+ if (aa_is_nameX(e, AA_BLOB, name)) {
7551+ u32 size;
7552+ if (!aa_inbounds(e, sizeof(u32)))
7553+ goto fail;
7554+ size = le32_to_cpu(get_unaligned((u32 *)e->pos));
7555+ e->pos += sizeof(u32);
7556+ if (aa_inbounds(e, (size_t) size)) {
2380c486 7557+ *blob = e->pos;
9f87b1bd 7558+ e->pos += size;
7559+ return size;
7560+ }
7561+ }
7562+fail:
7563+ e->pos = pos;
7564+ return 0;
7565+}
7566+
7567+static int aa_is_dynstring(struct aa_ext *e, char **string, const char *name)
7568+{
7569+ char *src_str;
7570+ size_t size = 0;
7571+ void *pos = e->pos;
7572+ *string = NULL;
7573+ if (aa_is_nameX(e, AA_STRING, name) &&
7574+ (size = aa_is_u16_chunk(e, &src_str))) {
2380c486
JR
7575+ char *str = kmalloc(size, GFP_KERNEL);
7576+ if (!str)
9f87b1bd 7577+ goto fail;
7578+ memcpy(str, src_str, size);
7579+ *string = str;
7580+ }
7581+
7582+ return size;
7583+
7584+fail:
7585+ e->pos = pos;
7586+ return 0;
7587+}
7588+
7589+/**
7590+ * aa_unpack_dfa - unpack a file rule dfa
7591+ * @e: serialized data extent information
7592+ *
7593+ * returns dfa or ERR_PTR
7594+ */
7595+static struct aa_dfa *aa_unpack_dfa(struct aa_ext *e)
7596+{
7597+ char *blob = NULL;
7598+ size_t size, error = 0;
7599+ struct aa_dfa *dfa = NULL;
7600+
7601+ size = aa_is_blob(e, &blob, "aadfa");
7602+ if (size) {
7603+ dfa = aa_match_alloc();
7604+ if (dfa) {
7605+ /*
7606+ * The dfa is aligned with in the blob to 8 bytes
7607+ * from the beginning of the stream.
7608+ */
7609+ size_t sz = blob - (char *) e->start;
7610+ size_t pad = ALIGN(sz, 8) - sz;
7611+ error = unpack_dfa(dfa, blob + pad, size - pad);
7612+ if (!error)
7613+ error = verify_dfa(dfa);
7614+ } else {
7615+ error = -ENOMEM;
7616+ }
7617+
7618+ if (error) {
7619+ aa_match_free(dfa);
7620+ dfa = ERR_PTR(error);
7621+ }
7622+ }
7623+
7624+ return dfa;
7625+}
7626+
7627+static int aa_unpack_exec_table(struct aa_ext *e, struct aa_profile *profile)
7628+{
7629+ void *pos = e->pos;
7630+
7631+ /* exec table is optional */
7632+ if (aa_is_nameX(e, AA_STRUCT, "xtable")) {
7633+ int i, size;
7634+
7635+ size = aa_is_array(e, NULL);
7636+ /* currently 4 exec bits and entries 0-3 are reserved iupcx */
7637+ if (size > 16 - 4)
7638+ goto fail;
7639+ profile->exec_table = kzalloc(sizeof(char *) * size,
7640+ GFP_KERNEL);
7641+ if (!profile->exec_table)
7642+ goto fail;
7643+
7644+ for (i = 0; i < size; i++) {
7645+ char *tmp;
7646+ if (!aa_is_dynstring(e, &tmp, NULL))
7647+ goto fail;
7648+ /* note: strings beginning with a : have an embedded
7649+ \0 seperating the profile ns name from the profile
7650+ name */
7651+ profile->exec_table[i] = tmp;
7652+ }
7653+ if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
7654+ goto fail;
7655+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
7656+ goto fail;
7657+ profile->exec_table_size = size;
7658+ }
7659+ return 1;
7660+
7661+fail:
7662+ e->pos = pos;
7663+ return 0;
7664+}
7665+
7666+int aa_unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
7667+{
7668+ void *pos = e->pos;
7669+
7670+ /* rlimits are optional */
7671+ if (aa_is_nameX(e, AA_STRUCT, "rlimits")) {
7672+ int i, size;
7673+ u32 tmp = 0;
7674+ if (!aa_is_u32(e, &tmp, NULL))
7675+ goto fail;
7676+ profile->rlimits.mask = tmp;
7677+
7678+ size = aa_is_array(e, NULL);
7679+ if (size > RLIM_NLIMITS)
7680+ goto fail;
7681+ for (i = 0; i < size; i++) {
7682+ u64 tmp = 0;
7683+ if (!aa_is_u64(e, &tmp, NULL))
7684+ goto fail;
7685+ profile->rlimits.limits[i].rlim_max = tmp;
7686+ }
7687+ if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
7688+ goto fail;
7689+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
7690+ goto fail;
7691+ }
7692+ return 1;
7693+
7694+fail:
7695+ e->pos = pos;
7696+ return 0;
7697+}
7698+
7699+/**
7700+ * aa_unpack_profile - unpack a serialized profile
7701+ * @e: serialized data extent information
7702+ * @sa: audit struct for the operation
7703+ */
7704+static struct aa_profile *aa_unpack_profile(struct aa_ext *e,
7705+ struct aa_audit *sa)
7706+{
2380c486 7707+ struct aa_profile *profile;
9f87b1bd 7708+ size_t size = 0;
7709+ int i, error = -EPROTO;
7710+
7711+ profile = alloc_aa_profile();
7712+ if (!profile)
7713+ return ERR_PTR(-ENOMEM);
7714+
7715+ /* check that we have the right struct being passed */
7716+ if (!aa_is_nameX(e, AA_STRUCT, "profile"))
7717+ goto fail;
7718+ if (!aa_is_dynstring(e, &profile->name, NULL))
7719+ goto fail;
7720+
7721+ /* per profile debug flags (complain, audit) */
7722+ if (!aa_is_nameX(e, AA_STRUCT, "flags"))
7723+ goto fail;
7724+ if (!aa_is_u32(e, &(profile->flags.hat), NULL))
7725+ goto fail;
7726+ if (!aa_is_u32(e, &(profile->flags.complain), NULL))
7727+ goto fail;
7728+ if (!aa_is_u32(e, &(profile->flags.audit), NULL))
7729+ goto fail;
7730+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
7731+ goto fail;
7732+
7733+ if (!aa_is_u32(e, &(profile->capabilities.cap[0]), NULL))
7734+ goto fail;
7735+ if (!aa_is_u32(e, &(profile->audit_caps.cap[0]), NULL))
7736+ goto fail;
7737+ if (!aa_is_u32(e, &(profile->quiet_caps.cap[0]), NULL))
7738+ goto fail;
7739+ if (!aa_is_u32(e, &(profile->set_caps.cap[0]), NULL))
7740+ goto fail;
7741+
7742+ if (aa_is_nameX(e, AA_STRUCT, "caps64")) {
7743+ /* optional upper half of 64 bit caps */
7744+ if (!aa_is_u32(e, &(profile->capabilities.cap[1]), NULL))
7745+ goto fail;
7746+ if (!aa_is_u32(e, &(profile->audit_caps.cap[1]), NULL))
7747+ goto fail;
7748+ if (!aa_is_u32(e, &(profile->quiet_caps.cap[1]), NULL))
7749+ goto fail;
7750+ if (!aa_is_u32(e, &(profile->set_caps.cap[1]), NULL))
7751+ goto fail;
7752+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
7753+ goto fail;
7754+ }
7755+
7756+ if (!aa_unpack_rlimits(e, profile))
7757+ goto fail;
7758+
7759+ size = aa_is_array(e, "net_allowed_af");
7760+ if (size) {
7761+ if (size > AF_MAX)
7762+ goto fail;
7763+
7764+ for (i = 0; i < size; i++) {
7765+ if (!aa_is_u16(e, &profile->network_families[i], NULL))
7766+ goto fail;
7767+ if (!aa_is_u16(e, &profile->audit_network[i], NULL))
7768+ goto fail;
7769+ if (!aa_is_u16(e, &profile->quiet_network[i], NULL))
7770+ goto fail;
7771+ }
7772+ if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
7773+ goto fail;
7774+ /* allow unix domain and netlink sockets they are handled
7775+ * by IPC
7776+ */
7777+ }
7778+ profile->network_families[AF_UNIX] = 0xffff;
7779+ profile->network_families[AF_NETLINK] = 0xffff;
7780+
7781+ /* get file rules */
7782+ profile->file_rules = aa_unpack_dfa(e);
7783+ if (IS_ERR(profile->file_rules)) {
7784+ error = PTR_ERR(profile->file_rules);
7785+ profile->file_rules = NULL;
7786+ goto fail;
7787+ }
7788+
7789+ if (!aa_unpack_exec_table(e, profile))
7790+ goto fail;
7791+
7792+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
7793+ goto fail;
7794+
7795+ return profile;
7796+
7797+fail:
7798+ sa->name = profile && profile->name ? profile->name : "unknown";
7799+ if (!sa->info)
7800+ sa->info = "failed to unpack profile";
7801+ aa_audit_status(NULL, sa);
7802+
2380c486 7803+ free_aa_profile(profile);
9f87b1bd 7804+
7805+ return ERR_PTR(error);
7806+}
7807+
7808+/**
7809+ * aa_verify_head - unpack serialized stream header
7810+ * @e: serialized data read head
7811+ * @operation: operation header is being verified for
7812+ *
7813+ * returns error or 0 if header is good
7814+ */
7815+static int aa_verify_header(struct aa_ext *e, struct aa_audit *sa)
7816+{
7817+ /* get the interface version */
7818+ if (!aa_is_u32(e, &e->version, "version")) {
7819+ sa->info = "invalid profile format";
7820+ aa_audit_status(NULL, sa);
7821+ return -EPROTONOSUPPORT;
7822+ }
7823+
7824+ /* check that the interface version is currently supported */
7825+ if (e->version != 5) {
7826+ sa->info = "unsupported interface version";
7827+ aa_audit_status(NULL, sa);
7828+ return -EPROTONOSUPPORT;
7829+ }
7830+
7831+ /* read the namespace if present */
2380c486 7832+ if (!aa_is_dynstring(e, &e->ns_name, "namespace"))
9f87b1bd 7833+ e->ns_name = NULL;
9f87b1bd 7834+
7835+ return 0;
7836+}
7837+
7838+/**
7839+ * aa_add_profile - Unpack and add a new profile to the profile list
7840+ * @data: serialized data stream
7841+ * @size: size of the serialized data stream
7842+ */
7843+ssize_t aa_add_profile(void *data, size_t size)
7844+{
2380c486 7845+ struct aa_profile *profile;
9f87b1bd 7846+ struct aa_namespace *ns = NULL;
7847+ struct aa_ext e = {
7848+ .start = data,
7849+ .end = data + size,
7850+ .pos = data,
7851+ .ns_name = NULL
7852+ };
7853+ ssize_t error;
7854+ struct aa_audit sa;
7855+ memset(&sa, 0, sizeof(sa));
7856+ sa.operation = "profile_load";
7857+ sa.gfp_mask = GFP_KERNEL;
7858+
7859+ error = aa_verify_header(&e, &sa);
7860+ if (error)
7861+ return error;
7862+
7863+ profile = aa_unpack_profile(&e, &sa);
7864+ if (IS_ERR(profile))
7865+ return PTR_ERR(profile);
7866+
7867+ mutex_lock(&aa_interface_lock);
7868+ write_lock(&profile_ns_list_lock);
7869+ if (e.ns_name)
7870+ ns = __aa_find_namespace(e.ns_name, &profile_ns_list);
7871+ else
7872+ ns = default_namespace;
7873+ if (!ns) {
7874+ struct aa_namespace *new_ns;
7875+ write_unlock(&profile_ns_list_lock);
7876+ new_ns = alloc_aa_namespace(e.ns_name);
7877+ if (!new_ns) {
7878+ mutex_unlock(&aa_interface_lock);
7879+ return -ENOMEM;
7880+ }
7881+ write_lock(&profile_ns_list_lock);
7882+ ns = __aa_find_namespace(e.ns_name, &profile_ns_list);
7883+ if (!ns) {
7884+ list_add(&new_ns->list, &profile_ns_list);
7885+ ns = new_ns;
7886+ } else
7887+ free_aa_namespace(new_ns);
7888+ }
7889+
7890+ write_lock(&ns->lock);
7891+ if (__aa_find_profile(profile->name, &ns->profiles)) {
7892+ /* A profile with this name exists already. */
7893+ write_unlock(&ns->lock);
7894+ write_unlock(&profile_ns_list_lock);
7895+ sa.name = profile->name;
7896+ sa.name2 = ns->name;
7897+ sa.info = "failed: profile already loaded";
7898+ aa_audit_status(NULL, &sa);
7899+ mutex_unlock(&aa_interface_lock);
7900+ aa_put_profile(profile);
7901+ return -EEXIST;
7902+ }
7903+ profile->ns = aa_get_namespace(ns);
7904+ ns->profile_count++;
7905+ list_add(&profile->list, &ns->profiles);
7906+ write_unlock(&ns->lock);
7907+ write_unlock(&profile_ns_list_lock);
7908+
7909+ sa.name = profile->name;
7910+ sa.name2 = ns->name;
7911+ aa_audit_status(NULL, &sa);
7912+ mutex_unlock(&aa_interface_lock);
7913+ return size;
7914+}
7915+
7916+/**
7917+ * task_replace - replace a task's profile
7918+ * @task: task to replace profile on
7919+ * @new_cxt: new aa_task_context to do replacement with
7920+ * @new_profile: new profile
7921+ */
2380c486 7922+static void task_replace(struct task_struct *task,
9f87b1bd 7923+ struct aa_task_context *new_cxt,
7924+ struct aa_profile *new_profile)
7925+{
7926+ struct aa_task_context *cxt = aa_task_context(task);
7927+
2380c486
JR
7928+ AA_DEBUG("%s: replacing profile for task %d profile=%s (%p)\n",
7929+ __func__, cxt->task->pid, cxt->profile->name, cxt->profile);
9f87b1bd 7930+
7931+ aa_change_task_context(task, new_cxt, new_profile, cxt->cookie,
7932+ cxt->previous_profile);
7933+}
7934+
7935+/**
7936+ * aa_replace_profile - replace a profile on the profile list
7937+ * @udata: serialized data stream
7938+ * @size: size of the serialized data stream
7939+ *
7940+ * unpack and replace a profile on the profile list and uses of that profile
7941+ * by any aa_task_context. If the profile does not exist on the profile list
7942+ * it is added. Return %0 or error.
7943+ */
7944+ssize_t aa_replace_profile(void *udata, size_t size)
7945+{
7946+ struct aa_profile *old_profile, *new_profile;
7947+ struct aa_namespace *ns;
7948+ struct aa_task_context *new_cxt;
7949+ struct aa_ext e = {
7950+ .start = udata,
7951+ .end = udata + size,
7952+ .pos = udata,
7953+ .ns_name = NULL
7954+ };
7955+ ssize_t error;
7956+ struct aa_audit sa;
7957+ memset(&sa, 0, sizeof(sa));
7958+ sa.operation = "profile_replace";
7959+ sa.gfp_mask = GFP_KERNEL;
7960+
7961+ error = aa_verify_header(&e, &sa);
7962+ if (error)
7963+ return error;
7964+
7965+ new_profile = aa_unpack_profile(&e, &sa);
7966+ if (IS_ERR(new_profile))
7967+ return PTR_ERR(new_profile);
7968+
7969+ mutex_lock(&aa_interface_lock);
7970+ write_lock(&profile_ns_list_lock);
7971+ if (e.ns_name)
7972+ ns = __aa_find_namespace(e.ns_name, &profile_ns_list);
7973+ else
7974+ ns = default_namespace;
7975+ if (!ns) {
7976+ struct aa_namespace *new_ns;
7977+ write_unlock(&profile_ns_list_lock);
7978+ new_ns = alloc_aa_namespace(e.ns_name);
7979+ if (!new_ns) {
7980+ mutex_unlock(&aa_interface_lock);
7981+ return -ENOMEM;
7982+ }
7983+ write_lock(&profile_ns_list_lock);
7984+ ns = __aa_find_namespace(e.ns_name, &profile_ns_list);
7985+ if (!ns) {
7986+ list_add(&new_ns->list, &profile_ns_list);
7987+ ns = new_ns;
7988+ } else
7989+ free_aa_namespace(new_ns);
7990+ }
7991+
7992+ write_lock(&ns->lock);
7993+ old_profile = __aa_find_profile(new_profile->name, &ns->profiles);
7994+ if (old_profile) {
7995+ lock_profile(old_profile);
7996+ old_profile->isstale = 1;
7997+ list_del_init(&old_profile->list);
7998+ unlock_profile(old_profile);
7999+ ns->profile_count--;
8000+ }
8001+ new_profile->ns = aa_get_namespace(ns);
8002+ ns->profile_count++;
8003+ /* not don't need an extra ref count to keep new_profile as
8004+ * it is protect by the interface mutex */
8005+ list_add(&new_profile->list, &ns->profiles);
8006+ write_unlock(&ns->lock);
8007+ write_unlock(&profile_ns_list_lock);
8008+
8009+ if (!old_profile) {
8010+ sa.operation = "profile_load";
8011+ goto out;
8012+ }
8013+ /* do not fail replacement based off of profile's NPROC rlimit */
8014+
8015+ /*
8016+ * Replacement needs to allocate a new aa_task_context for each
8017+ * task confined by old_profile. To do this the profile locks
8018+ * are only held when the actual switch is done per task. While
8019+ * looping to allocate a new aa_task_context the old_task list
8020+ * may get shorter if tasks exit/change their profile but will
8021+ * not get longer as new task will not use old_profile detecting
8022+ * that is stale.
8023+ */
8024+ do {
8025+ new_cxt = aa_alloc_task_context(GFP_KERNEL | __GFP_NOFAIL);
8026+
8027+ lock_both_profiles(old_profile, new_profile);
8028+ if (!list_empty(&old_profile->task_contexts)) {
8029+ struct task_struct *task =
8030+ list_entry(old_profile->task_contexts.next,
8031+ struct aa_task_context, list)->task;
8032+ task_lock(task);
8033+ task_replace(task, new_cxt, new_profile);
8034+ task_unlock(task);
8035+ aa_set_rlimits(task, new_profile);
8036+ new_cxt = NULL;
8037+ }
8038+ unlock_both_profiles(old_profile, new_profile);
8039+ } while (!new_cxt);
8040+ aa_free_task_context(new_cxt);
8041+ aa_put_profile(old_profile);
8042+
8043+out:
8044+ sa.name = new_profile->name;
8045+ sa.name2 = ns->name;
8046+ aa_audit_status(NULL, &sa);
8047+ mutex_unlock(&aa_interface_lock);
8048+ return size;
8049+}
8050+
8051+/**
8052+ * aa_remove_profile - remove a profile from the system
8053+ * @name: name of the profile to remove
8054+ * @size: size of the name
8055+ *
8056+ * remove a profile from the profile list and all aa_task_context references
8057+ * to said profile.
8058+ * NOTE: removing confinement does not restore rlimits to preconfinemnet values
8059+ */
8060+ssize_t aa_remove_profile(char *name, size_t size)
8061+{
8062+ struct aa_namespace *ns;
8063+ struct aa_profile *profile;
8064+ struct aa_audit sa;
8065+ memset(&sa, 0, sizeof(sa));
8066+ sa.operation = "profile_remove";
8067+ sa.gfp_mask = GFP_KERNEL;
8068+
8069+ mutex_lock(&aa_interface_lock);
8070+ write_lock(&profile_ns_list_lock);
8071+
8072+ if (name[0] == ':') {
8073+ char *split = strchr(name + 1, ':');
8074+ if (!split)
8075+ goto noent;
8076+ *split = 0;
8077+ ns = __aa_find_namespace(name + 1, &profile_ns_list);
8078+ name = split + 1;
8079+ } else {
8080+ ns = default_namespace;
8081+ }
8082+
8083+ if (!ns)
8084+ goto noent;
8085+ sa.name2 = ns->name;
8086+ write_lock(&ns->lock);
8087+ profile = __aa_find_profile(name, &ns->profiles);
8088+ if (!profile) {
8089+ write_unlock(&ns->lock);
8090+ goto noent;
8091+ }
8092+ sa.name = profile->name;
8093+
8094+ /* Remove the profile from each task context it is on. */
8095+ lock_profile(profile);
8096+ profile->isstale = 1;
8097+ aa_unconfine_tasks(profile);
8098+ list_del_init(&profile->list);
8099+ ns->profile_count--;
8100+ unlock_profile(profile);
8101+ /* Release the profile itself. */
8102+ write_unlock(&ns->lock);
8103+ /* check to see if the namespace has become stale */
8104+ if (ns != default_namespace && ns->profile_count == 0) {
8105+ list_del_init(&ns->list);
8106+ aa_put_namespace(ns);
8107+ }
8108+ write_unlock(&profile_ns_list_lock);
8109+
8110+ aa_audit_status(NULL, &sa);
8111+ mutex_unlock(&aa_interface_lock);
8112+ aa_put_profile(profile);
8113+
8114+ return size;
8115+
8116+noent:
8117+ write_unlock(&profile_ns_list_lock);
8118+ sa.info = "failed: profile does not exist";
8119+ aa_audit_status(NULL, &sa);
8120+ mutex_unlock(&aa_interface_lock);
8121+ return -ENOENT;
8122+}
8123+
8124+/**
8125+ * free_aa_namespace_kref - free aa_namespace by kref (see aa_put_namespace)
8126+ * @kr: kref callback for freeing of a namespace
8127+ */
8128+void free_aa_namespace_kref(struct kref *kref)
8129+{
2380c486 8130+ free_aa_namespace(container_of(kref, struct aa_namespace, count));
9f87b1bd 8131+}
8132+
8133+/**
8134+ * alloc_aa_namespace - allocate, initialize and return a new namespace
8135+ * @name: a preallocated name
8136+ * Returns NULL on failure.
8137+ */
8138+struct aa_namespace *alloc_aa_namespace(char *name)
8139+{
8140+ struct aa_namespace *ns;
8141+
8142+ ns = kzalloc(sizeof(*ns), GFP_KERNEL);
2380c486 8143+ AA_DEBUG("%s(%p)\n", __func__, ns);
9f87b1bd 8144+ if (ns) {
8145+ ns->name = name;
8146+ INIT_LIST_HEAD(&ns->list);
8147+ INIT_LIST_HEAD(&ns->profiles);
8148+ kref_init(&ns->count);
8149+ rwlock_init(&ns->lock);
8150+
8151+ ns->null_complain_profile = alloc_aa_profile();
8152+ if (!ns->null_complain_profile) {
8153+ if (!name)
8154+ kfree(ns->name);
8155+ kfree(ns);
8156+ return NULL;
8157+ }
8158+ ns->null_complain_profile->name =
8159+ kstrdup("null-complain-profile", GFP_KERNEL);
8160+ if (!ns->null_complain_profile->name) {
8161+ free_aa_profile(ns->null_complain_profile);
8162+ if (!name)
8163+ kfree(ns->name);
8164+ kfree(ns);
8165+ return NULL;
8166+ }
8167+ ns->null_complain_profile->flags.complain = 1;
8168+ /* null_complain_profile doesn't contribute to ns ref count */
8169+ ns->null_complain_profile->ns = ns;
8170+ }
8171+ return ns;
8172+}
8173+
8174+/**
8175+ * free_aa_namespace - free a profile namespace
8176+ * @namespace: the namespace to free
8177+ *
8178+ * Free a namespace. All references to the namespace must have been put.
8179+ * If the namespace was referenced by a profile confining a task,
8180+ * free_aa_namespace will be called indirectly (through free_aa_profile)
8181+ * from an rcu callback routine, so we must not sleep here.
8182+ */
8183+void free_aa_namespace(struct aa_namespace *ns)
8184+{
2380c486 8185+ AA_DEBUG("%s(%p)\n", __func__, ns);
9f87b1bd 8186+
8187+ if (!ns)
8188+ return;
8189+
8190+ /* namespace still contains profiles -- invalid */
8191+ if (!list_empty(&ns->profiles)) {
8192+ AA_ERROR("%s: internal error, "
8193+ "namespace '%s' still contains profiles\n",
2380c486 8194+ __func__, ns->name);
9f87b1bd 8195+ BUG();
8196+ }
8197+ if (!list_empty(&ns->list)) {
2380c486
JR
8198+ AA_ERROR("%s: internal error, namespace '%s' still on list\n",
8199+ __func__, ns->name);
9f87b1bd 8200+ BUG();
8201+ }
8202+ /* null_complain_profile doesn't contribute to ns ref counting */
8203+ ns->null_complain_profile->ns = NULL;
8204+ aa_put_profile(ns->null_complain_profile);
8205+ kfree(ns->name);
8206+ kfree(ns);
8207+}
8208+
8209+/**
8210+ * free_aa_profile_kref - free aa_profile by kref (called by aa_put_profile)
8211+ * @kr: kref callback for freeing of a profile
8212+ */
8213+void free_aa_profile_kref(struct kref *kref)
8214+{
2380c486 8215+ struct aa_profile *p = container_of(kref, struct aa_profile, count);
9f87b1bd 8216+
8217+ free_aa_profile(p);
8218+}
8219+
8220+/**
8221+ * alloc_aa_profile - allocate, initialize and return a new profile
8222+ * Returns NULL on failure.
8223+ */
8224+struct aa_profile *alloc_aa_profile(void)
8225+{
8226+ struct aa_profile *profile;
8227+
8228+ profile = kzalloc(sizeof(*profile), GFP_KERNEL);
2380c486 8229+ AA_DEBUG("%s(%p)\n", __func__, profile);
9f87b1bd 8230+ if (profile) {
8231+ INIT_LIST_HEAD(&profile->list);
8232+ kref_init(&profile->count);
8233+ INIT_LIST_HEAD(&profile->task_contexts);
8234+ spin_lock_init(&profile->lock);
8235+ }
8236+ return profile;
8237+}
8238+
8239+/**
8240+ * free_aa_profile - free a profile
8241+ * @profile: the profile to free
8242+ *
8243+ * Free a profile, its hats and null_profile. All references to the profile,
8244+ * its hats and null_profile must have been put.
8245+ *
8246+ * If the profile was referenced from a task context, free_aa_profile() will
8247+ * be called from an rcu callback routine, so we must not sleep here.
8248+ */
8249+void free_aa_profile(struct aa_profile *profile)
8250+{
2380c486 8251+ AA_DEBUG("%s(%p)\n", __func__, profile);
9f87b1bd 8252+
8253+ if (!profile)
8254+ return;
8255+
8256+ /* profile is still on profile namespace list -- invalid */
8257+ if (!list_empty(&profile->list)) {
8258+ AA_ERROR("%s: internal error, "
8259+ "profile '%s' still on global list\n",
2380c486 8260+ __func__, profile->name);
9f87b1bd 8261+ BUG();
8262+ }
8263+ aa_put_namespace(profile->ns);
8264+
8265+ aa_match_free(profile->file_rules);
8266+
8267+ if (profile->name) {
2380c486 8268+ AA_DEBUG("%s: %s\n", __func__, profile->name);
9f87b1bd 8269+ kfree(profile->name);
8270+ }
8271+
8272+ kfree(profile);
8273+}
8274+
8275+/**
8276+ * aa_unconfine_tasks - remove tasks on a profile's task context list
8277+ * @profile: profile to remove tasks from
8278+ *
8279+ * Assumes that @profile lock is held.
8280+ */
8281+void aa_unconfine_tasks(struct aa_profile *profile)
8282+{
8283+ while (!list_empty(&profile->task_contexts)) {
8284+ struct task_struct *task =
8285+ list_entry(profile->task_contexts.next,
8286+ struct aa_task_context, list)->task;
8287+ task_lock(task);
8288+ aa_change_task_context(task, NULL, NULL, 0, NULL);
8289+ task_unlock(task);
8290+ }
8291+}
2380c486
JR
8292diff -uprN a/security/apparmor/procattr.c b/security/apparmor/procattr.c
8293--- a/security/apparmor/procattr.c 1970-01-01 00:00:00.000000000 +0000
8294+++ b/security/apparmor/procattr.c 2009-02-08 13:26:38.945950214 +0000
8295@@ -0,0 +1,194 @@
9f87b1bd 8296+/*
8297+ * Copyright (C) 1998-2007 Novell/SUSE
8298+ *
8299+ * This program is free software; you can redistribute it and/or
8300+ * modify it under the terms of the GNU General Public License as
8301+ * published by the Free Software Foundation, version 2 of the
8302+ * License.
8303+ *
8304+ * AppArmor /proc/pid/attr handling
8305+ */
8306+
8307+#include "apparmor.h"
8308+#include "inline.h"
8309+
8310+int aa_getprocattr(struct aa_profile *profile, char **string, unsigned *len)
8311+{
8312+ char *str;
8313+
8314+ if (profile) {
8315+ const char *mode_str = PROFILE_COMPLAIN(profile) ?
8316+ " (complain)" : " (enforce)";
8317+ int mode_len, name_len, ns_len = 0;
8318+
8319+ mode_len = strlen(mode_str);
8320+ name_len = strlen(profile->name);
8321+ if (profile->ns != default_namespace)
8322+ ns_len = strlen(profile->ns->name) + 2;
8323+ *len = mode_len + ns_len + name_len + 1;
8324+ str = kmalloc(*len, GFP_ATOMIC);
8325+ if (!str)
8326+ return -ENOMEM;
8327+
8328+ if (ns_len) {
8329+ *str++ = ':';
8330+ memcpy(str, profile->ns->name, ns_len - 2);
8331+ str += ns_len - 2;
8332+ *str++ = ':';
8333+ }
8334+ memcpy(str, profile->name, name_len);
8335+ str += name_len;
8336+ memcpy(str, mode_str, mode_len);
8337+ str += mode_len;
8338+ *str++ = '\n';
8339+ str -= *len;
8340+ } else {
8341+ const char *unconfined_str = "unconfined\n";
8342+
8343+ *len = strlen(unconfined_str);
8344+ str = kmalloc(*len, GFP_ATOMIC);
8345+ if (!str)
8346+ return -ENOMEM;
8347+
8348+ memcpy(str, unconfined_str, *len);
8349+ }
8350+ *string = str;
8351+
8352+ return 0;
8353+}
8354+
8355+static char *split_token_from_name(const char *op, char *args, u64 *cookie)
8356+{
8357+ char *name;
8358+
8359+ *cookie = simple_strtoull(args, &name, 16);
8360+ if ((name == args) || *name != '^') {
8361+ AA_ERROR("%s: Invalid input '%s'", op, args);
8362+ return ERR_PTR(-EINVAL);
8363+ }
8364+
8365+ name++; /* skip ^ */
8366+ if (!*name)
8367+ name = NULL;
8368+ return name;
8369+}
8370+
8371+int aa_setprocattr_changehat(char *args)
8372+{
8373+ char *hat;
8374+ u64 cookie;
8375+
8376+ hat = split_token_from_name("change_hat", args, &cookie);
8377+ if (IS_ERR(hat))
8378+ return PTR_ERR(hat);
8379+
8380+ if (!hat && !cookie) {
8381+ AA_ERROR("change_hat: Invalid input, NULL hat and NULL magic");
8382+ return -EINVAL;
8383+ }
8384+
8385+ AA_DEBUG("%s: Magic 0x%llx Hat '%s'\n",
2380c486 8386+ __func__, cookie, hat ? hat : NULL);
9f87b1bd 8387+
8388+ return aa_change_hat(hat, cookie);
8389+}
8390+
8391+int aa_setprocattr_changeprofile(char *args)
8392+{
8393+ char *name = args, *ns_name = NULL;
8394+
8395+ if (name[0] == ':') {
8396+ char *split = strchr(&name[1], ':');
8397+ if (split) {
8398+ *split = 0;
8399+ ns_name = &name[1];
8400+ name = split + 1;
8401+ }
8402+ }
8403+
8404+ return aa_change_profile(ns_name, name);
8405+}
8406+
8407+int aa_setprocattr_setprofile(struct task_struct *task, char *args)
8408+{
8409+ struct aa_profile *old_profile, *new_profile;
8410+ struct aa_namespace *ns;
8411+ struct aa_audit sa;
8412+ char *name, *ns_name = NULL;
8413+
8414+ memset(&sa, 0, sizeof(sa));
8415+ sa.operation = "profile_set";
8416+ sa.gfp_mask = GFP_KERNEL;
8417+ sa.task = task->pid;
8418+
2380c486 8419+ AA_DEBUG("%s: current %d\n", __func__, current->pid);
9f87b1bd 8420+
8421+ name = args;
8422+ if (args[0] != '/') {
8423+ char *split = strchr(args, ':');
8424+ if (split) {
8425+ *split = 0;
8426+ ns_name = args;
8427+ name = split + 1;
8428+ }
8429+ }
8430+ if (ns_name)
8431+ ns = aa_find_namespace(ns_name);
8432+ else
8433+ ns = aa_get_namespace(default_namespace);
8434+ if (!ns) {
8435+ sa.name = ns_name;
8436+ sa.info = "unknown namespace";
8437+ aa_audit_reject(NULL, &sa);
8438+ aa_put_namespace(ns);
8439+ return -EINVAL;
8440+ }
8441+
8442+repeat:
8443+ if (strcmp(name, "unconfined") == 0)
8444+ new_profile = NULL;
8445+ else {
8446+ new_profile = aa_find_profile(ns, name);
8447+ if (!new_profile) {
8448+ sa.name = ns_name;
8449+ sa.name2 = name;
8450+ sa.info = "unknown profile";
8451+ aa_audit_reject(NULL, &sa);
8452+ aa_put_namespace(ns);
8453+ return -EINVAL;
8454+ }
8455+ }
8456+
8457+ old_profile = __aa_replace_profile(task, new_profile);
8458+ if (IS_ERR(old_profile)) {
8459+ int error;
8460+
8461+ aa_put_profile(new_profile);
8462+ error = PTR_ERR(old_profile);
8463+ if (error == -ESTALE)
8464+ goto repeat;
8465+ aa_put_namespace(ns);
8466+ return error;
8467+ }
8468+
8469+ if (new_profile) {
8470+ sa.name = ns_name;
8471+ sa.name2 = name;
8472+ sa.name3 = old_profile ? old_profile->name :
8473+ "unconfined";
8474+ aa_audit_status(NULL, &sa);
8475+ } else {
8476+ if (old_profile) {
8477+ sa.name = "unconfined";
8478+ sa.name2 = old_profile->name;
8479+ aa_audit_status(NULL, &sa);
8480+ } else {
8481+ sa.info = "task is unconfined";
8482+ aa_audit_status(NULL, &sa);
8483+ }
8484+ }
8485+ aa_put_namespace(ns);
8486+ aa_put_profile(old_profile);
8487+ aa_put_profile(new_profile);
8488+ return 0;
8489+}
2380c486
JR
8490diff -uprN a/security/capability.c b/security/capability.c
8491--- a/security/capability.c 2008-12-24 23:26:37.000000000 +0000
8492+++ b/security/capability.c 2009-02-08 13:26:38.902622774 +0000
9f87b1bd 8493@@ -155,52 +155,56 @@ static int cap_inode_init_security(struc
8494 }
8495
8496 static int cap_inode_create(struct inode *inode, struct dentry *dentry,
8497- int mask)
8498+ struct vfsmount *mnt, int mask)
8499 {
8500 return 0;
8501 }
8502
8503-static int cap_inode_link(struct dentry *old_dentry, struct inode *inode,
8504- struct dentry *new_dentry)
8505+static int cap_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt,
8506+ struct inode *inode,
8507+ struct dentry *new_dentry, struct vfsmount *new_mnt)
8508 {
8509 return 0;
8510 }
8511
8512-static int cap_inode_unlink(struct inode *inode, struct dentry *dentry)
8513+static int cap_inode_unlink(struct inode *inode, struct dentry *dentry,
8514+ struct vfsmount *mnt)
8515 {
8516 return 0;
8517 }
8518
8519 static int cap_inode_symlink(struct inode *inode, struct dentry *dentry,
8520- const char *name)
8521+ struct vfsmount *mnt, const char *name)
8522 {
8523 return 0;
8524 }
8525
8526 static int cap_inode_mkdir(struct inode *inode, struct dentry *dentry,
8527- int mask)
8528+ struct vfsmount *mnt, int mask)
8529 {
8530 return 0;
8531 }
8532
8533-static int cap_inode_rmdir(struct inode *inode, struct dentry *dentry)
8534+static int cap_inode_rmdir(struct inode *inode, struct dentry *dentry,
8535+ struct vfsmount *mnt)
8536 {
8537 return 0;
8538 }
8539
8540 static int cap_inode_mknod(struct inode *inode, struct dentry *dentry,
8541- int mode, dev_t dev)
8542+ struct vfsmount *mnt, int mode, dev_t dev)
8543 {
8544 return 0;
8545 }
8546
8547 static int cap_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
8548- struct inode *new_inode, struct dentry *new_dentry)
8549+ struct vfsmount *old_mnt, struct inode *new_inode,
8550+ struct dentry *new_dentry, struct vfsmount *new_mnt)
8551 {
8552 return 0;
8553 }
8554
8555-static int cap_inode_readlink(struct dentry *dentry)
8556+static int cap_inode_readlink(struct dentry *dentry, struct vfsmount *mnt)
8557 {
8558 return 0;
8559 }
8560@@ -216,7 +220,8 @@ static int cap_inode_permission(struct i
8561 return 0;
8562 }
8563
8564-static int cap_inode_setattr(struct dentry *dentry, struct iattr *iattr)
8565+static int cap_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
8566+ struct iattr *iattr)
8567 {
8568 return 0;
8569 }
8570@@ -230,17 +235,20 @@ static void cap_inode_delete(struct inod
8571 {
8572 }
8573
8574-static void cap_inode_post_setxattr(struct dentry *dentry, const char *name,
8575+static void cap_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt,
8576+ const char *name,
8577 const void *value, size_t size, int flags)
8578 {
8579 }
8580
8581-static int cap_inode_getxattr(struct dentry *dentry, const char *name)
8582+static int cap_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
8583+ const char *name, struct file *f)
8584 {
8585 return 0;
8586 }
8587
8588-static int cap_inode_listxattr(struct dentry *dentry)
8589+static int cap_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt,
8590+ struct file *f)
8591 {
8592 return 0;
8593 }
8594@@ -335,6 +343,11 @@ static int cap_dentry_open(struct file *
8595 return 0;
8596 }
8597
8598+static int cap_path_permission(struct path *path, int mask)
8599+{
8600+ return security_inode_permission(path->dentry->d_inode, mask);
8601+}
8602+
8603 static int cap_task_create(unsigned long clone_flags)
8604 {
8605 return 0;
8606@@ -889,6 +902,7 @@ void security_fixup_ops(struct security_
8607 set_to_cap_if_null(ops, file_send_sigiotask);
8608 set_to_cap_if_null(ops, file_receive);
8609 set_to_cap_if_null(ops, dentry_open);
8610+ set_to_cap_if_null(ops, path_permission);
8611 set_to_cap_if_null(ops, task_create);
8612 set_to_cap_if_null(ops, task_alloc_security);
8613 set_to_cap_if_null(ops, task_free_security);
2380c486
JR
8614diff -uprN a/security/commoncap.c b/security/commoncap.c
8615--- a/security/commoncap.c 2008-12-24 23:26:37.000000000 +0000
8616+++ b/security/commoncap.c 2009-02-08 13:26:38.895950162 +0000
9f87b1bd 8617@@ -411,8 +411,9 @@ int cap_bprm_secureexec (struct linux_bi
8618 current->egid != current->gid);
8619 }
8620
8621-int cap_inode_setxattr(struct dentry *dentry, const char *name,
8622- const void *value, size_t size, int flags)
8623+int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
8624+ const char *name, const void *value, size_t size,
8625+ int flags, struct file *file)
8626 {
8627 if (!strcmp(name, XATTR_NAME_CAPS)) {
8628 if (!capable(CAP_SETFCAP))
8629@@ -425,7 +426,8 @@ int cap_inode_setxattr(struct dentry *de
8630 return 0;
8631 }
8632
8633-int cap_inode_removexattr(struct dentry *dentry, const char *name)
8634+int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt,
8635+ const char *name, struct file *file)
8636 {
8637 if (!strcmp(name, XATTR_NAME_CAPS)) {
8638 if (!capable(CAP_SETFCAP))
2380c486
JR
8639diff -uprN a/security/security.c b/security/security.c
8640--- a/security/security.c 2008-12-24 23:26:37.000000000 +0000
8641+++ b/security/security.c 2009-02-08 13:26:38.932616900 +0000
8642@@ -18,7 +18,7 @@
8643 #include <linux/security.h>
8644
8645 /* Boot-time LSM user choice */
8646-static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1];
8647+static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = CONFIG_SECURITY_DEFAULT;
8648
8649 /* things that live in capability.c */
8650 extern struct security_operations default_security_ops;
8651@@ -367,72 +367,81 @@ int security_inode_init_security(struct
9f87b1bd 8652 }
8653 EXPORT_SYMBOL(security_inode_init_security);
8654
8655-int security_inode_create(struct inode *dir, struct dentry *dentry, int mode)
8656+int security_inode_create(struct inode *dir, struct dentry *dentry,
8657+ struct vfsmount *mnt, int mode)
8658 {
8659 if (unlikely(IS_PRIVATE(dir)))
8660 return 0;
8661- return security_ops->inode_create(dir, dentry, mode);
8662+ return security_ops->inode_create(dir, dentry, mnt, mode);
8663 }
8664
8665-int security_inode_link(struct dentry *old_dentry, struct inode *dir,
8666- struct dentry *new_dentry)
8667+int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt,
8668+ struct inode *dir, struct dentry *new_dentry,
8669+ struct vfsmount *new_mnt)
8670 {
8671 if (unlikely(IS_PRIVATE(old_dentry->d_inode)))
8672 return 0;
8673- return security_ops->inode_link(old_dentry, dir, new_dentry);
8674+ return security_ops->inode_link(old_dentry, old_mnt, dir,
8675+ new_dentry, new_mnt);
8676 }
8677
8678-int security_inode_unlink(struct inode *dir, struct dentry *dentry)
8679+int security_inode_unlink(struct inode *dir, struct dentry *dentry,
8680+ struct vfsmount *mnt)
8681 {
8682 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8683 return 0;
8684- return security_ops->inode_unlink(dir, dentry);
8685+ return security_ops->inode_unlink(dir, dentry, mnt);
8686 }
8687
8688 int security_inode_symlink(struct inode *dir, struct dentry *dentry,
8689- const char *old_name)
8690+ struct vfsmount *mnt, const char *old_name)
8691 {
8692 if (unlikely(IS_PRIVATE(dir)))
8693 return 0;
8694- return security_ops->inode_symlink(dir, dentry, old_name);
8695+ return security_ops->inode_symlink(dir, dentry, mnt, old_name);
8696 }
8697
8698-int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode)
8699+int security_inode_mkdir(struct inode *dir, struct dentry *dentry,
8700+ struct vfsmount *mnt, int mode)
8701 {
8702 if (unlikely(IS_PRIVATE(dir)))
8703 return 0;
8704- return security_ops->inode_mkdir(dir, dentry, mode);
8705+ return security_ops->inode_mkdir(dir, dentry, mnt, mode);
8706 }
8707
8708-int security_inode_rmdir(struct inode *dir, struct dentry *dentry)
8709+int security_inode_rmdir(struct inode *dir, struct dentry *dentry,
8710+ struct vfsmount *mnt)
8711 {
8712 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8713 return 0;
8714- return security_ops->inode_rmdir(dir, dentry);
8715+ return security_ops->inode_rmdir(dir, dentry, mnt);
8716 }
8717
8718-int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
8719+int security_inode_mknod(struct inode *dir, struct dentry *dentry,
8720+ struct vfsmount *mnt, int mode, dev_t dev)
8721 {
8722 if (unlikely(IS_PRIVATE(dir)))
8723 return 0;
8724- return security_ops->inode_mknod(dir, dentry, mode, dev);
8725+ return security_ops->inode_mknod(dir, dentry, mnt, mode, dev);
8726 }
8727+EXPORT_SYMBOL_GPL(security_inode_permission);
8728
8729 int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
8730- struct inode *new_dir, struct dentry *new_dentry)
8731+ struct vfsmount *old_mnt, struct inode *new_dir,
8732+ struct dentry *new_dentry, struct vfsmount *new_mnt)
8733 {
8734 if (unlikely(IS_PRIVATE(old_dentry->d_inode) ||
8735 (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode))))
8736 return 0;
8737- return security_ops->inode_rename(old_dir, old_dentry,
8738- new_dir, new_dentry);
8739+ return security_ops->inode_rename(old_dir, old_dentry, old_mnt,
8740+ new_dir, new_dentry, new_mnt);
8741 }
8742
8743-int security_inode_readlink(struct dentry *dentry)
8744+int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt)
8745 {
8746 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8747 return 0;
8748- return security_ops->inode_readlink(dentry);
8749+ return security_ops->inode_readlink(dentry, mnt);
8750 }
8751
8752 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
2380c486 8753@@ -449,11 +458,12 @@ int security_inode_permission(struct ino
9f87b1bd 8754 return security_ops->inode_permission(inode, mask);
8755 }
8756
8757-int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
8758+int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
8759+ struct iattr *attr)
8760 {
8761 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8762 return 0;
8763- return security_ops->inode_setattr(dentry, attr);
8764+ return security_ops->inode_setattr(dentry, mnt, attr);
8765 }
8766 EXPORT_SYMBOL_GPL(security_inode_setattr);
8767
2380c486 8768@@ -471,41 +481,48 @@ void security_inode_delete(struct inode
9f87b1bd 8769 security_ops->inode_delete(inode);
8770 }
8771
8772-int security_inode_setxattr(struct dentry *dentry, const char *name,
8773- const void *value, size_t size, int flags)
8774+int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
8775+ const char *name, const void *value, size_t size,
8776+ int flags, struct file *file)
8777 {
8778 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8779 return 0;
8780- return security_ops->inode_setxattr(dentry, name, value, size, flags);
8781+ return security_ops->inode_setxattr(dentry, mnt, name, value, size,
8782+ flags, file);
8783 }
8784
8785-void security_inode_post_setxattr(struct dentry *dentry, const char *name,
8786- const void *value, size_t size, int flags)
8787+void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt,
8788+ const char *name, const void *value,
8789+ size_t size, int flags)
8790 {
8791 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8792 return;
8793- security_ops->inode_post_setxattr(dentry, name, value, size, flags);
8794+ security_ops->inode_post_setxattr(dentry, mnt, name, value, size,
8795+ flags);
8796 }
8797
8798-int security_inode_getxattr(struct dentry *dentry, const char *name)
8799+int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
8800+ const char *name, struct file *file)
8801 {
8802 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8803 return 0;
8804- return security_ops->inode_getxattr(dentry, name);
8805+ return security_ops->inode_getxattr(dentry, mnt, name, file);
8806 }
8807
8808-int security_inode_listxattr(struct dentry *dentry)
8809+int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt,
8810+ struct file *file)
8811 {
8812 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8813 return 0;
8814- return security_ops->inode_listxattr(dentry);
8815+ return security_ops->inode_listxattr(dentry, mnt, file);
8816 }
8817
8818-int security_inode_removexattr(struct dentry *dentry, const char *name)
8819+int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt,
8820+ const char *name, struct file *file)
8821 {
8822 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8823 return 0;
8824- return security_ops->inode_removexattr(dentry, name);
8825+ return security_ops->inode_removexattr(dentry, mnt, name, file);
8826 }
8827
8828 int security_inode_need_killpriv(struct dentry *dentry)
2380c486 8829@@ -608,6 +625,15 @@ int security_dentry_open(struct file *fi
9f87b1bd 8830 return security_ops->dentry_open(file);
8831 }
8832
8833+int security_path_permission(struct path *path, int mask)
8834+{
8835+ struct inode *inode = path->dentry->d_inode;
8836+ if (unlikely(IS_PRIVATE(inode)))
8837+ return 0;
8838+
8839+ return security_ops->path_permission(path, mask);
8840+}
8841+
8842 int security_task_create(unsigned long clone_flags)
8843 {
8844 return security_ops->task_create(clone_flags);
2380c486
JR
8845diff -uprN a/security/selinux/hooks.c b/security/selinux/hooks.c
8846--- a/security/selinux/hooks.c 2008-12-24 23:26:37.000000000 +0000
8847+++ b/security/selinux/hooks.c 2009-02-08 13:26:38.902622774 +0000
8848@@ -1814,40 +1814,16 @@ static int selinux_capable(struct task_s
9f87b1bd 8849
8850 static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid)
8851 {
8852- int buflen, rc;
8853- char *buffer, *path, *end;
8854+ char *buffer, *path;
8855+ int rc = -ENOMEM;
8856
8857- rc = -ENOMEM;
8858 buffer = (char *)__get_free_page(GFP_KERNEL);
8859 if (!buffer)
8860 goto out;
8861
8862- buflen = PAGE_SIZE;
8863- end = buffer+buflen;
8864- *--end = '\0';
8865- buflen--;
8866- path = end-1;
8867- *path = '/';
8868- while (table) {
8869- const char *name = table->procname;
8870- size_t namelen = strlen(name);
8871- buflen -= namelen + 1;
8872- if (buflen < 0)
8873- goto out_free;
8874- end -= namelen;
8875- memcpy(end, name, namelen);
8876- *--end = '/';
8877- path = end;
8878- table = table->parent;
8879- }
8880- buflen -= 4;
8881- if (buflen < 0)
8882- goto out_free;
8883- end -= 4;
8884- memcpy(end, "/sys", 4);
8885- path = end;
8886- rc = security_genfs_sid("proc", path, tclass, sid);
8887-out_free:
8888+ path = sysctl_pathname(table, buffer, PAGE_SIZE);
8889+ if (path)
8890+ rc = security_genfs_sid("proc", path, tclass, sid);
8891 free_page((unsigned long)buffer);
8892 out:
8893 return rc;
2380c486 8894@@ -2564,64 +2540,79 @@ static int selinux_inode_init_security(s
9f87b1bd 8895 return 0;
8896 }
8897
8898-static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
8899+static int selinux_inode_create(struct inode *dir, struct dentry *dentry,
8900+ struct vfsmount *mnt, int mask)
8901 {
8902 return may_create(dir, dentry, SECCLASS_FILE);
8903 }
8904
8905-static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
8906+static int selinux_inode_link(struct dentry *old_dentry,
8907+ struct vfsmount *old_mnt,
8908+ struct inode *dir,
8909+ struct dentry *new_dentry,
8910+ struct vfsmount *new_mnt)
8911 {
8912 int rc;
8913
8914- rc = secondary_ops->inode_link(old_dentry, dir, new_dentry);
8915+ rc = secondary_ops->inode_link(old_dentry, old_mnt, dir, new_dentry,
8916+ new_mnt);
8917 if (rc)
8918 return rc;
8919 return may_link(dir, old_dentry, MAY_LINK);
8920 }
8921
8922-static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
8923+static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry,
8924+ struct vfsmount *mnt)
8925 {
8926 int rc;
8927
8928- rc = secondary_ops->inode_unlink(dir, dentry);
8929+ rc = secondary_ops->inode_unlink(dir, dentry, mnt);
8930 if (rc)
8931 return rc;
8932 return may_link(dir, dentry, MAY_UNLINK);
8933 }
8934
8935-static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name)
8936+static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry,
8937+ struct vfsmount *mnt, const char *name)
8938 {
8939 return may_create(dir, dentry, SECCLASS_LNK_FILE);
8940 }
8941
8942-static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask)
8943+static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry,
8944+ struct vfsmount *mnt, int mask)
8945 {
8946 return may_create(dir, dentry, SECCLASS_DIR);
8947 }
8948
8949-static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
8950+static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry,
8951+ struct vfsmount *mnt)
8952 {
8953 return may_link(dir, dentry, MAY_RMDIR);
8954 }
8955
8956-static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
8957+static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry,
8958+ struct vfsmount *mnt, int mode, dev_t dev)
8959 {
8960 int rc;
8961
8962- rc = secondary_ops->inode_mknod(dir, dentry, mode, dev);
8963+ rc = secondary_ops->inode_mknod(dir, dentry, mnt, mode, dev);
8964 if (rc)
8965 return rc;
8966
8967 return may_create(dir, dentry, inode_mode_to_security_class(mode));
8968 }
8969
8970-static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
8971- struct inode *new_inode, struct dentry *new_dentry)
8972+static int selinux_inode_rename(struct inode *old_inode,
8973+ struct dentry *old_dentry,
8974+ struct vfsmount *old_mnt,
8975+ struct inode *new_inode,
8976+ struct dentry *new_dentry,
8977+ struct vfsmount *new_mnt)
8978 {
8979 return may_rename(old_inode, old_dentry, new_inode, new_dentry);
8980 }
8981
8982-static int selinux_inode_readlink(struct dentry *dentry)
8983+static int selinux_inode_readlink(struct dentry *dentry, struct vfsmount *mnt)
8984 {
8985 return dentry_has_perm(current, NULL, dentry, FILE__READ);
8986 }
2380c486 8987@@ -2653,11 +2644,12 @@ static int selinux_inode_permission(stru
9f87b1bd 8988 open_file_mask_to_av(inode->i_mode, mask), NULL);
8989 }
8990
8991-static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
8992+static int selinux_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
8993+ struct iattr *iattr)
8994 {
8995 int rc;
8996
8997- rc = secondary_ops->inode_setattr(dentry, iattr);
8998+ rc = secondary_ops->inode_setattr(dentry, mnt, iattr);
8999 if (rc)
9000 return rc;
9001
2380c486 9002@@ -2695,8 +2687,9 @@ static int selinux_inode_setotherxattr(s
9f87b1bd 9003 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
9004 }
9005
9006-static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
9007- const void *value, size_t size, int flags)
9008+static int selinux_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
9009+ const char *name, const void *value,
9010+ size_t size, int flags, struct file *file)
9011 {
9012 struct task_security_struct *tsec = current->security;
9013 struct inode *inode = dentry->d_inode;
2380c486 9014@@ -2750,7 +2743,8 @@ static int selinux_inode_setxattr(struct
9f87b1bd 9015 &ad);
9016 }
9017
9018-static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
9019+static void selinux_inode_post_setxattr(struct dentry *dentry,
9020+ struct vfsmount *mnt, const char *name,
9021 const void *value, size_t size,
9022 int flags)
9023 {
2380c486 9024@@ -2776,17 +2770,21 @@ static void selinux_inode_post_setxattr(
9f87b1bd 9025 return;
9026 }
9027
9028-static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
9029+static int selinux_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
9030+ const char *name, struct file *file)
9031 {
9032 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
9033 }
9034
9035-static int selinux_inode_listxattr(struct dentry *dentry)
9036+static int selinux_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt,
9037+ struct file *file)
9038 {
9039 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
9040 }
9041
9042-static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
9043+static int selinux_inode_removexattr(struct dentry *dentry,
9044+ struct vfsmount *mnt, const char *name,
9045+ struct file *file)
9046 {
9047 if (strcmp(name, XATTR_NAME_SELINUX))
9048 return selinux_inode_setotherxattr(dentry, name);
2380c486
JR
9049diff -uprN a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
9050--- a/security/smack/smack_lsm.c 2008-12-24 23:26:37.000000000 +0000
9051+++ b/security/smack/smack_lsm.c 2009-02-08 13:26:38.899283105 +0000
9f87b1bd 9052@@ -432,8 +432,9 @@ static int smack_inode_init_security(str
9053 *
9054 * Returns 0 if access is permitted, an error code otherwise
9055 */
9056-static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
9057- struct dentry *new_dentry)
9058+static int smack_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt,
9059+ struct inode *dir,
9060+ struct dentry *new_dentry, struct vfsmount *new_mnt)
9061 {
9062 int rc;
9063 char *isp;
9064@@ -453,11 +454,13 @@ static int smack_inode_link(struct dentr
9065 * smack_inode_unlink - Smack check on inode deletion
9066 * @dir: containing directory object
9067 * @dentry: file to unlink
9068+ * @mnt: vfsmount of file to unlink
9069 *
9070 * Returns 0 if current can write the containing directory
9071 * and the object, error code otherwise
9072 */
9073-static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
9074+static int smack_inode_unlink(struct inode *dir, struct dentry *dentry,
9075+ struct vfsmount *mnt)
9076 {
9077 struct inode *ip = dentry->d_inode;
9078 int rc;
9079@@ -479,11 +482,13 @@ static int smack_inode_unlink(struct ino
9080 * smack_inode_rmdir - Smack check on directory deletion
9081 * @dir: containing directory object
9082 * @dentry: directory to unlink
9083+ * @mnt: vfsmount @dentry to unlink
9084 *
9085 * Returns 0 if current can write the containing directory
9086 * and the directory, error code otherwise
9087 */
9088-static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
9089+static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry,
9090+ struct vfsmount *mnt)
9091 {
9092 int rc;
9093
9094@@ -504,8 +509,10 @@ static int smack_inode_rmdir(struct inod
9095 * smack_inode_rename - Smack check on rename
9096 * @old_inode: the old directory
9097 * @old_dentry: unused
9098+ * @old_mnt: unused
9099 * @new_inode: the new directory
9100 * @new_dentry: unused
9101+ * @new_mnt: unused
9102 *
9103 * Read and write access is required on both the old and
9104 * new directories.
9105@@ -514,8 +521,10 @@ static int smack_inode_rmdir(struct inod
9106 */
9107 static int smack_inode_rename(struct inode *old_inode,
9108 struct dentry *old_dentry,
9109+ struct vfsmount *old_mnt,
9110 struct inode *new_inode,
9111- struct dentry *new_dentry)
9112+ struct dentry *new_dentry,
9113+ struct vfsmount *new_mnt)
9114 {
9115 int rc;
9116 char *isp;
9117@@ -559,7 +568,8 @@ static int smack_inode_permission(struct
9118 *
9119 * Returns 0 if access is permitted, an error code otherwise
9120 */
9121-static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
9122+static int smack_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
9123+ struct iattr *iattr)
9124 {
9125 /*
9126 * Need to allow for clearing the setuid bit.
9127@@ -585,17 +595,20 @@ static int smack_inode_getattr(struct vf
9128 /**
9129 * smack_inode_setxattr - Smack check for setting xattrs
9130 * @dentry: the object
9131+ * @mnt: unused
9132 * @name: name of the attribute
9133 * @value: unused
9134 * @size: unused
9135 * @flags: unused
9136+ * @file: unused
9137 *
9138 * This protects the Smack attribute explicitly.
9139 *
9140 * Returns 0 if access is permitted, an error code otherwise
9141 */
9142-static int smack_inode_setxattr(struct dentry *dentry, const char *name,
9143- const void *value, size_t size, int flags)
9144+static int smack_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
9145+ const char *name, const void *value,
9146+ size_t size, int flags, struct file *file)
9147 {
9148 int rc = 0;
9149
9150@@ -605,7 +618,8 @@ static int smack_inode_setxattr(struct d
9151 if (!capable(CAP_MAC_ADMIN))
9152 rc = -EPERM;
9153 } else
9154- rc = cap_inode_setxattr(dentry, name, value, size, flags);
9155+ rc = cap_inode_setxattr(dentry, mnt, name, value, size, flags,
9156+ file);
9157
9158 if (rc == 0)
9159 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
9160@@ -616,6 +630,7 @@ static int smack_inode_setxattr(struct d
9161 /**
9162 * smack_inode_post_setxattr - Apply the Smack update approved above
9163 * @dentry: object
9164+ * @mnt: unused
9165 * @name: attribute name
9166 * @value: attribute value
9167 * @size: attribute size
9168@@ -624,7 +639,8 @@ static int smack_inode_setxattr(struct d
9169 * Set the pointer in the inode blob to the entry found
9170 * in the master label list.
9171 */
9172-static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
9173+static void smack_inode_post_setxattr(struct dentry *dentry,
9174+ struct vfsmount *mnt, const char *name,
9175 const void *value, size_t size, int flags)
9176 {
9177 struct inode_smack *isp;
9178@@ -657,11 +673,14 @@ static void smack_inode_post_setxattr(st
9179 /*
9180 * smack_inode_getxattr - Smack check on getxattr
9181 * @dentry: the object
9182+ * @mnt: unused
9183 * @name: unused
9184+ * @file: unused
9185 *
9186 * Returns 0 if access is permitted, an error code otherwise
9187 */
9188-static int smack_inode_getxattr(struct dentry *dentry, const char *name)
9189+static int smack_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
9190+ const char *name, struct file *file)
9191 {
9192 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ);
9193 }
9194@@ -669,13 +688,16 @@ static int smack_inode_getxattr(struct d
9195 /*
9196 * smack_inode_removexattr - Smack check on removexattr
9197 * @dentry: the object
9198+ * @mnt: unused
9199 * @name: name of the attribute
9200+ * @file: unused
9201 *
9202 * Removing the Smack attribute requires CAP_MAC_ADMIN
9203 *
9204 * Returns 0 if access is permitted, an error code otherwise
9205 */
9206-static int smack_inode_removexattr(struct dentry *dentry, const char *name)
9207+static int smack_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt,
9208+ const char *name, struct file *file)
9209 {
9210 int rc = 0;
9211
9212@@ -685,7 +707,7 @@ static int smack_inode_removexattr(struc
9213 if (!capable(CAP_MAC_ADMIN))
9214 rc = -EPERM;
9215 } else
9216- rc = cap_inode_removexattr(dentry, name);
9217+ rc = cap_inode_removexattr(dentry, mnt, name, file);
9218
9219 if (rc == 0)
9220 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
2380c486
JR
9221---
9222 security/apparmor/main.c | 2 +-
9223 1 file changed, 1 insertion(+), 1 deletion(-)
9224
9225--- a/security/apparmor/main.c
9226+++ b/security/apparmor/main.c
9227@@ -503,10 +503,10 @@ static char *aa_get_name(struct dentry *
9228 *buffer = buf;
9229 return name;
9230 }
9231+ kfree(buf);
9232 if (PTR_ERR(name) != -ENAMETOOLONG)
9233 return name;
9234
9235- kfree(buf);
9236 size <<= 1;
9237 if (size > apparmor_path_max)
9238 return ERR_PTR(-ENAMETOOLONG);
This page took 1.189426 seconds and 4 git commands to generate.