]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.25/patches.apparmor/add-path_permission.diff
Added missing SuSE-Xen-Patches.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.apparmor / add-path_permission.diff
diff --git a/src/patches/suse-2.6.27.25/patches.apparmor/add-path_permission.diff b/src/patches/suse-2.6.27.25/patches.apparmor/add-path_permission.diff
new file mode 100644 (file)
index 0000000..0eb796d
--- /dev/null
@@ -0,0 +1,201 @@
+From: Jeff Mahoney <jeffm@suse.com>
+Subject: [PATCH] vfs: introduce path_permission()
+
+ 2.6.27 eliminated the nameidata parameter from permission and replaced
+ several call sites with inode_permission. This keeps the information
+ required by AppArmor from reaching it.
+
+ The following patch factors out the permission assessment part of
+ inode_permission into __inode_permission and adds a path_permission
+ function that takes a struct path instead of a struct inode and passes
+ it to security_path_permission instead of security_inode_permission.
+
+ All of the call sites that had access to a struct path whether by
+ itself or via a file or nameidata (and used it) in 2.6.26 are changed
+ to use the path_permission call.
+
+Signed-off-by: Jeff Mahoney <jeffm@suse.com>
+---
+ fs/inotify_user.c  |    2 +-
+ fs/namei.c         |   32 ++++++++++++++++++++++++--------
+ fs/open.c          |   10 +++++-----
+ include/linux/fs.h |    5 +++++
+ 4 files changed, 35 insertions(+), 14 deletions(-)
+
+--- a/fs/inotify_user.c
++++ b/fs/inotify_user.c
+@@ -372,7 +372,7 @@ static int find_inode(const char __user
+       if (error)
+               return error;
+       /* you can only watch an inode if you have read permissions on it */
+-      error = inode_permission(path->dentry->d_inode, MAY_READ);
++      error = path_permission(path, MAY_READ);
+       if (error)
+               path_put(path);
+       return error;
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -227,7 +227,7 @@ int generic_permission(struct inode *ino
+       return -EACCES;
+ }
+-int inode_permission(struct inode *inode, int mask)
++static int __inode_permission(struct inode *inode, int mask)
+ {
+       int retval;
+       int submask = mask;
+@@ -273,7 +273,12 @@ int inode_permission(struct inode *inode
+       if (retval)
+               return retval;
+-      retval = devcgroup_inode_permission(inode, mask);
++      return devcgroup_inode_permission(inode, mask);
++}
++
++int inode_permission(struct inode *inode, int mask)
++{
++      int retval = __inode_permission(inode, mask);
+       if (retval)
+               return retval;
+@@ -281,6 +286,15 @@ int inode_permission(struct inode *inode
+                       mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND));
+ }
++int path_permission(struct path *path, int mask)
++{
++      int retval = __inode_permission(path->dentry->d_inode, mask);
++      if (retval)
++              return retval;
++      return security_path_permission(path,
++                      mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND));
++}
++
+ /**
+  * vfs_permission  -  check for access rights to a given path
+  * @nd:               lookup result that describes the path
+@@ -293,7 +307,7 @@ int inode_permission(struct inode *inode
+  */
+ int vfs_permission(struct nameidata *nd, int mask)
+ {
+-      return inode_permission(nd->path.dentry->d_inode, mask);
++      return path_permission(&nd->path, mask);
+ }
+ /**
+@@ -310,7 +324,7 @@ int vfs_permission(struct nameidata *nd,
+  */
+ int file_permission(struct file *file, int mask)
+ {
+-      return inode_permission(file->f_path.dentry->d_inode, mask);
++      return path_permission(&file->f_path, mask);
+ }
+ /*
+@@ -452,8 +466,9 @@ static struct dentry * cached_lookup(str
+  * short-cut DAC fails, then call permission() to do more
+  * complete permission check.
+  */
+-static int exec_permission_lite(struct inode *inode)
++static int exec_permission_lite(struct path *path)
+ {
++      struct inode *inode = path->dentry->d_inode;
+       umode_t mode = inode->i_mode;
+       if (inode->i_op && inode->i_op->permission)
+@@ -478,7 +493,7 @@ static int exec_permission_lite(struct i
+       return -EACCES;
+ ok:
+-      return security_inode_permission(inode, MAY_EXEC);
++      return security_path_permission(path, MAY_EXEC);
+ }
+ /*
+@@ -875,7 +890,7 @@ static int __link_path_walk(const char *
+               unsigned int c;
+               nd->flags |= LOOKUP_CONTINUE;
+-              err = exec_permission_lite(inode);
++              err = exec_permission_lite(&nd->path);
+               if (err == -EAGAIN)
+                       err = vfs_permission(nd, MAY_EXEC);
+               if (err)
+@@ -1250,7 +1265,7 @@ static struct dentry *lookup_hash(struct
+ {
+       int err;
+-      err = inode_permission(nd->path.dentry->d_inode, MAY_EXEC);
++      err = path_permission(&nd->path, MAY_EXEC);
+       if (err)
+               return ERR_PTR(err);
+       return __lookup_hash(&nd->last, nd->path.dentry, nd);
+@@ -2907,6 +2922,7 @@ EXPORT_SYMBOL(page_symlink_inode_operati
+ EXPORT_SYMBOL(path_lookup);
+ EXPORT_SYMBOL(vfs_path_lookup);
+ EXPORT_SYMBOL(inode_permission);
++EXPORT_SYMBOL(path_permission);
+ EXPORT_SYMBOL(vfs_permission);
+ EXPORT_SYMBOL(file_permission);
+ EXPORT_SYMBOL(unlock_rename);
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -248,7 +248,7 @@ static long do_sys_truncate(const char _
+       if (error)
+               goto dput_and_out;
+-      error = inode_permission(inode, MAY_WRITE);
++      error = path_permission(&path, MAY_WRITE);
+       if (error)
+               goto mnt_drop_write_and_out;
+@@ -493,7 +493,7 @@ SYSCALL_DEFINE3(faccessat, int, dfd, con
+                       goto out_path_release;
+       }
+-      res = inode_permission(inode, mode | MAY_ACCESS);
++      res = path_permission(&path, mode | MAY_ACCESS);
+       /* SuS v2 requires we report a read only fs too */
+       if (res || !(mode & S_IWOTH) || special_file(inode->i_mode))
+               goto out_path_release;
+@@ -536,7 +536,7 @@ SYSCALL_DEFINE1(chdir, const char __user
+       if (error)
+               goto out;
+-      error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
++      error = path_permission(&path, MAY_EXEC | MAY_ACCESS);
+       if (error)
+               goto dput_and_out;
+@@ -565,7 +565,7 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd
+       if (!S_ISDIR(inode->i_mode))
+               goto out_putf;
+-      error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
++      error = path_permission(&file->f_path, MAY_EXEC | MAY_ACCESS);
+       if (!error)
+               set_fs_pwd(current->fs, &file->f_path);
+ out_putf:
+@@ -583,7 +583,7 @@ SYSCALL_DEFINE1(chroot, const char __use
+       if (error)
+               goto out;
+-      error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
++      error = path_permission(&path, MAY_EXEC | MAY_ACCESS);
+       if (error)
+               goto dput_and_out;
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1201,6 +1201,11 @@ extern void dentry_unhash(struct dentry
+ extern int file_permission(struct file *, int);
+ /*
++ * VFS path helper functions.
++ */
++extern int path_permission(struct path *, int);
++
++/*
+  * File types
+  *
+  * NOTE! These match bits 12..15 of stat.st_mode