1 diff -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
5 .readdir = afs_readdir,
7 .llseek = generic_file_llseek,
8 + .fsetattr = afs_fsetattr,
11 const struct inode_operations afs_dir_inode_operations = {
12 diff -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
15 @@ -36,6 +36,7 @@ const struct file_operations afs_file_op
19 + .fsetattr = afs_fsetattr,
22 const struct inode_operations afs_file_inode_operations = {
23 diff -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
26 @@ -358,7 +358,8 @@ void afs_clear_inode(struct inode *inode
28 * set the attributes of an inode
30 -int afs_setattr(struct dentry *dentry, struct iattr *attr)
31 +static int afs_do_setattr(struct dentry *dentry, struct iattr *attr,
34 struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode);
36 @@ -380,8 +381,8 @@ int afs_setattr(struct dentry *dentry, s
37 afs_writeback_all(vnode);
40 - if (attr->ia_valid & ATTR_FILE) {
41 - key = attr->ia_file->private_data;
43 + key = file->private_data;
45 key = afs_request_key(vnode->volume->cell);
47 @@ -391,10 +392,20 @@ int afs_setattr(struct dentry *dentry, s
50 ret = afs_vnode_setattr(vnode, key, attr);
51 - if (!(attr->ia_valid & ATTR_FILE))
60 +int afs_setattr(struct dentry *dentry, struct iattr *attr)
62 + return afs_do_setattr(dentry, attr, NULL);
65 +int afs_fsetattr(struct file *file, struct iattr *attr)
67 + return afs_do_setattr(file->f_path.dentry, attr, file);
69 diff -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
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 *);
80 diff -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
83 @@ -100,7 +100,8 @@ int inode_setattr(struct inode * inode,
85 EXPORT_SYMBOL(inode_setattr);
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)
91 struct inode *inode = dentry->d_inode;
92 mode_t mode = inode->i_mode;
93 @@ -159,7 +160,7 @@ int notify_change(struct dentry * dentry
94 if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID)))
97 - error = security_inode_setattr(dentry, attr);
98 + error = security_inode_setattr(dentry, mnt, attr);
102 @@ -167,7 +168,21 @@ int notify_change(struct dentry * dentry
103 down_write(&dentry->d_inode->i_alloc_sem);
105 if (inode->i_op && inode->i_op->setattr) {
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);
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. */
117 + attr->ia_valid |= ATTR_FILE;
118 + attr->ia_file = file;
120 + error = inode->i_op->setattr(dentry, attr);
123 error = inode_change_ok(inode, attr);
125 @@ -187,5 +202,12 @@ int notify_change(struct dentry * dentry
129 +EXPORT_SYMBOL_GPL(fnotify_change);
131 +int notify_change(struct dentry *dentry, struct vfsmount *mnt,
132 + struct iattr *attr)
134 + return fnotify_change(dentry, mnt, attr, NULL);
137 EXPORT_SYMBOL(notify_change);
138 diff -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
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
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.
150 - * Returns a pointer into the buffer or an error code if the
151 - * path was too long.
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.
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).
163 + * Returns the buffer or an error code if the path was too long.
165 char *__d_path(const struct path *path, struct path *root,
166 - char *buffer, int buflen)
167 + char *buffer, int buflen, int flags)
169 struct dentry *dentry = path->dentry;
170 struct vfsmount *vfsmnt = path->mnt;
171 - char *end = buffer + buflen;
173 + const unsigned char *name;
177 + prepend(&buffer, &buflen, "\0", 1);
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);
189 + if (prepend(&buffer, &buflen, " (deleted)", 10) != 0)
195 - /* Get '/' right */
200 + while (dentry != root->dentry || vfsmnt != root->mnt) {
201 struct dentry * parent;
203 - if (dentry == root->dentry && vfsmnt == root->mnt)
205 if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
207 if (vfsmnt->mnt_parent == vfsmnt) {
210 @@ -1955,27 +1957,51 @@ char *__d_path(const struct path *path,
212 parent = dentry->d_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))
222 + /* Get '/' right. */
223 + if (*buffer != '/' && prepend(&buffer, &buflen, "/", 1))
227 + spin_unlock(&dcache_lock);
228 spin_unlock(&vfsmount_lock);
233 - retval += 1; /* hit the slash */
234 - if (prepend_name(&retval, &buflen, &dentry->d_name) != 0)
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.
240 + namelen = dentry->d_name.len;
241 + name = dentry->d_name.name;
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:".
248 + if (IS_ROOT(dentry) && *buffer == '/') {
252 + if ((flags & D_PATH_DISCONNECT) && *name == '/') {
253 + /* Make sure we won't return a pathname starting with '/' */
257 + if (prepend(&buffer, &buflen, name, namelen))
260 root->dentry = dentry;
264 - retval = ERR_PTR(-ENAMETOOLONG);
265 + buffer = ERR_PTR(-ENAMETOOLONG);
269 @@ -2012,10 +2038,8 @@ char *d_path(const struct path *path, ch
270 root = current->fs->root;
272 read_unlock(¤t->fs->lock);
273 - spin_lock(&dcache_lock);
275 - res = __d_path(path, &tmp, buf, buflen);
276 - spin_unlock(&dcache_lock);
277 + res = __d_path(path, &tmp, buf, buflen, 0);
281 @@ -2098,9 +2122,9 @@ Elong:
283 SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
286 - struct path pwd, root;
287 - char *page = (char *) __get_free_page(GFP_USER);
289 + struct path pwd, root, tmp;
290 + char *page = (char *) __get_free_page(GFP_USER), *cwd;
294 @@ -2112,30 +2136,20 @@ SYSCALL_DEFINE2(getcwd, char __user *, b
296 read_unlock(¤t->fs->lock);
299 - /* Has the current directory has been unlinked? */
300 - spin_lock(&dcache_lock);
301 - if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) {
303 - struct path tmp = root;
306 - cwd = __d_path(&pwd, &tmp, page, PAGE_SIZE);
307 - spin_unlock(&dcache_lock);
310 + cwd = __d_path(&pwd, &tmp, page, PAGE_SIZE, D_PATH_FAIL_DELETED);
312 error = PTR_ERR(cwd);
319 - len = PAGE_SIZE + page - cwd;
322 - if (copy_to_user(buf, cwd, len))
326 - spin_unlock(&dcache_lock);
328 + len = PAGE_SIZE + page - cwd;
331 + if (copy_to_user(buf, cwd, len))
337 diff -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
340 @@ -403,19 +403,24 @@ static int ecryptfs_link(struct dentry *
341 struct dentry *new_dentry)
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;
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,
361 + rc = vfs_link(lower_old_dentry, lower_old_mnt,
362 + lower_dir_dentry->d_inode, lower_new_dentry,
364 if (rc || !lower_new_dentry->d_inode)
366 rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
367 @@ -474,11 +474,12 @@
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;
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);
379 printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
381 @@ -464,6 +470,7 @@ static int ecryptfs_symlink(struct inode
384 struct dentry *lower_dentry;
385 + struct vfsmount *lower_mnt;
386 struct dentry *lower_dir_dentry;
387 char *encoded_symname;
389 @@ -471,6 +478,7 @@ static int ecryptfs_symlink(struct inode
391 lower_dentry = ecryptfs_dentry_to_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,
401 - rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry,
402 + rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, lower_mnt
404 kfree(encoded_symname);
405 if (rc || !lower_dentry->d_inode)
406 @@ -501,11 +509,14 @@ static int ecryptfs_mkdir(struct inode *
409 struct dentry *lower_dentry;
410 + struct vfsmount *lower_mnt;
411 struct dentry *lower_dir_dentry;
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,
419 if (rc || !lower_dentry->d_inode)
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)
425 struct dentry *lower_dentry;
426 + struct vfsmount *lower_mnt;
427 struct dentry *lower_dir_dentry;
430 lower_dentry = ecryptfs_dentry_to_lower(dentry);
431 + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
433 lower_dir_dentry = lock_parent(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);
439 d_delete(lower_dentry);
440 @@ -549,11 +562,14 @@ ecryptfs_mknod(struct inode *dir, struct
443 struct dentry *lower_dentry;
444 + struct vfsmount *lower_mnt;
445 struct dentry *lower_dir_dentry;
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,
453 if (rc || !lower_dentry->d_inode)
455 rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
456 @@ -574,19 +590,24 @@ ecryptfs_rename(struct inode *old_dir, s
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;
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);
481 fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL);
482 @@ -850,6 +871,7 @@ static int ecryptfs_setattr(struct dentr
485 struct dentry *lower_dentry;
486 + struct vfsmount *lower_mnt;
488 struct inode *lower_inode;
489 struct ecryptfs_crypt_stat *crypt_stat;
490 @@ -860,6 +882,7 @@ static int ecryptfs_setattr(struct dentr
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);
498 @@ -911,7 +934,7 @@ static int ecryptfs_setattr(struct dentr
499 ia->ia_valid &= ~ATTR_MODE;
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);
506 fsstack_copy_attr_all(inode, lower_inode, NULL);
507 diff -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
512 if (!file->f_op->write)
514 - if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0)
516 + do_truncate(file->f_path.dentry, file->f_path.mnt, 0, 0, file) != 0)
519 retval = binfmt->core_dump(signr, regs, file, core_limit);
520 diff -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
524 * out the RO attribute for checking by the security
525 * module, just because it maps to a file mode.
527 - err = security_inode_setattr(filp->f_path.dentry, &ia);
528 + err = security_inode_setattr(filp->f_path.dentry, filp->f_path.mnt, &ia);
532 diff -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
535 @@ -1105,21 +1105,22 @@ static int fuse_dir_fsync(struct file *f
536 return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
539 -static bool update_mtime(unsigned ivalid)
540 +static bool update_mtime(unsigned ivalid, bool have_file)
542 /* Always update if mtime is explicitly set */
543 if (ivalid & ATTR_MTIME_SET)
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))
551 /* In all other cases update */
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,
559 unsigned ivalid = iattr->ia_valid;
561 @@ -1138,7 +1139,7 @@ static void iattr_to_fattr(struct iattr
562 if (!(ivalid & ATTR_ATIME_SET))
563 arg->valid |= FATTR_ATIME_NOW;
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.
574 -static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
576 +int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
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
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);
588 struct fuse_file *ff = file->private_data;
589 inarg.valid |= FATTR_FH;
590 @@ -1314,10 +1315,7 @@ error:
592 static int fuse_setattr(struct dentry *entry, struct iattr *attr)
594 - if (attr->ia_valid & ATTR_FILE)
595 - return fuse_do_setattr(entry, attr, attr->ia_file);
597 - return fuse_do_setattr(entry, attr, NULL);
598 + return fuse_do_setattr(entry, attr, NULL);
601 static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
602 diff -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
609 +static int fuse_fsetattr(struct file *file, struct iattr *attr)
611 + return fuse_do_setattr(file->f_path.dentry, attr, file);
614 static const struct file_operations fuse_file_operations = {
615 .llseek = fuse_file_llseek,
616 .read = do_sync_read,
617 @@ -1483,6 +1488,7 @@ static const struct file_operations fuse
619 .lock = fuse_file_lock,
620 .flock = fuse_file_flock,
621 + .fsetattr = fuse_fsetattr,
622 .splice_read = generic_file_splice_read,
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,
629 + .fsetattr = fuse_fsetattr,
630 /* no mmap and splice_read */
633 diff -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
638 int fuse_dev_init(void);
641 +int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
642 + struct file *file);
645 * Cleanup the client device
647 diff -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
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);
659 diff -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
662 @@ -372,7 +372,7 @@ static int find_inode(const char __user
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);
671 diff -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
678 -int inode_permission(struct inode *inode, int mask)
679 +static int __inode_permission(struct inode *inode, int mask)
683 @@ -256,7 +256,12 @@ int inode_permission(struct inode *inode
687 - retval = devcgroup_inode_permission(inode, mask);
688 + return devcgroup_inode_permission(inode, mask);
691 +int inode_permission(struct inode *inode, int mask)
693 + int retval = __inode_permission(inode, mask);
697 @@ -264,6 +269,15 @@ int inode_permission(struct inode *inode
698 mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND));
701 +int path_permission(struct path *path, int mask)
703 + int retval = __inode_permission(path->dentry->d_inode, mask);
706 + return security_path_permission(path,
707 + mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND));
711 * vfs_permission - check for access rights to a given path
712 * @nd: lookup result that describes the path
713 @@ -276,7 +290,7 @@ int inode_permission(struct inode *inode
715 int vfs_permission(struct nameidata *nd, int mask)
717 - return inode_permission(nd->path.dentry->d_inode, mask);
718 + return path_permission(&nd->path, mask);
722 @@ -293,7 +307,7 @@ int vfs_permission(struct nameidata *nd,
724 int file_permission(struct file *file, int mask)
726 - return inode_permission(file->f_path.dentry->d_inode, mask);
727 + return path_permission(&file->f_path, mask);
731 @@ -434,8 +448,9 @@ static struct dentry * cached_lookup(str
732 * short-cut DAC fails, then call permission() to do more
733 * complete permission check.
735 -static int exec_permission_lite(struct inode *inode)
736 +static int exec_permission_lite(struct path *path)
738 + struct inode *inode = path->dentry->d_inode;
739 umode_t mode = inode->i_mode;
741 if (inode->i_op && inode->i_op->permission)
742 @@ -460,7 +475,7 @@ static int exec_permission_lite(struct i
746 - return security_inode_permission(inode, MAY_EXEC);
747 + return security_path_permission(path, MAY_EXEC);
751 @@ -857,7 +872,7 @@ static int __link_path_walk(const char *
754 nd->flags |= LOOKUP_CONTINUE;
755 - err = exec_permission_lite(inode);
756 + err = exec_permission_lite(&nd->path);
758 err = vfs_permission(nd, MAY_EXEC);
760 @@ -1052,24 +1067,21 @@ static int do_path_lookup(int dfd, const
762 read_unlock(&fs->lock);
764 - struct dentry *dentry;
766 file = fget_light(dfd, &fput_needed);
771 - dentry = file->f_path.dentry;
772 + nd->path = file->f_path;
775 - if (!S_ISDIR(dentry->d_inode->i_mode))
776 + if (!S_ISDIR(nd->path.dentry->d_inode->i_mode))
779 retval = file_permission(file, MAY_EXEC);
783 - nd->path = file->f_path;
784 path_get(&file->f_path);
786 fput_light(file, fput_needed);
787 @@ -1216,7 +1228,7 @@ static struct dentry *lookup_hash(struct
791 - err = inode_permission(nd->path.dentry->d_inode, MAY_EXEC);
792 + err = path_permission(&nd->path, MAY_EXEC);
795 return __lookup_hash(&nd->last, nd->path.dentry, nd);
796 @@ -1481,7 +1493,7 @@ int vfs_create(struct inode *dir, struct
797 return -EACCES; /* shouldn't it be ENOSYS? */
800 - error = security_inode_create(dir, dentry, mode);
801 + error = security_inode_create(dir, dentry, nd ? nd->path.mnt : NULL, mode);
805 @@ -1557,7 +1569,7 @@ int may_open(struct nameidata *nd, int a
809 - error = do_truncate(dentry, 0,
810 + error = do_truncate(dentry, nd->path.mnt, 0,
811 ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
814 @@ -1924,7 +1936,8 @@ fail:
816 EXPORT_SYMBOL_GPL(lookup_create);
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)
822 int error = may_create(dir, dentry);
824 @@ -1941,7 +1954,7 @@ int vfs_mknod(struct inode *dir, struct
828 - error = security_inode_mknod(dir, dentry, mode, dev);
829 + error = security_inode_mknod(dir, dentry, mnt, mode, dev);
833 @@ -2002,11 +2015,12 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const
834 error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
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));
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);
848 mnt_drop_write(nd.path.mnt);
849 @@ -2025,7 +2039,8 @@ SYSCALL_DEFINE3(mknod, const char __user
850 return sys_mknodat(AT_FDCWD, filename, mode, dev);
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,
857 int error = may_create(dir, dentry);
859 @@ -2036,7 +2051,7 @@ int vfs_mkdir(struct inode *dir, struct
862 mode &= (S_IRWXUGO|S_ISVTX);
863 - error = security_inode_mkdir(dir, dentry, mode);
864 + error = security_inode_mkdir(dir, dentry, mnt, mode);
868 @@ -2068,7 +2083,7 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const
869 error = mnt_want_write(nd.path.mnt);
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);
877 @@ -2112,7 +2127,7 @@ void dentry_unhash(struct dentry *dentry
878 spin_unlock(&dcache_lock);
881 -int vfs_rmdir(struct inode *dir, struct dentry *dentry)
882 +int vfs_rmdir(struct inode *dir, struct dentry *dentry,struct vfsmount *mnt)
884 int error = may_delete(dir, dentry, 1);
886 @@ -2122,6 +2137,10 @@ int vfs_rmdir(struct inode *dir, struct
887 if (!dir->i_op || !dir->i_op->rmdir)
890 + error = security_inode_rmdir(dir, dentry, mnt);
896 mutex_lock(&dentry->d_inode->i_mutex);
897 @@ -2129,12 +2148,9 @@ int vfs_rmdir(struct inode *dir, struct
898 if (d_mountpoint(dentry))
901 - error = security_inode_rmdir(dir, dentry);
903 - error = dir->i_op->rmdir(dir, dentry);
905 - dentry->d_inode->i_flags |= S_DEAD;
907 + error = dir->i_op->rmdir(dir, dentry);
909 + dentry->d_inode->i_flags |= S_DEAD;
911 mutex_unlock(&dentry->d_inode->i_mutex);
913 @@ -2178,7 +2194,7 @@ static long do_rmdir(int dfd, const char
914 error = mnt_want_write(nd.path.mnt);
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);
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
923 return do_rmdir(AT_FDCWD, pathname);
926 -int vfs_unlink(struct inode *dir, struct dentry *dentry)
927 +int vfs_unlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt)
929 int error = may_delete(dir, dentry, 0);
931 @@ -2211,7 +2227,7 @@ int vfs_unlink(struct inode *dir, struct
932 if (d_mountpoint(dentry))
935 - error = security_inode_unlink(dir, dentry);
936 + error = security_inode_unlink(dir, dentry, mnt);
938 error = dir->i_op->unlink(dir, dentry);
940 @@ -2263,7 +2279,7 @@ static long do_unlinkat(int dfd, const c
941 error = mnt_want_write(nd.path.mnt);
944 - error = vfs_unlink(nd.path.dentry->d_inode, dentry);
945 + error = vfs_unlink(nd.path.dentry->d_inode, dentry, nd.path.mnt);
946 if (!error && (saved_ino || saved_dev))
947 gr_handle_delete(saved_ino, saved_dev);
948 mnt_drop_write(nd.path.mnt);
949 @@ -2298,7 +2314,8 @@ SYSCALL_DEFINE1(unlink, const char __use
950 return do_unlinkat(AT_FDCWD, pathname);
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)
957 int error = may_create(dir, dentry);
959 @@ -2308,7 +2325,7 @@ int vfs_symlink(struct inode *dir, struc
960 if (!dir->i_op || !dir->i_op->symlink)
963 - error = security_inode_symlink(dir, dentry, oldname);
964 + error = security_inode_symlink(dir, dentry, mnt, oldname);
968 @@ -2344,7 +2361,7 @@ SYSCALL_DEFINE3(symlinkat, const char __
969 error = mnt_want_write(nd.path.mnt);
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);
975 gr_handle_create(dentry, nd.path.mnt);
976 mnt_drop_write(nd.path.mnt);
977 @@ -2362,7 +2379,7 @@ SYSCALL_DEFINE2(symlink, const char __us
978 return sys_symlinkat(oldname, AT_FDCWD, newname);
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)
984 struct inode *inode = old_dentry->d_inode;
986 @@ -2387,7 +2404,8 @@ int vfs_link(struct dentry *old_dentry,
987 if (S_ISDIR(inode->i_mode))
990 - error = security_inode_link(old_dentry, dir, new_dentry);
991 + error = security_inode_link(old_dentry, old_mnt, dir, new_dentry,
996 @@ -2440,7 +2458,9 @@ SYSCALL_DEFINE5(linkat, int, olddfd, con
997 error = mnt_want_write(nd.path.mnt);
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);
1005 gr_handle_create(new_dentry, nd.path.mnt);
1006 mnt_drop_write(nd.path.mnt);
1007 @@ -2493,7 +2513,8 @@ SYSCALL_DEFINE2(link, const char __user
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)
1016 struct inode *target;
1017 @@ -2508,7 +2529,8 @@ static int vfs_rename_dir(struct inode *
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);
1027 @@ -2536,12 +2558,14 @@ static int vfs_rename_dir(struct inode *
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)
1035 struct inode *target;
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);
1044 @@ -2564,7 +2588,8 @@ static int vfs_rename_other(struct inode
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)
1053 int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
1054 @@ -2593,9 +2618,11 @@ int vfs_rename(struct inode *old_dir, st
1055 old_name = fsnotify_oldname_init(old_dentry->d_name.name);
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);
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);
1067 const char *new_name = old_dentry->d_name.name;
1068 @@ -2676,8 +2703,8 @@ SYSCALL_DEFINE4(renameat, int, olddfd, c
1069 error = mnt_want_write(oldnd.path.mnt);
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);
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);
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);
1087 diff -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 *
1091 release_mounts(&umount_list);
1095 +char *d_namespace_path(struct dentry *dentry, struct vfsmount *vfsmnt,
1096 + char *buf, int buflen)
1098 + struct path root, tmp, ns_root = { };
1099 + struct path path = { .mnt = vfsmnt, .dentry = dentry };
1102 + read_lock(¤t->fs->lock);
1103 + root = current->fs->root;
1104 + path_get(¤t->fs->root);
1105 + read_unlock(¤t->fs->lock);
1106 + spin_lock(&vfsmount_lock);
1107 + if (root.mnt && root.mnt->mnt_ns)
1108 + ns_root.mnt = mntget(root.mnt->mnt_ns->root);
1110 + ns_root.dentry = dget(ns_root.mnt->mnt_root);
1111 + spin_unlock(&vfsmount_lock);
1113 + res = __d_path(&path, &tmp, buf, buflen,
1114 + D_PATH_FAIL_DELETED | D_PATH_DISCONNECT);
1116 + path_put(&ns_root);
1118 + /* Prevent empty path for lazily unmounted filesystems. */
1119 + if (!IS_ERR(res) && *res == '\0')
1123 +EXPORT_SYMBOL(d_namespace_path);
1124 diff -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
1127 @@ -158,7 +158,8 @@ nfsd4_create_clid_dir(struct nfs4_client
1128 status = mnt_want_write(rec_dir.mnt);
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,
1134 mnt_drop_write(rec_dir.mnt);
1137 @@ -263,7 +264,7 @@ nfsd4_remove_clid_file(struct dentry *di
1140 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
1141 - status = vfs_unlink(dir->d_inode, dentry);
1142 + status = vfs_unlink(dir->d_inode, dentry, rec_dir.mnt);
1143 mutex_unlock(&dir->d_inode->i_mutex);
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);
1151 + status = vfs_rmdir(dir->d_inode, dentry, rec_dir.mnt);
1152 mutex_unlock(&dir->d_inode->i_mutex);
1155 diff -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
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)
1167 diff -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
1171 err = nfserr_notsync;
1172 if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
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);
1179 @@ -407,12 +407,13 @@ out_nfserr:
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)
1190 - buflen = vfs_getxattr(dentry, key, NULL, 0);
1191 + buflen = vfs_getxattr(dentry, mnt, key, NULL, 0, NULL);
1195 @@ -420,7 +421,7 @@ static ssize_t nfsd_getxattr(struct dent
1199 - ret = vfs_getxattr(dentry, key, *buf, buflen);
1200 + ret = vfs_getxattr(dentry, mnt, key, *buf, buflen, NULL);
1204 @@ -429,7 +430,8 @@ static ssize_t nfsd_getxattr(struct dent
1206 #if defined(CONFIG_NFSD_V4)
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)
1214 @@ -448,7 +450,7 @@ set_nfsv4_acl_one(struct dentry *dentry,
1218 - error = vfs_setxattr(dentry, key, buf, len, 0);
1219 + error = vfs_setxattr(dentry, mnt, key, buf, len, 0, NULL);
1223 @@ -461,6 +463,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
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;
1231 @@ -471,6 +474,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
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;
1239 @@ -481,12 +485,14 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
1240 } else if (host_error < 0)
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);
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);
1255 posix_acl_release(pacl);
1256 @@ -499,13 +505,13 @@ out_nfserr:
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)
1264 struct posix_acl *pacl = NULL;
1267 - buflen = nfsd_getxattr(dentry, key, &buf);
1268 + buflen = nfsd_getxattr(dentry, mnt, key, &buf);
1272 @@ -517,14 +523,15 @@ _get_posix_acl(struct dentry *dentry, ch
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)
1280 struct inode *inode = dentry->d_inode;
1282 struct posix_acl *pacl = NULL, *dpacl = NULL;
1283 unsigned int flags = 0;
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);
1290 @@ -534,7 +541,7 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqst
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)
1298 else if (IS_ERR(dpacl)) {
1299 @@ -947,13 +954,13 @@ out:
1303 -static void kill_suid(struct dentry *dentry)
1304 +static void kill_suid(struct dentry *dentry, struct vfsmount *mnt)
1307 ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
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);
1315 @@ -1012,7 +1019,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s
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);
1322 if (host_err >= 0 && stable) {
1323 static ino_t last_ino;
1324 @@ -1190,6 +1197,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
1325 int type, dev_t rdev, struct svc_fh *resfhp)
1327 struct dentry *dentry, *dchild = NULL;
1328 + struct svc_export *exp;
1332 @@ -1207,6 +1215,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
1335 dentry = fhp->fh_dentry;
1336 + exp = fhp->fh_export;
1337 dirp = dentry->d_inode;
1339 err = nfserr_notdir;
1340 @@ -1223,7 +1232,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
1341 host_err = PTR_ERR(dchild);
1344 - err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
1345 + err = fh_compose(resfhp, exp, dchild, fhp);
1349 @@ -1273,13 +1282,14 @@ nfsd_create(struct svc_rqst *rqstp, stru
1350 host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
1353 - host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
1354 + host_err = vfs_mkdir(dirp, dchild, exp->ex_path.mnt, iap->ia_mode);
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);
1366 @@ -1287,7 +1297,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
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);
1375 @@ -1517,6 +1527,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
1378 struct dentry *dentry, *dnew;
1379 + struct svc_export *exp;
1383 @@ -1541,6 +1552,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
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)
1391 @@ -1548,14 +1560,16 @@ nfsd_symlink(struct svc_rqst *rqstp, str
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);
1401 - host_err = vfs_symlink(dentry->d_inode, dnew, path);
1402 + host_err = vfs_symlink(dentry->d_inode, dnew, exp->ex_path.mnt,
1406 - if (EX_ISSYNC(fhp->fh_export))
1407 + if (EX_ISSYNC(exp))
1408 host_err = nfsd_sync_dir(dentry);
1410 err = nfserrno(host_err);
1411 @@ -1563,7 +1577,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
1413 mnt_drop_write(fhp->fh_export->ex_path.mnt);
1415 - cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp);
1416 + cerr = fh_compose(resfhp, exp, dnew, fhp);
1418 if (err==0) err = cerr;
1420 @@ -1618,7 +1632,8 @@ nfsd_link(struct svc_rqst *rqstp, struct
1421 err = nfserrno(host_err);
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);
1428 if (EX_ISSYNC(ffhp->fh_export)) {
1429 err = nfserrno(nfsd_sync_dir(ddir));
1430 @@ -1719,7 +1734,8 @@ nfsd_rename(struct svc_rqst *rqstp, stru
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);
1440 @@ -1757,6 +1773,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
1441 char *fname, int flen)
1443 struct dentry *dentry, *rdentry;
1444 + struct svc_export *exp;
1448 @@ -1771,6 +1788,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
1449 fh_lock_nested(fhp, I_MUTEX_PARENT);
1450 dentry = fhp->fh_dentry;
1451 dirp = dentry->d_inode;
1452 + exp = fhp->fh_export;
1454 rdentry = lookup_one_len(fname, dentry, flen);
1455 host_err = PTR_ERR(rdentry);
1456 @@ -1792,21 +1810,21 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
1458 if (type != S_IFDIR) { /* It's UNLINK */
1460 - if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
1461 + if ((exp->ex_flags & NFSEXP_MSNFS) &&
1462 (atomic_read(&rdentry->d_count) > 1)) {
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);
1477 - if (EX_ISSYNC(fhp->fh_export))
1478 + if (EX_ISSYNC(exp))
1479 host_err = nfsd_sync_dir(dentry);
1482 @@ -2143,7 +2161,8 @@ nfsd_get_posix_acl(struct svc_fh *fhp, i
1483 return ERR_PTR(-EOPNOTSUPP);
1486 - size = nfsd_getxattr(fhp->fh_dentry, name, &value);
1487 + size = nfsd_getxattr(fhp->fh_dentry, fhp->fh_export->ex_path.mnt, name,
1490 return ERR_PTR(size);
1492 @@ -2155,6 +2174,7 @@ nfsd_get_posix_acl(struct svc_fh *fhp, i
1494 nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
1496 + struct vfsmount *mnt;
1497 struct inode *inode = fhp->fh_dentry->d_inode;
1500 @@ -2187,21 +2207,24 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i
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);
1510 - error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0);
1511 + error = vfs_setxattr(fhp->fh_dentry, mnt, name, value, size, 0,
1514 if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
1517 - error = vfs_removexattr(fhp->fh_dentry, name);
1518 + error = vfs_removexattr(fhp->fh_dentry, mnt, name,
1520 if (error == -ENODATA)
1524 - mnt_drop_write(fhp->fh_export->ex_path.mnt);
1525 + mnt_drop_write(mnt);
1529 diff -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:
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)
1542 struct iattr newattrs;
1543 @@ -207,16 +207,15 @@ int do_truncate(struct dentry *dentry, l
1545 newattrs.ia_size = length;
1546 newattrs.ia_valid = ATTR_SIZE | time_attrs;
1548 - newattrs.ia_file = filp;
1551 newattrs.ia_valid |= ATTR_FILE;
1554 /* Remove suid/sgid on truncate too */
1555 newattrs.ia_valid |= should_remove_suid(dentry);
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);
1563 @@ -249,7 +248,7 @@ static long do_sys_truncate(const char _
1567 - error = inode_permission(inode, MAY_WRITE);
1568 + error = path_permission(&path, MAY_WRITE);
1570 goto mnt_drop_write_and_out;
1572 @@ -272,7 +271,7 @@ static long do_sys_truncate(const char _
1573 error = locks_verify_truncate(inode, NULL, length);
1576 - error = do_truncate(path.dentry, length, 0, NULL);
1577 + error = do_truncate(path.dentry, path.mnt, length, 0, NULL);
1581 @@ -327,7 +326,8 @@ static long do_sys_ftruncate(unsigned in
1583 error = locks_verify_truncate(inode, file, length);
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);
1591 @@ -493,7 +493,7 @@ SYSCALL_DEFINE3(faccessat, int, dfd, con
1592 goto out_path_release;
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;
1600 @@ -536,7 +536,7 @@ SYSCALL_DEFINE1(chdir, const char __user
1604 - error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
1605 + error = path_permission(&path, MAY_EXEC | MAY_ACCESS);
1609 @@ -565,7 +565,7 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd
1610 if (!S_ISDIR(inode->i_mode))
1613 - error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
1614 + error = path_permission(&file->f_path, MAY_EXEC | MAY_ACCESS);
1616 if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
1618 @@ -583,7 +583,7 @@ SYSCALL_DEFINE1(chroot, const char __use
1622 - error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
1623 + error = path_permission(&path, MAY_EXEC | MAY_ACCESS);
1627 @@ -623,8 +623,8 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd
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);
1638 @@ -653,7 +653,7 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
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);
1647 @@ -667,7 +667,8 @@ SYSCALL_DEFINE2(chmod, const char __user
1648 return sys_fchmodat(AT_FDCWD, filename, mode);
1651 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
1652 +static int chown_common(struct dentry * dentry, struct vfsmount *mnt,
1653 + uid_t user, gid_t group, struct file *file)
1655 struct inode *inode = dentry->d_inode;
1657 @@ -685,8 +686,11 @@ static int chown_common(struct dentry *
1658 if (!S_ISDIR(inode->i_mode))
1659 newattrs.ia_valid |=
1660 ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
1662 + newattrs.ia_valid |= ATTR_FILE;
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);
1670 @@ -703,7 +707,7 @@ SYSCALL_DEFINE3(chown, const char __user
1671 error = cow_check_and_break(&path);
1674 - error = chown_common(path.dentry, user, group, path.mnt);
1675 + error = chown_common(path.dentry, path.mnt, user, group, NULL);
1676 mnt_drop_write(path.mnt);
1679 @@ -728,7 +732,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, cons
1680 error = cow_check_and_break(&path);
1683 - error = chown_common(path.dentry, user, group, path.mnt);
1684 + error = chown_common(path.dentry, path.mnt, user, group, NULL);
1685 mnt_drop_write(path.mnt);
1688 @@ -747,7 +751,7 @@ SYSCALL_DEFINE3(lchown, const char __use
1689 error = cow_check_and_break(&path);
1692 - error = chown_common(path.dentry, user, group, path.mnt);
1693 + error = chown_common(path.dentry, path.mnt, user, group, NULL);
1694 mnt_drop_write(path.mnt);
1697 @@ -770,7 +774,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd
1699 dentry = file->f_path.dentry;
1700 audit_inode(NULL, dentry);
1701 - error = chown_common(dentry, user, group, file->f_path.mnt);
1702 + error = chown_common(dentry, file->f_path.mnt, user, group, file);
1703 mnt_drop_write(file->f_path.mnt);
1706 diff -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
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);
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);
1727 @@ -790,7 +790,7 @@ reiserfs_chown_xattrs_filler(void *buf,
1730 if (!S_ISDIR(xafile->d_inode->i_mode))
1731 - err = notify_change(xafile, attrs);
1732 + err = notify_change(xafile, NULL, attrs);
1736 @@ -834,7 +834,7 @@ int reiserfs_chown_xattrs(struct inode *
1740 - err = notify_change(dir, attrs);
1741 + err = notify_change(dir, NULL, attrs);
1745 diff -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
1748 @@ -412,9 +412,7 @@ int seq_path_root(struct seq_file *m, st
1749 char *s = m->buf + m->count;
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);
1758 s = mangle_path(s, p, esc);
1759 diff -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
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);
1769 touch_atime(path.mnt, path.dentry);
1770 error = inode->i_op->readlink(path.dentry,
1771 diff -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
1774 @@ -48,7 +48,8 @@ static bool nsec_valid(long nsec)
1775 return nsec >= 0 && nsec <= 999999999;
1778 -static int utimes_common(struct path *path, struct timespec *times)
1779 +static int utimes_common(struct path *path, struct timespec *times,
1783 struct iattr newattrs;
1784 @@ -102,7 +103,7 @@ static int utimes_common(struct path *pa
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);
1792 mnt_drop_write_and_out:
1793 @@ -149,7 +150,7 @@ long do_utimes(int dfd, char __user *fil
1797 - error = utimes_common(&file->f_path, times);
1798 + error = utimes_common(&file->f_path, times, file);
1802 @@ -162,7 +163,7 @@ long do_utimes(int dfd, char __user *fil
1806 - error = utimes_common(&path, times);
1807 + error = utimes_common(&path, times, NULL);
1811 diff -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
1814 @@ -67,8 +67,8 @@ xattr_permission(struct inode *inode, co
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)
1823 struct inode *inode = dentry->d_inode;
1825 @@ -78,7 +78,7 @@ vfs_setxattr(struct dentry *dentry, cons
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);
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);
1837 fsnotify_xattr(dentry);
1838 - security_inode_post_setxattr(dentry, name, value,
1839 + security_inode_post_setxattr(dentry, mnt, name, value,
1842 } else if (!strncmp(name, XATTR_SECURITY_PREFIX,
1843 @@ -131,7 +131,8 @@ out_noalloc:
1844 EXPORT_SYMBOL_GPL(xattr_getsecurity);
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)
1851 struct inode *inode = dentry->d_inode;
1853 @@ -140,7 +141,7 @@ vfs_getxattr(struct dentry *dentry, cons
1857 - error = security_inode_getxattr(dentry, name);
1858 + error = security_inode_getxattr(dentry, mnt, name, file);
1862 @@ -167,18 +168,20 @@ nolsm:
1863 EXPORT_SYMBOL_GPL(vfs_getxattr);
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)
1870 + struct inode *inode = dentry->d_inode;
1873 - error = security_inode_listxattr(d);
1874 + error = security_inode_listxattr(dentry, mnt, file);
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);
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);
1885 + error = security_inode_listsecurity(inode, list, size);
1886 if (size && error > size)
1889 @@ -187,7 +190,8 @@ vfs_listxattr(struct dentry *d, char *li
1890 EXPORT_SYMBOL_GPL(vfs_listxattr);
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)
1897 struct inode *inode = dentry->d_inode;
1899 @@ -199,7 +203,7 @@ vfs_removexattr(struct dentry *dentry, c
1903 - error = security_inode_removexattr(dentry, name);
1904 + error = security_inode_removexattr(dentry, mnt, name, file);
1908 @@ -218,8 +222,8 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
1909 * Extended attribute SET operations
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)
1918 void *kvalue = NULL;
1919 @@ -246,7 +250,7 @@ setxattr(struct dentry *d, const char __
1923 - error = vfs_setxattr(d, kname, kvalue, size, flags);
1924 + error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags, file);
1928 @@ -263,7 +267,7 @@ SYSCALL_DEFINE5(setxattr, const char __u
1930 error = mnt_want_write(path.mnt);
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);
1937 @@ -282,7 +286,7 @@ SYSCALL_DEFINE5(lsetxattr, const char __
1939 error = mnt_want_write(path.mnt);
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);
1946 @@ -303,7 +307,8 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, cons
1947 audit_inode(NULL, dentry);
1948 error = mnt_want_write(f->f_path.mnt);
1950 - error = setxattr(dentry, name, value, size, flags);
1951 + error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags,
1953 mnt_drop_write(f->f_path.mnt);
1956 @@ -314,8 +319,8 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, cons
1957 * Extended attribute GET operations
1960 -getxattr(struct dentry *d, const char __user *name, void __user *value,
1962 +getxattr(struct dentry *dentry, struct vfsmount *mnt, const char __user *name,
1963 + void __user *value, size_t size, struct file *file)
1966 void *kvalue = NULL;
1967 @@ -335,7 +340,7 @@ getxattr(struct dentry *d, const char __
1971 - error = vfs_getxattr(d, kname, kvalue, size);
1972 + error = vfs_getxattr(dentry, mnt, kname, kvalue, size, file);
1974 if (size && copy_to_user(value, kvalue, error))
1976 @@ -357,7 +362,7 @@ SYSCALL_DEFINE4(getxattr, const char __u
1977 error = user_path(pathname, &path);
1980 - error = getxattr(path.dentry, name, value, size);
1981 + error = getxattr(path.dentry, path.mnt, name, value, size, NULL);
1985 @@ -371,7 +376,7 @@ SYSCALL_DEFINE4(lgetxattr, const char __
1986 error = user_lpath(pathname, &path);
1989 - error = getxattr(path.dentry, name, value, size);
1990 + error = getxattr(path.dentry, path.mnt, name, value, size, NULL);
1994 @@ -386,7 +391,7 @@ SYSCALL_DEFINE4(fgetxattr, int, fd, cons
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);
2003 @@ -395,7 +400,8 @@ SYSCALL_DEFINE4(fgetxattr, int, fd, cons
2004 * Extended attribute LIST operations
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)
2013 @@ -408,7 +414,7 @@ listxattr(struct dentry *d, char __user
2017 - error = vfs_listxattr(d, klist, size);
2018 + error = vfs_listxattr(dentry, mnt, klist, size, file);
2020 if (size && copy_to_user(list, klist, error))
2022 @@ -430,7 +436,7 @@ SYSCALL_DEFINE3(listxattr, const char __
2023 error = user_path(pathname, &path);
2026 - error = listxattr(path.dentry, list, size);
2027 + error = listxattr(path.dentry, path.mnt, list, size, NULL);
2031 @@ -444,7 +450,7 @@ SYSCALL_DEFINE3(llistxattr, const char _
2032 error = user_lpath(pathname, &path);
2035 - error = listxattr(path.dentry, list, size);
2036 + error = listxattr(path.dentry, path.mnt, list, size, NULL);
2040 @@ -458,7 +464,7 @@ SYSCALL_DEFINE3(flistxattr, int, fd, cha
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);
2049 @@ -467,7 +473,8 @@ SYSCALL_DEFINE3(flistxattr, int, fd, cha
2050 * Extended attribute REMOVE operations
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)
2058 char kname[XATTR_NAME_MAX + 1];
2059 @@ -478,7 +485,7 @@ removexattr(struct dentry *d, const char
2063 - return vfs_removexattr(d, kname);
2064 + return vfs_removexattr(dentry, mnt, kname, file);
2067 SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
2068 @@ -492,7 +499,7 @@ SYSCALL_DEFINE2(removexattr, const char
2070 error = mnt_want_write(path.mnt);
2072 - error = removexattr(path.dentry, name);
2073 + error = removexattr(path.dentry, path.mnt, name, NULL);
2074 mnt_drop_write(path.mnt);
2077 @@ -510,7 +517,7 @@ SYSCALL_DEFINE2(lremovexattr, const char
2079 error = mnt_want_write(path.mnt);
2081 - error = removexattr(path.dentry, name);
2082 + error = removexattr(path.dentry, path.mnt, name, NULL);
2083 mnt_drop_write(path.mnt);
2086 @@ -530,7 +537,7 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, c
2087 audit_inode(NULL, dentry);
2088 error = mnt_want_write(f->f_path.mnt);
2090 - error = removexattr(dentry, name);
2091 + error = removexattr(dentry, f->f_path.mnt, name, f);
2092 mnt_drop_write(f->f_path.mnt);
2095 diff -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
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 */
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 */
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 */
2121 @@ -547,6 +554,9 @@ extern void audit_log(struct audit_
2122 __attribute__((format(printf,4,5)));
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)));
2131 diff -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
2136 * helper function for dentry_operations.d_dname() members
2138 +#define D_PATH_FAIL_DELETED 1
2139 +#define D_PATH_DISCONNECT 2
2140 extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
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,
2145 extern char *d_path(const struct path *, char *, int);
2146 extern char *dentry_path(struct dentry *, char *, int);
2148 diff -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 {
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).
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.
2160 struct file *ia_file;
2162 @@ -1207,13 +1211,13 @@ extern void unlock_super(struct super_bl
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 *);
2182 * VFS dentry helper functions.
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);
2187 + * VFS path helper functions.
2189 +extern int path_permission(struct path *, int);
2194 * NOTE! These match bits 12..15 of stat.st_mode
2195 @@ -1308,6 +1317,7 @@ struct file_operations {
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 *);
2202 struct inode_operations {
2203 @@ -1671,8 +1681,8 @@ static inline int break_lease(struct ino
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,
2213 extern struct file *filp_open(const char *, int, int);
2214 @@ -1832,7 +1842,8 @@ extern int do_remount_sb(struct super_bl
2216 extern sector_t bmap(struct inode *, sector_t);
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));
2224 diff -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
2228 extern spinlock_t vfsmount_lock;
2229 extern dev_t name_to_dev_t(char *name);
2231 +extern char *d_namespace_path(struct dentry *, struct vfsmount *, char *, int);
2233 #endif /* _LINUX_MOUNT_H */
2234 diff -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 *,
2238 #ifdef CONFIG_NFSD_V4
2239 __be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *,
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,
2247 diff -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
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.
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.
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.
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.
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.
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.
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.
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.
2341 @@ -426,18 +440,18 @@ static inline void security_free_mnt_opt
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.
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.
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.
2368 + * Security hook for path
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.
2382 * Security hooks for task operations.
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);
2457 int (*task_create) (unsigned long clone_flags);
2458 int (*task_alloc_security) (struct task_struct *p);
2459 @@ -1618,30 +1660,43 @@ int security_inode_alloc(struct inode *i
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);
2521 @@ -1664,6 +1719,7 @@ int security_file_send_sigiotask(struct
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);
2529 @@ -1973,26 +2029,31 @@ static inline int security_inode_init_se
2531 static inline int security_inode_create(struct inode *dir,
2532 struct dentry *dentry,
2533 + struct vfsmount *mnt,
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)
2550 static inline int security_inode_unlink(struct inode *dir,
2551 - struct dentry *dentry)
2552 + struct dentry *dentry,
2553 + struct vfsmount *mnt)
2558 static inline int security_inode_symlink(struct inode *dir,
2559 struct dentry *dentry,
2560 + struct vfsmount *mnt,
2561 const char *old_name)
2564 @@ -2000,19 +2061,22 @@ static inline int security_inode_symlink
2566 static inline int security_inode_mkdir(struct inode *dir,
2567 struct dentry *dentry,
2568 + struct vfsmount *mnt,
2574 static inline int security_inode_rmdir(struct inode *dir,
2575 - struct dentry *dentry)
2576 + struct dentry *dentry,
2577 + struct vfsmount *mnt)
2582 static inline int security_inode_mknod(struct inode *dir,
2583 struct dentry *dentry,
2584 + struct vfsmount *mnt,
2585 int mode, dev_t dev)
2588 @@ -2020,13 +2084,16 @@ static inline int security_inode_mknod(s
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)
2601 -static inline int security_inode_readlink(struct dentry *dentry)
2602 +static inline int security_inode_readlink(struct dentry *dentry,
2603 + struct vfsmount *mnt)
2607 @@ -2043,7 +2110,8 @@ static inline int security_inode_permiss
2610 static inline int security_inode_setattr(struct dentry *dentry,
2611 - struct iattr *attr)
2612 + struct vfsmount *mnt,
2613 + struct iattr *attr)
2617 @@ -2058,30 +2126,42 @@ static inline void security_inode_delete
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)
2627 - return cap_inode_setxattr(dentry, name, value, size, flags);
2628 + return cap_inode_setxattr(dentry, mnt, name, value, size, flags, file);
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,
2635 + const void *value,
2636 + size_t size, int flags)
2639 static inline int security_inode_getxattr(struct dentry *dentry,
2641 + struct vfsmount *mnt,
2643 + struct file *file)
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)
2656 static inline int security_inode_removexattr(struct dentry *dentry,
2658 + struct vfsmount *mnt,
2660 + struct file *file)
2662 - return cap_inode_removexattr(dentry, name);
2663 + return cap_inode_removexattr(dentry, mnt, name, file);
2666 static inline int security_inode_need_killpriv(struct dentry *dentry)
2667 @@ -2182,6 +2262,11 @@ static inline int security_dentry_open(s
2671 +static inline int security_path_permission(struct path *path, int mask)
2676 static inline int security_task_create(unsigned long clone_flags)
2679 diff -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
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 *);
2686 +extern char *sysctl_pathname(ctl_table *, char *, int);
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);
2691 diff -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
2697 #include <linux/types.h>
2698 +#include <linux/mount.h>
2699 +#include <linux/fs.h>
2702 #define XATTR_OS2_PREFIX "os2."
2703 @@ -47,10 +49,10 @@ struct xattr_handler {
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);
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);
2718 diff -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 __
2722 err = mnt_want_write(mqueue_mnt);
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);
2730 diff -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
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.
2737 -static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
2739 +void audit_log_vformat(struct audit_buffer *ab, const char *fmt, va_list args)
2742 struct sk_buff *skb;
2743 @@ -1518,3 +1517,6 @@ EXPORT_SYMBOL(audit_log_start);
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);
2750 diff -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
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);
2762 diff -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
2766 spin_unlock(&sysctl_lock);
2769 +char *sysctl_pathname(struct ctl_table *table, char *buffer, int buflen)
2773 + buffer += --buflen;
2777 + int namelen = strlen(table->procname);
2779 + if (buflen < namelen + 1)
2781 + buflen -= namelen + 1;
2782 + buffer -= namelen;
2783 + memcpy(buffer, table->procname, namelen);
2785 + table = table->parent;
2790 + memcpy(buffer, "/sys", 4);
2794 +EXPORT_SYMBOL_GPL(sysctl_pathname);
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,
2799 diff -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
2804 EXPORT_SYMBOL(should_remove_suid);
2806 -static int __remove_suid(struct dentry *dentry, int kill)
2807 +static int __remove_suid(struct path *path, int kill)
2809 struct iattr newattrs;
2811 newattrs.ia_valid = ATTR_FORCE | kill;
2812 - return notify_change(dentry, &newattrs);
2813 + return notify_change(path->dentry, path->mnt, &newattrs);
2816 int file_remove_suid(struct file *file)
2817 @@ -1801,7 +1801,7 @@ int file_remove_suid(struct file *file)
2819 error = security_inode_killpriv(dentry);
2820 if (!error && killsuid)
2821 - error = __remove_suid(dentry, killsuid);
2822 + error = __remove_suid(&file->f_path, killsuid);
2826 diff -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
2830 goto out_mknod_dput;
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,
2836 mnt_drop_write(nd.path.mnt);
2838 goto out_mknod_dput;
2839 diff -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
2844 If you are unsure how to answer this question, answer N.
2846 +config SECURITY_DEFAULT
2847 + string "Default security module"
2848 + depends on SECURITY
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.
2855 config SECURITY_NETWORK
2856 bool "Socket and Networking Security Hooks"
2858 @@ -125,6 +134,7 @@ config SECURITY_DEFAULT_MMAP_MIN_ADDR
2860 source security/selinux/Kconfig
2861 source security/smack/Kconfig
2862 +source security/apparmor/Kconfig
2866 diff -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
2870 obj-$(CONFIG_KEYS) += keys/
2871 subdir-$(CONFIG_SECURITY_SELINUX) += selinux
2872 subdir-$(CONFIG_SECURITY_SMACK) += smack
2873 +subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
2875 # always enable default capabilities
2876 obj-y += commoncap.o
2877 @@ -15,5 +16,6 @@ obj-$(CONFIG_SECURITYFS) += inode.o
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
2881 +obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o
2882 obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o
2883 obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
2884 diff -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
2888 +config SECURITY_APPARMOR
2889 + bool "AppArmor support"
2890 + depends on SECURITY
2891 + depends on SECURITY_NETWORK
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>
2900 + If you are unsure how to answer this question, answer N.
2902 +config SECURITY_APPARMOR_BOOTPARAM_VALUE
2903 + int "AppArmor boot parameter default value"
2904 + depends on SECURITY_APPARMOR
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
2916 + If you are unsure how to answer this question, answer 1.
2918 +config SECURITY_APPARMOR_DISABLE
2919 + bool "AppArmor runtime disable"
2920 + depends on SECURITY_APPARMOR
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.
2931 + If you are unsure how to answer this question, answer N.
2932 diff -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
2936 +# Makefile for AppArmor Linux Security Module
2938 +obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
2940 +apparmor-y := main.o list.o procattr.o lsm.o apparmorfs.o \
2941 + module_interface.o match.o
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 > $@
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 > $@
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)
2954 diff -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
2959 + * Copyright (C) 1998-2007 Novell/SUSE
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
2966 + * AppArmor internal prototypes
2969 +#ifndef __APPARMOR_H
2970 +#define __APPARMOR_H
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>
2981 + * We use MAY_READ, MAY_WRITE, MAY_EXEC, MAY_APPEND and the following flags
2982 + * for profile permissions
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
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 | \
3003 +#define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \
3004 + AA_EXEC_MOD_2 | AA_EXEC_MOD_3)
3006 +#define AA_EXEC_TYPE (AA_EXEC_UNSAFE | AA_EXEC_INHERIT | \
3007 + AA_EXEC_MODIFIERS)
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)
3015 +#define AA_USER_SHIFT 0
3016 +#define AA_OTHER_SHIFT 14
3018 +#define AA_USER_PERMS (AA_BASE_PERMS << AA_USER_SHIFT)
3019 +#define AA_OTHER_PERMS (AA_BASE_PERMS << AA_OTHER_SHIFT)
3021 +#define AA_FILE_PERMS (AA_USER_PERMS | AA_OTHER_PERMS)
3023 +#define AA_LINK_BITS ((AA_MAY_LINK << AA_USER_SHIFT) | \
3024 + (AA_MAY_LINK << AA_OTHER_SHIFT))
3026 +#define AA_USER_EXEC (MAY_EXEC << AA_USER_SHIFT)
3027 +#define AA_OTHER_EXEC (MAY_EXEC << AA_OTHER_SHIFT)
3029 +#define AA_USER_EXEC_TYPE (AA_EXEC_TYPE << AA_USER_SHIFT)
3030 +#define AA_OTHER_EXEC_TYPE (AA_EXEC_TYPE << AA_OTHER_SHIFT)
3032 +#define AA_EXEC_BITS (AA_USER_EXEC | AA_OTHER_EXEC)
3034 +#define ALL_AA_EXEC_UNSAFE ((AA_EXEC_UNSAFE << AA_USER_SHIFT) | \
3035 + (AA_EXEC_UNSAFE << AA_OTHER_SHIFT))
3037 +#define ALL_AA_EXEC_TYPE (AA_USER_EXEC_TYPE | AA_OTHER_EXEC_TYPE)
3039 +/* overloaded permissions for link pairs */
3040 +#define AA_LINK_SUBSET_TEST 0x0020
3042 +#define AA_USER_PTRACE 0x10000000
3043 +#define AA_OTHER_PTRACE 0x20000000
3044 +#define AA_PTRACE_PERMS (AA_USER_PTRACE | AA_OTHER_PTRACE)
3046 +/* shared permissions that are not duplicated in user::other */
3047 +#define AA_CHANGE_HAT 0x40000000
3048 +#define AA_CHANGE_PROFILE 0x80000000
3050 +#define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE)
3052 +#define AA_VALID_PERM_MASK (AA_FILE_PERMS | AA_PTRACE_PERMS | \
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
3060 +#define AA_SECURE_EXEC_NEEDED 1
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;
3070 +#define PROFILE_COMPLAIN(_profile) \
3071 + (apparmor_complain == 1 || ((_profile) && (_profile)->flags.complain))
3073 +#define APPARMOR_COMPLAIN(_cxt) \
3074 + (apparmor_complain == 1 || \
3075 + ((_cxt) && (_cxt)->profile && (_cxt)->profile->flags.complain))
3077 +#define PROFILE_AUDIT(_profile) \
3078 + (apparmor_audit == 1 || ((_profile) && (_profile)->flags.audit))
3080 +#define APPARMOR_AUDIT(_cxt) \
3081 + (apparmor_audit == 1 || \
3082 + ((_cxt) && (_cxt)->profile && (_cxt)->profile->flags.audit))
3084 +#define PROFILE_IS_HAT(_profile) \
3085 + ((_profile) && (_profile)->flags.hat)
3088 + * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
3089 + * which is not related to profile accesses.
3092 +#define AA_DEBUG(fmt, args...) \
3094 + if (apparmor_debug) \
3095 + printk(KERN_DEBUG "AppArmor: " fmt, ##args); \
3098 +#define AA_ERROR(fmt, args...) do { if (printk_ratelimit()) printk(KERN_ERR "AppArmor: " fmt, ##args); } while (0)
3100 +/* struct aa_rlimit - rlimits settings for the profile
3101 + * @mask: which hard limits to set
3102 + * @limits: rlimit values that override task limits
3104 + * AppArmor rlimits are used to set confined task rlimits. Only the
3105 + * limits specified in @mask will be controlled by apparmor.
3108 + unsigned int mask;
3109 + struct rlimit limits[RLIM_NLIMITS];
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
3123 +struct aa_namespace {
3125 + struct list_head list;
3126 + struct list_head profiles;
3127 + int profile_count;
3128 + struct aa_profile *null_complain_profile;
3130 + struct kref count;
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
3155 + * The AppArmor profile contains the basic confinement data. Each profile
3156 + * has a name, and all nonstale profile are in a profile namespace.
3158 + * The task_contexts list and the isstale flag are protected by the
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
3165 +struct aa_profile {
3167 + struct list_head list;
3168 + struct aa_namespace *ns;
3170 + int exec_table_size;
3171 + char **exec_table;
3172 + struct aa_dfa *file_rules;
3180 + kernel_cap_t set_caps;
3181 + kernel_cap_t capabilities;
3182 + kernel_cap_t audit_caps;
3183 + kernel_cap_t quiet_caps;
3185 + struct aa_rlimit rlimits;
3186 + unsigned int task_count;
3188 + struct kref count;
3189 + struct list_head task_contexts;
3191 + unsigned long int_flags;
3192 + u16 network_families[AF_MAX];
3193 + u16 audit_network[AF_MAX];
3194 + u16 quiet_network[AF_MAX];
3197 +extern struct list_head profile_ns_list;
3198 +extern rwlock_t profile_ns_list_lock;
3199 +extern struct mutex aa_interface_lock;
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
3211 + * Contains the task's current profile (which could change due to
3212 + * change_hat). Plus the hat_magic needed during change_hat.
3214 +struct aa_task_context {
3215 + struct aa_profile *profile;
3216 + struct aa_profile *previous_profile;
3218 + struct list_head list;
3219 + struct task_struct *task;
3220 + struct rcu_head rcu;
3221 + kernel_cap_t caps_logged;
3224 +extern struct aa_namespace *default_namespace;
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.
3232 + const char *operation;
3236 + const char *name2;
3237 + const char *name3;
3238 + int request_mask, denied_mask, audit_mask;
3240 + struct iattr *iattr;
3241 + pid_t task, parent;
3242 + int family, type, protocol;
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 */
3250 +/* lock subtypes so lockdep does not raise false dependencies */
3251 +enum aa_lock_class {
3254 + aa_lock_task_release
3257 +/* apparmor/profiles */
3258 +extern struct seq_operations apparmorfs_profiles_op;
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,
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,
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,
3280 +extern int aa_perm_dir(struct aa_profile *profile, const char *operation,
3281 + struct dentry *dentry, struct vfsmount *mnt,
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,
3296 + struct aa_profile *profile);
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);
3315 +extern int apparmor_initialized;
3316 +extern void info_message(const char *str);
3317 +extern void apparmor_disable(void);
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);
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);
3339 +extern int aa_getprocattr(struct aa_profile *profile, char **string,
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);
3346 +extern int create_apparmorfs(void);
3347 +extern void destroy_apparmorfs(void);
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,
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);
3362 +#endif /* __APPARMOR_H */
3363 diff -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
3368 + * Copyright (C) 1998-2007 Novell/SUSE
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
3375 + * AppArmor filesystem (part of securityfs)
3378 +#include <linux/security.h>
3379 +#include <linux/vmalloc.h>
3380 +#include <linux/module.h>
3381 +#include <linux/seq_file.h>
3382 +#include <linux/uaccess.h>
3383 +#include <linux/namei.h>
3385 +#include "apparmor.h"
3386 +#include "inline.h"
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)
3392 + struct aa_profile *profile;
3396 + /* only writes from pos 0, that is complete writes */
3397 + data = ERR_PTR(-ESPIPE);
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.
3406 + profile = aa_get_profile(current);
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);
3418 + data = vmalloc(alloc_size);
3419 + if (data == NULL) {
3420 + data = ERR_PTR(-ENOMEM);
3424 + if (copy_from_user(data, userbuf, copy_size)) {
3426 + data = ERR_PTR(-EFAULT);
3434 +static int aa_profiles_open(struct inode *inode, struct file *file)
3436 + return seq_open(file, &apparmorfs_profiles_op);
3440 +static int aa_profiles_release(struct inode *inode, struct file *file)
3442 + return seq_release(inode, file);
3445 +static struct file_operations apparmorfs_profiles_fops = {
3446 + .open = aa_profiles_open,
3448 + .llseek = seq_lseek,
3449 + .release = aa_profiles_release,
3452 +/* apparmor/matching */
3453 +static ssize_t aa_matching_read(struct file *file, char __user *buf,
3454 + size_t size, loff_t *ppos)
3456 + const char *matching = "pattern=aadfa audit perms=rwxamlk/ user::other";
3458 + return simple_read_from_buffer(buf, size, ppos, matching,
3459 + strlen(matching));
3462 +static struct file_operations apparmorfs_matching_fops = {
3463 + .read = aa_matching_read,
3466 +/* apparmor/features */
3467 +static ssize_t aa_features_read(struct file *file, char __user *buf,
3468 + size_t size, loff_t *ppos)
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";
3474 + return simple_read_from_buffer(buf, size, ppos, features,
3475 + strlen(features));
3478 +static struct file_operations apparmorfs_features_fops = {
3479 + .read = aa_features_read,
3482 +/* apparmor/.load */
3483 +static ssize_t aa_profile_load(struct file *f, const char __user *buf,
3484 + size_t size, loff_t *pos)
3489 + data = aa_simple_write_to_buffer(buf, size, size, pos, "profile_load");
3491 + error = PTR_ERR(data);
3492 + if (!IS_ERR(data)) {
3493 + error = aa_add_profile(data, size);
3501 +static struct file_operations apparmorfs_profile_load = {
3502 + .write = aa_profile_load
3505 +/* apparmor/.replace */
3506 +static ssize_t aa_profile_replace(struct file *f, const char __user *buf,
3507 + size_t size, loff_t *pos)
3512 + data = aa_simple_write_to_buffer(buf, size, size, pos,
3513 + "profile_replace");
3515 + error = PTR_ERR(data);
3516 + if (!IS_ERR(data)) {
3517 + error = aa_replace_profile(data, size);
3525 +static struct file_operations apparmorfs_profile_replace = {
3526 + .write = aa_profile_replace
3529 +/* apparmor/.remove */
3530 +static ssize_t aa_profile_remove(struct file *f, const char __user *buf,
3531 + size_t size, loff_t *pos)
3537 + * aa_remove_profile needs a null terminated string so 1 extra
3538 + * byte is allocated and the copied data is null terminated.
3540 + data = aa_simple_write_to_buffer(buf, size + 1, size, pos,
3541 + "profile_remove");
3543 + error = PTR_ERR(data);
3544 + if (!IS_ERR(data)) {
3546 + error = aa_remove_profile(data, size);
3553 +static struct file_operations apparmorfs_profile_remove = {
3554 + .write = aa_profile_remove
3557 +static struct dentry *apparmor_dentry;
3559 +static void aafs_remove(const char *name)
3561 + struct dentry *dentry;
3563 + dentry = lookup_one_len(name, apparmor_dentry, strlen(name));
3564 + if (!IS_ERR(dentry)) {
3565 + securityfs_remove(dentry);
3570 +static int aafs_create(const char *name, int mask, struct file_operations *fops)
3572 + struct dentry *dentry;
3574 + dentry = securityfs_create_file(name, S_IFREG | mask, apparmor_dentry,
3577 + return IS_ERR(dentry) ? PTR_ERR(dentry) : 0;
3580 +void destroy_apparmorfs(void)
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;
3594 +int create_apparmorfs(void)
3598 + if (!apparmor_initialized)
3601 + if (apparmor_dentry) {
3602 + AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
3606 + apparmor_dentry = securityfs_create_dir("apparmor", NULL);
3607 + if (IS_ERR(apparmor_dentry)) {
3608 + error = PTR_ERR(apparmor_dentry);
3609 + apparmor_dentry = NULL;
3612 + error = aafs_create("profiles", 0440, &apparmorfs_profiles_fops);
3615 + error = aafs_create("matching", 0444, &apparmorfs_matching_fops);
3618 + error = aafs_create("features", 0444, &apparmorfs_features_fops);
3621 + error = aafs_create(".load", 0640, &apparmorfs_profile_load);
3624 + error = aafs_create(".replace", 0640, &apparmorfs_profile_replace);
3627 + error = aafs_create(".remove", 0640, &apparmorfs_profile_remove);
3631 + /* Report that AppArmor fs is enabled */
3632 + info_message("AppArmor Filesystem Enabled");
3636 + destroy_apparmorfs();
3637 + AA_ERROR("Error creating AppArmor securityfs\n");
3638 + apparmor_disable();
3642 +fs_initcall(create_apparmorfs);
3644 diff -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
3649 + * Copyright (C) 1998-2007 Novell/SUSE
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
3660 +#include <linux/sched.h>
3664 +static inline int mediated_filesystem(struct inode *inode)
3666 + return !(inode->i_sb->s_flags & MS_NOUSER);
3669 +static inline struct aa_task_context *aa_task_context(struct task_struct *task)
3671 + return rcu_dereference(task->security);
3674 +static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns)
3677 + kref_get(&(ns->count));
3682 +static inline void aa_put_namespace(struct aa_namespace *ns)
3685 + kref_put(&ns->count, free_aa_namespace_kref);
3689 +static inline struct aa_namespace *aa_find_namespace(const char *name)
3691 + struct aa_namespace *ns = NULL;
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);
3701 + * aa_dup_profile - increment refcount on profile @p
3704 +static inline struct aa_profile *aa_dup_profile(struct aa_profile *p)
3707 + kref_get(&(p->count));
3713 + * aa_put_profile - decrement refcount on profile @p
3716 +static inline void aa_put_profile(struct aa_profile *p)
3719 + kref_put(&p->count, free_aa_profile_kref);
3722 +static inline struct aa_profile *aa_get_profile(struct task_struct *task)
3724 + struct aa_task_context *cxt;
3725 + struct aa_profile *profile = NULL;
3728 + cxt = aa_task_context(task);
3730 + profile = cxt->profile;
3731 + aa_dup_profile(profile);
3733 + rcu_read_unlock();
3738 +static inline struct aa_profile *aa_find_profile(struct aa_namespace *ns,
3741 + struct aa_profile *profile;
3743 + read_lock(&ns->lock);
3744 + profile = aa_dup_profile(__aa_find_profile(name, &ns->profiles));
3745 + read_unlock(&ns->lock);
3750 +static inline struct aa_task_context *aa_alloc_task_context(gfp_t flags)
3752 + struct aa_task_context *cxt;
3754 + cxt = kzalloc(sizeof(*cxt), flags);
3756 + INIT_LIST_HEAD(&cxt->list);
3757 + INIT_RCU_HEAD(&cxt->rcu);
3763 +static inline void aa_free_task_context(struct aa_task_context *cxt)
3766 + aa_put_profile(cxt->profile);
3767 + aa_put_profile(cxt->previous_profile);
3773 + * lock_profile - lock a profile
3774 + * @profile: the profile to lock
3776 + * While the profile is locked, local interrupts are disabled. This also
3777 + * gives us RCU reader safety.
3779 +static inline void lock_profile_nested(struct aa_profile *profile,
3780 + enum aa_lock_class lock_class)
3783 + * Lock the profile.
3785 + * Need to disable interrupts here because this lock is used in
3786 + * the task_free_security hook, which may run in RCU context.
3789 + spin_lock_irqsave_nested(&profile->lock, profile->int_flags,
3793 +static inline void lock_profile(struct aa_profile *profile)
3795 + lock_profile_nested(profile, aa_lock_normal);
3799 + * unlock_profile - unlock a profile
3800 + * @profile: the profile to unlock
3802 +static inline void unlock_profile(struct aa_profile *profile)
3804 + /* Unlock the profile. */
3806 + spin_unlock_irqrestore(&profile->lock, profile->int_flags);
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)
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.
3819 +static inline void lock_both_profiles(struct aa_profile *profile1,
3820 + struct aa_profile *profile2)
3823 + * Lock the two profiles.
3825 + * We need to disable interrupts because the profile locks are
3826 + * used in the task_free_security hook, which may run in RCU
3829 + * Do not nest spin_lock_irqsave()/spin_unlock_irqresore():
3830 + * interrupts only need to be turned off once.
3832 + if (!profile1 || profile1 == profile2) {
3834 + spin_lock_irqsave_nested(&profile2->lock,
3835 + profile2->int_flags,
3837 + } else if (profile1 > profile2) {
3838 + /* profile1 cannot be NULL here. */
3839 + spin_lock_irqsave_nested(&profile1->lock, profile1->int_flags,
3842 + spin_lock_nested(&profile2->lock, aa_lock_nested);
3845 + /* profile2 cannot be NULL here. */
3846 + spin_lock_irqsave_nested(&profile2->lock, profile2->int_flags,
3848 + spin_lock_nested(&profile1->lock, aa_lock_nested);
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)
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.
3862 +static inline void unlock_both_profiles(struct aa_profile *profile1,
3863 + struct aa_profile *profile2)
3865 + /* Unlock the two profiles. */
3866 + if (!profile1 || profile1 == profile2) {
3868 + spin_unlock_irqrestore(&profile2->lock,
3869 + profile2->int_flags);
3870 + } else if (profile1 > profile2) {
3871 + /* profile1 cannot be NULL here. */
3873 + spin_unlock(&profile2->lock);
3874 + spin_unlock_irqrestore(&profile1->lock, profile1->int_flags);
3876 + /* profile2 cannot be NULL here. */
3877 + spin_unlock(&profile1->lock);
3878 + spin_unlock_irqrestore(&profile2->lock, profile2->int_flags);
3882 +static inline unsigned int aa_match(struct aa_dfa *dfa, const char *pathname,
3886 + return aa_dfa_match(dfa, pathname, audit_mask);
3892 +static inline int dfa_audit_mask(struct aa_dfa *dfa, unsigned int state)
3894 + return ACCEPT_TABLE2(dfa)[state];
3897 +#endif /* __INLINE_H__ */
3898 diff -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
3903 + * Copyright (C) 1998-2007 Novell/SUSE
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
3910 + * AppArmor Profile List Management
3913 +#include <linux/seq_file.h>
3914 +#include "apparmor.h"
3915 +#include "inline.h"
3917 +/* list of profile namespaces and lock */
3918 +LIST_HEAD(profile_ns_list);
3919 +DEFINE_RWLOCK(profile_ns_list_lock);
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
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.
3929 +struct aa_namespace *__aa_find_namespace(const char *name,
3930 + struct list_head *head)
3932 + struct aa_namespace *ns;
3934 + list_for_each_entry(ns, head, list) {
3935 + if (!strcmp(ns->name, name))
3943 + * __aa_find_profile - look up a profile on the profile list
3944 + * @name: name of profile to find
3945 + * @head: list to search
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.
3950 +struct aa_profile *__aa_find_profile(const char *name, struct list_head *head)
3952 + struct aa_profile *profile;
3954 + list_for_each_entry(profile, head, list) {
3955 + if (!strcmp(profile->name, name))
3962 +static void aa_profile_list_release(struct list_head *head)
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);
3977 + * aa_profilelist_release - Remove all profiles from profile_list
3979 +void aa_profile_ns_list_release(void)
3981 + struct aa_namespace *ns, *tmp;
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);
3992 + write_unlock(&profile_ns_list_lock);
3996 +static struct aa_profile *next_profile(struct aa_profile *profile)
3998 + struct aa_profile *next = profile;
3999 + struct aa_namespace *ns;
4001 + list_for_each_entry_continue(next, &profile->ns->profiles, list)
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)
4010 + read_unlock(&ns->lock);
4015 +static void *p_start(struct seq_file *f, loff_t *pos)
4016 + __acquires(profile_ns_list_lock)
4018 + struct aa_namespace *ns;
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);
4030 + read_unlock(&ns->lock);
4031 + for ( ; profile && l > 0; l--)
4032 + profile = next_profile(profile);
4038 +static void *p_next(struct seq_file *f, void *p, loff_t *pos)
4040 + struct aa_profile *profile = (struct aa_profile *) p;
4043 + profile = next_profile(profile);
4048 +static void p_stop(struct seq_file *f, void *p)
4049 + __releases(profile_ns_list_lock)
4051 + struct aa_profile *profile = (struct aa_profile *) p;
4054 + read_unlock(&profile->ns->lock);
4055 + read_unlock(&profile_ns_list_lock);
4058 +static int seq_show_profile(struct seq_file *f, void *p)
4060 + struct aa_profile *profile = (struct aa_profile *)p;
4062 + if (profile->ns == default_namespace)
4063 + seq_printf(f, "%s (%s)\n", profile->name,
4064 + PROFILE_COMPLAIN(profile) ? "complain" : "enforce");
4066 + seq_printf(f, ":%s:%s (%s)\n", profile->ns->name, profile->name,
4067 + PROFILE_COMPLAIN(profile) ? "complain" : "enforce");
4071 +/* Used in apparmorfs.c */
4072 +struct seq_operations apparmorfs_profiles_op = {
4076 + .show = seq_show_profile,
4078 diff -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
4082 +Locking in AppArmor
4083 +===================
4093 +Which lock protects what?
4095 + /-----------------------+-------------------------------\
4096 + | Variable | Lock |
4097 + >-----------------------+-------------------------------<
4098 + | profile_list | profile_list_lock |
4099 + +-----------------------+-------------------------------+
4100 + | aa_profile | (reference count) |
4101 + +-----------------------+-------------------------------+
4102 + | aa_profile-> | aa_profile->lock |
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 + \-----------------------+-------------------------------/
4113 +(Obviously, the list_heads embedded in data structures are always
4114 +protected with the lock that also protects the list.)
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.
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
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).
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.
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.
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.
4150 diff -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
4155 + * Copyright (C) 1998-2007 Novell/SUSE
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
4162 + * AppArmor LSM interface
4165 +#include <linux/security.h>
4166 +#include <linux/moduleparam.h>
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>
4176 +#include "apparmor.h"
4177 +#include "inline.h"
4179 +/* Flag indicating whether initialization completed */
4180 +int apparmor_initialized;
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)
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)
4190 +/* Flag values, also controllable via /sys/module/apparmor/parameters
4191 + * We define special types as we want to do additional mediation.
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
4199 +int apparmor_complain;
4200 +module_param_named(complain, apparmor_complain, aabool, S_IRUSR | S_IWUSR);
4203 +int apparmor_debug;
4204 +module_param_named(debug, apparmor_debug, aabool, S_IRUSR | S_IWUSR);
4207 +int apparmor_audit;
4208 +module_param_named(audit, apparmor_audit, aabool, S_IRUSR | S_IWUSR);
4209 +/* Syscall logging mode */
4210 +int apparmor_logsyscall;
4211 +module_param_named(logsyscall, apparmor_logsyscall, aabool, S_IRUSR | S_IWUSR);
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);
4217 +/* Boot time disable flag */
4218 +#ifdef CONFIG_SECURITY_APPARMOR_DISABLE
4219 +#define AA_ENABLED_PERMS 0600
4221 +#define AA_ENABLED_PERMS 0400
4223 +static int param_set_aa_enabled(const char *val, struct kernel_param *kp);
4224 +static unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
4225 +module_param_call(enabled, param_set_aa_enabled, param_get_aauint,
4226 + &apparmor_enabled, AA_ENABLED_PERMS);
4228 +static int __init apparmor_enabled_setup(char *str)
4230 + apparmor_enabled = simple_strtol(str, NULL, 0);
4233 +__setup("apparmor=", apparmor_enabled_setup);
4235 +static int param_set_aabool(const char *val, struct kernel_param *kp)
4237 + if (aa_task_context(current))
4239 + return param_set_bool(val, kp);
4242 +static int param_get_aabool(char *buffer, struct kernel_param *kp)
4244 + if (aa_task_context(current))
4246 + return param_get_bool(buffer, kp);
4249 +static int param_set_aauint(const char *val, struct kernel_param *kp)
4251 + if (aa_task_context(current))
4253 + return param_set_uint(val, kp);
4256 +static int param_get_aauint(char *buffer, struct kernel_param *kp)
4258 + if (aa_task_context(current))
4260 + return param_get_uint(buffer, kp);
4263 +/* allow run time disabling of apparmor */
4264 +static int param_set_aa_enabled(const char *val, struct kernel_param *kp)
4268 + if (!apparmor_initialized) {
4269 + apparmor_enabled = 0;
4273 + if (aa_task_context(current))
4276 + if (!apparmor_enabled)
4282 + if (strict_strtoul(val, 0, &l) || l != 0)
4285 + apparmor_enabled = 0;
4286 + apparmor_disable();
4290 +static int apparmor_ptrace(struct task_struct *tracer,
4291 + struct task_struct *tracee)
4293 + struct aa_task_context *cxt;
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
4306 + cxt = aa_task_context(tracer);
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);
4319 + struct aa_task_context *tracee_cxt =
4320 + aa_task_context(tracee);
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);
4335 + rcu_read_unlock();
4340 +static int apparmor_ptrace_may_access(struct task_struct *child,
4341 + unsigned int mode)
4343 + return apparmor_ptrace(current, child);
4347 +static int apparmor_ptrace_traceme(struct task_struct *parent)
4349 + return apparmor_ptrace(parent, current);
4352 +static int apparmor_capable(struct task_struct *task, int cap)
4355 + struct aa_task_context *cxt;
4357 + /* cap_capable returns 0 on success, else -EPERM */
4358 + error = cap_capable(task, cap);
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();
4369 +static int apparmor_sysctl(struct ctl_table *table, int op)
4371 + struct aa_profile *profile = aa_get_profile(current);
4375 + char *buffer, *name;
4382 + mask |= MAY_WRITE;
4385 + buffer = (char *)__get_free_page(GFP_KERNEL);
4388 + name = sysctl_pathname(table, buffer, PAGE_SIZE);
4389 + if (name && name - buffer >= 5) {
4391 + memcpy(name, "/proc", 5);
4392 + error = aa_perm_path(profile, "sysctl", name, mask, 0);
4394 + free_page((unsigned long)buffer);
4398 + aa_put_profile(profile);
4402 +static int apparmor_bprm_set_security(struct linux_binprm *bprm)
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)
4409 + return aa_register(bprm);
4412 +static int apparmor_bprm_secureexec(struct linux_binprm *bprm)
4414 + int ret = cap_bprm_secureexec(bprm);
4416 + if (!ret && (unsigned long)bprm->security & AA_SECURE_EXEC_NEEDED) {
4417 + AA_DEBUG("%s: secureexec required for %s\n",
4418 + __func__, bprm->filename);
4425 +static int apparmor_inode_mkdir(struct inode *dir, struct dentry *dentry,
4426 + struct vfsmount *mnt, int mask)
4428 + struct aa_profile *profile;
4431 + if (!mnt || !mediated_filesystem(dir))
4434 + profile = aa_get_profile(current);
4437 + error = aa_perm_dir(profile, "inode_mkdir", dentry, mnt,
4440 + aa_put_profile(profile);
4446 +static int apparmor_inode_rmdir(struct inode *dir, struct dentry *dentry,
4447 + struct vfsmount *mnt)
4449 + struct aa_profile *profile;
4452 + if (!mnt || !mediated_filesystem(dir))
4455 + profile = aa_get_profile(current);
4458 + error = aa_perm_dir(profile, "inode_rmdir", dentry, mnt,
4461 + aa_put_profile(profile);
4467 +static int aa_permission(const char *operation, struct inode *inode,
4468 + struct dentry *dentry, struct vfsmount *mnt,
4469 + int mask, int check)
4473 + if (mnt && mediated_filesystem(inode)) {
4474 + struct aa_profile *profile;
4476 + profile = aa_get_profile(current);
4478 + error = aa_perm(profile, operation, dentry, mnt, mask,
4480 + aa_put_profile(profile);
4485 +static inline int aa_mask_permissions(int mask)
4487 + if (mask & MAY_APPEND)
4488 + mask &= (MAY_READ | MAY_APPEND | MAY_EXEC);
4490 + mask &= (MAY_READ | MAY_WRITE | MAY_EXEC);
4494 +static int apparmor_inode_create(struct inode *dir, struct dentry *dentry,
4495 + struct vfsmount *mnt, int mask)
4497 + return aa_permission("inode_create", dir, dentry, mnt, MAY_APPEND, 0);
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)
4506 + struct aa_profile *profile;
4508 + if (!old_mnt || !new_mnt || !mediated_filesystem(dir))
4511 + profile = aa_get_profile(current);
4514 + error = aa_link(profile, new_dentry, new_mnt,
4515 + old_dentry, old_mnt);
4517 + aa_put_profile(profile);
4523 +static int apparmor_inode_unlink(struct inode *dir, struct dentry *dentry,
4524 + struct vfsmount *mnt)
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,
4534 +static int apparmor_inode_symlink(struct inode *dir, struct dentry *dentry,
4535 + struct vfsmount *mnt, const char *old_name)
4537 + return aa_permission("inode_symlink", dir, dentry, mnt, MAY_WRITE, 0);
4540 +static int apparmor_inode_mknod(struct inode *dir, struct dentry *dentry,
4541 + struct vfsmount *mnt, int mode, dev_t dev)
4543 + return aa_permission("inode_mknod", dir, dentry, mnt, MAY_WRITE, 0);
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)
4553 + struct aa_profile *profile;
4556 + if ((!old_mnt && !new_mnt) || !mediated_filesystem(old_dir))
4559 + profile = aa_get_profile(current);
4562 + struct inode *inode = old_dentry->d_inode;
4565 + if (inode && S_ISDIR(inode->i_mode))
4566 + check |= AA_CHECK_DIR;
4568 + error = aa_perm(profile, "inode_rename", old_dentry,
4569 + old_mnt, MAY_READ | MAY_WRITE, check);
4571 + if (!error && new_mnt) {
4572 + error = aa_perm(profile, "inode_rename", new_dentry,
4573 + new_mnt, MAY_WRITE, check);
4577 + aa_put_profile(profile);
4583 +static int apparmor_inode_permission(struct inode *inode, int mask)
4588 +static int apparmor_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
4589 + struct iattr *iattr)
4596 + if (mediated_filesystem(dentry->d_inode)) {
4597 + struct aa_profile *profile;
4599 + profile = aa_get_profile(current);
4601 + * Mediate any attempt to change attributes of a file
4602 + * (chmod, chown, chgrp, etc)
4605 + error = aa_attr(profile, dentry, mnt, iattr);
4607 + aa_put_profile(profile);
4614 +static int aa_xattr_permission(struct dentry *dentry, struct vfsmount *mnt,
4615 + const char *operation, int mask,
4616 + struct file *file)
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;
4625 + error = aa_perm_xattr(profile, operation, dentry, mnt,
4627 + aa_put_profile(profile);
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)
4637 + int error = cap_inode_setxattr(dentry, mnt, name, value, size, flags,
4641 + error = aa_xattr_permission(dentry, mnt, "xattr set",
4646 +static int apparmor_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
4647 + const char *name, struct file *file)
4649 + return aa_xattr_permission(dentry, mnt, "xattr get", MAY_READ, file);
4652 +static int apparmor_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt,
4653 + struct file *file)
4655 + return aa_xattr_permission(dentry, mnt, "xattr list", MAY_READ, file);
4658 +static int apparmor_inode_removexattr(struct dentry *dentry,
4659 + struct vfsmount *mnt, const char *name,
4660 + struct file *file)
4662 + return aa_xattr_permission(dentry, mnt, "xattr remove", MAY_WRITE,
4666 +static int aa_file_permission(const char *op, struct file *file, int mask)
4668 + struct aa_profile *profile;
4669 + struct aa_profile *file_profile = file->f_security;
4672 + if (!file_profile)
4676 + * If this file was opened under a different profile, we
4677 + * revalidate the access against the current profile.
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;
4687 + * FIXME: We should remember which profiles we revalidated
4690 + if (S_ISDIR(inode->i_mode))
4691 + check |= AA_CHECK_DIR;
4692 + error = aa_permission(op, inode, dentry, mnt, mask, check);
4694 + aa_put_profile(profile);
4700 +static int apparmor_file_permission(struct file *file, int mask)
4702 + return aa_file_permission("file_permission", file,
4703 + aa_mask_permissions(mask));
4706 +static int apparmor_file_lock(struct file *file, unsigned int cmd)
4708 + int mask = AA_MAY_LOCK;
4709 + if (cmd == F_WRLCK)
4710 + mask |= MAY_WRITE;
4711 + return aa_file_permission("file_lock", file, mask);
4714 +static int apparmor_file_alloc_security(struct file *file)
4716 + struct aa_profile *profile;
4718 + profile = aa_get_profile(current);
4720 + file->f_security = profile;
4725 +static void apparmor_file_free_security(struct file *file)
4727 + struct aa_profile *file_profile = file->f_security;
4729 + aa_put_profile(file_profile);
4732 +static int aa_mmap(struct file *file, const char *operation,
4733 + unsigned long prot, unsigned long flags)
4735 + struct dentry *dentry;
4738 + if (!file || !file->f_security)
4741 + if (prot & PROT_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;
4750 + dentry = file->f_dentry;
4751 + return aa_permission(operation, dentry->d_inode, dentry,
4752 + file->f_vfsmnt, mask, AA_CHECK_FD);
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)
4759 + if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) {
4760 + struct aa_profile *profile = aa_get_profile(current);
4762 + /* future control check here */
4766 + aa_put_profile(profile);
4769 + return aa_mmap(file, "file_mmap", prot, flags);
4772 +static int apparmor_file_mprotect(struct vm_area_struct *vma,
4773 + unsigned long reqprot, unsigned long prot)
4775 + return aa_mmap(vma->vm_file, "file_mprotect", prot,
4776 + !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
4779 +static int apparmor_path_permission(struct path *path, int mask)
4781 + struct inode *inode;
4787 + inode = path->dentry->d_inode;
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;
4798 + return aa_permission("inode_permission", inode, path->dentry,
4799 + path->mnt, mask, check);
4802 +static int apparmor_task_alloc_security(struct task_struct *task)
4804 + return aa_clone(task);
4808 + * Called from IRQ context from RCU callback.
4810 +static void apparmor_task_free_security(struct task_struct *task)
4815 +static int apparmor_socket_create(int family, int type, int protocol, int kern)
4817 + struct aa_profile *profile;
4823 + profile = aa_get_profile(current);
4825 + error = aa_net_perm(profile, "socket_create", family,
4827 + aa_put_profile(profile);
4832 +static int apparmor_socket_post_create(struct socket *sock, int family,
4833 + int type, int protocol, int kern)
4835 + struct sock *sk = sock->sk;
4840 + return aa_revalidate_sk(sk, "socket_post_create");
4843 +static int apparmor_socket_bind(struct socket *sock,
4844 + struct sockaddr *address, int addrlen)
4846 + struct sock *sk = sock->sk;
4848 + return aa_revalidate_sk(sk, "socket_bind");
4851 +static int apparmor_socket_connect(struct socket *sock,
4852 + struct sockaddr *address, int addrlen)
4854 + struct sock *sk = sock->sk;
4856 + return aa_revalidate_sk(sk, "socket_connect");
4859 +static int apparmor_socket_listen(struct socket *sock, int backlog)
4861 + struct sock *sk = sock->sk;
4863 + return aa_revalidate_sk(sk, "socket_listen");
4866 +static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
4868 + struct sock *sk = sock->sk;
4870 + return aa_revalidate_sk(sk, "socket_accept");
4873 +static int apparmor_socket_sendmsg(struct socket *sock,
4874 + struct msghdr *msg, int size)
4876 + struct sock *sk = sock->sk;
4878 + return aa_revalidate_sk(sk, "socket_sendmsg");
4881 +static int apparmor_socket_recvmsg(struct socket *sock,
4882 + struct msghdr *msg, int size, int flags)
4884 + struct sock *sk = sock->sk;
4886 + return aa_revalidate_sk(sk, "socket_recvmsg");
4889 +static int apparmor_socket_getsockname(struct socket *sock)
4891 + struct sock *sk = sock->sk;
4893 + return aa_revalidate_sk(sk, "socket_getsockname");
4896 +static int apparmor_socket_getpeername(struct socket *sock)
4898 + struct sock *sk = sock->sk;
4900 + return aa_revalidate_sk(sk, "socket_getpeername");
4903 +static int apparmor_socket_getsockopt(struct socket *sock, int level,
4906 + struct sock *sk = sock->sk;
4908 + return aa_revalidate_sk(sk, "socket_getsockopt");
4911 +static int apparmor_socket_setsockopt(struct socket *sock, int level,
4914 + struct sock *sk = sock->sk;
4916 + return aa_revalidate_sk(sk, "socket_setsockopt");
4919 +static int apparmor_socket_shutdown(struct socket *sock, int how)
4921 + struct sock *sk = sock->sk;
4923 + return aa_revalidate_sk(sk, "socket_shutdown");
4926 +static int apparmor_getprocattr(struct task_struct *task, char *name,
4931 + struct aa_profile *profile;
4933 + /* AppArmor only supports the "current" process attribute */
4934 + if (strcmp(name, "current") != 0)
4937 + /* must be task querying itself or admin */
4938 + if (current != task && !capable(CAP_SYS_ADMIN))
4941 + profile = aa_get_profile(task);
4942 + error = aa_getprocattr(profile, value, &len);
4943 + aa_put_profile(profile);
4950 +static int apparmor_setprocattr(struct task_struct *task, char *name,
4951 + void *value, size_t size)
4953 + char *command, *args;
4956 + if (strcmp(name, "current") != 0 || size == 0 || size >= PAGE_SIZE)
4959 + args[size] = '\0';
4960 + args = strstrip(args);
4961 + command = strsep(&args, " ");
4964 + while (isspace(*args))
4969 + if (strcmp(command, "changehat") == 0) {
4970 + if (current != task)
4972 + error = aa_setprocattr_changehat(args);
4973 + } else if (strcmp(command, "changeprofile") == 0) {
4974 + if (current != task)
4976 + error = aa_setprocattr_changeprofile(args);
4977 + } else if (strcmp(command, "setprofile") == 0) {
4978 + struct aa_profile *profile;
4980 + /* Only an unconfined process with admin capabilities
4981 + * may change the profile of another task.
4984 + if (!capable(CAP_SYS_ADMIN))
4987 + profile = aa_get_profile(current);
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);
4999 + error = aa_setprocattr_setprofile(task, args);
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);
5017 +static int apparmor_task_setrlimit(unsigned int resource,
5018 + struct rlimit *new_rlim)
5020 + struct aa_profile *profile;
5023 + profile = aa_get_profile(current);
5025 + error = aa_task_setrlimit(profile, resource, new_rlim);
5027 + aa_put_profile(profile);
5032 +static struct security_operations apparmor_ops = {
5033 + .name = "apparmor",
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,
5043 + .bprm_apply_creds = cap_bprm_apply_creds,
5044 + .bprm_set_security = apparmor_bprm_set_security,
5045 + .bprm_secureexec = apparmor_bprm_secureexec,
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,
5068 + .path_permission = apparmor_path_permission,
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,
5076 + .getprocattr = apparmor_getprocattr,
5077 + .setprocattr = apparmor_setprocattr,
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,
5094 +void info_message(const char *str)
5096 + struct aa_audit sa;
5097 + memset(&sa, 0, sizeof(sa));
5098 + sa.gfp_mask = GFP_KERNEL;
5100 + printk(KERN_INFO "AppArmor: %s\n", str);
5101 + if (audit_enabled)
5102 + aa_audit_message(NULL, &sa, AUDIT_APPARMOR_STATUS);
5105 +static int __init apparmor_init(void)
5109 + if (!apparmor_enabled || !security_module_enable(&apparmor_ops)) {
5110 + info_message("AppArmor disabled by boot time parameter\n");
5114 + error = create_apparmorfs();
5116 + AA_ERROR("Unable to activate AppArmor filesystem\n");
5117 + goto createfs_out;
5120 + error = alloc_default_namespace();
5122 + AA_ERROR("Unable to allocate default profile namespace\n");
5126 + error = register_security(&apparmor_ops);
5128 + AA_ERROR("Unable to register AppArmor\n");
5129 + goto register_security_out;
5132 + /* Report that AppArmor successfully initialized */
5133 + apparmor_initialized = 1;
5134 + if (apparmor_complain)
5135 + info_message("AppArmor initialized: complainmode enabled");
5137 + info_message("AppArmor initialized");
5141 +register_security_out:
5142 + free_default_namespace();
5145 + destroy_apparmorfs();
5152 +security_initcall(apparmor_init);
5154 +void apparmor_disable(void)
5156 + /* Remove and release all the profiles on the profile list. */
5157 + mutex_lock(&aa_interface_lock);
5158 + aa_profile_ns_list_release();
5160 + /* FIXME: cleanup profiles references on files */
5161 + free_default_namespace();
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.
5168 + synchronize_rcu();
5170 + destroy_apparmorfs();
5171 + mutex_unlock(&aa_interface_lock);
5173 + apparmor_initialized = 0;
5175 + info_message("AppArmor protection removed");
5178 diff -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
5183 + * Copyright (C) 2002-2007 Novell/SUSE
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
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>
5202 +#include "apparmor.h"
5204 +#include "inline.h"
5207 + * Table of capability names: we generate it from capabilities.h.
5209 +static const char *capability_names[] = {
5210 +#include "capability_names.h"
5213 +struct aa_namespace *default_namespace;
5215 +static int aa_inode_mode(struct inode *inode)
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;
5223 +int alloc_default_namespace(void)
5225 + struct aa_namespace *ns;
5226 + char *name = kstrdup("default", GFP_KERNEL);
5229 + ns = alloc_aa_namespace(name);
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);
5244 +void free_default_namespace(void)
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;
5253 +static void aa_audit_file_sub_mask(struct audit_buffer *ab, char *buffer,
5256 + const char unsafex[] = "upcn";
5257 + const char safex[] = "UPCN";
5260 + if (mask & AA_EXEC_MMAP)
5262 + if (mask & MAY_READ)
5264 + if (mask & MAY_WRITE)
5266 + else if (mask & MAY_APPEND)
5268 + if (mask & MAY_EXEC) {
5269 + int index = AA_EXEC_INDEX(mask);
5270 + /* all indexes > 4 are also named transitions */
5274 + if (mask & AA_EXEC_UNSAFE)
5275 + *m++ = unsafex[index - 1];
5277 + *m++ = safex[index - 1];
5279 + if (mask & AA_EXEC_INHERIT)
5283 + if (mask & AA_MAY_LINK)
5285 + if (mask & AA_MAY_LOCK)
5290 +static void aa_audit_file_mask(struct audit_buffer *ab, const char *name,
5293 + char user[10], other[10];
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);
5300 + audit_log_format(ab, " %s=\"%s::%s\"", name, user, other);
5303 +static const char *address_families[] = {
5304 +#include "af_names.h"
5307 +static const char *sock_types[] = {
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
5328 +static int aa_audit_base(struct aa_profile *profile, struct aa_audit *sa,
5329 + struct audit_context *audit_cxt, int type)
5331 + struct audit_buffer *ab = NULL;
5333 + ab = audit_log_start(audit_cxt, sa->gfp_mask, type);
5336 + AA_ERROR("Unable to log event (%d) to audit subsys\n",
5338 + /* don't fail operations in complain mode even if logging
5340 + return type == AUDIT_APPARMOR_ALLOWED ? 0 : -ENOMEM;
5343 + if (sa->operation)
5344 + audit_log_format(ab, "operation=\"%s\"", sa->operation);
5347 + audit_log_format(ab, " info=\"%s\"", sa->info);
5348 + if (sa->error_code)
5349 + audit_log_format(ab, " error=%d", sa->error_code);
5352 + if (sa->request_mask)
5353 + aa_audit_file_mask(ab, "requested_mask", sa->request_mask);
5355 + if (sa->denied_mask)
5356 + aa_audit_file_mask(ab, "denied_mask", sa->denied_mask);
5358 + if (sa->request_mask)
5359 + audit_log_format(ab, " fsuid=%d", current->fsuid);
5362 + audit_log_format(ab, " rlimit=%d", sa->rlimit - 1);
5365 + struct iattr *iattr = sa->iattr;
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) ?
5374 + iattr->ia_valid & (ATTR_MTIME | ATTR_MTIME_SET) ?
5376 + iattr->ia_valid & ATTR_CTIME ? "ctime," : "");
5380 + audit_log_format(ab, " task=%d", sa->task);
5383 + audit_log_format(ab, " parent=%d", sa->parent);
5386 + audit_log_format(ab, " name=");
5387 + audit_log_untrustedstring(ab, sa->name);
5391 + audit_log_format(ab, " name2=");
5392 + audit_log_untrustedstring(ab, sa->name2);
5395 + if (sa->family || sa->type) {
5396 + if (address_families[sa->family])
5397 + audit_log_format(ab, " family=\"%s\"",
5398 + address_families[sa->family]);
5400 + audit_log_format(ab, " family=\"unknown(%d)\"",
5403 + if (sock_types[sa->type])
5404 + audit_log_format(ab, " sock_type=\"%s\"",
5405 + sock_types[sa->type]);
5407 + audit_log_format(ab, " sock_type=\"unknown(%d)\"",
5410 + audit_log_format(ab, " protocol=%d", sa->protocol);
5413 + audit_log_format(ab, " pid=%d", current->pid);
5417 + audit_log_format(ab, " parent=%d",
5418 + current->real_parent->pid);
5420 + audit_log_format(ab, " profile=");
5421 + audit_log_untrustedstring(ab, profile->name);
5423 + if (profile->ns != default_namespace) {
5424 + audit_log_format(ab, " namespace=");
5425 + audit_log_untrustedstring(ab, profile->ns->name);
5429 + audit_log_end(ab);
5431 + return type == AUDIT_APPARMOR_ALLOWED ? 0 : sa->error_code;
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
5440 +int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp,
5443 + struct aa_audit sa;
5444 + memset(&sa, 0, sizeof(sa));
5445 + sa.operation = "syscall";
5447 + sa.gfp_mask = gfp;
5448 + sa.error_code = -EPERM;
5450 + return aa_audit_base(profile, &sa, current->audit_context,
5451 + AUDIT_APPARMOR_DENIED);
5454 +int aa_audit_message(struct aa_profile *profile, struct aa_audit *sa,
5457 + struct audit_context *audit_cxt;
5459 + audit_cxt = apparmor_logsyscall ? current->audit_context : NULL;
5460 + return aa_audit_base(profile, sa, audit_cxt, type);
5463 +void aa_audit_hint(struct aa_profile *profile, struct aa_audit *sa)
5465 + aa_audit_message(profile, sa, AUDIT_APPARMOR_HINT);
5468 +void aa_audit_status(struct aa_profile *profile, struct aa_audit *sa)
5470 + aa_audit_message(profile, sa, AUDIT_APPARMOR_STATUS);
5473 +int aa_audit_reject(struct aa_profile *profile, struct aa_audit *sa)
5475 + return aa_audit_message(profile, sa, AUDIT_APPARMOR_DENIED);
5479 + * aa_audit - Log an audit event to the audit subsystem
5480 + * @profile: profile to check against
5481 + * @sa: audit event
5483 +static int aa_audit(struct aa_profile *profile, struct aa_audit *sa)
5485 + int type = AUDIT_APPARMOR_DENIED;
5486 + struct audit_context *audit_cxt;
5488 + if (likely(!sa->error_code))
5489 + type = AUDIT_APPARMOR_AUDIT;
5490 + else if (PROFILE_COMPLAIN(profile))
5491 + type = AUDIT_APPARMOR_ALLOWED;
5493 + audit_cxt = apparmor_logsyscall ? current->audit_context : NULL;
5494 + return aa_audit_base(profile, sa, audit_cxt, type);
5497 +static int aa_audit_file(struct aa_profile *profile, struct aa_audit *sa)
5499 + if (likely(!sa->error_code)) {
5500 + int mask = sa->audit_mask & AUDIT_FILE_MASK;
5502 + if (unlikely(PROFILE_AUDIT(profile)))
5503 + mask |= AUDIT_FILE_MASK;
5505 + if (likely(!(sa->request_mask & mask)))
5508 + /* mask off perms that are not being force audited */
5509 + sa->request_mask &= mask | ALL_AA_EXEC_TYPE;
5511 + int mask = AUDIT_QUIET_MASK(sa->audit_mask);
5513 + if (!(sa->denied_mask & ~mask) && !PROFILE_COMPLAIN(profile))
5514 + return sa->error_code;
5516 + /* mask off perms whose denial is being silenced */
5517 + if (!PROFILE_COMPLAIN(profile))
5518 + sa->denied_mask &= (~mask) | ALL_AA_EXEC_TYPE;
5521 + return aa_audit(profile, sa);
5524 +static int aa_audit_caps(struct aa_profile *profile, struct aa_audit *sa,
5527 + if (likely(!sa->error_code)) {
5528 + if (likely(!PROFILE_AUDIT(profile) &&
5529 + !cap_raised(profile->audit_caps, cap)))
5533 + /* quieting of capabilities is handled the caps_logged cache */
5534 + return aa_audit(profile, sa);
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
5544 + * Return %0 on success, or else the permissions in @mask that the
5547 +static int aa_file_denied(struct aa_profile *profile, const char *name,
5548 + int mask, int *audit_mask)
5550 + return (mask & ~aa_match(profile->file_rules, name, audit_mask));
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.
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)
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;
5571 + *request_mask = link_mask;
5573 + l_mode = aa_match_state(profile->file_rules, DFA_START, link, &state);
5575 + if (l_mode & link_mask) {
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,
5582 + if (!(mode & link_mask))
5583 + denied_mask |= link_mask;
5585 + *audit_mask = dfa_audit_mask(profile->file_rules, state);
5587 + /* return if link subset test is not required */
5588 + if (!(mode & (AA_LINK_SUBSET_TEST << target_mode)))
5589 + return denied_mask;
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.
5598 + * If the link has 'x', an exact match of all the execute flags
5601 + denied_mask |= ~l_mode & link_mask;
5603 + t_mode = aa_match(profile->file_rules, target, NULL);
5605 + l_x = l_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS);
5606 + t_x = t_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS);
5608 + /* For actual subset test ignore valid-profile-transition flags,
5611 + l_mode &= AA_FILE_PERMS & ~AA_LINK_BITS;
5612 + t_mode &= AA_FILE_PERMS & ~AA_LINK_BITS;
5614 + *request_mask = l_mode | link_mask;
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 */
5621 + /* handle exec subset
5622 + * - link safe exec issubset of unsafe exec
5623 + * - no link x perm is subset of target having x perm
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) &&
5629 + (x & AA_OTHER_EXEC_TYPE) != (t_x & AA_OTHER_EXEC_TYPE)) {
5631 + AA_OTHER_EXEC | (l_x & AA_OTHER_EXEC_TYPE);
5635 + return denied_mask;
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
5645 + * Returns a pointer to the beginning of the pathname (which usually differs
5646 + * from the beginning of the buffer), or an error code.
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.
5651 +static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt,
5652 + char **buffer, int check)
5655 + int is_dir, size = 256;
5657 + is_dir = (check & AA_CHECK_DIR) ? 1 : 0;
5660 + char *buf = kmalloc(size, GFP_KERNEL);
5662 + return ERR_PTR(-ENOMEM);
5664 + name = d_namespace_path(dentry, mnt, buf, size - is_dir);
5665 + if (!IS_ERR(name)) {
5666 + if (name[0] != '/') {
5668 + * This dentry is not connected to the
5669 + * namespace root -- reject access.
5672 + return ERR_PTR(-ENOENT);
5674 + if (is_dir && name[1] != '\0') {
5676 + * Append "/" to the pathname. The root
5677 + * directory is a special case; it already
5680 + buf[size - 2] = '/';
5681 + buf[size - 1] = '\0';
5687 + if (PTR_ERR(name) != -ENAMETOOLONG)
5692 + if (size > apparmor_path_max)
5693 + return ERR_PTR(-ENAMETOOLONG);
5697 +static char *new_compound_name(const char *n1, const char *n2)
5699 + char *name = kmalloc(strlen(n1) + strlen(n2) + 3, GFP_KERNEL);
5701 + sprintf(name, "%s//%s", n1, n2);
5705 +static void aa_put_name_buffer(char *buffer)
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
5719 + * Returns 0 upon success, or else an error code.
5721 + * @check indicates the file type, and whether the file was accessed through
5722 + * an open file descriptor (AA_CHECK_FD) or not.
5724 +static int aa_perm_dentry(struct aa_profile *profile, struct dentry *dentry,
5725 + struct vfsmount *mnt, struct aa_audit *sa, int check)
5728 + char *buffer = NULL;
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)) {
5734 + * deleted files are given a pass on permission checks when
5735 + * accessed through a file descriptor.
5737 + if (PTR_ERR(sa->name) == -ENOENT && (check & AA_CHECK_FD))
5738 + sa->denied_mask = 0;
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";
5747 + sa->info = "Failed name resolution";
5751 + sa->denied_mask = aa_file_denied(profile, sa->name,
5755 + if (!sa->denied_mask)
5756 + sa->error_code = 0;
5758 + error = aa_audit_file(profile, sa);
5759 + aa_put_name_buffer(buffer);
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
5771 +int aa_attr(struct aa_profile *profile, struct dentry *dentry,
5772 + struct vfsmount *mnt, struct iattr *iattr)
5774 + struct inode *inode = dentry->d_inode;
5776 + struct aa_audit sa;
5778 + memset(&sa, 0, sizeof(sa));
5779 + sa.operation = "setattr";
5780 + sa.gfp_mask = GFP_KERNEL;
5782 + sa.request_mask = MAY_WRITE;
5783 + sa.error_code = -EACCES;
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;
5791 + error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
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
5805 +int aa_perm_xattr(struct aa_profile *profile, const char *operation,
5806 + struct dentry *dentry, struct vfsmount *mnt, int mask,
5809 + struct inode *inode = dentry->d_inode;
5811 + struct aa_audit sa;
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;
5819 + if (inode && S_ISDIR(inode->i_mode))
5820 + check |= AA_CHECK_DIR;
5822 + error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
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
5835 + * Determine if access @mask for the file is authorized by @profile.
5836 + * Returns 0 on success, or else an error code.
5838 +int aa_perm(struct aa_profile *profile, const char *operation,
5839 + struct dentry *dentry, struct vfsmount *mnt, int mask, int check)
5841 + struct aa_audit sa;
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;
5853 + error = aa_perm_dentry(profile, dentry, mnt, &sa, check);
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
5867 + * Determine if directory operation (make/remove) for dentry is authorized
5869 + * Returns 0 on success, or else an error code.
5871 +int aa_perm_dir(struct aa_profile *profile, const char *operation,
5872 + struct dentry *dentry, struct vfsmount *mnt, int mask)
5874 + struct aa_audit sa;
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;
5882 + return aa_perm_dentry(profile, dentry, mnt, &sa, AA_CHECK_DIR);
5885 +int aa_perm_path(struct aa_profile *profile, const char *operation,
5886 + const char *name, int mask, uid_t uid)
5888 + struct aa_audit sa;
5890 + memset(&sa, 0, sizeof(sa));
5891 + sa.operation = operation;
5892 + sa.gfp_mask = GFP_KERNEL;
5893 + sa.request_mask = mask;
5895 + if (current->fsuid == uid)
5896 + sa.request_mask = mask << AA_USER_SHIFT;
5898 + sa.request_mask = mask << AA_OTHER_SHIFT;
5900 + sa.denied_mask = aa_file_denied(profile, name, sa.request_mask,
5902 + sa.error_code = sa.denied_mask ? -EACCES : 0;
5904 + return aa_audit_file(profile, &sa);
5908 + * aa_capability - test permission to use capability
5909 + * @cxt: aa_task_context with profile to check against
5910 + * @cap: capability to be tested
5912 + * Look up capability in profile capability set.
5913 + * Returns 0 on success, or else an error code.
5915 +int aa_capability(struct aa_task_context *cxt, int cap)
5917 + int error = cap_raised(cxt->profile->capabilities, cap) ? 0 : -EPERM;
5918 + struct aa_audit sa;
5920 + /* test if cap has alread been logged */
5921 + if (cap_raised(cxt->caps_logged, cap)) {
5922 + if (PROFILE_COMPLAIN(cxt->profile))
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
5932 + cap_raise(cxt->caps_logged, cap);
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;
5940 + error = aa_audit_caps(cxt->profile, &sa, cap);
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)
5948 + if (!cxt || cxt->profile == tracee)
5950 + return aa_capability(cxt, CAP_SYS_PTRACE);
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
5961 + * Returns 0 on success, or else an error code.
5963 +int aa_link(struct aa_profile *profile,
5964 + struct dentry *link, struct vfsmount *link_mnt,
5965 + struct dentry *target, struct vfsmount *target_mnt)
5968 + struct aa_audit sa;
5969 + char *buffer = NULL, *buffer2 = NULL;
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);
5977 + if (IS_ERR(sa.name)) {
5978 + sa.error_code = PTR_ERR(sa.name);
5981 + if (IS_ERR(sa.name2)) {
5982 + sa.error_code = PTR_ERR(sa.name2);
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),
5991 + sa.error_code = sa.denied_mask ? -EACCES : 0;
5994 + error = aa_audit_file(profile, &sa);
5996 + aa_put_name_buffer(buffer);
5997 + aa_put_name_buffer(buffer2);
6002 +int aa_net_perm(struct aa_profile *profile, char *operation,
6003 + int family, int type, int protocol)
6005 + struct aa_audit sa;
6007 + u16 family_mask, audit_mask, quiet_mask;
6009 + if ((family < 0) || (family >= AF_MAX))
6012 + if ((type < 0) || (type >= SOCK_MAX))
6015 + /* unix domain and netlink sockets are handled by ipc */
6016 + if (family == AF_UNIX || family == AF_NETLINK)
6019 + family_mask = profile->network_families[family];
6020 + audit_mask = profile->audit_network[family];
6021 + quiet_mask = profile->quiet_network[family];
6023 + error = (family_mask & (1 << type)) ? 0 : -EACCES;
6025 + memset(&sa, 0, sizeof(sa));
6026 + sa.operation = operation;
6027 + sa.gfp_mask = GFP_KERNEL;
6028 + sa.family = family;
6030 + sa.protocol = protocol;
6031 + sa.error_code = error;
6033 + if (likely(!error)) {
6034 + if (!PROFILE_AUDIT(profile) && !(family_mask & audit_mask))
6036 + } else if (!((1 << type) & ~quiet_mask)) {
6040 + error = aa_audit(profile, &sa);
6045 +int aa_revalidate_sk(struct sock *sk, char *operation)
6047 + struct aa_profile *profile;
6050 + /* this is some debugging code to flush out the network hooks that
6051 + that are called in interrupt context */
6052 + if (in_interrupt()) {
6053 + printk(KERN_WARNING "AppArmor Debug: Hook being called from interrupt context\n");
6058 + profile = aa_get_profile(current);
6060 + error = aa_net_perm(profile, operation,
6061 + sk->sk_family, sk->sk_type,
6063 + aa_put_profile(profile);
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
6073 + * Control raising the processes hard limit.
6075 +int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource,
6076 + struct rlimit *new_rlim)
6078 + struct aa_audit sa;
6081 + memset(&sa, 0, sizeof(sa));
6082 + sa.operation = "setrlimit";
6083 + sa.gfp_mask = GFP_KERNEL;
6084 + sa.rlimit = resource + 1;
6086 + if (profile->rlimits.mask & (1 << resource) &&
6087 + new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max) {
6088 + sa.error_code = -EACCES;
6090 + error = aa_audit(profile, &sa);
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)
6103 +void aa_set_rlimits(struct task_struct *task, struct aa_profile *profile)
6110 + if (!profile->rlimits.mask)
6113 + task_lock(task->group_leader);
6115 + for (i = 0; i < RLIM_NLIMITS; i++, mask <<= 1) {
6116 + struct rlimit new_rlim, *old_rlim;
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
6122 + if (i == RLIMIT_NPROC || i == RLIMIT_CPU)
6125 + old_rlim = task->signal->rlim + i;
6126 + new_rlim = *old_rlim;
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;
6136 + *old_rlim = new_rlim;
6138 + task_unlock(task->group_leader);
6141 +/*******************************
6142 + * Global task related functions
6143 + *******************************/
6146 + * aa_clone - initialize the task context for a new task
6147 + * @child: task that is being created
6149 + * Returns 0 on success, or else an error code.
6151 +int aa_clone(struct task_struct *child)
6153 + struct aa_audit sa;
6154 + struct aa_task_context *cxt, *child_cxt;
6155 + struct aa_profile *profile;
6157 + if (!aa_task_context(current))
6159 + child_cxt = aa_alloc_task_context(GFP_KERNEL);
6163 + memset(&sa, 0, sizeof(sa));
6164 + sa.operation = "clone";
6165 + sa.task = child->pid;
6166 + sa.gfp_mask = GFP_KERNEL;
6169 + profile = aa_get_profile(current);
6171 + lock_profile(profile);
6172 + cxt = aa_task_context(current);
6173 + if (unlikely(profile->isstale || !cxt ||
6174 + cxt->profile != profile)) {
6176 + * Race with profile replacement or removal, or with
6177 + * task context removal.
6179 + unlock_profile(profile);
6180 + aa_put_profile(profile);
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);
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);
6196 + unlock_profile(profile);
6198 + aa_put_profile(profile);
6200 + aa_free_task_context(child_cxt);
6205 +static struct aa_profile *
6206 +aa_register_find(struct aa_profile *profile, const char *ns_name,
6207 + const char *name, int mandatory, int complain,
6208 + struct aa_audit *sa)
6210 + struct aa_namespace *ns;
6211 + struct aa_profile *new_profile;
6217 + ns = default_namespace;
6220 + /* locate the profile namespace */
6221 + ns = aa_find_namespace(ns_name);
6224 + sa->info = "profile namespace not found";
6225 + sa->denied_mask = sa->request_mask;
6226 + sa->error_code = -ENOENT;
6227 + return ERR_PTR(-ENOENT);
6235 + /* Locate new profile */
6236 + new_profile = aa_find_profile(ns, name);
6238 + if (new_profile) {
6239 + AA_DEBUG("%s: setting profile %s\n",
6240 + __func__, new_profile->name);
6241 + } else if (mandatory && profile) {
6242 + sa->info = "mandatory profile missing";
6243 + sa->denied_mask = sa->request_mask; /* shifted MAY_EXEC */
6245 + aa_audit_hint(profile, sa);
6247 + aa_dup_profile(profile->ns->null_complain_profile);
6249 + sa->error_code = -EACCES;
6251 + aa_put_namespace(ns);
6252 + return ERR_PTR(-EACCES);
6255 + /* Only way we can get into this code is if task
6256 + * is unconfined, pix, nix.
6258 + AA_DEBUG("%s: No profile found for exec image '%s'\n",
6262 + aa_put_namespace(ns);
6263 + return new_profile;
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)
6270 + struct aa_profile *new_profile = NULL;
6271 + int ix = xmode & AA_EXEC_INHERIT;
6272 + int complain = PROFILE_COMPLAIN(profile);
6276 + switch (xmode & AA_EXEC_MODIFIERS) {
6278 + /* only valid with ix flag */
6281 + case AA_EXEC_UNCONFINED:
6282 + /* only valid without ix flag */
6285 + case AA_EXEC_PROFILE:
6286 + new_profile = aa_register_find(profile, NULL, filename, !ix,
6289 + case AA_EXEC_CHILD:
6290 + *child = new_compound_name(profile->name, filename);
6291 + sa->name2 = *child;
6293 + sa->info = "Failed name resolution - exec failed";
6294 + sa->error_code = -ENOMEM;
6295 + new_profile = ERR_PTR(-ENOMEM);
6297 + new_profile = aa_register_find(profile, NULL, *child,
6298 + !ix, complain, sa);
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);
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;
6316 + sa->name3 = ns_name;
6318 + aa_register_find(profile, ns_name, name,
6319 + !ix, complain, sa);
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;
6329 + * aa_register - register a new program
6330 + * @bprm: binprm of program being registered
6332 + * Try to register a new program during execve(). This should give the
6333 + * new program a valid aa_task_context if confined.
6335 +int aa_register(struct linux_binprm *bprm)
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;
6344 + AA_DEBUG("%s\n", __func__);
6346 + profile = aa_get_profile(current);
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;
6354 + filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer, 0);
6355 + if (IS_ERR(filename)) {
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;
6364 + sa.name = filename;
6366 + exec_mode = AA_EXEC_UNSAFE << shift;
6370 + complain = PROFILE_COMPLAIN(profile);
6372 + /* Confined task, determine what mode inherit, unconfined or
6373 + * mandatory to load new profile
6375 + exec_mode = aa_match(profile->file_rules, filename,
6379 + if (exec_mode & sa.request_mask) {
6380 + int xm = exec_mode >> shift;
6381 + new_profile = aa_x_to_profile(profile, filename,
6384 + if (!new_profile && (xm & AA_EXEC_INHERIT))
6385 + /* (p|c|n|)ix - don't change profile */
6387 + /* error case caught below */
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).
6398 + aa_dup_profile(profile->ns->null_complain_profile);
6399 + exec_mode |= AA_EXEC_UNSAFE << shift;
6401 + sa.denied_mask = sa.request_mask;
6402 + sa.error_code = -EACCES;
6403 + new_profile = ERR_PTR(aa_audit_file(profile, &sa));
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)
6412 + if (IS_ERR(new_profile))
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);
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);
6429 + if (PTR_ERR(old_profile) == -EAGAIN) {
6430 + sa.info = "rlimit nproc limit exceeded";
6431 + aa_audit_reject(profile, &sa);
6433 + new_profile = old_profile;
6436 + aa_put_profile(old_profile);
6437 + aa_put_profile(profile);
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
6445 + * Cases 2 and 3 are marked as requiring secure exec
6446 + * (unless policy specified "unsafe exec")
6448 + if (!(exec_mode & (AA_EXEC_UNSAFE << shift))) {
6449 + unsigned long bprm_flags;
6451 + bprm_flags = AA_SECURE_EXEC_NEEDED;
6452 + bprm->security = (void *)
6453 + ((unsigned long)bprm->security | bprm_flags);
6456 + if (complain && new_profile &&
6457 + new_profile == new_profile->ns->null_complain_profile) {
6458 + sa.request_mask = 0;
6460 + sa.info = "set profile";
6461 + aa_audit_hint(new_profile, &sa);
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);
6474 + * aa_release - release a task context
6475 + * @task: task being released
6477 + * This is called after a task has exited and the parent has reaped it.
6479 +void aa_release(struct task_struct *task)
6481 + struct aa_task_context *cxt;
6482 + struct aa_profile *profile;
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
6492 + * Use lock subtyping to avoid lockdep reporting a false irq
6493 + * possible inversion between the task_lock and profile_lock
6495 + * We also avoid taking the task_lock here because lock_dep
6496 + * would report another false {softirq-on-W} potential irq_lock
6499 + * If the task does not have a profile attached we are safe;
6500 + * nothing can race with us at this point.
6504 + profile = aa_get_profile(task);
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);
6513 + aa_change_task_context(task, NULL, NULL, 0, NULL);
6514 + unlock_profile(profile);
6515 + aa_put_profile(profile);
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)
6524 + struct aa_profile *new_profile = NULL, *old_profile = NULL,
6525 + *previous_profile = NULL;
6526 + struct aa_task_context *new_cxt, *cxt;
6531 + new_cxt = aa_alloc_task_context(GFP_KERNEL);
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);
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);
6548 + cxt = lock_task_and_profiles(current, new_profile);
6553 + old_profile = cxt->profile;
6555 + if (cxt->profile != expected || (new_profile && new_profile->isstale)) {
6560 + if (cxt->previous_profile) {
6561 + if (cxt->cookie != cookie) {
6563 + sa->info = "killing process";
6564 + aa_audit_reject(cxt->profile, sa);
6565 + /* terminate process */
6566 + (void)send_sig_info(SIGKILL, NULL, current);
6571 + previous_profile = cxt->previous_profile;
6573 + previous_profile = cxt->profile;
6575 + if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, new_profile)) {
6580 + if ((error = aa_rlimit_nproc(new_profile))) {
6581 + sa->info = "rlimit nproc limit exceeded";
6582 + aa_audit_reject(cxt->profile, sa);
6586 + if (new_profile == ns->null_complain_profile)
6587 + aa_audit_hint(cxt->profile, sa);
6589 + if (APPARMOR_AUDIT(cxt))
6590 + aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT);
6592 + if (!restore && cookie)
6593 + aa_change_task_context(current, new_cxt, new_profile, cookie,
6594 + previous_profile);
6596 + /* either return to previous_profile, or a permanent change */
6597 + aa_change_task_context(current, new_cxt, new_profile, 0, NULL);
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);
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
6615 + * Returns %0 on success, error otherwise.
6617 +int aa_change_profile(const char *ns_name, const char *name)
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;
6629 + memset(&sa, 0, sizeof(sa));
6630 + sa.gfp_mask = GFP_ATOMIC;
6631 + sa.operation = "change_profile";
6634 + task_lock(current);
6635 + cxt = aa_task_context(current);
6637 + profile = aa_dup_profile(cxt->profile);
6638 + task_unlock(current);
6641 + ns = aa_find_namespace(ns_name);
6643 + ns = aa_get_namespace(profile->ns);
6645 + ns = aa_get_namespace(default_namespace);
6648 + aa_put_profile(profile);
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);
6657 + /* check for a rule with a namespace prepended */
6658 + aa_match_state(profile->file_rules, DFA_START, ns->name,
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,
6666 + /* no permission to transition to profile @name */
6670 + aa_put_namespace(ns);
6671 + aa_put_profile(profile);
6672 + if (error == -ESTALE)
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
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
6687 + * Returns %0 on success, error otherwise.
6689 +int aa_change_hat(const char *hat_name, u64 cookie)
6691 + struct aa_task_context *cxt;
6692 + struct aa_profile *profile, *previous_profile;
6693 + struct aa_audit sa;
6696 + memset(&sa, 0, sizeof(sa));
6697 + sa.gfp_mask = GFP_ATOMIC;
6698 + sa.operation = "change_hat";
6701 + task_lock(current);
6702 + cxt = aa_task_context(current);
6704 + task_unlock(current);
6707 + profile = aa_dup_profile(cxt->profile);
6708 + previous_profile = aa_dup_profile(cxt->previous_profile);
6709 + task_unlock(current);
6712 + char *name, *profile_name;
6714 + if (previous_profile)
6715 + profile_name = previous_profile->name;
6717 + profile_name = profile->name;
6719 + name = new_compound_name(profile_name, hat_name);
6724 + error = do_change_profile(profile, profile->ns, name, cookie,
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,
6731 + /* else ignore restores when there is no saved profile */
6734 + aa_put_profile(previous_profile);
6735 + aa_put_profile(profile);
6736 + if (error == -ESTALE)
6743 + * __aa_replace_profile - replace a task's profile
6744 + * @task: task to switch the profile of
6745 + * @profile: profile to switch to
6747 + * Returns a handle to the previous profile upon success, or else an
6750 +struct aa_profile *__aa_replace_profile(struct task_struct *task,
6751 + struct aa_profile *profile)
6753 + struct aa_task_context *cxt, *new_cxt = NULL;
6754 + struct aa_profile *old_profile = NULL;
6757 + new_cxt = aa_alloc_task_context(GFP_KERNEL);
6759 + return ERR_PTR(-ENOMEM);
6762 + cxt = lock_task_and_profiles(task, profile);
6763 + if (unlikely(profile && profile->isstale)) {
6764 + old_profile = ERR_PTR(-ESTALE);
6768 + if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) {
6769 + old_profile = ERR_PTR(-EPERM);
6773 + if (aa_rlimit_nproc(profile)) {
6774 + old_profile = ERR_PTR(-EAGAIN);
6779 + old_profile = aa_dup_profile(cxt->profile);
6780 + aa_change_task_context(task, new_cxt, profile, 0, NULL);
6782 + task_unlock(task);
6783 + aa_set_rlimits(task, profile);
6784 + unlock_both_profiles(profile, old_profile);
6785 + return old_profile;
6788 + task_unlock(task);
6789 + unlock_both_profiles(profile, cxt ? cxt->profile : NULL);
6790 + aa_free_task_context(new_cxt);
6791 + return old_profile;
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
6799 + * Handle the spinning on locking to make sure the task context and
6800 + * profile are consistent once all locks are aquired.
6802 + * return the aa_task_context currently confining the task. The task lock
6803 + * will be held whether or not the task is confined.
6805 +struct aa_task_context *
6806 +lock_task_and_profiles(struct task_struct *task, struct aa_profile *profile)
6808 + struct aa_task_context *cxt;
6809 + struct aa_profile *old_profile = NULL;
6813 + cxt = aa_task_context(task);
6815 + old_profile = cxt->profile;
6817 + lock_both_profiles(profile, old_profile);
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;
6827 + rcu_read_unlock();
6831 +static void free_aa_task_context_rcu_callback(struct rcu_head *head)
6833 + struct aa_task_context *cxt;
6835 + cxt = container_of(head, struct aa_task_context, rcu);
6836 + aa_free_task_context(cxt);
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
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)
6852 + struct aa_task_context *old_cxt = aa_task_context(task);
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);
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
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);
6872 + rcu_assign_pointer(task->security, new_cxt);
6874 diff -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
6879 + * Copyright (C) 2007 Novell/SUSE
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
6886 + * Regular expression transition table matching
6889 +#include <linux/kernel.h>
6890 +#include <linux/slab.h>
6891 +#include <linux/errno.h>
6892 +#include "apparmor.h"
6894 +#include "inline.h"
6896 +static struct table_header *unpack_table(void *blob, size_t bsize)
6898 + struct table_header *table = NULL;
6899 + struct table_header th;
6902 + if (bsize < sizeof(struct table_header))
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);
6910 + if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
6911 + th.td_flags == YYTD_DATA8))
6914 + tsize = table_size(th.td_lolen, th.td_flags);
6915 + if (bsize < tsize)
6918 + table = kmalloc(tsize, GFP_KERNEL);
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);
6928 + UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
6929 + u32, be32_to_cpu);
6936 +int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size)
6939 + int error = -ENOMEM;
6941 + /* get dfa table set header */
6942 + if (size < sizeof(struct table_set_header))
6945 + if (ntohl(*(u32 *)blob) != YYTH_MAGIC)
6948 + hsize = ntohl(*(u32 *)(blob + 4));
6956 + while (size > 0) {
6957 + struct table_header *table;
6958 + table = unpack_table(blob, size);
6962 + switch (table->td_id) {
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)
6973 + dfa->tables[table->td_id - 1] = table;
6974 + if (table->td_flags != YYTD_DATA16)
6978 + dfa->tables[table->td_id - 1] = table;
6979 + if (table->td_flags != YYTD_DATA8)
6987 + blob += table_size(table->td_lolen, table->td_flags);
6988 + size -= table_size(table->td_lolen, table->td_flags);
6994 + for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) {
6995 + kfree(dfa->tables[i]);
6996 + dfa->tables[i] = NULL;
7002 + * verify_dfa - verify that all the transitions and states in the dfa tables
7004 + * @dfa: dfa to test
7006 + * assumes dfa has gone through the verification done by unpacking
7008 +int verify_dfa(struct aa_dfa *dfa)
7010 + size_t i, state_count, trans_count;
7011 + int error = -EPROTO;
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]))
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))
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)
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)
7039 + for (i = 0; i < state_count; i++) {
7040 + if (DEFAULT_TABLE(dfa)[i] >= state_count)
7042 + if (BASE_TABLE(dfa)[i] >= trans_count + 256)
7046 + for (i = 0; i < trans_count ; i++) {
7047 + if (NEXT_TABLE(dfa)[i] >= state_count)
7049 + if (CHECK_TABLE(dfa)[i] >= state_count)
7053 + /* verify accept permissions */
7054 + for (i = 0; i < state_count; i++) {
7055 + int mode = ACCEPT_TABLE(dfa)[i];
7057 + if (mode & ~AA_VALID_PERM_MASK)
7059 + if (ACCEPT_TABLE2(dfa)[i] & ~AA_VALID_PERM2_MASK)
7062 + /* if any exec modifier is set MAY_EXEC must be set */
7063 + if ((mode & AA_USER_EXEC_TYPE) && !(mode & AA_USER_EXEC))
7065 + if ((mode & AA_OTHER_EXEC_TYPE) && !(mode & AA_OTHER_EXEC))
7074 +struct aa_dfa *aa_match_alloc(void)
7076 + return kzalloc(sizeof(struct aa_dfa), GFP_KERNEL);
7079 +void aa_match_free(struct aa_dfa *dfa)
7084 + for (i = 0; i < ARRAY_SIZE(dfa->tables); i++)
7085 + kfree(dfa->tables[i]);
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
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.
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
7106 +static unsigned int aa_dfa_next_state_len(struct aa_dfa *dfa,
7107 + unsigned int start,
7108 + const char *str, int len)
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;
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];
7127 + state = def[state];
7130 + for (; len; len--) {
7131 + pos = base[state] + (u8)*str++;
7132 + if (check[pos] == state)
7133 + state = next[pos];
7135 + state = def[state];
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
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.
7151 +unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start,
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;
7163 + /* current state is <state>, matching character *str */
7164 + if (dfa->tables[YYTD_ID_EC - 1]) {
7165 + u8 *equiv = EQUIV_TABLE(dfa);
7167 + pos = base[state] + equiv[(u8)*str++];
7168 + if (check[pos] == state)
7169 + state = next[pos];
7171 + state = def[state];
7175 + pos = base[state] + (u8)*str++;
7176 + if (check[pos] == state)
7177 + state = next[pos];
7179 + state = def[state];
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
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.
7194 +unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start)
7196 + return aa_dfa_next_state_len(dfa, start, "", 1);
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
7205 + * aa_dfa_match will match @str and return the accept perms for the
7208 +unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str, int *audit_mask)
7210 + int state = aa_dfa_next_state(dfa, DFA_START, str);
7212 + *audit_mask = dfa_audit_mask(dfa, state);
7213 + return ACCEPT_TABLE(dfa)[state];
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
7223 + * aa_match_state will match @str and return the accept perms, and @final
7224 + * state, the match occured in.
7226 +unsigned int aa_match_state(struct aa_dfa *dfa, unsigned int start,
7227 + const char *str, unsigned int *final)
7229 + unsigned int state;
7231 + state = aa_dfa_next_state(dfa, start, str);
7234 + return ACCEPT_TABLE(dfa)[state];
7241 diff -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
7246 + * Copyright (C) 2007 Novell/SUSE
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
7253 + * AppArmor submodule (match) prototypes
7259 +#define DFA_START 1
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).
7270 +#define YYTH_MAGIC 0x1B5E783D
7272 +struct table_set_header {
7273 + u32 th_magic; /* YYTH_MAGIC */
7277 + char th_version[];
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
7290 +#define YYTD_DATA8 1
7291 +#define YYTD_DATA16 2
7292 +#define YYTD_DATA32 4
7294 +struct table_header {
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))
7308 +#define ACCEPT_TABLE2(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT2 - 1]->td_data))
7311 + struct table_header *tables[YYTD_ID_NXT];
7314 +#define byte_to_byte(X) (X)
7316 +#define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \
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]); \
7326 +static inline size_t table_size(size_t len, size_t el_size)
7328 + return ALIGN(sizeof(struct table_header) + len * el_size, 8);
7331 +#endif /* __MATCH_H */
7332 diff -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
7337 + * Copyright (C) 1998-2007 Novell/SUSE
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
7344 + * AppArmor userspace policy interface
7347 +#include <asm/unaligned.h>
7349 +#include "apparmor.h"
7350 +#include "inline.h"
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.)
7359 +DEFINE_MUTEX(aa_interface_lock);
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.
7375 + AA_NAME, /* same as string except it is items name */
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.
7394 + void *pos; /* pointer to current position in the buffer */
7399 +static int aa_inbounds(struct aa_ext *e, size_t size)
7401 + return (size <= e->end - e->pos);
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
7409 + * return the size of chunk found with the read head at the end of
7412 +static size_t aa_is_u16_chunk(struct aa_ext *e, char **chunk)
7414 + void *pos = e->pos;
7417 + if (!aa_inbounds(e, sizeof(u16)))
7419 + size = le16_to_cpu(get_unaligned((u16 *)e->pos));
7420 + e->pos += sizeof(u16);
7421 + if (!aa_inbounds(e, size))
7432 +static int aa_is_X(struct aa_ext *e, enum aa_code code)
7434 + if (!aa_inbounds(e, 1))
7436 + if (*(u8 *) e->pos != code)
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.
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
7456 +static int aa_is_nameX(struct aa_ext *e, enum aa_code code, const char *name)
7458 + void *pos = e->pos;
7460 + * Check for presence of a tagname, and if present name size
7461 + * AA_NAME tag value is a u16.
7463 + if (aa_is_X(e, AA_NAME)) {
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)))
7469 + } else if (name) {
7470 + /* if a name is specified and there is no name tag fail */
7474 + /* now check if type code matches */
7475 + if (aa_is_X(e, code))
7483 +static int aa_is_u16(struct aa_ext *e, u16 *data, const char *name)
7485 + void *pos = e->pos;
7486 + if (aa_is_nameX(e, AA_U16, name)) {
7487 + if (!aa_inbounds(e, sizeof(u16)))
7490 + *data = le16_to_cpu(get_unaligned((u16 *)e->pos));
7491 + e->pos += sizeof(u16);
7499 +static int aa_is_u32(struct aa_ext *e, u32 *data, const char *name)
7501 + void *pos = e->pos;
7502 + if (aa_is_nameX(e, AA_U32, name)) {
7503 + if (!aa_inbounds(e, sizeof(u32)))
7506 + *data = le32_to_cpu(get_unaligned((u32 *)e->pos));
7507 + e->pos += sizeof(u32);
7515 +static int aa_is_u64(struct aa_ext *e, u64 *data, const char *name)
7517 + void *pos = e->pos;
7518 + if (aa_is_nameX(e, AA_U64, name)) {
7519 + if (!aa_inbounds(e, sizeof(u64)))
7522 + *data = le64_to_cpu(get_unaligned((u64 *)e->pos));
7523 + e->pos += sizeof(u64);
7531 +static size_t aa_is_array(struct aa_ext *e, const char *name)
7533 + void *pos = e->pos;
7534 + if (aa_is_nameX(e, AA_ARRAY, name)) {
7536 + if (!aa_inbounds(e, sizeof(u16)))
7538 + size = (int) le16_to_cpu(get_unaligned((u16 *)e->pos));
7539 + e->pos += sizeof(u16);
7547 +static size_t aa_is_blob(struct aa_ext *e, char **blob, const char *name)
7549 + void *pos = e->pos;
7550 + if (aa_is_nameX(e, AA_BLOB, name)) {
7552 + if (!aa_inbounds(e, sizeof(u32)))
7554 + size = le32_to_cpu(get_unaligned((u32 *)e->pos));
7555 + e->pos += sizeof(u32);
7556 + if (aa_inbounds(e, (size_t) size)) {
7567 +static int aa_is_dynstring(struct aa_ext *e, char **string, const char *name)
7571 + void *pos = e->pos;
7573 + if (aa_is_nameX(e, AA_STRING, name) &&
7574 + (size = aa_is_u16_chunk(e, &src_str))) {
7575 + char *str = kmalloc(size, GFP_KERNEL);
7578 + memcpy(str, src_str, size);
7590 + * aa_unpack_dfa - unpack a file rule dfa
7591 + * @e: serialized data extent information
7593 + * returns dfa or ERR_PTR
7595 +static struct aa_dfa *aa_unpack_dfa(struct aa_ext *e)
7597 + char *blob = NULL;
7598 + size_t size, error = 0;
7599 + struct aa_dfa *dfa = NULL;
7601 + size = aa_is_blob(e, &blob, "aadfa");
7603 + dfa = aa_match_alloc();
7606 + * The dfa is aligned with in the blob to 8 bytes
7607 + * from the beginning of the stream.
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);
7613 + error = verify_dfa(dfa);
7619 + aa_match_free(dfa);
7620 + dfa = ERR_PTR(error);
7627 +static int aa_unpack_exec_table(struct aa_ext *e, struct aa_profile *profile)
7629 + void *pos = e->pos;
7631 + /* exec table is optional */
7632 + if (aa_is_nameX(e, AA_STRUCT, "xtable")) {
7635 + size = aa_is_array(e, NULL);
7636 + /* currently 4 exec bits and entries 0-3 are reserved iupcx */
7637 + if (size > 16 - 4)
7639 + profile->exec_table = kzalloc(sizeof(char *) * size,
7641 + if (!profile->exec_table)
7644 + for (i = 0; i < size; i++) {
7646 + if (!aa_is_dynstring(e, &tmp, NULL))
7648 + /* note: strings beginning with a : have an embedded
7649 + \0 seperating the profile ns name from the profile
7651 + profile->exec_table[i] = tmp;
7653 + if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
7655 + if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
7657 + profile->exec_table_size = size;
7666 +int aa_unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
7668 + void *pos = e->pos;
7670 + /* rlimits are optional */
7671 + if (aa_is_nameX(e, AA_STRUCT, "rlimits")) {
7674 + if (!aa_is_u32(e, &tmp, NULL))
7676 + profile->rlimits.mask = tmp;
7678 + size = aa_is_array(e, NULL);
7679 + if (size > RLIM_NLIMITS)
7681 + for (i = 0; i < size; i++) {
7683 + if (!aa_is_u64(e, &tmp, NULL))
7685 + profile->rlimits.limits[i].rlim_max = tmp;
7687 + if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
7689 + if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
7700 + * aa_unpack_profile - unpack a serialized profile
7701 + * @e: serialized data extent information
7702 + * @sa: audit struct for the operation
7704 +static struct aa_profile *aa_unpack_profile(struct aa_ext *e,
7705 + struct aa_audit *sa)
7707 + struct aa_profile *profile;
7709 + int i, error = -EPROTO;
7711 + profile = alloc_aa_profile();
7713 + return ERR_PTR(-ENOMEM);
7715 + /* check that we have the right struct being passed */
7716 + if (!aa_is_nameX(e, AA_STRUCT, "profile"))
7718 + if (!aa_is_dynstring(e, &profile->name, NULL))
7721 + /* per profile debug flags (complain, audit) */
7722 + if (!aa_is_nameX(e, AA_STRUCT, "flags"))
7724 + if (!aa_is_u32(e, &(profile->flags.hat), NULL))
7726 + if (!aa_is_u32(e, &(profile->flags.complain), NULL))
7728 + if (!aa_is_u32(e, &(profile->flags.audit), NULL))
7730 + if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
7733 + if (!aa_is_u32(e, &(profile->capabilities.cap[0]), NULL))
7735 + if (!aa_is_u32(e, &(profile->audit_caps.cap[0]), NULL))
7737 + if (!aa_is_u32(e, &(profile->quiet_caps.cap[0]), NULL))
7739 + if (!aa_is_u32(e, &(profile->set_caps.cap[0]), NULL))
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))
7746 + if (!aa_is_u32(e, &(profile->audit_caps.cap[1]), NULL))
7748 + if (!aa_is_u32(e, &(profile->quiet_caps.cap[1]), NULL))
7750 + if (!aa_is_u32(e, &(profile->set_caps.cap[1]), NULL))
7752 + if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
7756 + if (!aa_unpack_rlimits(e, profile))
7759 + size = aa_is_array(e, "net_allowed_af");
7761 + if (size > AF_MAX)
7764 + for (i = 0; i < size; i++) {
7765 + if (!aa_is_u16(e, &profile->network_families[i], NULL))
7767 + if (!aa_is_u16(e, &profile->audit_network[i], NULL))
7769 + if (!aa_is_u16(e, &profile->quiet_network[i], NULL))
7772 + if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
7774 + /* allow unix domain and netlink sockets they are handled
7778 + profile->network_families[AF_UNIX] = 0xffff;
7779 + profile->network_families[AF_NETLINK] = 0xffff;
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;
7789 + if (!aa_unpack_exec_table(e, profile))
7792 + if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
7798 + sa->name = profile && profile->name ? profile->name : "unknown";
7800 + sa->info = "failed to unpack profile";
7801 + aa_audit_status(NULL, sa);
7803 + free_aa_profile(profile);
7805 + return ERR_PTR(error);
7809 + * aa_verify_head - unpack serialized stream header
7810 + * @e: serialized data read head
7811 + * @operation: operation header is being verified for
7813 + * returns error or 0 if header is good
7815 +static int aa_verify_header(struct aa_ext *e, struct aa_audit *sa)
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;
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;
7831 + /* read the namespace if present */
7832 + if (!aa_is_dynstring(e, &e->ns_name, "namespace"))
7833 + e->ns_name = NULL;
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
7843 +ssize_t aa_add_profile(void *data, size_t size)
7845 + struct aa_profile *profile;
7846 + struct aa_namespace *ns = NULL;
7847 + struct aa_ext e = {
7849 + .end = data + size,
7854 + struct aa_audit sa;
7855 + memset(&sa, 0, sizeof(sa));
7856 + sa.operation = "profile_load";
7857 + sa.gfp_mask = GFP_KERNEL;
7859 + error = aa_verify_header(&e, &sa);
7863 + profile = aa_unpack_profile(&e, &sa);
7864 + if (IS_ERR(profile))
7865 + return PTR_ERR(profile);
7867 + mutex_lock(&aa_interface_lock);
7868 + write_lock(&profile_ns_list_lock);
7870 + ns = __aa_find_namespace(e.ns_name, &profile_ns_list);
7872 + ns = default_namespace;
7874 + struct aa_namespace *new_ns;
7875 + write_unlock(&profile_ns_list_lock);
7876 + new_ns = alloc_aa_namespace(e.ns_name);
7878 + mutex_unlock(&aa_interface_lock);
7881 + write_lock(&profile_ns_list_lock);
7882 + ns = __aa_find_namespace(e.ns_name, &profile_ns_list);
7884 + list_add(&new_ns->list, &profile_ns_list);
7887 + free_aa_namespace(new_ns);
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);
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);
7909 + sa.name = profile->name;
7910 + sa.name2 = ns->name;
7911 + aa_audit_status(NULL, &sa);
7912 + mutex_unlock(&aa_interface_lock);
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
7922 +static void task_replace(struct task_struct *task,
7923 + struct aa_task_context *new_cxt,
7924 + struct aa_profile *new_profile)
7926 + struct aa_task_context *cxt = aa_task_context(task);
7928 + AA_DEBUG("%s: replacing profile for task %d profile=%s (%p)\n",
7929 + __func__, cxt->task->pid, cxt->profile->name, cxt->profile);
7931 + aa_change_task_context(task, new_cxt, new_profile, cxt->cookie,
7932 + cxt->previous_profile);
7936 + * aa_replace_profile - replace a profile on the profile list
7937 + * @udata: serialized data stream
7938 + * @size: size of the serialized data stream
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.
7944 +ssize_t aa_replace_profile(void *udata, size_t size)
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 = {
7951 + .end = udata + size,
7956 + struct aa_audit sa;
7957 + memset(&sa, 0, sizeof(sa));
7958 + sa.operation = "profile_replace";
7959 + sa.gfp_mask = GFP_KERNEL;
7961 + error = aa_verify_header(&e, &sa);
7965 + new_profile = aa_unpack_profile(&e, &sa);
7966 + if (IS_ERR(new_profile))
7967 + return PTR_ERR(new_profile);
7969 + mutex_lock(&aa_interface_lock);
7970 + write_lock(&profile_ns_list_lock);
7972 + ns = __aa_find_namespace(e.ns_name, &profile_ns_list);
7974 + ns = default_namespace;
7976 + struct aa_namespace *new_ns;
7977 + write_unlock(&profile_ns_list_lock);
7978 + new_ns = alloc_aa_namespace(e.ns_name);
7980 + mutex_unlock(&aa_interface_lock);
7983 + write_lock(&profile_ns_list_lock);
7984 + ns = __aa_find_namespace(e.ns_name, &profile_ns_list);
7986 + list_add(&new_ns->list, &profile_ns_list);
7989 + free_aa_namespace(new_ns);
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--;
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);
8009 + if (!old_profile) {
8010 + sa.operation = "profile_load";
8013 + /* do not fail replacement based off of profile's NPROC rlimit */
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
8025 + new_cxt = aa_alloc_task_context(GFP_KERNEL | __GFP_NOFAIL);
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;
8033 + task_replace(task, new_cxt, new_profile);
8034 + task_unlock(task);
8035 + aa_set_rlimits(task, new_profile);
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);
8044 + sa.name = new_profile->name;
8045 + sa.name2 = ns->name;
8046 + aa_audit_status(NULL, &sa);
8047 + mutex_unlock(&aa_interface_lock);
8052 + * aa_remove_profile - remove a profile from the system
8053 + * @name: name of the profile to remove
8054 + * @size: size of the name
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
8060 +ssize_t aa_remove_profile(char *name, size_t size)
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;
8069 + mutex_lock(&aa_interface_lock);
8070 + write_lock(&profile_ns_list_lock);
8072 + if (name[0] == ':') {
8073 + char *split = strchr(name + 1, ':');
8077 + ns = __aa_find_namespace(name + 1, &profile_ns_list);
8080 + ns = default_namespace;
8085 + sa.name2 = ns->name;
8086 + write_lock(&ns->lock);
8087 + profile = __aa_find_profile(name, &ns->profiles);
8089 + write_unlock(&ns->lock);
8092 + sa.name = profile->name;
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);
8108 + write_unlock(&profile_ns_list_lock);
8110 + aa_audit_status(NULL, &sa);
8111 + mutex_unlock(&aa_interface_lock);
8112 + aa_put_profile(profile);
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);
8125 + * free_aa_namespace_kref - free aa_namespace by kref (see aa_put_namespace)
8126 + * @kr: kref callback for freeing of a namespace
8128 +void free_aa_namespace_kref(struct kref *kref)
8130 + free_aa_namespace(container_of(kref, struct aa_namespace, count));
8134 + * alloc_aa_namespace - allocate, initialize and return a new namespace
8135 + * @name: a preallocated name
8136 + * Returns NULL on failure.
8138 +struct aa_namespace *alloc_aa_namespace(char *name)
8140 + struct aa_namespace *ns;
8142 + ns = kzalloc(sizeof(*ns), GFP_KERNEL);
8143 + AA_DEBUG("%s(%p)\n", __func__, ns);
8146 + INIT_LIST_HEAD(&ns->list);
8147 + INIT_LIST_HEAD(&ns->profiles);
8148 + kref_init(&ns->count);
8149 + rwlock_init(&ns->lock);
8151 + ns->null_complain_profile = alloc_aa_profile();
8152 + if (!ns->null_complain_profile) {
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);
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;
8175 + * free_aa_namespace - free a profile namespace
8176 + * @namespace: the namespace to free
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.
8183 +void free_aa_namespace(struct aa_namespace *ns)
8185 + AA_DEBUG("%s(%p)\n", __func__, ns);
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",
8194 + __func__, ns->name);
8197 + if (!list_empty(&ns->list)) {
8198 + AA_ERROR("%s: internal error, namespace '%s' still on list\n",
8199 + __func__, ns->name);
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);
8210 + * free_aa_profile_kref - free aa_profile by kref (called by aa_put_profile)
8211 + * @kr: kref callback for freeing of a profile
8213 +void free_aa_profile_kref(struct kref *kref)
8215 + struct aa_profile *p = container_of(kref, struct aa_profile, count);
8217 + free_aa_profile(p);
8221 + * alloc_aa_profile - allocate, initialize and return a new profile
8222 + * Returns NULL on failure.
8224 +struct aa_profile *alloc_aa_profile(void)
8226 + struct aa_profile *profile;
8228 + profile = kzalloc(sizeof(*profile), GFP_KERNEL);
8229 + AA_DEBUG("%s(%p)\n", __func__, 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);
8240 + * free_aa_profile - free a profile
8241 + * @profile: the profile to free
8243 + * Free a profile, its hats and null_profile. All references to the profile,
8244 + * its hats and null_profile must have been put.
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.
8249 +void free_aa_profile(struct aa_profile *profile)
8251 + AA_DEBUG("%s(%p)\n", __func__, profile);
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",
8260 + __func__, profile->name);
8263 + aa_put_namespace(profile->ns);
8265 + aa_match_free(profile->file_rules);
8267 + if (profile->name) {
8268 + AA_DEBUG("%s: %s\n", __func__, profile->name);
8269 + kfree(profile->name);
8276 + * aa_unconfine_tasks - remove tasks on a profile's task context list
8277 + * @profile: profile to remove tasks from
8279 + * Assumes that @profile lock is held.
8281 +void aa_unconfine_tasks(struct aa_profile *profile)
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;
8288 + aa_change_task_context(task, NULL, NULL, 0, NULL);
8289 + task_unlock(task);
8292 diff -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
8297 + * Copyright (C) 1998-2007 Novell/SUSE
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
8304 + * AppArmor /proc/pid/attr handling
8307 +#include "apparmor.h"
8308 +#include "inline.h"
8310 +int aa_getprocattr(struct aa_profile *profile, char **string, unsigned *len)
8315 + const char *mode_str = PROFILE_COMPLAIN(profile) ?
8316 + " (complain)" : " (enforce)";
8317 + int mode_len, name_len, ns_len = 0;
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);
8330 + memcpy(str, profile->ns->name, ns_len - 2);
8331 + str += ns_len - 2;
8334 + memcpy(str, profile->name, name_len);
8336 + memcpy(str, mode_str, mode_len);
8341 + const char *unconfined_str = "unconfined\n";
8343 + *len = strlen(unconfined_str);
8344 + str = kmalloc(*len, GFP_ATOMIC);
8348 + memcpy(str, unconfined_str, *len);
8355 +static char *split_token_from_name(const char *op, char *args, u64 *cookie)
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);
8365 + name++; /* skip ^ */
8371 +int aa_setprocattr_changehat(char *args)
8376 + hat = split_token_from_name("change_hat", args, &cookie);
8378 + return PTR_ERR(hat);
8380 + if (!hat && !cookie) {
8381 + AA_ERROR("change_hat: Invalid input, NULL hat and NULL magic");
8385 + AA_DEBUG("%s: Magic 0x%llx Hat '%s'\n",
8386 + __func__, cookie, hat ? hat : NULL);
8388 + return aa_change_hat(hat, cookie);
8391 +int aa_setprocattr_changeprofile(char *args)
8393 + char *name = args, *ns_name = NULL;
8395 + if (name[0] == ':') {
8396 + char *split = strchr(&name[1], ':');
8399 + ns_name = &name[1];
8404 + return aa_change_profile(ns_name, name);
8407 +int aa_setprocattr_setprofile(struct task_struct *task, char *args)
8409 + struct aa_profile *old_profile, *new_profile;
8410 + struct aa_namespace *ns;
8411 + struct aa_audit sa;
8412 + char *name, *ns_name = NULL;
8414 + memset(&sa, 0, sizeof(sa));
8415 + sa.operation = "profile_set";
8416 + sa.gfp_mask = GFP_KERNEL;
8417 + sa.task = task->pid;
8419 + AA_DEBUG("%s: current %d\n", __func__, current->pid);
8422 + if (args[0] != '/') {
8423 + char *split = strchr(args, ':');
8431 + ns = aa_find_namespace(ns_name);
8433 + ns = aa_get_namespace(default_namespace);
8435 + sa.name = ns_name;
8436 + sa.info = "unknown namespace";
8437 + aa_audit_reject(NULL, &sa);
8438 + aa_put_namespace(ns);
8443 + if (strcmp(name, "unconfined") == 0)
8444 + new_profile = NULL;
8446 + new_profile = aa_find_profile(ns, name);
8447 + if (!new_profile) {
8448 + sa.name = ns_name;
8450 + sa.info = "unknown profile";
8451 + aa_audit_reject(NULL, &sa);
8452 + aa_put_namespace(ns);
8457 + old_profile = __aa_replace_profile(task, new_profile);
8458 + if (IS_ERR(old_profile)) {
8461 + aa_put_profile(new_profile);
8462 + error = PTR_ERR(old_profile);
8463 + if (error == -ESTALE)
8465 + aa_put_namespace(ns);
8469 + if (new_profile) {
8470 + sa.name = ns_name;
8472 + sa.name3 = old_profile ? old_profile->name :
8474 + aa_audit_status(NULL, &sa);
8476 + if (old_profile) {
8477 + sa.name = "unconfined";
8478 + sa.name2 = old_profile->name;
8479 + aa_audit_status(NULL, &sa);
8481 + sa.info = "task is unconfined";
8482 + aa_audit_status(NULL, &sa);
8485 + aa_put_namespace(ns);
8486 + aa_put_profile(old_profile);
8487 + aa_put_profile(new_profile);
8490 diff -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
8493 @@ -155,52 +155,56 @@ static int cap_inode_init_security(struc
8496 static int cap_inode_create(struct inode *inode, struct dentry *dentry,
8498 + struct vfsmount *mnt, int mask)
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)
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)
8519 static int cap_inode_symlink(struct inode *inode, struct dentry *dentry,
8521 + struct vfsmount *mnt, const char *name)
8526 static int cap_inode_mkdir(struct inode *inode, struct dentry *dentry,
8528 + struct vfsmount *mnt, int mask)
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)
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)
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)
8555 -static int cap_inode_readlink(struct dentry *dentry)
8556 +static int cap_inode_readlink(struct dentry *dentry, struct vfsmount *mnt)
8560 @@ -216,7 +220,8 @@ static int cap_inode_permission(struct i
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)
8570 @@ -230,17 +235,20 @@ static void cap_inode_delete(struct inod
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,
8577 const void *value, size_t size, int flags)
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)
8588 -static int cap_inode_listxattr(struct dentry *dentry)
8589 +static int cap_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt,
8594 @@ -335,6 +343,11 @@ static int cap_dentry_open(struct file *
8598 +static int cap_path_permission(struct path *path, int mask)
8600 + return security_inode_permission(path->dentry->d_inode, mask);
8603 static int cap_task_create(unsigned long clone_flags)
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);
8614 diff -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
8617 @@ -411,8 +411,9 @@ int cap_bprm_secureexec (struct linux_bi
8618 current->egid != current->gid);
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)
8627 if (!strcmp(name, XATTR_NAME_CAPS)) {
8628 if (!capable(CAP_SETFCAP))
8629 @@ -425,7 +426,8 @@ int cap_inode_setxattr(struct dentry *de
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)
8637 if (!strcmp(name, XATTR_NAME_CAPS)) {
8638 if (!capable(CAP_SETFCAP))
8639 diff -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
8643 #include <linux/security.h>
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;
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
8653 EXPORT_SYMBOL(security_inode_init_security);
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)
8659 if (unlikely(IS_PRIVATE(dir)))
8661 - return security_ops->inode_create(dir, dentry, mode);
8662 + return security_ops->inode_create(dir, dentry, mnt, mode);
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)
8671 if (unlikely(IS_PRIVATE(old_dentry->d_inode)))
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);
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)
8682 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8684 - return security_ops->inode_unlink(dir, dentry);
8685 + return security_ops->inode_unlink(dir, dentry, mnt);
8688 int security_inode_symlink(struct inode *dir, struct dentry *dentry,
8689 - const char *old_name)
8690 + struct vfsmount *mnt, const char *old_name)
8692 if (unlikely(IS_PRIVATE(dir)))
8694 - return security_ops->inode_symlink(dir, dentry, old_name);
8695 + return security_ops->inode_symlink(dir, dentry, mnt, old_name);
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)
8702 if (unlikely(IS_PRIVATE(dir)))
8704 - return security_ops->inode_mkdir(dir, dentry, mode);
8705 + return security_ops->inode_mkdir(dir, dentry, mnt, mode);
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)
8712 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8714 - return security_ops->inode_rmdir(dir, dentry);
8715 + return security_ops->inode_rmdir(dir, dentry, mnt);
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)
8722 if (unlikely(IS_PRIVATE(dir)))
8724 - return security_ops->inode_mknod(dir, dentry, mode, dev);
8725 + return security_ops->inode_mknod(dir, dentry, mnt, mode, dev);
8727 +EXPORT_SYMBOL_GPL(security_inode_permission);
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)
8734 if (unlikely(IS_PRIVATE(old_dentry->d_inode) ||
8735 (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode))))
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);
8743 -int security_inode_readlink(struct dentry *dentry)
8744 +int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt)
8746 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8748 - return security_ops->inode_readlink(dentry);
8749 + return security_ops->inode_readlink(dentry, mnt);
8752 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
8753 @@ -449,11 +458,12 @@ int security_inode_permission(struct ino
8754 return security_ops->inode_permission(inode, mask);
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)
8761 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8763 - return security_ops->inode_setattr(dentry, attr);
8764 + return security_ops->inode_setattr(dentry, mnt, attr);
8766 EXPORT_SYMBOL_GPL(security_inode_setattr);
8768 @@ -471,41 +481,48 @@ void security_inode_delete(struct inode
8769 security_ops->inode_delete(inode);
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)
8778 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8780 - return security_ops->inode_setxattr(dentry, name, value, size, flags);
8781 + return security_ops->inode_setxattr(dentry, mnt, name, value, size,
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)
8791 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8793 - security_ops->inode_post_setxattr(dentry, name, value, size, flags);
8794 + security_ops->inode_post_setxattr(dentry, mnt, name, value, size,
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)
8802 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8804 - return security_ops->inode_getxattr(dentry, name);
8805 + return security_ops->inode_getxattr(dentry, mnt, name, file);
8808 -int security_inode_listxattr(struct dentry *dentry)
8809 +int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt,
8810 + struct file *file)
8812 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8814 - return security_ops->inode_listxattr(dentry);
8815 + return security_ops->inode_listxattr(dentry, mnt, file);
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)
8822 if (unlikely(IS_PRIVATE(dentry->d_inode)))
8824 - return security_ops->inode_removexattr(dentry, name);
8825 + return security_ops->inode_removexattr(dentry, mnt, name, file);
8828 int security_inode_need_killpriv(struct dentry *dentry)
8829 @@ -608,6 +625,15 @@ int security_dentry_open(struct file *fi
8830 return security_ops->dentry_open(file);
8833 +int security_path_permission(struct path *path, int mask)
8835 + struct inode *inode = path->dentry->d_inode;
8836 + if (unlikely(IS_PRIVATE(inode)))
8839 + return security_ops->path_permission(path, mask);
8842 int security_task_create(unsigned long clone_flags)
8844 return security_ops->task_create(clone_flags);
8845 diff -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
8850 static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid)
8853 - char *buffer, *path, *end;
8854 + char *buffer, *path;
8858 buffer = (char *)__get_free_page(GFP_KERNEL);
8862 - buflen = PAGE_SIZE;
8863 - end = buffer+buflen;
8869 - const char *name = table->procname;
8870 - size_t namelen = strlen(name);
8871 - buflen -= namelen + 1;
8875 - memcpy(end, name, namelen);
8878 - table = table->parent;
8884 - memcpy(end, "/sys", 4);
8886 - rc = security_genfs_sid("proc", path, tclass, sid);
8888 + path = sysctl_pathname(table, buffer, PAGE_SIZE);
8890 + rc = security_genfs_sid("proc", path, tclass, sid);
8891 free_page((unsigned long)buffer);
8894 @@ -2564,64 +2540,79 @@ static int selinux_inode_init_security(s
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)
8902 return may_create(dir, dentry, SECCLASS_FILE);
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)
8914 - rc = secondary_ops->inode_link(old_dentry, dir, new_dentry);
8915 + rc = secondary_ops->inode_link(old_dentry, old_mnt, dir, new_dentry,
8919 return may_link(dir, old_dentry, MAY_LINK);
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)
8928 - rc = secondary_ops->inode_unlink(dir, dentry);
8929 + rc = secondary_ops->inode_unlink(dir, dentry, mnt);
8932 return may_link(dir, dentry, MAY_UNLINK);
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)
8939 return may_create(dir, dentry, SECCLASS_LNK_FILE);
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)
8946 return may_create(dir, dentry, SECCLASS_DIR);
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)
8953 return may_link(dir, dentry, MAY_RMDIR);
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)
8962 - rc = secondary_ops->inode_mknod(dir, dentry, mode, dev);
8963 + rc = secondary_ops->inode_mknod(dir, dentry, mnt, mode, dev);
8967 return may_create(dir, dentry, inode_mode_to_security_class(mode));
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)
8979 return may_rename(old_inode, old_dentry, new_inode, new_dentry);
8982 -static int selinux_inode_readlink(struct dentry *dentry)
8983 +static int selinux_inode_readlink(struct dentry *dentry, struct vfsmount *mnt)
8985 return dentry_has_perm(current, NULL, dentry, FILE__READ);
8987 @@ -2653,11 +2644,12 @@ static int selinux_inode_permission(stru
8988 open_file_mask_to_av(inode->i_mode, mask), NULL);
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)
8997 - rc = secondary_ops->inode_setattr(dentry, iattr);
8998 + rc = secondary_ops->inode_setattr(dentry, mnt, iattr);
9002 @@ -2695,8 +2687,9 @@ static int selinux_inode_setotherxattr(s
9003 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
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)
9012 struct task_security_struct *tsec = current->security;
9013 struct inode *inode = dentry->d_inode;
9014 @@ -2750,7 +2743,8 @@ static int selinux_inode_setxattr(struct
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,
9024 @@ -2776,17 +2770,21 @@ static void selinux_inode_post_setxattr(
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)
9032 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
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)
9039 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
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)
9047 if (strcmp(name, XATTR_NAME_SELINUX))
9048 return selinux_inode_setotherxattr(dentry, name);
9049 diff -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
9052 @@ -432,8 +432,9 @@ static int smack_inode_init_security(str
9054 * Returns 0 if access is permitted, an error code otherwise
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)
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
9070 * Returns 0 if current can write the containing directory
9071 * and the object, error code otherwise
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)
9077 struct inode *ip = dentry->d_inode;
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
9085 * Returns 0 if current can write the containing directory
9086 * and the directory, error code otherwise
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)
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
9103 * Read and write access is required on both the old and
9105 @@ -514,8 +521,10 @@ static int smack_inode_rmdir(struct inod
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)
9117 @@ -559,7 +568,8 @@ static int smack_inode_permission(struct
9119 * Returns 0 if access is permitted, an error code otherwise
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)
9126 * Need to allow for clearing the setuid bit.
9127 @@ -585,17 +595,20 @@ static int smack_inode_getattr(struct vf
9129 * smack_inode_setxattr - Smack check for setting xattrs
9130 * @dentry: the object
9132 * @name: name of the attribute
9138 * This protects the Smack attribute explicitly.
9140 * Returns 0 if access is permitted, an error code otherwise
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)
9150 @@ -605,7 +618,8 @@ static int smack_inode_setxattr(struct d
9151 if (!capable(CAP_MAC_ADMIN))
9154 - rc = cap_inode_setxattr(dentry, name, value, size, flags);
9155 + rc = cap_inode_setxattr(dentry, mnt, name, value, size, flags,
9159 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
9160 @@ -616,6 +630,7 @@ static int smack_inode_setxattr(struct d
9162 * smack_inode_post_setxattr - Apply the Smack update approved above
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.
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)
9177 struct inode_smack *isp;
9178 @@ -657,11 +673,14 @@ static void smack_inode_post_setxattr(st
9180 * smack_inode_getxattr - Smack check on getxattr
9181 * @dentry: the object
9186 * Returns 0 if access is permitted, an error code otherwise
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)
9192 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ);
9194 @@ -669,13 +688,16 @@ static int smack_inode_getxattr(struct d
9196 * smack_inode_removexattr - Smack check on removexattr
9197 * @dentry: the object
9199 * @name: name of the attribute
9202 * Removing the Smack attribute requires CAP_MAC_ADMIN
9204 * Returns 0 if access is permitted, an error code otherwise
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)
9212 @@ -685,7 +707,7 @@ static int smack_inode_removexattr(struc
9213 if (!capable(CAP_MAC_ADMIN))
9216 - rc = cap_inode_removexattr(dentry, name);
9217 + rc = cap_inode_removexattr(dentry, mnt, name, file);
9220 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE);
9222 security/apparmor/main.c | 2 +-
9223 1 file changed, 1 insertion(+), 1 deletion(-)
9225 --- a/security/apparmor/main.c
9226 +++ b/security/apparmor/main.c
9227 @@ -503,10 +503,10 @@ static char *aa_get_name(struct dentry *
9232 if (PTR_ERR(name) != -ENAMETOOLONG)
9237 if (size > apparmor_path_max)
9238 return ERR_PTR(-ENAMETOOLONG);