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