From ffa60342435a3772569e6c29dbf6a47b8279728a Mon Sep 17 00:00:00 2001 From: John Johansen Date: Tue, 27 May 2008 12:04:33 +0000 Subject: [PATCH] remove for-mainline dir from kernel patches --- .../for-mainline/__d_path-keep-connected.diff | 144 - .../for-mainline/apparmor-audit-flags2.diff | 745 ----- .../for-mainline/apparmor-audit.diff | 72 - .../for-mainline/apparmor-bootdisable.diff | 61 - .../for-mainline/apparmor-builtin-only.diff | 50 - .../for-mainline/apparmor-create-append.diff | 16 - .../apparmor-failed-name-error.diff | 83 - .../for-mainline/apparmor-features.diff | 47 - .../apparmor-fix-lock-letter.diff | 36 - .../apparmor-fix-sysctl-refcount.diff | 14 - .../for-mainline/apparmor-intree.diff | 30 - .../for-mainline/apparmor-link-pairs.diff | 162 - kernel-patches/for-mainline/apparmor-lsm.diff | 904 ------ .../for-mainline/apparmor-main-2.diff | 59 - .../for-mainline/apparmor-main.diff | 1494 ---------- .../for-mainline/apparmor-misc.diff | 1418 --------- .../apparmor-module_interface.diff | 1350 --------- .../for-mainline/apparmor-network.diff | 408 --- .../for-mainline/apparmor-rlimits.diff | 461 --- .../apparmor-secondary-accept.diff | 73 - .../for-mainline/apparmor-security-goal.diff | 141 - .../audit-log-type-in-syslog.diff | 18 - kernel-patches/for-mainline/audit-uid.diff | 16 - kernel-patches/for-mainline/cap-set.diff | 87 - .../change-profile-kernel-v2.diff | 95 - .../for-mainline/d_namespace_path.diff | 86 - .../do_path_lookup-nameidata.diff | 47 - .../for-mainline/ecryptfs-d_revalidate.diff | 42 - kernel-patches/for-mainline/expand-dfa.diff | 173 -- .../for-mainline/extend-x-mods.diff | 72 - kernel-patches/for-mainline/fgetattr.diff | 130 - .../for-mainline/file-handle-ops.diff | 83 - .../file_permission-nameidata.diff | 31 - .../fix-change_profile-namespace.diff | 17 - kernel-patches/for-mainline/fix-d_path.diff | 68 - kernel-patches/for-mainline/fix-dfa.diff | 134 - kernel-patches/for-mainline/fix-fuse.diff | 37 - kernel-patches/for-mainline/fix-getcwd.diff | 30 - .../for-mainline/fix-link-subset.diff | 76 - .../for-mainline/fix-name-errorpath.diff | 22 - .../for-mainline/fix-named-transitions.diff | 26 - kernel-patches/for-mainline/fix-net.diff | 38 - .../for-mainline/fix-profile-namespaces.diff | 92 - .../for-mainline/fix-rcu-deref.diff | 18 - .../for-mainline/fix-user-audit.diff | 15 - .../for-mainline/fix-vfs_rmdir.diff | 44 - kernel-patches/for-mainline/foobar.diff | 278 -- .../fsetattr-reintro-ATTR_FILE.diff | 27 - kernel-patches/for-mainline/fsetattr.diff | 392 --- kernel-patches/for-mainline/hat_perm.diff | 39 - .../for-mainline/may_create-args.diff | 86 - .../for-mainline/may_delete-args.diff | 74 - .../mount-consistent-__d_path.diff | 60 - .../for-mainline/nfs-nameidata-check.diff | 47 - .../nfsd_permission-nameidata.diff | 45 - .../for-mainline/no-safex-link-subset.diff | 139 - .../for-mainline/null_module/Kbuild | 3 - .../for-mainline/null_module/Makefile | 1 - .../for-mainline/null_module/foobar-lsm.c | 197 -- .../for-mainline/owner-perm-set.diff | 561 ---- .../for-mainline/parent-permission.diff | 24 - .../proc-mounts-check-d_path-result.diff | 129 - .../for-mainline/proc-mounts-cleanup.diff | 98 - .../for-mainline/profile-namespaces.diff | 1158 -------- kernel-patches/for-mainline/remove_suid.diff | 144 - .../for-mainline/security-create.diff | 107 - .../for-mainline/security-getxattr.diff | 110 - .../for-mainline/security-link.diff | 134 - .../for-mainline/security-listxattr.diff | 105 - .../for-mainline/security-mkdir.diff | 106 - .../for-mainline/security-mknod.diff | 110 - .../for-mainline/security-readlink.diff | 104 - .../for-mainline/security-removexattr.diff | 126 - .../for-mainline/security-rename.diff | 136 - .../for-mainline/security-rmdir.diff | 109 - .../for-mainline/security-setattr.diff | 119 - .../for-mainline/security-setxattr.diff | 210 -- .../for-mainline/security-symlink.diff | 105 - .../for-mainline/security-unlink.diff | 114 - .../for-mainline/security-xattr-file.diff | 540 ---- .../for-mainline/security_chroot.diff | 85 - kernel-patches/for-mainline/series | 123 - .../for-mainline/should_remove_suid.diff | 96 - .../for-mainline/slash-null-dfa.diff | 40 - .../for-mainline/split-up-nameidata.diff | 2604 ----------------- kernel-patches/for-mainline/split_init.diff | 215 -- kernel-patches/for-mainline/statvfs-2.diff | 494 ---- kernel-patches/for-mainline/statvfs.diff | 370 --- .../for-mainline/struct_path/series | 5 - .../struct_path/struct_path-getattr-iop.diff | 504 ---- .../struct_path/struct_path-nameidata.diff | 2287 --------------- .../struct_path/struct_path-nfsfh.diff | 920 ------ .../struct_path-security-getattr.diff | 91 - .../struct_path/struct_path-vfs_getattr.diff | 241 -- .../for-mainline/sys_fchdir-nameidata.diff | 51 - .../for-mainline/sysctl-pathname.diff | 111 - .../for-mainline/unambiguous-__d_path.diff | 268 -- kernel-patches/for-mainline/vfs-getxattr.diff | 190 -- kernel-patches/for-mainline/vfs-link.diff | 90 - .../for-mainline/vfs-listxattr.diff | 102 - kernel-patches/for-mainline/vfs-mkdir.diff | 137 - kernel-patches/for-mainline/vfs-mknod.diff | 98 - .../for-mainline/vfs-notify_change.diff | 387 --- .../for-mainline/vfs-removexattr.diff | 111 - kernel-patches/for-mainline/vfs-rename.diff | 125 - kernel-patches/for-mainline/vfs-rmdir.diff | 135 - kernel-patches/for-mainline/vfs-setxattr.diff | 152 - kernel-patches/for-mainline/vfs-symlink.diff | 122 - kernel-patches/for-mainline/vfs-unlink.diff | 98 - .../for-mainline/vfs_create-args.diff | 150 - .../for-mainline/vfs_create-nameidata.diff | 183 -- .../for-mainline/vfs_link-args.diff | 166 -- .../for-mainline/vfs_mkdir-args.diff | 121 - .../for-mainline/vfs_mknod-args.diff | 126 - .../for-mainline/vfs_rename-args.diff | 261 -- .../for-mainline/vfs_rmdir-args.diff | 189 -- .../for-mainline/vfs_symlink-args.diff | 163 -- .../for-mainline/vfs_unlink-args.diff | 159 - .../for-mainline/xattr_permission.diff | 69 - 119 files changed, 26841 deletions(-) delete mode 100644 kernel-patches/for-mainline/__d_path-keep-connected.diff delete mode 100644 kernel-patches/for-mainline/apparmor-audit-flags2.diff delete mode 100644 kernel-patches/for-mainline/apparmor-audit.diff delete mode 100644 kernel-patches/for-mainline/apparmor-bootdisable.diff delete mode 100644 kernel-patches/for-mainline/apparmor-builtin-only.diff delete mode 100644 kernel-patches/for-mainline/apparmor-create-append.diff delete mode 100644 kernel-patches/for-mainline/apparmor-failed-name-error.diff delete mode 100644 kernel-patches/for-mainline/apparmor-features.diff delete mode 100644 kernel-patches/for-mainline/apparmor-fix-lock-letter.diff delete mode 100644 kernel-patches/for-mainline/apparmor-fix-sysctl-refcount.diff delete mode 100644 kernel-patches/for-mainline/apparmor-intree.diff delete mode 100644 kernel-patches/for-mainline/apparmor-link-pairs.diff delete mode 100644 kernel-patches/for-mainline/apparmor-lsm.diff delete mode 100644 kernel-patches/for-mainline/apparmor-main-2.diff delete mode 100644 kernel-patches/for-mainline/apparmor-main.diff delete mode 100644 kernel-patches/for-mainline/apparmor-misc.diff delete mode 100644 kernel-patches/for-mainline/apparmor-module_interface.diff delete mode 100644 kernel-patches/for-mainline/apparmor-network.diff delete mode 100644 kernel-patches/for-mainline/apparmor-rlimits.diff delete mode 100644 kernel-patches/for-mainline/apparmor-secondary-accept.diff delete mode 100644 kernel-patches/for-mainline/apparmor-security-goal.diff delete mode 100644 kernel-patches/for-mainline/audit-log-type-in-syslog.diff delete mode 100644 kernel-patches/for-mainline/audit-uid.diff delete mode 100644 kernel-patches/for-mainline/cap-set.diff delete mode 100644 kernel-patches/for-mainline/change-profile-kernel-v2.diff delete mode 100644 kernel-patches/for-mainline/d_namespace_path.diff delete mode 100644 kernel-patches/for-mainline/do_path_lookup-nameidata.diff delete mode 100644 kernel-patches/for-mainline/ecryptfs-d_revalidate.diff delete mode 100644 kernel-patches/for-mainline/expand-dfa.diff delete mode 100644 kernel-patches/for-mainline/extend-x-mods.diff delete mode 100644 kernel-patches/for-mainline/fgetattr.diff delete mode 100644 kernel-patches/for-mainline/file-handle-ops.diff delete mode 100644 kernel-patches/for-mainline/file_permission-nameidata.diff delete mode 100644 kernel-patches/for-mainline/fix-change_profile-namespace.diff delete mode 100644 kernel-patches/for-mainline/fix-d_path.diff delete mode 100644 kernel-patches/for-mainline/fix-dfa.diff delete mode 100644 kernel-patches/for-mainline/fix-fuse.diff delete mode 100644 kernel-patches/for-mainline/fix-getcwd.diff delete mode 100644 kernel-patches/for-mainline/fix-link-subset.diff delete mode 100644 kernel-patches/for-mainline/fix-name-errorpath.diff delete mode 100644 kernel-patches/for-mainline/fix-named-transitions.diff delete mode 100644 kernel-patches/for-mainline/fix-net.diff delete mode 100644 kernel-patches/for-mainline/fix-profile-namespaces.diff delete mode 100644 kernel-patches/for-mainline/fix-rcu-deref.diff delete mode 100644 kernel-patches/for-mainline/fix-user-audit.diff delete mode 100644 kernel-patches/for-mainline/fix-vfs_rmdir.diff delete mode 100644 kernel-patches/for-mainline/foobar.diff delete mode 100644 kernel-patches/for-mainline/fsetattr-reintro-ATTR_FILE.diff delete mode 100644 kernel-patches/for-mainline/fsetattr.diff delete mode 100644 kernel-patches/for-mainline/hat_perm.diff delete mode 100644 kernel-patches/for-mainline/may_create-args.diff delete mode 100644 kernel-patches/for-mainline/may_delete-args.diff delete mode 100644 kernel-patches/for-mainline/mount-consistent-__d_path.diff delete mode 100644 kernel-patches/for-mainline/nfs-nameidata-check.diff delete mode 100644 kernel-patches/for-mainline/nfsd_permission-nameidata.diff delete mode 100644 kernel-patches/for-mainline/no-safex-link-subset.diff delete mode 100644 kernel-patches/for-mainline/null_module/Kbuild delete mode 100644 kernel-patches/for-mainline/null_module/Makefile delete mode 100644 kernel-patches/for-mainline/null_module/foobar-lsm.c delete mode 100644 kernel-patches/for-mainline/owner-perm-set.diff delete mode 100644 kernel-patches/for-mainline/parent-permission.diff delete mode 100644 kernel-patches/for-mainline/proc-mounts-check-d_path-result.diff delete mode 100644 kernel-patches/for-mainline/proc-mounts-cleanup.diff delete mode 100644 kernel-patches/for-mainline/profile-namespaces.diff delete mode 100644 kernel-patches/for-mainline/remove_suid.diff delete mode 100644 kernel-patches/for-mainline/security-create.diff delete mode 100644 kernel-patches/for-mainline/security-getxattr.diff delete mode 100644 kernel-patches/for-mainline/security-link.diff delete mode 100644 kernel-patches/for-mainline/security-listxattr.diff delete mode 100644 kernel-patches/for-mainline/security-mkdir.diff delete mode 100644 kernel-patches/for-mainline/security-mknod.diff delete mode 100644 kernel-patches/for-mainline/security-readlink.diff delete mode 100644 kernel-patches/for-mainline/security-removexattr.diff delete mode 100644 kernel-patches/for-mainline/security-rename.diff delete mode 100644 kernel-patches/for-mainline/security-rmdir.diff delete mode 100644 kernel-patches/for-mainline/security-setattr.diff delete mode 100644 kernel-patches/for-mainline/security-setxattr.diff delete mode 100644 kernel-patches/for-mainline/security-symlink.diff delete mode 100644 kernel-patches/for-mainline/security-unlink.diff delete mode 100644 kernel-patches/for-mainline/security-xattr-file.diff delete mode 100644 kernel-patches/for-mainline/security_chroot.diff delete mode 100644 kernel-patches/for-mainline/series delete mode 100644 kernel-patches/for-mainline/should_remove_suid.diff delete mode 100644 kernel-patches/for-mainline/slash-null-dfa.diff delete mode 100644 kernel-patches/for-mainline/split-up-nameidata.diff delete mode 100644 kernel-patches/for-mainline/split_init.diff delete mode 100644 kernel-patches/for-mainline/statvfs-2.diff delete mode 100644 kernel-patches/for-mainline/statvfs.diff delete mode 100644 kernel-patches/for-mainline/struct_path/series delete mode 100644 kernel-patches/for-mainline/struct_path/struct_path-getattr-iop.diff delete mode 100644 kernel-patches/for-mainline/struct_path/struct_path-nameidata.diff delete mode 100644 kernel-patches/for-mainline/struct_path/struct_path-nfsfh.diff delete mode 100644 kernel-patches/for-mainline/struct_path/struct_path-security-getattr.diff delete mode 100644 kernel-patches/for-mainline/struct_path/struct_path-vfs_getattr.diff delete mode 100644 kernel-patches/for-mainline/sys_fchdir-nameidata.diff delete mode 100644 kernel-patches/for-mainline/sysctl-pathname.diff delete mode 100644 kernel-patches/for-mainline/unambiguous-__d_path.diff delete mode 100644 kernel-patches/for-mainline/vfs-getxattr.diff delete mode 100644 kernel-patches/for-mainline/vfs-link.diff delete mode 100644 kernel-patches/for-mainline/vfs-listxattr.diff delete mode 100644 kernel-patches/for-mainline/vfs-mkdir.diff delete mode 100644 kernel-patches/for-mainline/vfs-mknod.diff delete mode 100644 kernel-patches/for-mainline/vfs-notify_change.diff delete mode 100644 kernel-patches/for-mainline/vfs-removexattr.diff delete mode 100644 kernel-patches/for-mainline/vfs-rename.diff delete mode 100644 kernel-patches/for-mainline/vfs-rmdir.diff delete mode 100644 kernel-patches/for-mainline/vfs-setxattr.diff delete mode 100644 kernel-patches/for-mainline/vfs-symlink.diff delete mode 100644 kernel-patches/for-mainline/vfs-unlink.diff delete mode 100644 kernel-patches/for-mainline/vfs_create-args.diff delete mode 100644 kernel-patches/for-mainline/vfs_create-nameidata.diff delete mode 100644 kernel-patches/for-mainline/vfs_link-args.diff delete mode 100644 kernel-patches/for-mainline/vfs_mkdir-args.diff delete mode 100644 kernel-patches/for-mainline/vfs_mknod-args.diff delete mode 100644 kernel-patches/for-mainline/vfs_rename-args.diff delete mode 100644 kernel-patches/for-mainline/vfs_rmdir-args.diff delete mode 100644 kernel-patches/for-mainline/vfs_symlink-args.diff delete mode 100644 kernel-patches/for-mainline/vfs_unlink-args.diff delete mode 100644 kernel-patches/for-mainline/xattr_permission.diff diff --git a/kernel-patches/for-mainline/__d_path-keep-connected.diff b/kernel-patches/for-mainline/__d_path-keep-connected.diff deleted file mode 100644 index e2d3de47f..000000000 --- a/kernel-patches/for-mainline/__d_path-keep-connected.diff +++ /dev/null @@ -1,144 +0,0 @@ -From: John Johansen -Subject: Fix __d_path to allow for old and new behavior bnc#380763 - -Fix __d_path so that it can be told whether or not to connect -disconnect path to the root. This is easier and more efficient -than trying to reconnect these paths for d_path and get_cwd -after the fact. - -Signed-off-by: John Johansen - ---- - fs/dcache.c | 57 ++++++++++++++++++------------------------------- - fs/namespace.c | 2 - - include/linux/dcache.h | 2 - - 3 files changed, 24 insertions(+), 37 deletions(-) - ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -1772,6 +1772,7 @@ shouldnt_be_hashed: - * @buffer: buffer to return value in - * @buflen: buffer length - * @fail_deleted: what to return for deleted files -+ * @disconnect: don't return a path starting with / when disconnected - * - * Convert a dentry into an ASCII path name. If the entry has been deleted, - * then if @fail_deleted is true, ERR_PTR(-ENOENT) is returned. Otherwise, -@@ -1784,9 +1785,10 @@ shouldnt_be_hashed: - */ - char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt, - struct dentry *root, struct vfsmount *rootmnt, -- char *buffer, int buflen, int fail_deleted) -+ char *buffer, int buflen, int fail_deleted, int disconnect) - { -- int namelen, is_slash, vfsmount_locked = 0; -+ int namelen, vfsmount_locked = 0; -+ const unsigned char *name; - - if (buflen < 2) - return ERR_PTR(-ENAMETOOLONG); -@@ -1847,27 +1849,26 @@ global_root: - * unconnected dentry, or the file is on a pseudo filesystem. - */ - namelen = dentry->d_name.len; -- is_slash = (namelen == 1 && *dentry->d_name.name == '/'); -- if (is_slash || (dentry->d_sb->s_flags & MS_NOUSER)) { -- /* -- * Make sure we won't return a pathname starting with '/'. -- * -- * Historically, we also glue together the root dentry and -- * remaining name for pseudo filesystems like pipefs, which -- * have the MS_NOUSER flag set. This results in pathnames -- * like "pipe:[439336]". -- */ -- if (*buffer == '/') { -- buffer++; -- buflen++; -- } -- if (is_slash) -- goto out; -+ name = dentry->d_name.name; -+ -+ /* -+ * If this is a root dentry, then overwrite the slash. This -+ * will also DTRT with pseudo filesystems which have root -+ * dentries named "foo:". -+ */ -+ if (IS_ROOT(dentry)) { -+ buffer++; -+ buflen++; -+ } -+ if (disconnect && *name == '/') { -+ /* Make sure we won't return a pathname starting with '/' */ -+ name++; -+ namelen--; - } - if (buflen < namelen) - goto Elong; - buffer -= namelen; -- memcpy(buffer, dentry->d_name.name, namelen); -+ memcpy(buffer, name, namelen); - goto out; - - Elong: -@@ -1875,18 +1876,6 @@ Elong: - goto out; - } - --static char *__connect_d_path(char *path, char *buffer) --{ -- if (!IS_ERR(path) && *path != '/') { -- /* Pretend that disconnected paths are hanging off the root. */ -- if (path == buffer) -- path = ERR_PTR(-ENAMETOOLONG); -- else -- *--path = '/'; -- } -- return path; --} -- - /* write full pathname into buffer and return start of pathname */ - char *d_path(struct dentry *dentry, struct vfsmount *vfsmnt, char *buf, - int buflen) -@@ -1909,8 +1898,7 @@ char *d_path(struct dentry *dentry, stru - rootmnt = mntget(current->fs->rootmnt); - root = dget(current->fs->root); - read_unlock(¤t->fs->lock); -- res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, 0); -- res = __connect_d_path(res, buf); -+ res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, 0, 0); - dput(root); - mntput(rootmnt); - return res; -@@ -1972,8 +1960,7 @@ asmlinkage long sys_getcwd(char __user * - root = dget(current->fs->root); - read_unlock(¤t->fs->lock); - -- cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1); -- cwd = __connect_d_path(cwd, page); -+ cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1, 0); - error = PTR_ERR(cwd); - if (IS_ERR(cwd)) - goto out; ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -1901,7 +1901,7 @@ char *d_namespace_path(struct dentry *de - mntput(rootmnt); - if (nsrootmnt) - root = dget(nsrootmnt->mnt_root); -- res = __d_path(dentry, vfsmnt, root, nsrootmnt, buf, buflen, 1); -+ res = __d_path(dentry, vfsmnt, root, nsrootmnt, buf, buflen, 1, 1); - dput(root); - mntput(nsrootmnt); - /* Prevent empty path for lazily unmounted filesystems. */ ---- a/include/linux/dcache.h -+++ b/include/linux/dcache.h -@@ -301,7 +301,7 @@ extern int d_validate(struct dentry *, s - extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); - - extern char *__d_path(struct dentry *, struct vfsmount *, struct dentry *, -- struct vfsmount *, char *, int, int); -+ struct vfsmount *, char *, int, int, int); - extern char * d_path(struct dentry *, struct vfsmount *, char *, int); - - /* Allocation counts.. */ diff --git a/kernel-patches/for-mainline/apparmor-audit-flags2.diff b/kernel-patches/for-mainline/apparmor-audit-flags2.diff deleted file mode 100644 index b53298e6d..000000000 --- a/kernel-patches/for-mainline/apparmor-audit-flags2.diff +++ /dev/null @@ -1,745 +0,0 @@ ---- - security/apparmor/apparmor.h | 14 - - security/apparmor/apparmorfs.c | 2 - security/apparmor/inline.h | 14 - - security/apparmor/main.c | 490 +++++++++++++++++++---------------- - security/apparmor/match.c | 9 - security/apparmor/module_interface.c | 10 - 6 files changed, 309 insertions(+), 230 deletions(-) - ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -44,8 +44,7 @@ - AA_EXEC_MOD_2 | AA_EXEC_MOD_3 | \ - AA_EXEC_MOD_4) - --#define AA_EXEC_TYPE (MAY_EXEC | AA_EXEC_UNSAFE | \ -- AA_EXEC_MODIFIERS) -+#define AA_EXEC_TYPE (AA_EXEC_UNSAFE | AA_EXEC_MODIFIERS) - - #define AA_EXEC_UNCONFINED AA_EXEC_MOD_0 - #define AA_EXEC_INHERIT AA_EXEC_MOD_1 -@@ -85,6 +84,10 @@ - AA_AUDIT_FIELD) - - #define AA_VALID_PERM_MASK (AA_FILE_PERMS | AA_SHARED_PERMS) -+ -+/* audit bits for the second accept field */ -+#define AUDIT_FILE_MASK 0x1fc07f -+#define AUDIT_QUIET_MASK(mask) ((mask >> 7) & AUDIT_FILE_MASK) - #define AA_VALID_PERM2_MASK 0x0fffffff - - #define AA_SECURE_EXEC_NEEDED 1 -@@ -179,6 +182,9 @@ struct aa_profile { - int isstale; - - kernel_cap_t capabilities; -+ kernel_cap_t audit_caps; -+ kernel_cap_t quiet_caps; -+ - struct kref count; - struct list_head task_contexts; - spinlock_t lock; -@@ -226,7 +232,7 @@ struct aa_audit { - const char *name; - const char *name2; - const char *name3; -- int request_mask, denied_mask; -+ int request_mask, denied_mask, audit_mask; - struct iattr *iattr; - pid_t task, parent; - int error_code; -@@ -331,7 +337,7 @@ extern struct aa_dfa *aa_match_alloc(voi - extern void aa_match_free(struct aa_dfa *dfa); - extern int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size); - extern int verify_dfa(struct aa_dfa *dfa); --extern unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str); -+extern unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str, int *); - extern unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start, - const char *str); - extern unsigned int aa_match_state(struct aa_dfa *dfa, unsigned int start, ---- a/security/apparmor/apparmorfs.c -+++ b/security/apparmor/apparmorfs.c -@@ -89,7 +89,7 @@ static struct file_operations apparmorfs - static ssize_t aa_matching_read(struct file *file, char __user *buf, - size_t size, loff_t *ppos) - { -- const char *matching = "pattern=aadfa perms=rwxamlk/ user::other"; -+ const char *matching = "pattern=aadfa audit perms=rwxamlk/ user::other"; - - return simple_read_from_buffer(buf, size, ppos, matching, - strlen(matching)); ---- a/security/apparmor/inline.h -+++ b/security/apparmor/inline.h -@@ -232,9 +232,19 @@ static inline void unlock_both_profiles( - } - } - --static inline unsigned int aa_match(struct aa_dfa *dfa, const char *pathname) -+static inline unsigned int aa_match(struct aa_dfa *dfa, const char *pathname, -+ int *audit_mask) - { -- return dfa ? aa_dfa_match(dfa, pathname) : 0; -+ if (dfa) -+ return aa_dfa_match(dfa, pathname, audit_mask); -+ if (audit_mask) -+ *audit_mask = 0; -+ return 0; -+} -+ -+static inline int dfa_audit_mask(struct aa_dfa *dfa, unsigned int state) -+{ -+ return ACCEPT_TABLE2(dfa)[state]; - } - - #endif /* __INLINE_H__ */ ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -36,204 +36,6 @@ static int aa_inode_mode(struct inode *i - return AA_OTHER_SHIFT; - } - --/** -- * aa_file_denied - check for @mask access on a file -- * @profile: profile to check against -- * @name: pathname of file -- * @mask: permission mask requested for file -- * -- * Return %0 on success, or else the permissions in @mask that the -- * profile denies. -- */ --static int aa_file_denied(struct aa_profile *profile, const char *name, -- int mask) --{ -- return (mask & ~aa_match(profile->file_rules, name)); --} -- --/** -- * aa_link_denied - check for permission to link a file -- * @profile: profile to check against -- * @link: pathname of link being created -- * @target: pathname of target to be linked to -- * @target_mode: UGO shift for target inode -- * @request_mask: the permissions subset valid only if link succeeds -- * Return %0 on success, or else the permissions that the profile denies. -- */ --static int aa_link_denied(struct aa_profile *profile, const char *link, -- const char *target, int target_mode, -- int *request_mask) --{ -- unsigned int state; -- int l_mode, t_mode, denied_mask = 0; -- int link_mask = AA_MAY_LINK << target_mode; -- -- *request_mask = link_mask; -- -- l_mode = aa_match_state(profile->file_rules, DFA_START, link, &state); -- if (l_mode & link_mask) { -- int mode; -- /* test to see if target can be paired with link */ -- state = aa_dfa_null_transition(profile->file_rules, state); -- mode = aa_match_state(profile->file_rules, state, target, -- NULL); -- -- if (!(mode & link_mask)) -- denied_mask |= link_mask; -- /* return if link subset test is not required */ -- if (!(mode & (AA_LINK_SUBSET_TEST << target_mode))) -- return denied_mask; -- } -- -- /* Do link perm subset test -- * If a subset test is required a permission subset test of the -- * perms for the link are done against the user::other of the -- * target's 'r', 'w', 'x', 'a', 'k', and 'm' permissions. -- * -- * If the link has 'x', an exact match of all the execute flags -- * must match. -- */ -- denied_mask |= ~l_mode & link_mask; -- -- t_mode = aa_match(profile->file_rules, target); -- -- /* For actual subset test ignore valid-profile-transition flags, -- * and link bits -- */ -- l_mode &= AA_FILE_PERMS & ~AA_LINK_BITS; -- t_mode &= AA_FILE_PERMS & ~AA_LINK_BITS; -- -- *request_mask = l_mode | link_mask; -- -- if (l_mode) { -- denied_mask |= l_mode & ~t_mode; -- if ((l_mode & AA_EXEC_BITS) && -- (l_mode & ALL_AA_EXEC_TYPE) != -- (t_mode & ALL_AA_EXEC_TYPE)) -- denied_mask = (denied_mask & ~ALL_AA_EXEC_TYPE) | -- (l_mode & ALL_AA_EXEC_TYPE); -- } -- -- return denied_mask; --} -- --/** -- * aa_get_name - compute the pathname of a file -- * @dentry: dentry of the file -- * @mnt: vfsmount of the file -- * @buffer: buffer that aa_get_name() allocated -- * @check: AA_CHECK_DIR is set if the file is a directory -- * -- * Returns a pointer to the beginning of the pathname (which usually differs -- * from the beginning of the buffer), or an error code. -- * -- * We need @check to indicate whether the file is a directory or not because -- * the file may not yet exist, and so we cannot check the inode's file type. -- */ --static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt, -- char **buffer, int check) --{ -- char *name; -- int is_dir, size = 256; -- -- is_dir = (check & AA_CHECK_DIR) ? 1 : 0; -- -- for (;;) { -- char *buf = kmalloc(size, GFP_KERNEL); -- if (!buf) -- return ERR_PTR(-ENOMEM); -- -- name = d_namespace_path(dentry, mnt, buf, size - is_dir); -- if (!IS_ERR(name)) { -- if (name[0] != '/') { -- /* -- * This dentry is not connected to the -- * namespace root -- reject access. -- */ -- kfree(buf); -- return ERR_PTR(-ENOENT); -- } -- if (is_dir && name[1] != '\0') { -- /* -- * Append "/" to the pathname. The root -- * directory is a special case; it already -- * ends in slash. -- */ -- buf[size - 2] = '/'; -- buf[size - 1] = '\0'; -- } -- -- *buffer = buf; -- return name; -- } -- if (PTR_ERR(name) != -ENAMETOOLONG) -- return name; -- -- kfree(buf); -- size <<= 1; -- if (size > apparmor_path_max) -- return ERR_PTR(-ENAMETOOLONG); -- } --} -- --static inline void aa_put_name_buffer(char *buffer) --{ -- kfree(buffer); --} -- --/** -- * aa_perm_dentry - check if @profile allows @mask for a file -- * @profile: profile to check against -- * @dentry: dentry of the file -- * @mnt: vfsmount o the file -- * @sa: audit context -- * @mask: requested profile permissions -- * @check: kind of check to perform -- * -- * Returns 0 upon success, or else an error code. -- * -- * @check indicates the file type, and whether the file was accessed through -- * an open file descriptor (AA_CHECK_FD) or not. -- */ --static int aa_perm_dentry(struct aa_profile *profile, struct dentry *dentry, -- struct vfsmount *mnt, struct aa_audit *sa, int check) --{ -- int error; -- char *buffer = NULL; -- -- sa->name = aa_get_name(dentry, mnt, &buffer, check); -- sa->request_mask <<= aa_inode_mode(dentry->d_inode); -- if (IS_ERR(sa->name)) { -- /* -- * deleted files are given a pass on permission checks when -- * accessed through a file descriptor. -- */ -- if (PTR_ERR(sa->name) == -ENOENT && (check & AA_CHECK_FD)) -- sa->denied_mask = 0; -- else { -- sa->denied_mask = sa->request_mask; -- sa->error_code = PTR_ERR(sa->name); -- if (sa->error_code == -ENOENT) -- sa->info = "Failed name resolution - object not a valid entry"; -- else if (sa->error_code == -ENAMETOOLONG) -- sa->info = "Failed name resolution - name too long"; -- else -- sa->info = "Failed name resolution"; -- } -- sa->name = NULL; -- } else -- sa->denied_mask = aa_file_denied(profile, sa->name, -- sa->request_mask); -- -- if (!sa->denied_mask) -- sa->error_code = 0; -- -- error = aa_audit(profile, sa); -- aa_put_name_buffer(buffer); -- -- return error; --} -- - int alloc_default_namespace(void) - { - struct aa_namespace *ns; -@@ -471,20 +273,259 @@ int aa_audit(struct aa_profile *profile, - int type = AUDIT_APPARMOR_DENIED; - struct audit_context *audit_cxt; - -- if (likely(!sa->error_code)) { -- if (likely(!PROFILE_AUDIT(profile))) -- /* nothing to log */ -- return 0; -- else -- type = AUDIT_APPARMOR_AUDIT; -- } else if (PROFILE_COMPLAIN(profile)) { -+ if (likely(!sa->error_code)) -+ type = AUDIT_APPARMOR_AUDIT; -+ else if (PROFILE_COMPLAIN(profile)) - type = AUDIT_APPARMOR_ALLOWED; -- } - - audit_cxt = apparmor_logsyscall ? current->audit_context : NULL; - return aa_audit_base(profile, sa, audit_cxt, type); - } - -+static int aa_audit_file(struct aa_profile *profile, struct aa_audit *sa) -+{ -+ if (likely(!sa->error_code)) { -+ int mask = sa->audit_mask & AUDIT_FILE_MASK; -+ -+ if (unlikely(PROFILE_AUDIT(profile))) -+ mask |= AUDIT_FILE_MASK; -+ -+ if (likely(!(sa->request_mask & mask))) -+ return 0; -+ -+ /* mask off perms that are not being force audited */ -+ sa->request_mask &= mask | ALL_AA_EXEC_TYPE; -+ } else { -+ int mask = AUDIT_QUIET_MASK(sa->audit_mask); -+ -+ if (!(sa->denied_mask & ~mask)) -+ return sa->error_code; -+ -+ /* mask off perms whose denial is being silenced */ -+ sa->denied_mask &= (~mask) | ALL_AA_EXEC_TYPE; -+ } -+ -+ return aa_audit(profile, sa); -+} -+ -+static int aa_audit_caps(struct aa_profile *profile, struct aa_audit *sa, -+ int cap) -+{ -+ if (likely(!sa->error_code)) { -+ if (likely(!PROFILE_AUDIT(profile) && -+ !cap_raised(profile->audit_caps, cap))) -+ return 0; -+ } -+ -+ /* quieting of capabilities is handled the caps_logged cache */ -+ return aa_audit(profile, sa); -+} -+ -+/** -+ * aa_file_denied - check for @mask access on a file -+ * @profile: profile to check against -+ * @name: pathname of file -+ * @mask: permission mask requested for file -+ * @audit_mask: return audit mask for the match -+ * -+ * Return %0 on success, or else the permissions in @mask that the -+ * profile denies. -+ */ -+static int aa_file_denied(struct aa_profile *profile, const char *name, -+ int mask, int *audit_mask) -+{ -+ return (mask & ~aa_match(profile->file_rules, name, audit_mask)); -+} -+ -+/** -+ * aa_link_denied - check for permission to link a file -+ * @profile: profile to check against -+ * @link: pathname of link being created -+ * @target: pathname of target to be linked to -+ * @target_mode: UGO shift for target inode -+ * @request_mask: the permissions subset valid only if link succeeds -+ * @audit_mask: return the audit_mask for the link permission -+ * Return %0 on success, or else the permissions that the profile denies. -+ */ -+static int aa_link_denied(struct aa_profile *profile, const char *link, -+ const char *target, int target_mode, -+ int *request_mask, int *audit_mask) -+{ -+ unsigned int state; -+ int l_mode, t_mode, denied_mask = 0; -+ int link_mask = AA_MAY_LINK << target_mode; -+ -+ *request_mask = link_mask; -+ -+ l_mode = aa_match_state(profile->file_rules, DFA_START, link, &state); -+ -+ if (l_mode & link_mask) { -+ int mode; -+ /* test to see if target can be paired with link */ -+ state = aa_dfa_null_transition(profile->file_rules, state); -+ mode = aa_match_state(profile->file_rules, state, target, -+ &state); -+ -+ if (!(mode & link_mask)) -+ denied_mask |= link_mask; -+ -+ *audit_mask = dfa_audit_mask(profile->file_rules, state); -+ -+ /* return if link subset test is not required */ -+ if (!(mode & (AA_LINK_SUBSET_TEST << target_mode))) -+ return denied_mask; -+ } -+ -+ /* Do link perm subset test -+ * If a subset test is required a permission subset test of the -+ * perms for the link are done against the user::other of the -+ * target's 'r', 'w', 'x', 'a', 'k', and 'm' permissions. -+ * -+ * If the link has 'x', an exact match of all the execute flags -+ * must match. -+ */ -+ denied_mask |= ~l_mode & link_mask; -+ -+ t_mode = aa_match(profile->file_rules, target, NULL); -+ -+ /* For actual subset test ignore valid-profile-transition flags, -+ * and link bits -+ */ -+ l_mode &= AA_FILE_PERMS & ~AA_LINK_BITS; -+ t_mode &= AA_FILE_PERMS & ~AA_LINK_BITS; -+ -+ *request_mask = l_mode | link_mask; -+ -+ if (l_mode) { -+ denied_mask |= l_mode & ~t_mode; -+ if ((l_mode & AA_EXEC_BITS) && -+ (l_mode & ALL_AA_EXEC_TYPE) != -+ (t_mode & ALL_AA_EXEC_TYPE)) -+ denied_mask = (denied_mask & ~ALL_AA_EXEC_TYPE) | -+ (l_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS)); -+ } -+ -+ return denied_mask; -+} -+ -+/** -+ * aa_get_name - compute the pathname of a file -+ * @dentry: dentry of the file -+ * @mnt: vfsmount of the file -+ * @buffer: buffer that aa_get_name() allocated -+ * @check: AA_CHECK_DIR is set if the file is a directory -+ * -+ * Returns a pointer to the beginning of the pathname (which usually differs -+ * from the beginning of the buffer), or an error code. -+ * -+ * We need @check to indicate whether the file is a directory or not because -+ * the file may not yet exist, and so we cannot check the inode's file type. -+ */ -+static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt, -+ char **buffer, int check) -+{ -+ char *name; -+ int is_dir, size = 256; -+ -+ is_dir = (check & AA_CHECK_DIR) ? 1 : 0; -+ -+ for (;;) { -+ char *buf = kmalloc(size, GFP_KERNEL); -+ if (!buf) -+ return ERR_PTR(-ENOMEM); -+ -+ name = d_namespace_path(dentry, mnt, buf, size - is_dir); -+ if (!IS_ERR(name)) { -+ if (name[0] != '/') { -+ /* -+ * This dentry is not connected to the -+ * namespace root -- reject access. -+ */ -+ kfree(buf); -+ return ERR_PTR(-ENOENT); -+ } -+ if (is_dir && name[1] != '\0') { -+ /* -+ * Append "/" to the pathname. The root -+ * directory is a special case; it already -+ * ends in slash. -+ */ -+ buf[size - 2] = '/'; -+ buf[size - 1] = '\0'; -+ } -+ -+ *buffer = buf; -+ return name; -+ } -+ if (PTR_ERR(name) != -ENAMETOOLONG) -+ return name; -+ -+ kfree(buf); -+ size <<= 1; -+ if (size > apparmor_path_max) -+ return ERR_PTR(-ENAMETOOLONG); -+ } -+} -+ -+static inline void aa_put_name_buffer(char *buffer) -+{ -+ kfree(buffer); -+} -+ -+/** -+ * aa_perm_dentry - check if @profile allows @mask for a file -+ * @profile: profile to check against -+ * @dentry: dentry of the file -+ * @mnt: vfsmount o the file -+ * @sa: audit context -+ * @mask: requested profile permissions -+ * @check: kind of check to perform -+ * -+ * Returns 0 upon success, or else an error code. -+ * -+ * @check indicates the file type, and whether the file was accessed through -+ * an open file descriptor (AA_CHECK_FD) or not. -+ */ -+static int aa_perm_dentry(struct aa_profile *profile, struct dentry *dentry, -+ struct vfsmount *mnt, struct aa_audit *sa, int check) -+{ -+ int error; -+ char *buffer = NULL; -+ -+ sa->name = aa_get_name(dentry, mnt, &buffer, check); -+ sa->request_mask <<= aa_inode_mode(dentry->d_inode); -+ if (IS_ERR(sa->name)) { -+ /* -+ * deleted files are given a pass on permission checks when -+ * accessed through a file descriptor. -+ */ -+ if (PTR_ERR(sa->name) == -ENOENT && (check & AA_CHECK_FD)) -+ sa->denied_mask = 0; -+ else { -+ sa->denied_mask = sa->request_mask; -+ sa->error_code = PTR_ERR(sa->name); -+ if (sa->error_code == -ENOENT) -+ sa->info = "Failed name resolution - object not a valid entry"; -+ else if (sa->error_code == -ENAMETOOLONG) -+ sa->info = "Failed name resolution - name too long"; -+ else -+ sa->info = "Failed name resolution"; -+ } -+ sa->name = NULL; -+ } else -+ sa->denied_mask = aa_file_denied(profile, sa->name, -+ sa->request_mask, -+ &sa->audit_mask); -+ -+ if (!sa->denied_mask) -+ sa->error_code = 0; -+ -+ error = aa_audit_file(profile, sa); -+ aa_put_name_buffer(buffer); -+ -+ return error; -+} -+ - /** - * aa_attr - check if attribute change is allowed - * @profile: profile to check against -@@ -621,10 +662,11 @@ int aa_perm_path(struct aa_profile *prof - else - sa.request_mask = mask << AA_OTHER_SHIFT; - -- sa.denied_mask = aa_file_denied(profile, name, sa.request_mask) ; -+ sa.denied_mask = aa_file_denied(profile, name, sa.request_mask, -+ &sa.audit_mask) ; - sa.error_code = sa.denied_mask ? -EACCES : 0; - -- return aa_audit(profile, &sa); -+ return aa_audit_file(profile, &sa); - } - - /** -@@ -660,7 +702,7 @@ int aa_capability(struct aa_task_context - sa.name = capability_names[cap]; - sa.error_code = error; - -- error = aa_audit(cxt->profile, &sa); -+ error = aa_audit_caps(cxt->profile, &sa, cap); - - return error; - } -@@ -709,11 +751,12 @@ int aa_link(struct aa_profile *profile, - if (sa.name && sa.name2) { - sa.denied_mask = aa_link_denied(profile, sa.name, sa.name2, - aa_inode_mode(target->d_inode), -- &sa.request_mask); -+ &sa.request_mask, -+ &sa.audit_mask); - sa.error_code = sa.denied_mask ? -EACCES : 0; - } - -- error = aa_audit(profile, &sa); -+ error = aa_audit_file(profile, &sa); - - aa_put_name_buffer(buffer); - aa_put_name_buffer(buffer2); -@@ -802,8 +845,8 @@ aa_register_find(struct aa_profile *prof - new_profile = - aa_dup_profile(profile->ns->null_complain_profile); - } else { -- aa_audit_reject(profile, sa); -- return ERR_PTR(-EACCES); /* was -EPERM */ -+ sa->error_code = -EACCES; -+ return ERR_PTR(aa_audit_file(profile, sa)); - } - } else { - /* Only way we can get into this code is if task -@@ -863,7 +906,8 @@ repeat: - /* Confined task, determine what mode inherit, unconfined or - * mandatory to load new profile - */ -- exec_mode = aa_match(profile->file_rules, filename); -+ exec_mode = aa_match(profile->file_rules, filename, -+ &sa.audit_mask); - - if (exec_mode & sa.request_mask) { - switch ((exec_mode >> shift) & AA_EXEC_MODIFIERS) { -@@ -906,6 +950,9 @@ repeat: - break; - } - -+ } else if (sa.request_mask & AUDIT_QUIET_MASK(sa.audit_mask)) { -+ /* quiet failed exit */ -+ new_profile = ERR_PTR(-EACCES); - } else if (complain) { - /* There was no entry in calling profile - * describing mode to execute image in. -@@ -916,8 +963,8 @@ repeat: - exec_mode |= AA_EXEC_UNSAFE << shift; - } else { - sa.denied_mask = sa.request_mask; -- aa_audit_reject(profile, &sa); -- new_profile = ERR_PTR(-EPERM); -+ sa.error_code = -EACCES; -+ new_profile = ERR_PTR(aa_audit_file(profile, &sa)); - } - } else { - /* Unconfined task, load profile if it exists */ -@@ -973,6 +1020,7 @@ repeat: - sa.info = "set profile"; - aa_audit_hint(new_profile, &sa); - } -+ - cleanup: - aa_put_name_buffer(buffer); - if (IS_ERR(new_profile)) -@@ -1149,7 +1197,7 @@ repeat: - - if (PROFILE_COMPLAIN(profile) || - (ns == profile->ns && -- (aa_match(profile->file_rules, name) & AA_CHANGE_PROFILE))) -+ (aa_match(profile->file_rules, name, NULL) & AA_CHANGE_PROFILE))) - error = do_change_profile(profile, ns, name, 0, 0, &sa); - else { - /* check for a rule with a namespace prepended */ -@@ -1356,9 +1404,11 @@ void aa_change_task_context(struct task_ - call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback); - } - if (new_cxt) { -- /* clear the caps_logged cache, so that new profile/hat has -- * chance to emit its own set of cap messages */ -- new_cxt->caps_logged = CAP_EMPTY_SET; -+ /* set the caps_logged cache to the quiet_caps mask -+ * this has the effect of quieting caps that are not -+ * supposed to be logged -+ */ -+ new_cxt->caps_logged = profile->quiet_caps; - new_cxt->cookie = cookie; - new_cxt->task = task; - new_cxt->profile = aa_dup_profile(profile); ---- a/security/apparmor/match.c -+++ b/security/apparmor/match.c -@@ -14,6 +14,7 @@ - #include - #include "apparmor.h" - #include "match.h" -+#include "inline.h" - - static struct table_header *unpack_table(void *blob, size_t bsize) - { -@@ -295,13 +296,17 @@ unsigned int aa_dfa_null_transition(stru - * aa_dfa_match - find accept perm for @str in @dfa - * @dfa: the dfa to match @str against - * @str: the string to match against the dfa -+ * @audit_mask: the audit_mask for the final state - * - * aa_dfa_match will match @str and return the accept perms for the - * final state. - */ --unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str) -+unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str, int *audit_mask) - { -- return ACCEPT_TABLE(dfa)[aa_dfa_next_state(dfa, DFA_START, str)]; -+ int state = aa_dfa_next_state(dfa, DFA_START, str); -+ if (audit_mask) -+ *audit_mask = dfa_audit_mask(dfa, state); -+ return ACCEPT_TABLE(dfa)[state]; - } - - /** ---- a/security/apparmor/module_interface.c -+++ b/security/apparmor/module_interface.c -@@ -310,6 +310,10 @@ static struct aa_profile *aa_unpack_prof - - if (!aa_is_u32(e, &(profile->capabilities), NULL)) - goto fail; -+ if (!aa_is_u32(e, &(profile->audit_caps), NULL)) -+ goto fail; -+ if (!aa_is_u32(e, &(profile->quiet_caps), NULL)) -+ goto fail; - - /* get file rules */ - profile->file_rules = aa_unpack_dfa(e); -@@ -317,6 +321,10 @@ static struct aa_profile *aa_unpack_prof - error = PTR_ERR(profile->file_rules); - profile->file_rules = NULL; - goto fail; -+ if (!aa_is_u16(e, &profile->audit_network[i], NULL)) -+ goto fail; -+ if (!aa_is_u16(e, &profile->quiet_network[i], NULL)) -+ goto fail; - } - - if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) -@@ -360,7 +368,7 @@ static int aa_verify_header(struct aa_ex - } - - /* check that the interface version is currently supported */ -- if (e->version != 3) { -+ if (e->version != 4) { - struct aa_audit sa; - memset(&sa, 0, sizeof(sa)); - sa.operation = operation; diff --git a/kernel-patches/for-mainline/apparmor-audit.diff b/kernel-patches/for-mainline/apparmor-audit.diff deleted file mode 100644 index 7f905af21..000000000 --- a/kernel-patches/for-mainline/apparmor-audit.diff +++ /dev/null @@ -1,72 +0,0 @@ -From: Tony Jones -Subject: Export audit subsystem for use by modules - -Update kenel audit range comments to show AppArmor's registered range of -1500-1599. This range used to be reserved for LSPP but LSPP uses the -SE Linux range and the range was given to AppArmor. -Adds necessary export symbols for audit subsystem routines. -Changes audit_log_vformat to be externally visible (analagous to vprintf) -Patch is not in mainline -- pending AppArmor code submission to lkml - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - include/linux/audit.h | 12 +++++++++++- - kernel/audit.c | 6 ++++-- - 2 files changed, 15 insertions(+), 3 deletions(-) - ---- a/include/linux/audit.h -+++ b/include/linux/audit.h -@@ -33,7 +33,7 @@ - * 1200 - 1299 messages internal to the audit daemon - * 1300 - 1399 audit event messages - * 1400 - 1499 SE Linux use -- * 1500 - 1599 kernel LSPP events -+ * 1500 - 1599 AppArmor use - * 1600 - 1699 kernel crypto events - * 1700 - 1799 kernel anomaly records - * 1800 - 1999 future kernel use (maybe integrity labels and related events) -@@ -116,6 +116,13 @@ - #define AUDIT_MAC_IPSEC_DELSPD 1414 /* Not used */ - #define AUDIT_MAC_IPSEC_EVENT 1415 /* Audit an IPSec event */ - -+#define AUDIT_APPARMOR_AUDIT 1501 /* AppArmor audited grants */ -+#define AUDIT_APPARMOR_ALLOWED 1502 /* Allowed Access for learning */ -+#define AUDIT_APPARMOR_DENIED 1503 -+#define AUDIT_APPARMOR_HINT 1504 /* Process Tracking information */ -+#define AUDIT_APPARMOR_STATUS 1505 /* Changes in config */ -+#define AUDIT_APPARMOR_ERROR 1506 /* Internal AppArmor Errors */ -+ - #define AUDIT_FIRST_KERN_ANOM_MSG 1700 - #define AUDIT_LAST_KERN_ANOM_MSG 1799 - #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */ -@@ -513,6 +520,9 @@ extern void audit_log(struct audit_ - __attribute__((format(printf,4,5))); - - extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type); -+extern void audit_log_vformat(struct audit_buffer *ab, -+ const char *fmt, va_list args) -+ __attribute__((format(printf,2,0))); - extern void audit_log_format(struct audit_buffer *ab, - const char *fmt, ...) - __attribute__((format(printf,2,3))); ---- a/kernel/audit.c -+++ b/kernel/audit.c -@@ -1215,8 +1215,7 @@ static inline int audit_expand(struct au - * will be called a second time. Currently, we assume that a printk - * can't format message larger than 1024 bytes, so we don't either. - */ --static void audit_log_vformat(struct audit_buffer *ab, const char *fmt, -- va_list args) -+void audit_log_vformat(struct audit_buffer *ab, const char *fmt, va_list args) - { - int len, avail; - struct sk_buff *skb; -@@ -1471,3 +1470,6 @@ EXPORT_SYMBOL(audit_log_start); - EXPORT_SYMBOL(audit_log_end); - EXPORT_SYMBOL(audit_log_format); - EXPORT_SYMBOL(audit_log); -+EXPORT_SYMBOL_GPL(audit_log_vformat); -+EXPORT_SYMBOL_GPL(audit_log_untrustedstring); -+EXPORT_SYMBOL_GPL(audit_log_d_path); diff --git a/kernel-patches/for-mainline/apparmor-bootdisable.diff b/kernel-patches/for-mainline/apparmor-bootdisable.diff deleted file mode 100644 index 954e50043..000000000 --- a/kernel-patches/for-mainline/apparmor-bootdisable.diff +++ /dev/null @@ -1,61 +0,0 @@ ---- - security/apparmor/Kconfig | 17 +++++++++++++++++ - security/apparmor/lsm.c | 16 ++++++++++++++++ - 2 files changed, 33 insertions(+) - ---- a/security/apparmor/Kconfig -+++ b/security/apparmor/Kconfig -@@ -7,4 +7,21 @@ config SECURITY_APPARMOR - Required userspace tools (if they are not included in your - distribution) and further information may be found at - -+ - If you are unsure how to answer this question, answer N. -+ -+config SECURITY_APPARMOR_BOOTPARAM_VALUE -+ int "AppArmor boot parameter default value" -+ depends on SECURITY_APPARMOR -+ range 0 1 -+ default 1 -+ help -+ This option sets the default value for the kernel parameter -+ 'apparmor', which allows AppArmor to be enabled or disabled -+ at boot. If this option is set to 0 (zero), the AppArmor -+ kernel parameter will default to 0, disabling AppArmor at -+ bootup. If this option is set to 1 (one), the AppArmor -+ kernel parameter will default to 1, enabling AppArmor at -+ bootup. -+ -+ If you are unsure how to answer this question, answer 1. ---- a/security/apparmor/lsm.c -+++ b/security/apparmor/lsm.c -@@ -23,6 +23,17 @@ - #include "apparmor.h" - #include "inline.h" - -+/* Boot time disable flag */ -+int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE; -+ -+static int __init apparmor_enabled_setup(char *str) -+{ -+ apparmor_enabled = simple_strtol(str, NULL, 0); -+ return 1; -+} -+__setup("apparmor=", apparmor_enabled_setup); -+ -+ - static int param_set_aabool(const char *val, struct kernel_param *kp); - static int param_get_aabool(char *buffer, struct kernel_param *kp); - #define param_check_aabool(name, p) __param_check(name, p, int) -@@ -882,6 +893,11 @@ static int __init apparmor_init(void) - { - int error; - -+ if (!apparmor_enabled) { -+ info_message("AppArmor disabled by boottime parameter\n"); -+ return 0; -+ } -+ - if ((error = create_apparmorfs())) { - AA_ERROR("Unable to activate AppArmor filesystem\n"); - goto createfs_out; diff --git a/kernel-patches/for-mainline/apparmor-builtin-only.diff b/kernel-patches/for-mainline/apparmor-builtin-only.diff deleted file mode 100644 index 155a27a26..000000000 --- a/kernel-patches/for-mainline/apparmor-builtin-only.diff +++ /dev/null @@ -1,50 +0,0 @@ ---- - security/apparmor/Kconfig | 2 +- - security/apparmor/lsm.c | 26 -------------------------- - 2 files changed, 1 insertion(+), 27 deletions(-) - ---- a/security/apparmor/Kconfig -+++ b/security/apparmor/Kconfig -@@ -1,5 +1,5 @@ - config SECURITY_APPARMOR -- tristate "AppArmor support" -+ bool "AppArmor support" - depends on SECURITY - select AUDIT - help ---- a/security/apparmor/lsm.c -+++ b/security/apparmor/lsm.c -@@ -931,33 +931,7 @@ createfs_out: - - } - --static void __exit apparmor_exit(void) --{ -- /* Remove and release all the profiles on the profile list. */ -- mutex_lock(&aa_interface_lock); -- aa_profile_ns_list_release(); -- -- /* FIXME: cleanup profiles references on files */ -- free_default_namespace(); -- -- /* -- * Delay for an rcu cycle to make sure that all active task -- * context readers have finished, and all profiles have been -- * freed by their rcu callbacks. -- */ -- synchronize_rcu(); -- -- destroy_apparmorfs(); -- mutex_unlock(&aa_interface_lock); -- -- if (unregister_security(&apparmor_ops)) -- info_message("Unable to properly unregister AppArmor"); -- -- info_message("AppArmor protection removed"); --} -- - module_init(apparmor_init); --module_exit(apparmor_exit); - - MODULE_DESCRIPTION("AppArmor process confinement"); - MODULE_AUTHOR("Novell/Immunix, http://bugs.opensuse.org"); diff --git a/kernel-patches/for-mainline/apparmor-create-append.diff b/kernel-patches/for-mainline/apparmor-create-append.diff deleted file mode 100644 index 38fb0fd09..000000000 --- a/kernel-patches/for-mainline/apparmor-create-append.diff +++ /dev/null @@ -1,16 +0,0 @@ ---- - security/apparmor/lsm.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/security/apparmor/lsm.c -+++ b/security/apparmor/lsm.c -@@ -366,8 +366,7 @@ static inline int aa_mask_permissions(in - static int apparmor_inode_create(struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, int mask) - { -- /* FIXME: may move to MAY_APPEND later */ -- return aa_permission("inode_create", dir, dentry, mnt, MAY_WRITE, 0); -+ return aa_permission("inode_create", dir, dentry, mnt, MAY_APPEND, 0); - } - - static int apparmor_inode_link(struct dentry *old_dentry, diff --git a/kernel-patches/for-mainline/apparmor-failed-name-error.diff b/kernel-patches/for-mainline/apparmor-failed-name-error.diff deleted file mode 100644 index cb86c5fce..000000000 --- a/kernel-patches/for-mainline/apparmor-failed-name-error.diff +++ /dev/null @@ -1,83 +0,0 @@ ---- - security/apparmor/main.c | 39 ++++++++++++++++++++++++++++----------- - 1 file changed, 28 insertions(+), 11 deletions(-) - ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -216,6 +216,12 @@ static int aa_perm_dentry(struct aa_prof - else { - sa->denied_mask = sa->request_mask; - sa->error_code = PTR_ERR(sa->name); -+ if (sa->error_code == -ENOENT) -+ sa->info = "Failed name resolution - object not a valid entry"; -+ else if (sa->error_code == -ENAMETOOLONG) -+ sa->info = "Failed name resolution - name too long"; -+ else -+ sa->info = "Failed name resolution"; - } - sa->name = NULL; - } else -@@ -371,8 +377,11 @@ static int aa_audit_base(struct aa_profi - if (sa->operation) - audit_log_format(ab, "operation=\"%s\"", sa->operation); - -- if (sa->info) -+ if (sa->info) { - audit_log_format(ab, " info=\"%s\"", sa->info); -+ if (sa->error_code) -+ audit_log_format(ab, " error=%d", sa->error_code); -+ } - - if (sa->request_mask) - aa_audit_file_mask(ab, "requested_mask", sa->request_mask); -@@ -918,23 +927,29 @@ int aa_register(struct linux_binprm *bpr - - AA_DEBUG("%s\n", __FUNCTION__); - -- filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer, 0); -- if (IS_ERR(filename)) { -- AA_ERROR("%s: Failed to get filename", __FUNCTION__); -- return -ENOENT; -- } -+ profile = aa_get_profile(current); - - shift = aa_inode_mode(filp->f_dentry->d_inode); -- exec_mode = AA_EXEC_UNSAFE << shift; -- - memset(&sa, 0, sizeof(sa)); - sa.operation = "exec"; - sa.gfp_mask = GFP_KERNEL; -- sa.name = filename; - sa.request_mask = MAY_EXEC << shift; - -+ filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer, 0); -+ if (IS_ERR(filename)) { -+ if (profile) { -+ sa.info = "Failed name resolution - exec failed"; -+ sa.error_code = PTR_ERR(filename); -+ aa_audit_reject(profile, &sa); -+ return sa.error_code; -+ } else -+ return 0; -+ } -+ sa.name = filename; -+ -+ exec_mode = AA_EXEC_UNSAFE << shift; -+ - repeat: -- profile = aa_get_profile(current); - if (profile) { - complain = PROFILE_COMPLAIN(profile); - -@@ -1011,8 +1026,10 @@ repeat: - if (IS_ERR(old_profile)) { - aa_put_profile(new_profile); - aa_put_profile(profile); -- if (PTR_ERR(old_profile) == -ESTALE) -+ if (PTR_ERR(old_profile) == -ESTALE) { -+ profile = aa_get_profile(current); - goto repeat; -+ } - if (PTR_ERR(old_profile) == -EPERM) { - sa.denied_mask = sa.request_mask; - sa.info = "unable to set profile due to ptrace"; diff --git a/kernel-patches/for-mainline/apparmor-features.diff b/kernel-patches/for-mainline/apparmor-features.diff deleted file mode 100644 index e888e5f98..000000000 --- a/kernel-patches/for-mainline/apparmor-features.diff +++ /dev/null @@ -1,47 +0,0 @@ ---- - security/apparmor/apparmorfs.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - ---- a/security/apparmor/apparmorfs.c -+++ b/security/apparmor/apparmorfs.c -@@ -99,6 +99,22 @@ static struct file_operations apparmorfs - .read = aa_matching_read, - }; - -+/* apparmor/features */ -+static ssize_t aa_features_read(struct file *file, char __user *buf, -+ size_t size, loff_t *ppos) -+{ -+ const char *features = "file=3.0 capability=1.0 network=1.0 " -+ "change_hat=1.3 change_profile=1.0 " -+ "aanamespaces=1.0"; -+ -+ return simple_read_from_buffer(buf, size, ppos, features, -+ strlen(features)); -+} -+ -+static struct file_operations apparmorfs_features_fops = { -+ .read = aa_features_read, -+}; -+ - /* apparmor/.load */ - static ssize_t aa_profile_load(struct file *f, const char __user *buf, - size_t size, loff_t *pos) -@@ -204,6 +220,7 @@ void destroy_apparmorfs(void) - aafs_remove(".replace"); - aafs_remove(".load"); - aafs_remove("matching"); -+ aafs_remove("features"); - aafs_remove("profiles"); - securityfs_remove(apparmor_dentry); - apparmor_dentry = NULL; -@@ -232,6 +249,9 @@ int create_apparmorfs(void) - error = aafs_create("matching", 0444, &apparmorfs_matching_fops); - if (error) - goto error; -+ error = aafs_create("features", 0444, &apparmorfs_features_fops); -+ if (error) -+ goto error; - error = aafs_create(".load", 0640, &apparmorfs_profile_load); - if (error) - goto error; diff --git a/kernel-patches/for-mainline/apparmor-fix-lock-letter.diff b/kernel-patches/for-mainline/apparmor-fix-lock-letter.diff deleted file mode 100644 index 134d92be1..000000000 --- a/kernel-patches/for-mainline/apparmor-fix-lock-letter.diff +++ /dev/null @@ -1,36 +0,0 @@ ---- - security/apparmor/apparmorfs.c | 2 +- - security/apparmor/main.c | 4 ++-- - 2 files changed, 3 insertions(+), 3 deletions(-) - ---- a/security/apparmor/apparmorfs.c -+++ b/security/apparmor/apparmorfs.c -@@ -89,7 +89,7 @@ static struct file_operations apparmorfs - static ssize_t aa_matching_read(struct file *file, char __user *buf, - size_t size, loff_t *ppos) - { -- const char *matching = "pattern=aadfa perms=rwxamlz user:other"; -+ const char *matching = "pattern=aadfa perms=rwxamlk/ user::other"; - - return simple_read_from_buffer(buf, size, ppos, matching, - strlen(matching)); ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -99,7 +99,7 @@ static int aa_link_denied(struct aa_prof - /* Link always requires 'l' on the link for both parts of the pair. - * If a subset test is required a permission subset test of the - * perms for the link are done against the user:group:other of the -- * target's 'r', 'w', 'x', 'a', 'z', and 'm' permissions. -+ * target's 'r', 'w', 'x', 'a', 'k', and 'm' permissions. - * - * If the link has 'x', an exact match of all the execute flags - * ('i', 'u', 'p'). safe exec is treated as a subset of unsafe exec -@@ -388,7 +388,7 @@ static int aa_audit_base(struct aa_profi - audit_log_format(ab, " info=\"%s\"", sa->info); - - if (sa->request_mask) -- aa_audit_file_mask(ab, "request_mask", sa->request_mask); -+ aa_audit_file_mask(ab, "requested_mask", sa->request_mask); - - if (sa->denied_mask) - aa_audit_file_mask(ab, "denied_mask", sa->denied_mask); diff --git a/kernel-patches/for-mainline/apparmor-fix-sysctl-refcount.diff b/kernel-patches/for-mainline/apparmor-fix-sysctl-refcount.diff deleted file mode 100644 index 1fcc82e78..000000000 --- a/kernel-patches/for-mainline/apparmor-fix-sysctl-refcount.diff +++ /dev/null @@ -1,14 +0,0 @@ ---- - security/apparmor/lsm.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/security/apparmor/lsm.c -+++ b/security/apparmor/lsm.c -@@ -249,6 +249,7 @@ static int apparmor_sysctl(struct ctl_ta - } - - out: -+ aa_put_profile(profile); - return error; - } - diff --git a/kernel-patches/for-mainline/apparmor-intree.diff b/kernel-patches/for-mainline/apparmor-intree.diff deleted file mode 100644 index 2a5edc013..000000000 --- a/kernel-patches/for-mainline/apparmor-intree.diff +++ /dev/null @@ -1,30 +0,0 @@ -From: John Johansen -Subject: Add AppArmor LSM to security/Makefile - -Signed-off-by: John Johansen -Signed-off-by: Andreas Gruenbacher - ---- - security/Kconfig | 1 + - security/Makefile | 1 + - 2 files changed, 2 insertions(+) - ---- a/security/Kconfig -+++ b/security/Kconfig -@@ -104,6 +104,7 @@ config SECURITY_ROOTPLUG - If you are unsure how to answer this question, answer N. - - source security/selinux/Kconfig -+source security/apparmor/Kconfig - - endmenu - ---- a/security/Makefile -+++ b/security/Makefile -@@ -14,5 +14,6 @@ endif - obj-$(CONFIG_SECURITY) += security.o dummy.o inode.o - # Must precede capability.o in order to stack properly. - obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o -+obj-$(CONFIG_SECURITY_APPARMOR) += commoncap.o apparmor/ - obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o - obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o diff --git a/kernel-patches/for-mainline/apparmor-link-pairs.diff b/kernel-patches/for-mainline/apparmor-link-pairs.diff deleted file mode 100644 index 7ec9fcc20..000000000 --- a/kernel-patches/for-mainline/apparmor-link-pairs.diff +++ /dev/null @@ -1,162 +0,0 @@ -Change link to use pairs to provide tighter control of how links -can be made. The permission subset test is controled by an -extra flag of the link perm, this allows for compatibility with -old style links which have a broad pair, but also allows for -pairs to not require the subset test when needed. - -The pairs are stored as two matches in the dfa seperated by the -null transition. Both matches must be made and have the link -perm set. If the second match has the AA_LINK_SUBSET_TEST perm -set, then the subset test is done. - - -The link keyword can be used or just the link mask -User side these pairs are expressed as follows -link [link_mask] linkname -> [subset_mask] targetname, -[link_mask] linkname -> [subset_mask] targetname, - -link /linkname -> /targetname, #link to targetname, link is perm subset - -if user:group:other link specification is desired then a user:group:other -mask containing only the link perm in the appropriate positions can be -specified -eg. -link l:: /linkname -> /targetname, # links to targetname if owned by -or -l:: /linkname -> /targetname, - -Both the linkname and the target support full AppArmor globbing. -link l:: /** -> /**, # allow any link to target owned by user - -to override the default subset test -l:: /linkname -> px /targetname, - - -Traditional AA style links are still supported and are mapped by the -parser into the newer link pair for the kernel, with the LINK_SUBSET_TEST -bits set. - /linkname rwl, -is mapped to - link /linkname -> /**, - /linkname rw, - ---- - security/apparmor/apparmor.h | 4 +++ - security/apparmor/main.c | 45 ++++++++++++++++++++++++++++++++----------- - 2 files changed, 38 insertions(+), 11 deletions(-) - ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -34,6 +34,7 @@ - AA_MAY_LOCK | AA_EXEC_MMAP | \ - AA_EXEC_UNSAFE | AA_EXEC_MOD_0 | \ - AA_EXEC_MOD_1) -+#define AA_LINK_SUBSET_TEST 0x0020 - - #define AA_EXEC_UNCONFINED 0 - #define AA_EXEC_INHERIT AA_EXEC_MOD_0 -@@ -59,6 +60,9 @@ - #define AA_USER_EXEC_MODS (AA_EXEC_MODIFIERS << AA_USER_SHIFT) - #define AA_OTHER_EXEC_MODS (AA_EXEC_MODIFIERS << AA_OTHER_SHIFT) - -+#define AA_USER_EXEC_UNSAFE (AA_EXEC_UNSAFE << AA_USER_SHIFT) -+#define AA_OTHER_EXEC_UNSAFE (AA_EXEC_UNSAFE << AA_OTHER_SHIFT) -+ - #define AA_EXEC_BITS (AA_USER_EXEC | AA_OTHER_EXEC) - - #define AA_ALL_EXEC_MODS (AA_USER_EXEC_MODS | \ ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -67,10 +67,27 @@ static int aa_link_denied(struct aa_prof - const char *target, int target_mode, - int *request_mask) - { -- int l_mode, t_mode, denied_mask; -+ unsigned int state; -+ int l_mode, t_mode, denied_mask = 0; - int link_mask = AA_MAY_LINK << target_mode; - -- l_mode = aa_match(profile->file_rules, link); -+ *request_mask = link_mask; -+ -+ l_mode = aa_match_state(profile->file_rules, DFA_START, link, &state); -+ if (l_mode & link_mask) { -+ int mode; -+ /* test to see if target can be paired with link */ -+ state = aa_dfa_null_transition(profile->file_rules, state); -+ mode = aa_match_state(profile->file_rules, state, target, -+ NULL); -+ -+ if (!(mode & link_mask)) -+ denied_mask |= link_mask; -+ if (!(mode & (AA_LINK_SUBSET_TEST << target_mode))) -+ return denied_mask; -+ } -+ -+ /* do link perm subset test */ - t_mode = aa_match(profile->file_rules, target); - - /* Ignore valid-profile-transition flags. */ -@@ -79,23 +96,30 @@ static int aa_link_denied(struct aa_prof - - *request_mask = l_mode | link_mask; - -- /* Link always requires 'l' on the link, a subset for user:other -- * of the target's 'r', 'w', 'x', 'a', 'z', and 'm' permissions on -- * the link, and if the link has 'x', an exact match of all the -- * execute flags ('i', 'u', 'U', 'p', 'P'). -+ /* Link always requires 'l' on the link for both parts of the pair. -+ * If a subset test is required a permission subset test of the -+ * perms for the link are done against the user:group:other of the -+ * target's 'r', 'w', 'x', 'a', 'z', and 'm' permissions. -+ * -+ * If the link has 'x', an exact match of all the execute flags -+ * ('i', 'u', 'p'). safe exec is treated as a subset of unsafe exec - */ - #define SUBSET_PERMS (AA_FILE_PERMS & ~AA_LINK_BITS) -- denied_mask = ~l_mode & link_mask; -+ denied_mask |= ~l_mode & link_mask; - if (l_mode & SUBSET_PERMS) { - denied_mask |= (l_mode & SUBSET_PERMS) & ~t_mode; - if (denied_mask & AA_EXEC_BITS) - denied_mask |= l_mode & AA_ALL_EXEC_MODS; - else if (l_mode & AA_EXEC_BITS) { -+ if (!(l_mode & AA_USER_EXEC_UNSAFE)) -+ l_mode |= t_mode & AA_USER_EXEC_UNSAFE; - if (l_mode & AA_USER_EXEC && - (l_mode & AA_USER_EXEC_MODS) != - (t_mode & AA_USER_EXEC_MODS)) - denied_mask |= AA_USER_EXEC | - (l_mode & AA_USER_EXEC_MODS); -+ if (!(l_mode & AA_OTHER_EXEC_UNSAFE)) -+ l_mode |= t_mode & AA_OTHER_EXEC_UNSAFE; - if (l_mode & AA_OTHER_EXEC && - (l_mode & AA_OTHER_EXEC_MODS) != - (t_mode & AA_OTHER_EXEC_MODS)) -@@ -703,15 +727,15 @@ int aa_link(struct aa_profile *profile, - struct dentry *link, struct vfsmount *link_mnt, - struct dentry *target, struct vfsmount *target_mnt) - { -- int error, check = 0; -+ int error; - struct aa_audit sa; - char *buffer = NULL, *buffer2 = NULL; - - memset(&sa, 0, sizeof(sa)); - sa.operation = "inode_link"; - sa.gfp_mask = GFP_KERNEL; -- sa.name = aa_get_name(link, link_mnt, &buffer, check); -- sa.name2 = aa_get_name(target, target_mnt, &buffer2, check); -+ sa.name = aa_get_name(link, link_mnt, &buffer, 0); -+ sa.name2 = aa_get_name(target, target_mnt, &buffer2, 0); - - if (IS_ERR(sa.name)) { - sa.error_code = PTR_ERR(sa.name); -@@ -723,7 +747,6 @@ int aa_link(struct aa_profile *profile, - } - - if (sa.name && sa.name2) { -- sa.request_mask = AA_MAY_LINK; - sa.denied_mask = aa_link_denied(profile, sa.name, sa.name2, - aa_inode_mode(target->d_inode), - &sa.request_mask); diff --git a/kernel-patches/for-mainline/apparmor-lsm.diff b/kernel-patches/for-mainline/apparmor-lsm.diff deleted file mode 100644 index 63af28c4f..000000000 --- a/kernel-patches/for-mainline/apparmor-lsm.diff +++ /dev/null @@ -1,904 +0,0 @@ -From: John Johansen -Subject: AppArmor: Module and LSM hooks - -Module parameters, LSM hooks, initialization and teardown. - -Signed-off-by: John Johansen -Signed-off-by: Andreas Gruenbacher - ---- - security/apparmor/lsm.c | 889 ++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 889 insertions(+) - ---- /dev/null -+++ b/security/apparmor/lsm.c -@@ -0,0 +1,889 @@ -+/* -+ * Copyright (C) 1998-2007 Novell/SUSE -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation, version 2 of the -+ * License. -+ * -+ * AppArmor LSM interface -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "apparmor.h" -+#include "inline.h" -+ -+/* Flag indicating whether initialization completed */ -+int apparmor_initialized = 0; -+ -+static int param_set_aabool(const char *val, struct kernel_param *kp); -+static int param_get_aabool(char *buffer, struct kernel_param *kp); -+#define param_check_aabool(name, p) __param_check(name, p, int) -+ -+static int param_set_aauint(const char *val, struct kernel_param *kp); -+static int param_get_aauint(char *buffer, struct kernel_param *kp); -+#define param_check_aauint(name, p) __param_check(name, p, int) -+ -+/* Flag values, also controllable via /sys/module/apparmor/parameters -+ * We define special types as we want to do additional mediation. -+ * -+ * Complain mode -- in complain mode access failures result in auditing only -+ * and task is allowed access. audit events are processed by userspace to -+ * generate policy. Default is 'enforce' (0). -+ * Value is also togglable per profile and referenced when global value is -+ * enforce. -+ */ -+int apparmor_complain = 0; -+module_param_named(complain, apparmor_complain, aabool, S_IRUSR | S_IWUSR); -+MODULE_PARM_DESC(apparmor_complain, "Toggle AppArmor complain mode"); -+ -+/* Debug mode */ -+int apparmor_debug = 0; -+module_param_named(debug, apparmor_debug, aabool, S_IRUSR | S_IWUSR); -+MODULE_PARM_DESC(apparmor_debug, "Toggle AppArmor debug mode"); -+ -+/* Audit mode */ -+int apparmor_audit = 0; -+module_param_named(audit, apparmor_audit, aabool, S_IRUSR | S_IWUSR); -+MODULE_PARM_DESC(apparmor_audit, "Toggle AppArmor audit mode"); -+ -+/* Syscall logging mode */ -+int apparmor_logsyscall = 0; -+module_param_named(logsyscall, apparmor_logsyscall, aabool, S_IRUSR | S_IWUSR); -+MODULE_PARM_DESC(apparmor_logsyscall, "Toggle AppArmor logsyscall mode"); -+ -+/* Maximum pathname length before accesses will start getting rejected */ -+unsigned int apparmor_path_max = 2 * PATH_MAX; -+module_param_named(path_max, apparmor_path_max, aauint, S_IRUSR | S_IWUSR); -+MODULE_PARM_DESC(apparmor_path_max, "Maximum pathname length allowed"); -+ -+/* Boot time disable flag */ -+#ifdef CONFIG_SECURITY_APPARMOR_DISABLE -+#define AA_ENABLED_PERMS 0600 -+#else -+#define AA_ENABLED_PERMS 0400 -+#endif -+static int param_set_aa_enabled(const char *val, struct kernel_param *kp); -+unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE; -+module_param_call(enabled, param_set_aa_enabled, param_get_aauint, -+ &apparmor_enabled, AA_ENABLED_PERMS); -+MODULE_PARM_DESC(apparmor_enabled, "Enable/Disable Apparmor on boot"); -+ -+static int __init apparmor_enabled_setup(char *str) -+{ -+ apparmor_enabled = simple_strtol(str, NULL, 0); -+ return 1; -+} -+__setup("apparmor=", apparmor_enabled_setup); -+ -+static int param_set_aabool(const char *val, struct kernel_param *kp) -+{ -+ if (aa_task_context(current)) -+ return -EPERM; -+ return param_set_bool(val, kp); -+} -+ -+static int param_get_aabool(char *buffer, struct kernel_param *kp) -+{ -+ if (aa_task_context(current)) -+ return -EPERM; -+ return param_get_bool(buffer, kp); -+} -+ -+static int param_set_aauint(const char *val, struct kernel_param *kp) -+{ -+ if (aa_task_context(current)) -+ return -EPERM; -+ return param_set_uint(val, kp); -+} -+ -+static int param_get_aauint(char *buffer, struct kernel_param *kp) -+{ -+ if (aa_task_context(current)) -+ return -EPERM; -+ return param_get_uint(buffer, kp); -+} -+ -+/* allow run time disabling of apparmor */ -+static int param_set_aa_enabled(const char *val, struct kernel_param *kp) -+{ -+ char *endp; -+ unsigned long l; -+ -+ if (!apparmor_initialized) { -+ apparmor_enabled = 0; -+ return 0; -+ } -+ -+ if (aa_task_context(current)) -+ return -EPERM; -+ -+ if (!apparmor_enabled) -+ return -EINVAL; -+ -+ if (!val) -+ return -EINVAL; -+ -+ l = simple_strtoul(val, &endp, 0); -+ if (endp == val || l != 0) -+ return -EINVAL; -+ -+ apparmor_enabled = 0; -+ apparmor_disable(); -+ return 0; -+} -+ -+static int aa_reject_syscall(struct task_struct *task, gfp_t flags, -+ const char *name) -+{ -+ struct aa_profile *profile = aa_get_profile(task); -+ int error = 0; -+ -+ if (profile) { -+ error = aa_audit_syscallreject(profile, flags, name); -+ aa_put_profile(profile); -+ } -+ -+ return error; -+} -+ -+static int apparmor_ptrace(struct task_struct *parent, -+ struct task_struct *child) -+{ -+ struct aa_task_context *cxt; -+ int error = 0; -+ -+ /* -+ * parent can ptrace child when -+ * - parent is unconfined -+ * - parent & child are in the same namespace && -+ * - parent is in complain mode -+ * - parent and child are confined by the same profile -+ * - parent profile has CAP_SYS_PTRACE -+ */ -+ -+ rcu_read_lock(); -+ cxt = aa_task_context(parent); -+ if (cxt) { -+ if (parent->nsproxy != child->nsproxy) { -+ struct aa_audit sa; -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "ptrace"; -+ sa.gfp_mask = GFP_ATOMIC; -+ sa.parent = parent->pid; -+ sa.task = child->pid; -+ sa.info = "different namespaces"; -+ aa_audit_reject(cxt->profile, &sa); -+ error = -EPERM; -+ } else { -+ struct aa_task_context *child_cxt = -+ aa_task_context(child); -+ -+ error = aa_may_ptrace(cxt, child_cxt ? -+ child_cxt->profile : NULL); -+ if (PROFILE_COMPLAIN(cxt->profile)) { -+ struct aa_audit sa; -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "ptrace"; -+ sa.gfp_mask = GFP_ATOMIC; -+ sa.parent = parent->pid; -+ sa.task = child->pid; -+ aa_audit_hint(cxt->profile, &sa); -+ } -+ } -+ } -+ rcu_read_unlock(); -+ -+ return error; -+} -+ -+static int apparmor_capable(struct task_struct *task, int cap) -+{ -+ int error; -+ struct aa_task_context *cxt; -+ -+ /* cap_capable returns 0 on success, else -EPERM */ -+ error = cap_capable(task, cap); -+ -+ rcu_read_lock(); -+ cxt = aa_task_context(task); -+ if (cxt && (!error || cap_raised(cxt->profile->set_caps, cap))) -+ error = aa_capability(cxt, cap); -+ rcu_read_unlock(); -+ -+ return error; -+} -+ -+static int apparmor_sysctl(struct ctl_table *table, int op) -+{ -+ struct aa_profile *profile = aa_get_profile(current); -+ int error = 0; -+ -+ if (profile) { -+ char *buffer, *name; -+ int mask; -+ -+ mask = 0; -+ if (op & 4) -+ mask |= MAY_READ; -+ if (op & 2) -+ mask |= MAY_WRITE; -+ -+ error = -ENOMEM; -+ buffer = (char*)__get_free_page(GFP_KERNEL); -+ if (!buffer) -+ goto out; -+ name = sysctl_pathname(table, buffer, PAGE_SIZE); -+ if (name && name - buffer >= 5) { -+ name -= 5; -+ memcpy(name, "/proc", 5); -+ error = aa_perm_path(profile, "sysctl", name, mask, 0); -+ } -+ free_page((unsigned long)buffer); -+ } -+ -+out: -+ aa_put_profile(profile); -+ return error; -+} -+ -+static int apparmor_bprm_set_security(struct linux_binprm *bprm) -+{ -+ /* handle capability bits with setuid, etc */ -+ cap_bprm_set_security(bprm); -+ /* already set based on script name */ -+ if (bprm->sh_bang) -+ return 0; -+ return aa_register(bprm); -+} -+ -+static int apparmor_bprm_secureexec(struct linux_binprm *bprm) -+{ -+ int ret = cap_bprm_secureexec(bprm); -+ -+ if (!ret && (unsigned long)bprm->security & AA_SECURE_EXEC_NEEDED) { -+ AA_DEBUG("%s: secureexec required for %s\n", -+ __FUNCTION__, bprm->filename); -+ ret = 1; -+ } -+ -+ return ret; -+} -+ -+static int apparmor_sb_mount(char *dev_name, struct nameidata *nd, char *type, -+ unsigned long flags, void *data) -+{ -+ return aa_reject_syscall(current, GFP_KERNEL, "mount"); -+} -+ -+static int apparmor_umount(struct vfsmount *mnt, int flags) -+{ -+ return aa_reject_syscall(current, GFP_KERNEL, "umount"); -+} -+ -+static int apparmor_inode_mkdir(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mask) -+{ -+ struct aa_profile *profile; -+ int error = 0; -+ -+ if (!mnt || !mediated_filesystem(dir)) -+ goto out; -+ -+ profile = aa_get_profile(current); -+ -+ if (profile) -+ error = aa_perm_dir(profile, "inode_mkdir", dentry, mnt, -+ MAY_WRITE); -+ -+ aa_put_profile(profile); -+ -+out: -+ return error; -+} -+ -+static int apparmor_inode_rmdir(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt) -+{ -+ struct aa_profile *profile; -+ int error = 0; -+ -+ if (!mnt || !mediated_filesystem(dir)) -+ goto out; -+ -+ profile = aa_get_profile(current); -+ -+ if (profile) -+ error = aa_perm_dir(profile, "inode_rmdir", dentry, mnt, -+ MAY_WRITE); -+ -+ aa_put_profile(profile); -+ -+out: -+ return error; -+} -+ -+static int aa_permission(const char *operation, struct inode *inode, -+ struct dentry *dentry, struct vfsmount *mnt, -+ int mask, int check) -+{ -+ int error = 0; -+ -+ if (mnt && mediated_filesystem(inode)) { -+ struct aa_profile *profile; -+ -+ profile = aa_get_profile(current); -+ if (profile) -+ error = aa_perm(profile, operation, dentry, mnt, mask, -+ check); -+ aa_put_profile(profile); -+ } -+ return error; -+} -+ -+static inline int aa_mask_permissions(int mask) -+{ -+ if (mask & MAY_APPEND) -+ mask &= (MAY_READ | MAY_APPEND | MAY_EXEC); -+ else -+ mask &= (MAY_READ | MAY_WRITE | MAY_EXEC); -+ return mask; -+} -+ -+static int apparmor_inode_create(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mask) -+{ -+ return aa_permission("inode_create", dir, dentry, mnt, MAY_APPEND, 0); -+} -+ -+static int apparmor_inode_link(struct dentry *old_dentry, -+ struct vfsmount *old_mnt, struct inode *dir, -+ struct dentry *new_dentry, -+ struct vfsmount *new_mnt) -+{ -+ int error = 0; -+ struct aa_profile *profile; -+ -+ if (!old_mnt || !new_mnt || !mediated_filesystem(dir)) -+ goto out; -+ -+ profile = aa_get_profile(current); -+ -+ if (profile) -+ error = aa_link(profile, new_dentry, new_mnt, -+ old_dentry, old_mnt); -+ -+ aa_put_profile(profile); -+ -+out: -+ return error; -+} -+ -+static int apparmor_inode_unlink(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt) -+{ -+ int check = 0; -+ -+ if (S_ISDIR(dentry->d_inode->i_mode)) -+ check |= AA_CHECK_DIR; -+ return aa_permission("inode_unlink", dir, dentry, mnt, MAY_WRITE, -+ check); -+} -+ -+static int apparmor_inode_symlink(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, const char *old_name) -+{ -+ return aa_permission("inode_symlink", dir, dentry, mnt, MAY_WRITE, 0); -+} -+ -+static int apparmor_inode_mknod(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mode, dev_t dev) -+{ -+ return aa_permission("inode_mknod", dir, dentry, mnt, MAY_WRITE, 0); -+} -+ -+static int apparmor_inode_rename(struct inode *old_dir, -+ struct dentry *old_dentry, -+ struct vfsmount *old_mnt, -+ struct inode *new_dir, -+ struct dentry *new_dentry, -+ struct vfsmount *new_mnt) -+{ -+ struct aa_profile *profile; -+ int error = 0; -+ -+ if ((!old_mnt && !new_mnt) || !mediated_filesystem(old_dir)) -+ goto out; -+ -+ profile = aa_get_profile(current); -+ -+ if (profile) { -+ struct inode *inode = old_dentry->d_inode; -+ int check = 0; -+ -+ if (inode && S_ISDIR(inode->i_mode)) -+ check |= AA_CHECK_DIR; -+ if (old_mnt) -+ error = aa_perm(profile, "inode_rename", old_dentry, -+ old_mnt, MAY_READ | MAY_WRITE, check); -+ -+ if (!error && new_mnt) { -+ error = aa_perm(profile, "inode_rename", new_dentry, -+ new_mnt, MAY_WRITE, check); -+ } -+ } -+ -+ aa_put_profile(profile); -+ -+out: -+ return error; -+} -+ -+static int apparmor_inode_permission(struct inode *inode, int mask, -+ struct nameidata *nd) -+{ -+ int check = 0; -+ -+ if (!nd || nd->flags & (LOOKUP_PARENT | LOOKUP_CONTINUE)) -+ return 0; -+ mask = aa_mask_permissions(mask); -+ if (S_ISDIR(inode->i_mode)) { -+ check |= AA_CHECK_DIR; -+ /* allow traverse accesses to directories */ -+ mask &= ~MAY_EXEC; -+ } -+ return aa_permission("inode_permission", inode, nd->dentry, nd->mnt, -+ mask, check); -+} -+ -+static int apparmor_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, -+ struct iattr *iattr) -+{ -+ int error = 0; -+ -+ if (!mnt) -+ goto out; -+ -+ if (mediated_filesystem(dentry->d_inode)) { -+ struct aa_profile *profile; -+ -+ profile = aa_get_profile(current); -+ /* -+ * Mediate any attempt to change attributes of a file -+ * (chmod, chown, chgrp, etc) -+ */ -+ if (profile) -+ error = aa_attr(profile, dentry, mnt, iattr); -+ -+ aa_put_profile(profile); -+ } -+ -+out: -+ return error; -+} -+ -+static int aa_xattr_permission(struct dentry *dentry, struct vfsmount *mnt, -+ const char *operation, int mask, -+ struct file *file) -+{ -+ int error = 0; -+ -+ if (mnt && mediated_filesystem(dentry->d_inode)) { -+ struct aa_profile *profile = aa_get_profile(current); -+ int check = file ? AA_CHECK_FD : 0; -+ -+ if (profile) -+ error = aa_perm_xattr(profile, operation, dentry, mnt, -+ mask, check); -+ aa_put_profile(profile); -+ } -+ -+ return error; -+} -+ -+static int apparmor_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *name, void *value, size_t size, -+ int flags, struct file *file) -+{ -+ return aa_xattr_permission(dentry, mnt, "xattr set", MAY_WRITE, file); -+} -+ -+static int apparmor_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *name, struct file *file) -+{ -+ return aa_xattr_permission(dentry, mnt, "xattr get", MAY_READ, file); -+} -+ -+static int apparmor_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, -+ struct file *file) -+{ -+ return aa_xattr_permission(dentry, mnt, "xattr list", MAY_READ, file); -+} -+ -+static int apparmor_inode_removexattr(struct dentry *dentry, -+ struct vfsmount *mnt, char *name, -+ struct file *file) -+{ -+ return aa_xattr_permission(dentry, mnt, "xattr remove", MAY_WRITE, -+ file); -+} -+ -+static int aa_file_permission(const char *op, struct file *file, int mask) -+{ -+ struct aa_profile *profile; -+ struct aa_profile *file_profile = (struct aa_profile*)file->f_security; -+ int error = 0; -+ -+ if (!file_profile) -+ goto out; -+ -+ /* -+ * If this file was opened under a different profile, we -+ * revalidate the access against the current profile. -+ */ -+ profile = aa_get_profile(current); -+ if (profile && (file_profile != profile || mask & AA_MAY_LOCK)) { -+ struct dentry *dentry = file->f_dentry; -+ struct vfsmount *mnt = file->f_vfsmnt; -+ struct inode *inode = dentry->d_inode; -+ int check = AA_CHECK_FD; -+ -+ /* -+ * FIXME: We should remember which profiles we revalidated -+ * against. -+ */ -+ if (S_ISDIR(inode->i_mode)) -+ check |= AA_CHECK_DIR; -+ error = aa_permission(op, inode, dentry, mnt, mask, check); -+ } -+ aa_put_profile(profile); -+ -+out: -+ return error; -+} -+ -+static int apparmor_file_permission(struct file *file, int mask) -+{ -+ return aa_file_permission("file_permission", file, -+ aa_mask_permissions(mask)); -+} -+ -+static inline int apparmor_file_lock (struct file *file, unsigned int cmd) -+{ -+ int mask = AA_MAY_LOCK; -+ if (cmd == F_WRLCK) -+ mask |= MAY_WRITE; -+ return aa_file_permission("file_lock", file, mask); -+} -+ -+static int apparmor_file_alloc_security(struct file *file) -+{ -+ struct aa_profile *profile; -+ -+ profile = aa_get_profile(current); -+ if (profile) -+ file->f_security = profile; -+ -+ return 0; -+} -+ -+static void apparmor_file_free_security(struct file *file) -+{ -+ struct aa_profile *file_profile = (struct aa_profile*)file->f_security; -+ -+ aa_put_profile(file_profile); -+} -+ -+static inline int aa_mmap(struct file *file, const char *operation, -+ unsigned long prot, unsigned long flags) -+{ -+ struct dentry *dentry; -+ int mask = 0; -+ -+ if (!file || !file->f_security) -+ return 0; -+ -+ if (prot & PROT_READ) -+ mask |= MAY_READ; -+ /* Private mappings don't require write perms since they don't -+ * write back to the files */ -+ if ((prot & PROT_WRITE) && !(flags & MAP_PRIVATE)) -+ mask |= MAY_WRITE; -+ if (prot & PROT_EXEC) -+ mask |= AA_EXEC_MMAP; -+ -+ dentry = file->f_dentry; -+ return aa_permission(operation, dentry->d_inode, dentry, -+ file->f_vfsmnt, mask, AA_CHECK_FD); -+} -+ -+static int apparmor_file_mmap(struct file *file, unsigned long reqprot, -+ unsigned long prot, unsigned long flags, -+ unsigned long addr, unsigned long addr_only) -+{ -+ if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) { -+ struct aa_profile *profile = aa_get_profile(current); -+ if (profile) -+ /* future control check here */ -+ return -EACCES; -+ else -+ return -EACCES; -+ aa_put_profile(profile); -+ } -+ -+ return aa_mmap(file, "file_mmap", prot, flags); -+} -+ -+static int apparmor_file_mprotect(struct vm_area_struct *vma, -+ unsigned long reqprot, unsigned long prot) -+{ -+ return aa_mmap(vma->vm_file, "file_mprotect", prot, -+ !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0); -+} -+ -+static int apparmor_task_alloc_security(struct task_struct *task) -+{ -+ return aa_clone(task); -+} -+ -+/* -+ * Called from IRQ context from RCU callback. -+ */ -+static void apparmor_task_free_security(struct task_struct *task) -+{ -+ aa_release(task); -+} -+ -+static int apparmor_getprocattr(struct task_struct *task, char *name, -+ char **value) -+{ -+ unsigned len; -+ int error; -+ struct aa_profile *profile; -+ -+ /* AppArmor only supports the "current" process attribute */ -+ if (strcmp(name, "current") != 0) -+ return -EINVAL; -+ -+ /* must be task querying itself or admin */ -+ if (current != task && !capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ -+ profile = aa_get_profile(task); -+ error = aa_getprocattr(profile, value, &len); -+ aa_put_profile(profile); -+ if (!error) -+ error = len; -+ -+ return error; -+} -+ -+static int apparmor_setprocattr(struct task_struct *task, char *name, -+ void *value, size_t size) -+{ -+ char *command, *args; -+ int error; -+ -+ if (strcmp(name, "current") != 0 || size == 0 || size >= PAGE_SIZE) -+ return -EINVAL; -+ args = value; -+ args[size] = '\0'; -+ args = strstrip(args); -+ command = strsep(&args, " "); -+ if (!args) -+ return -EINVAL; -+ while (isspace(*args)) -+ args++; -+ if (!*args) -+ return -EINVAL; -+ -+ if (strcmp(command, "changehat") == 0) { -+ if (current != task) -+ return -EACCES; -+ error = aa_setprocattr_changehat(args); -+ } else if (strcmp(command, "changeprofile") == 0) { -+ if (current != task) -+ return -EACCES; -+ error = aa_setprocattr_changeprofile(args); -+ } else if (strcmp(command, "setprofile") == 0) { -+ struct aa_profile *profile; -+ -+ /* Only an unconfined process with admin capabilities -+ * may change the profile of another task. -+ */ -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ -+ profile = aa_get_profile(current); -+ if (profile) { -+ struct aa_audit sa; -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "profile_set"; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.task = task->pid; -+ sa.info = "from confined process"; -+ aa_audit_reject(profile, &sa); -+ aa_put_profile(profile); -+ return -EACCES; -+ } -+ error = aa_setprocattr_setprofile(task, args); -+ } else { -+ struct aa_audit sa; -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "setprocattr"; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.info = "invalid command"; -+ sa.name = command; -+ sa.task = task->pid; -+ aa_audit_reject(NULL, &sa); -+ return -EINVAL; -+ } -+ -+ if (!error) -+ error = size; -+ return error; -+} -+ -+struct security_operations apparmor_ops = { -+ .ptrace = apparmor_ptrace, -+ .capget = cap_capget, -+ .capset_check = cap_capset_check, -+ .capset_set = cap_capset_set, -+ .sysctl = apparmor_sysctl, -+ .capable = apparmor_capable, -+ .syslog = cap_syslog, -+ -+ .netlink_send = cap_netlink_send, -+ .netlink_recv = cap_netlink_recv, -+ -+ .bprm_apply_creds = cap_bprm_apply_creds, -+ .bprm_set_security = apparmor_bprm_set_security, -+ .bprm_secureexec = apparmor_bprm_secureexec, -+ -+ .sb_mount = apparmor_sb_mount, -+ .sb_umount = apparmor_umount, -+ -+ .inode_mkdir = apparmor_inode_mkdir, -+ .inode_rmdir = apparmor_inode_rmdir, -+ .inode_create = apparmor_inode_create, -+ .inode_link = apparmor_inode_link, -+ .inode_unlink = apparmor_inode_unlink, -+ .inode_symlink = apparmor_inode_symlink, -+ .inode_mknod = apparmor_inode_mknod, -+ .inode_rename = apparmor_inode_rename, -+ .inode_permission = apparmor_inode_permission, -+ .inode_setattr = apparmor_inode_setattr, -+ .inode_setxattr = apparmor_inode_setxattr, -+ .inode_getxattr = apparmor_inode_getxattr, -+ .inode_listxattr = apparmor_inode_listxattr, -+ .inode_removexattr = apparmor_inode_removexattr, -+ .file_permission = apparmor_file_permission, -+ .file_alloc_security = apparmor_file_alloc_security, -+ .file_free_security = apparmor_file_free_security, -+ .file_mmap = apparmor_file_mmap, -+ .file_mprotect = apparmor_file_mprotect, -+ .file_lock = apparmor_file_lock, -+ -+ .task_alloc_security = apparmor_task_alloc_security, -+ .task_free_security = apparmor_task_free_security, -+ .task_post_setuid = cap_task_post_setuid, -+ .task_reparent_to_init = cap_task_reparent_to_init, -+ -+ .getprocattr = apparmor_getprocattr, -+ .setprocattr = apparmor_setprocattr, -+}; -+ -+void info_message(const char *str) -+{ -+ struct aa_audit sa; -+ memset(&sa, 0, sizeof(sa)); -+ sa.gfp_mask = GFP_KERNEL; -+ sa.info = str; -+ printk(KERN_INFO "AppArmor: %s\n", str); -+ if (audit_enabled) -+ aa_audit_message(NULL, &sa, AUDIT_APPARMOR_STATUS); -+} -+ -+static int __init apparmor_init(void) -+{ -+ int error; -+ -+ if (!apparmor_enabled) { -+ info_message("AppArmor disabled by boottime parameter\n"); -+ return 0; -+ } -+ -+ if ((error = create_apparmorfs())) { -+ AA_ERROR("Unable to activate AppArmor filesystem\n"); -+ goto createfs_out; -+ } -+ -+ if ((error = alloc_default_namespace())){ -+ AA_ERROR("Unable to allocate default profile namespace\n"); -+ goto alloc_out; -+ } -+ -+ if ((error = register_security(&apparmor_ops))) { -+ AA_ERROR("Unable to register AppArmor\n"); -+ goto register_security_out; -+ } -+ -+ /* Report that AppArmor successfully initialized */ -+ apparmor_initialized = 1; -+ if (apparmor_complain) -+ info_message("AppArmor initialized: complainmode enabled"); -+ else -+ info_message("AppArmor initialized"); -+ -+ return error; -+ -+register_security_out: -+ free_default_namespace(); -+ -+alloc_out: -+ destroy_apparmorfs(); -+ -+createfs_out: -+ return error; -+ -+} -+ -+security_initcall(apparmor_init); -+ -+void apparmor_disable(void) -+{ -+ /* Remove and release all the profiles on the profile list. */ -+ mutex_lock(&aa_interface_lock); -+ aa_profile_ns_list_release(); -+ -+ /* FIXME: cleanup profiles references on files */ -+ free_default_namespace(); -+ -+ /* -+ * Delay for an rcu cycle to make sure that all active task -+ * context readers have finished, and all profiles have been -+ * freed by their rcu callbacks. -+ */ -+ synchronize_rcu(); -+ -+ destroy_apparmorfs(); -+ mutex_unlock(&aa_interface_lock); -+ -+ apparmor_initialized = 0; -+ -+ info_message("AppArmor protection removed"); -+} -+ -+MODULE_DESCRIPTION("AppArmor process confinement"); -+MODULE_AUTHOR("Novell/Immunix, http://bugs.opensuse.org"); -+MODULE_LICENSE("GPL"); diff --git a/kernel-patches/for-mainline/apparmor-main-2.diff b/kernel-patches/for-mainline/apparmor-main-2.diff deleted file mode 100644 index 4ac83cde0..000000000 --- a/kernel-patches/for-mainline/apparmor-main-2.diff +++ /dev/null @@ -1,59 +0,0 @@ ---- - security/apparmor/main.c | 23 ++++++++++++++--------- - 1 file changed, 14 insertions(+), 9 deletions(-) - ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -172,15 +172,18 @@ escape: - static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt, - char **buffer, int check) - { -- char *name; -+ char *buf = NULL, *name; - int is_dir, size = 256; - - is_dir = (check & AA_CHECK_DIR) ? 1 : 0; - - for (;;) { -- char *buf = kmalloc(size, GFP_KERNEL); -- if (!buf) -- return ERR_PTR(-ENOMEM); -+ char *b = krealloc(buf, size, GFP_KERNEL); -+ -+ name = ERR_PTR(-ENOMEM); -+ if (!b) -+ break; -+ buf = b; - - name = d_namespace_path(dentry, mnt, buf, size - is_dir); - -@@ -195,8 +198,8 @@ static char *aa_get_name(struct dentry * - * This dentry is not connected to the - * namespace root -- reject access. - */ -- kfree(buf); -- return ERR_PTR(-ENOENT); -+ name = ERR_PTR(-ENOENT); -+ break; - } - if (is_dir && name[1] != '\0') { - /* -@@ -212,13 +215,15 @@ static char *aa_get_name(struct dentry * - return name; - } - if (PTR_ERR(name) != -ENAMETOOLONG) -- return name; -+ break; - -- kfree(buf); - size <<= 1; -+ name = ERR_PTR(-ENAMETOOLONG); - if (size > apparmor_path_max) -- return ERR_PTR(-ENAMETOOLONG); -+ break; - } -+ kfree(buf); -+ return name; - } - - static inline void aa_put_name_buffer(char *buffer) diff --git a/kernel-patches/for-mainline/apparmor-main.diff b/kernel-patches/for-mainline/apparmor-main.diff deleted file mode 100644 index c48c16277..000000000 --- a/kernel-patches/for-mainline/apparmor-main.diff +++ /dev/null @@ -1,1494 +0,0 @@ -From: John Johansen -Subject: AppArmor: Main Part - -The underlying functions by which the AppArmor LSM hooks are implemented. - -Signed-off-by: John Johansen -Signed-off-by: Andreas Gruenbacher - ---- - security/apparmor/main.c | 1479 +++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 1479 insertions(+) - ---- /dev/null -+++ b/security/apparmor/main.c -@@ -0,0 +1,1479 @@ -+/* -+ * Copyright (C) 2002-2007 Novell/SUSE -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation, version 2 of the -+ * License. -+ * -+ * AppArmor Core -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "apparmor.h" -+ -+#include "inline.h" -+ -+/* -+ * Table of capability names: we generate it from capabilities.h. -+ */ -+static const char *capability_names[] = { -+#include "capability_names.h" -+}; -+ -+struct aa_namespace *default_namespace; -+ -+static int aa_inode_mode(struct inode *inode) -+{ -+ /* if the inode doesn't exist the user is creating it */ -+ if (!inode || current->fsuid == inode->i_uid) -+ return AA_USER_SHIFT; -+ return AA_OTHER_SHIFT; -+} -+ -+int alloc_default_namespace(void) -+{ -+ struct aa_namespace *ns; -+ char *name = kstrdup("default", GFP_KERNEL); -+ if (!name) -+ return -ENOMEM; -+ ns = alloc_aa_namespace(name); -+ if (!ns) { -+ kfree(name); -+ return -ENOMEM; -+ } -+ -+ write_lock(&profile_ns_list_lock); -+ default_namespace = ns; -+ aa_get_namespace(ns); -+ list_add(&ns->list, &profile_ns_list); -+ write_unlock(&profile_ns_list_lock); -+ -+ return 0; -+} -+ -+void free_default_namespace(void) -+{ -+ write_lock(&profile_ns_list_lock); -+ list_del_init(&default_namespace->list); -+ write_unlock(&profile_ns_list_lock); -+ aa_put_namespace(default_namespace); -+ default_namespace = NULL; -+} -+ -+static void aa_audit_file_sub_mask(struct audit_buffer *ab, char *buffer, -+ int mask) -+{ -+ const char unsafex[] = "upcn"; -+ const char safex[] = "UPCN"; -+ char *m = buffer; -+ -+ if (mask & AA_EXEC_MMAP) -+ *m++ = 'm'; -+ if (mask & MAY_READ) -+ *m++ = 'r'; -+ if (mask & MAY_WRITE) -+ *m++ = 'w'; -+ else if (mask & MAY_APPEND) -+ *m++ = 'a'; -+ if (mask & MAY_EXEC) { -+ int index = AA_EXEC_INDEX(mask); -+ /* all indexes > 4 are also named transitions */ -+ if (index > 4) -+ index = 4; -+ if (index > 0) { -+ if (mask & AA_EXEC_UNSAFE) -+ *m++ = unsafex[index - 1]; -+ else -+ *m++ = safex[index - 1]; -+ } -+ if (mask & AA_EXEC_INHERIT) -+ *m++ = 'i'; -+ *m++ = 'x'; -+ } -+ if (mask & AA_MAY_LINK) -+ *m++ = 'l'; -+ if (mask & AA_MAY_LOCK) -+ *m++ = 'k'; -+ *m++ = '\0'; -+} -+ -+static void aa_audit_file_mask(struct audit_buffer *ab, const char *name, -+ int mask) -+{ -+ char user[10], other[10]; -+ -+ aa_audit_file_sub_mask(ab, user, -+ (mask & AA_USER_PERMS) >> AA_USER_SHIFT); -+ aa_audit_file_sub_mask(ab, other, -+ (mask & AA_OTHER_PERMS) >> AA_OTHER_SHIFT); -+ -+ audit_log_format(ab, " %s=\"%s::%s\"", name, user, other); -+} -+ -+/** -+ * aa_audit - Log an audit event to the audit subsystem -+ * @profile: profile to check against -+ * @sa: audit event -+ * @audit_cxt: audit context to log message to -+ * @type: audit event number -+ */ -+static int aa_audit_base(struct aa_profile *profile, struct aa_audit *sa, -+ struct audit_context *audit_cxt, int type) -+{ -+ struct audit_buffer *ab = NULL; -+ -+ ab = audit_log_start(audit_cxt, sa->gfp_mask, type); -+ -+ if (!ab) { -+ AA_ERROR("Unable to log event (%d) to audit subsys\n", -+ type); -+ /* don't fail operations in complain mode even if logging -+ * fails */ -+ return type == AUDIT_APPARMOR_ALLOWED ? 0 : -ENOMEM; -+ } -+ -+ if (sa->operation) -+ audit_log_format(ab, "operation=\"%s\"", sa->operation); -+ -+ if (sa->info) { -+ audit_log_format(ab, " info=\"%s\"", sa->info); -+ if (sa->error_code) -+ audit_log_format(ab, " error=%d", sa->error_code); -+ } -+ -+ if (sa->request_mask) -+ aa_audit_file_mask(ab, "requested_mask", sa->request_mask); -+ -+ if (sa->denied_mask) -+ aa_audit_file_mask(ab, "denied_mask", sa->denied_mask); -+ -+ if (sa->request_mask) -+ audit_log_format(ab, " fsuid=%d", current->fsuid); -+ -+ if (sa->iattr) { -+ struct iattr *iattr = sa->iattr; -+ -+ audit_log_format(ab, " attribute=\"%s%s%s%s%s%s%s\"", -+ iattr->ia_valid & ATTR_MODE ? "mode," : "", -+ iattr->ia_valid & ATTR_UID ? "uid," : "", -+ iattr->ia_valid & ATTR_GID ? "gid," : "", -+ iattr->ia_valid & ATTR_SIZE ? "size," : "", -+ iattr->ia_valid & (ATTR_ATIME | ATTR_ATIME_SET) ? -+ "atime," : "", -+ iattr->ia_valid & (ATTR_MTIME | ATTR_MTIME_SET) ? -+ "mtime," : "", -+ iattr->ia_valid & ATTR_CTIME ? "ctime," : ""); -+ } -+ -+ if (sa->task) -+ audit_log_format(ab, " task=%d", sa->task); -+ -+ if (sa->parent) -+ audit_log_format(ab, " parent=%d", sa->parent); -+ -+ if (sa->name) { -+ audit_log_format(ab, " name="); -+ audit_log_untrustedstring(ab, sa->name); -+ } -+ -+ if (sa->name2) { -+ audit_log_format(ab, " name2="); -+ audit_log_untrustedstring(ab, sa->name2); -+ } -+ -+ audit_log_format(ab, " pid=%d", current->pid); -+ -+ if (profile) { -+ audit_log_format(ab, " profile="); -+ audit_log_untrustedstring(ab, profile->name); -+ -+ if (profile->ns != default_namespace) { -+ audit_log_format(ab, " namespace="); -+ audit_log_untrustedstring(ab, profile->ns->name); -+ } -+ } -+ -+ audit_log_end(ab); -+ -+ return type == AUDIT_APPARMOR_ALLOWED ? 0 : sa->error_code; -+} -+ -+/** -+ * aa_audit_syscallreject - Log a syscall rejection to the audit subsystem -+ * @profile: profile to check against -+ * @gfp: memory allocation flags -+ * @msg: string describing syscall being rejected -+ */ -+int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp, -+ const char *msg) -+{ -+ struct aa_audit sa; -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "syscall"; -+ sa.name = msg; -+ sa.gfp_mask = gfp; -+ sa.error_code = -EPERM; -+ -+ return aa_audit_base(profile, &sa, current->audit_context, -+ AUDIT_APPARMOR_DENIED); -+} -+ -+int aa_audit_message(struct aa_profile *profile, struct aa_audit *sa, -+ int type) -+{ -+ struct audit_context *audit_cxt; -+ -+ audit_cxt = apparmor_logsyscall ? current->audit_context : NULL; -+ return aa_audit_base(profile, sa, audit_cxt, type); -+} -+ -+void aa_audit_hint(struct aa_profile *profile, struct aa_audit *sa) -+{ -+ aa_audit_message(profile, sa, AUDIT_APPARMOR_HINT); -+} -+ -+void aa_audit_status(struct aa_profile *profile, struct aa_audit *sa) -+{ -+ aa_audit_message(profile, sa, AUDIT_APPARMOR_STATUS); -+} -+ -+int aa_audit_reject(struct aa_profile *profile, struct aa_audit *sa) -+{ -+ return aa_audit_message(profile, sa, AUDIT_APPARMOR_DENIED); -+} -+ -+/** -+ * aa_audit - Log an audit event to the audit subsystem -+ * @profile: profile to check against -+ * @sa: audit event -+ */ -+int aa_audit(struct aa_profile *profile, struct aa_audit *sa) -+{ -+ int type = AUDIT_APPARMOR_DENIED; -+ struct audit_context *audit_cxt; -+ -+ if (likely(!sa->error_code)) -+ type = AUDIT_APPARMOR_AUDIT; -+ else if (PROFILE_COMPLAIN(profile)) -+ type = AUDIT_APPARMOR_ALLOWED; -+ -+ audit_cxt = apparmor_logsyscall ? current->audit_context : NULL; -+ return aa_audit_base(profile, sa, audit_cxt, type); -+} -+ -+static int aa_audit_file(struct aa_profile *profile, struct aa_audit *sa) -+{ -+ if (likely(!sa->error_code)) { -+ int mask = sa->audit_mask & AUDIT_FILE_MASK; -+ -+ if (unlikely(PROFILE_AUDIT(profile))) -+ mask |= AUDIT_FILE_MASK; -+ -+ if (likely(!(sa->request_mask & mask))) -+ return 0; -+ -+ /* mask off perms that are not being force audited */ -+ sa->request_mask &= mask | ALL_AA_EXEC_TYPE; -+ } else { -+ int mask = AUDIT_QUIET_MASK(sa->audit_mask); -+ -+ if (!(sa->denied_mask & ~mask)) -+ return sa->error_code; -+ -+ /* mask off perms whose denial is being silenced */ -+ sa->denied_mask &= (~mask) | ALL_AA_EXEC_TYPE; -+ } -+ -+ return aa_audit(profile, sa); -+} -+ -+static int aa_audit_caps(struct aa_profile *profile, struct aa_audit *sa, -+ int cap) -+{ -+ if (likely(!sa->error_code)) { -+ if (likely(!PROFILE_AUDIT(profile) && -+ !cap_raised(profile->audit_caps, cap))) -+ return 0; -+ } -+ -+ /* quieting of capabilities is handled the caps_logged cache */ -+ return aa_audit(profile, sa); -+} -+ -+/** -+ * aa_file_denied - check for @mask access on a file -+ * @profile: profile to check against -+ * @name: pathname of file -+ * @mask: permission mask requested for file -+ * @audit_mask: return audit mask for the match -+ * -+ * Return %0 on success, or else the permissions in @mask that the -+ * profile denies. -+ */ -+static int aa_file_denied(struct aa_profile *profile, const char *name, -+ int mask, int *audit_mask) -+{ -+ return (mask & ~aa_match(profile->file_rules, name, audit_mask)); -+} -+ -+/** -+ * aa_link_denied - check for permission to link a file -+ * @profile: profile to check against -+ * @link: pathname of link being created -+ * @target: pathname of target to be linked to -+ * @target_mode: UGO shift for target inode -+ * @request_mask: the permissions subset valid only if link succeeds -+ * @audit_mask: return the audit_mask for the link permission -+ * Return %0 on success, or else the permissions that the profile denies. -+ */ -+static int aa_link_denied(struct aa_profile *profile, const char *link, -+ const char *target, int target_mode, -+ int *request_mask, int *audit_mask) -+{ -+ unsigned int state; -+ int l_mode, t_mode, l_x, t_x, denied_mask = 0; -+ int link_mask = AA_MAY_LINK << target_mode; -+ -+ *request_mask = link_mask; -+ -+ l_mode = aa_match_state(profile->file_rules, DFA_START, link, &state); -+ -+ if (l_mode & link_mask) { -+ int mode; -+ /* test to see if target can be paired with link */ -+ state = aa_dfa_null_transition(profile->file_rules, state); -+ mode = aa_match_state(profile->file_rules, state, target, -+ &state); -+ -+ if (!(mode & link_mask)) -+ denied_mask |= link_mask; -+ -+ *audit_mask = dfa_audit_mask(profile->file_rules, state); -+ -+ /* return if link subset test is not required */ -+ if (!(mode & (AA_LINK_SUBSET_TEST << target_mode))) -+ return denied_mask; -+ } -+ -+ /* Do link perm subset test requiring permission on link are a -+ * subset of the permissions on target. -+ * If a subset test is required a permission subset test of the -+ * perms for the link are done against the user::other of the -+ * target's 'r', 'w', 'x', 'a', 'k', and 'm' permissions. -+ * -+ * If the link has 'x', an exact match of all the execute flags -+ * must match. -+ */ -+ denied_mask |= ~l_mode & link_mask; -+ -+ t_mode = aa_match(profile->file_rules, target, NULL); -+ -+ l_x = l_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS); -+ t_x = t_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS); -+ -+ /* For actual subset test ignore valid-profile-transition flags, -+ * and link bits -+ */ -+ l_mode &= AA_FILE_PERMS & ~AA_LINK_BITS; -+ t_mode &= AA_FILE_PERMS & ~AA_LINK_BITS; -+ -+ *request_mask = l_mode | link_mask; -+ -+ if (l_mode) { -+ int x = l_x | (t_x & ALL_AA_EXEC_UNSAFE); -+ denied_mask |= l_mode & ~t_mode; -+ /* mask off x modes not used by link */ -+ -+ /* handle exec subset -+ * - link safe exec issubset of unsafe exec -+ * - no link x perm is subset of target having x perm -+ */ -+ if ((l_mode & AA_USER_EXEC) && -+ (x & AA_USER_EXEC_TYPE) != (t_x & AA_USER_EXEC_TYPE)) -+ denied_mask = AA_USER_EXEC | (l_x & AA_USER_EXEC_TYPE); -+ if ((l_mode & AA_OTHER_EXEC) && -+ (x & AA_OTHER_EXEC_TYPE) != (t_x & AA_OTHER_EXEC_TYPE)) -+ denied_mask = AA_OTHER_EXEC | (l_x & AA_OTHER_EXEC_TYPE); -+ } -+ -+ return denied_mask; -+} -+ -+/** -+ * aa_get_name - compute the pathname of a file -+ * @dentry: dentry of the file -+ * @mnt: vfsmount of the file -+ * @buffer: buffer that aa_get_name() allocated -+ * @check: AA_CHECK_DIR is set if the file is a directory -+ * -+ * Returns a pointer to the beginning of the pathname (which usually differs -+ * from the beginning of the buffer), or an error code. -+ * -+ * We need @check to indicate whether the file is a directory or not because -+ * the file may not yet exist, and so we cannot check the inode's file type. -+ */ -+static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt, -+ char **buffer, int check) -+{ -+ char *name; -+ int is_dir, size = 256; -+ -+ is_dir = (check & AA_CHECK_DIR) ? 1 : 0; -+ -+ for (;;) { -+ char *buf = kmalloc(size, GFP_KERNEL); -+ if (!buf) -+ return ERR_PTR(-ENOMEM); -+ -+ name = d_namespace_path(dentry, mnt, buf, size - is_dir); -+ if (!IS_ERR(name)) { -+ if (name[0] != '/') { -+ /* -+ * This dentry is not connected to the -+ * namespace root -- reject access. -+ */ -+ kfree(buf); -+ return ERR_PTR(-ENOENT); -+ } -+ if (is_dir && name[1] != '\0') { -+ /* -+ * Append "/" to the pathname. The root -+ * directory is a special case; it already -+ * ends in slash. -+ */ -+ buf[size - 2] = '/'; -+ buf[size - 1] = '\0'; -+ } -+ -+ *buffer = buf; -+ return name; -+ } -+ if (PTR_ERR(name) != -ENAMETOOLONG) -+ return name; -+ -+ kfree(buf); -+ size <<= 1; -+ if (size > apparmor_path_max) -+ return ERR_PTR(-ENAMETOOLONG); -+ } -+} -+ -+static char *new_compound_name(const char *n1, const char *n2) -+{ -+ char *name = kmalloc(strlen(n1) + strlen(n2) + 3, GFP_KERNEL); -+ if (name) -+ sprintf(name, "%s//%s", n1, n2); -+ return name; -+} -+static inline void aa_put_name_buffer(char *buffer) -+{ -+ kfree(buffer); -+} -+ -+/** -+ * aa_perm_dentry - check if @profile allows @mask for a file -+ * @profile: profile to check against -+ * @dentry: dentry of the file -+ * @mnt: vfsmount o the file -+ * @sa: audit context -+ * @mask: requested profile permissions -+ * @check: kind of check to perform -+ * -+ * Returns 0 upon success, or else an error code. -+ * -+ * @check indicates the file type, and whether the file was accessed through -+ * an open file descriptor (AA_CHECK_FD) or not. -+ */ -+static int aa_perm_dentry(struct aa_profile *profile, struct dentry *dentry, -+ struct vfsmount *mnt, struct aa_audit *sa, int check) -+{ -+ int error; -+ char *buffer = NULL; -+ -+ sa->name = aa_get_name(dentry, mnt, &buffer, check); -+ sa->request_mask <<= aa_inode_mode(dentry->d_inode); -+ if (IS_ERR(sa->name)) { -+ /* -+ * deleted files are given a pass on permission checks when -+ * accessed through a file descriptor. -+ */ -+ if (PTR_ERR(sa->name) == -ENOENT && (check & AA_CHECK_FD)) -+ sa->denied_mask = 0; -+ else { -+ sa->denied_mask = sa->request_mask; -+ sa->error_code = PTR_ERR(sa->name); -+ if (sa->error_code == -ENOENT) -+ sa->info = "Failed name resolution - object not a valid entry"; -+ else if (sa->error_code == -ENAMETOOLONG) -+ sa->info = "Failed name resolution - name too long"; -+ else -+ sa->info = "Failed name resolution"; -+ } -+ sa->name = NULL; -+ } else -+ sa->denied_mask = aa_file_denied(profile, sa->name, -+ sa->request_mask, -+ &sa->audit_mask); -+ -+ if (!sa->denied_mask) -+ sa->error_code = 0; -+ -+ error = aa_audit_file(profile, sa); -+ aa_put_name_buffer(buffer); -+ -+ return error; -+} -+ -+/** -+ * aa_attr - check if attribute change is allowed -+ * @profile: profile to check against -+ * @dentry: dentry of the file to check -+ * @mnt: vfsmount of the file to check -+ * @iattr: attribute changes requested -+ */ -+int aa_attr(struct aa_profile *profile, struct dentry *dentry, -+ struct vfsmount *mnt, struct iattr *iattr) -+{ -+ struct inode *inode = dentry->d_inode; -+ int error, check; -+ struct aa_audit sa; -+ -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "setattr"; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.iattr = iattr; -+ sa.request_mask = MAY_WRITE; -+ sa.error_code = -EACCES; -+ -+ check = 0; -+ if (inode && S_ISDIR(inode->i_mode)) -+ check |= AA_CHECK_DIR; -+ if (iattr->ia_valid & ATTR_FILE) -+ check |= AA_CHECK_FD; -+ -+ error = aa_perm_dentry(profile, dentry, mnt, &sa, check); -+ -+ return error; -+} -+ -+/** -+ * aa_perm_xattr - check if xattr attribute change is allowed -+ * @profile: profile to check against -+ * @dentry: dentry of the file to check -+ * @mnt: vfsmount of the file to check -+ * @operation: xattr operation being done -+ * @mask: access mode requested -+ * @check: kind of check to perform -+ */ -+int aa_perm_xattr(struct aa_profile *profile, const char *operation, -+ struct dentry *dentry, struct vfsmount *mnt, int mask, -+ int check) -+{ -+ struct inode *inode = dentry->d_inode; -+ int error; -+ struct aa_audit sa; -+ -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = operation; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.request_mask = mask; -+ sa.error_code = -EACCES; -+ -+ if (inode && S_ISDIR(inode->i_mode)) -+ check |= AA_CHECK_DIR; -+ -+ error = aa_perm_dentry(profile, dentry, mnt, &sa, check); -+ -+ return error; -+} -+ -+/** -+ * aa_perm - basic apparmor permissions check -+ * @profile: profile to check against -+ * @dentry: dentry of the file to check -+ * @mnt: vfsmount of the file to check -+ * @mask: access mode requested -+ * @check: kind of check to perform -+ * -+ * Determine if access @mask for the file is authorized by @profile. -+ * Returns 0 on success, or else an error code. -+ */ -+int aa_perm(struct aa_profile *profile, const char *operation, -+ struct dentry *dentry, struct vfsmount *mnt, int mask, int check) -+{ -+ struct aa_audit sa; -+ int error = 0; -+ -+ if (mask == 0) -+ goto out; -+ -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = operation; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.request_mask = mask; -+ sa.error_code = -EACCES; -+ -+ error = aa_perm_dentry(profile, dentry, mnt, &sa, check); -+ -+out: -+ return error; -+} -+ -+/** -+ * aa_perm_dir -+ * @profile: profile to check against -+ * @dentry: dentry of directory to check -+ * @mnt: vfsmount of directory to check -+ * @operation: directory operation being performed -+ * @mask: access mode requested -+ * -+ * Determine if directory operation (make/remove) for dentry is authorized -+ * by @profile. -+ * Returns 0 on success, or else an error code. -+ */ -+int aa_perm_dir(struct aa_profile *profile, const char *operation, -+ struct dentry *dentry, struct vfsmount *mnt, int mask) -+{ -+ struct aa_audit sa; -+ -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = operation; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.request_mask = mask; -+ sa.error_code = -EACCES; -+ -+ return aa_perm_dentry(profile, dentry, mnt, &sa, AA_CHECK_DIR); -+} -+ -+int aa_perm_path(struct aa_profile *profile, const char *operation, -+ const char *name, int mask, uid_t uid) -+{ -+ struct aa_audit sa; -+ -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = operation; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.request_mask = mask; -+ sa.name = name; -+ if (current->fsuid == uid) -+ sa.request_mask = mask << AA_USER_SHIFT; -+ else -+ sa.request_mask = mask << AA_OTHER_SHIFT; -+ -+ sa.denied_mask = aa_file_denied(profile, name, sa.request_mask, -+ &sa.audit_mask) ; -+ sa.error_code = sa.denied_mask ? -EACCES : 0; -+ -+ return aa_audit_file(profile, &sa); -+} -+ -+/** -+ * aa_capability - test permission to use capability -+ * @cxt: aa_task_context with profile to check against -+ * @cap: capability to be tested -+ * -+ * Look up capability in profile capability set. -+ * Returns 0 on success, or else an error code. -+ */ -+int aa_capability(struct aa_task_context *cxt, int cap) -+{ -+ int error = cap_raised(cxt->profile->capabilities, cap) ? 0 : -EPERM; -+ struct aa_audit sa; -+ -+ /* test if cap has alread been logged */ -+ if (cap_raised(cxt->caps_logged, cap)) { -+ if (PROFILE_COMPLAIN(cxt->profile)) -+ error = 0; -+ return error; -+ } else -+ /* don't worry about rcu replacement of the cxt here. -+ * caps_logged is a cache to reduce the occurence of -+ * duplicate messages in the log. The worst that can -+ * happen is duplicate capability messages shows up in -+ * the audit log -+ */ -+ cap_raise(cxt->caps_logged, cap); -+ -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "capable"; -+ sa.gfp_mask = GFP_ATOMIC; -+ sa.name = capability_names[cap]; -+ sa.error_code = error; -+ -+ error = aa_audit_caps(cxt->profile, &sa, cap); -+ -+ return error; -+} -+ -+/* must be used inside rcu_read_lock or task_lock */ -+int aa_may_ptrace(struct aa_task_context *cxt, struct aa_profile *tracee) -+{ -+ if (!cxt || cxt->profile == tracee) -+ return 0; -+ return aa_capability(cxt, CAP_SYS_PTRACE); -+} -+ -+/** -+ * aa_link - hard link check -+ * @profile: profile to check against -+ * @link: dentry of link being created -+ * @link_mnt: vfsmount of link being created -+ * @target: dentry of link target -+ * @target_mnt: vfsmunt of link target -+ * -+ * Returns 0 on success, or else an error code. -+ */ -+int aa_link(struct aa_profile *profile, -+ struct dentry *link, struct vfsmount *link_mnt, -+ struct dentry *target, struct vfsmount *target_mnt) -+{ -+ int error; -+ struct aa_audit sa; -+ char *buffer = NULL, *buffer2 = NULL; -+ -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "inode_link"; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.name = aa_get_name(link, link_mnt, &buffer, 0); -+ sa.name2 = aa_get_name(target, target_mnt, &buffer2, 0); -+ -+ if (IS_ERR(sa.name)) { -+ sa.error_code = PTR_ERR(sa.name); -+ sa.name = NULL; -+ } -+ if (IS_ERR(sa.name2)) { -+ sa.error_code = PTR_ERR(sa.name2); -+ sa.name2 = NULL; -+ } -+ -+ if (sa.name && sa.name2) { -+ sa.denied_mask = aa_link_denied(profile, sa.name, sa.name2, -+ aa_inode_mode(target->d_inode), -+ &sa.request_mask, -+ &sa.audit_mask); -+ sa.error_code = sa.denied_mask ? -EACCES : 0; -+ } -+ -+ error = aa_audit_file(profile, &sa); -+ -+ aa_put_name_buffer(buffer); -+ aa_put_name_buffer(buffer2); -+ -+ return error; -+} -+ -+/******************************* -+ * Global task related functions -+ *******************************/ -+ -+/** -+ * aa_clone - initialize the task context for a new task -+ * @child: task that is being created -+ * -+ * Returns 0 on success, or else an error code. -+ */ -+int aa_clone(struct task_struct *child) -+{ -+ struct aa_task_context *cxt, *child_cxt; -+ struct aa_profile *profile; -+ -+ if (!aa_task_context(current)) -+ return 0; -+ child_cxt = aa_alloc_task_context(GFP_KERNEL); -+ if (!child_cxt) -+ return -ENOMEM; -+ -+repeat: -+ profile = aa_get_profile(current); -+ if (profile) { -+ lock_profile(profile); -+ cxt = aa_task_context(current); -+ if (unlikely(profile->isstale || !cxt || -+ cxt->profile != profile)) { -+ /** -+ * Race with profile replacement or removal, or with -+ * task context removal. -+ */ -+ unlock_profile(profile); -+ aa_put_profile(profile); -+ goto repeat; -+ } -+ -+ /* No need to grab the child's task lock here. */ -+ aa_change_task_context(child, child_cxt, profile, -+ cxt->cookie, cxt->previous_profile); -+ unlock_profile(profile); -+ -+ if (APPARMOR_COMPLAIN(child_cxt) && -+ profile == profile->ns->null_complain_profile) { -+ struct aa_audit sa; -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "clone"; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.task = child->pid; -+ aa_audit_hint(profile, &sa); -+ } -+ aa_put_profile(profile); -+ } else -+ aa_free_task_context(child_cxt); -+ -+ return 0; -+} -+ -+static struct aa_profile * -+aa_register_find(struct aa_profile *profile, const char* ns_name, -+ const char *name, int mandatory, int complain, -+ struct aa_audit *sa) -+{ -+ struct aa_namespace *ns; -+ struct aa_profile *new_profile; -+ int ns_ref = 0; -+ -+ if (profile) -+ ns = profile->ns; -+ else -+ ns = default_namespace; -+ -+ if (ns_name) { -+ /* locate the profile namespace */ -+ ns = aa_find_namespace(ns_name); -+ if (!ns) { -+ if (mandatory) { -+ sa->info = "profile namespace not found"; -+ sa->denied_mask = sa->request_mask; -+ sa->error_code = -ENOENT; -+ return ERR_PTR(-ENOENT); -+ } else { -+ return NULL; -+ } -+ } -+ ns_ref++; -+ } -+ -+ /* Locate new profile */ -+ new_profile = aa_find_profile(ns, name); -+ -+ if (new_profile) { -+ AA_DEBUG("%s: setting profile %s\n", -+ __FUNCTION__, new_profile->name); -+ } else if (mandatory && profile) { -+ sa->info = "mandatory profile missing"; -+ sa->denied_mask = sa->request_mask; /* shifted MAY_EXEC */ -+ if (complain) { -+ aa_audit_hint(profile, sa); -+ new_profile = -+ aa_dup_profile(profile->ns->null_complain_profile); -+ } else { -+ sa->error_code = -EACCES; -+ if (ns_ref) -+ aa_put_namespace(ns); -+ return ERR_PTR(-EACCES); -+ } -+ } else { -+ /* Only way we can get into this code is if task -+ * is unconfined, pix, nix. -+ */ -+ AA_DEBUG("%s: No profile found for exec image '%s'\n", -+ __FUNCTION__, -+ name); -+ } -+ if (ns_ref) -+ aa_put_namespace(ns); -+ return new_profile; -+} -+ -+static struct aa_profile * -+aa_x_to_profile(struct aa_profile *profile, const char *filename, int xmode, -+ struct aa_audit *sa, char **child) -+{ -+ struct aa_profile *new_profile = NULL; -+ int ix = xmode & AA_EXEC_INHERIT; -+ int complain = PROFILE_COMPLAIN(profile); -+ int index; -+ -+ *child = NULL; -+ switch (xmode & AA_EXEC_MODIFIERS) { -+ case 0: -+ /* only valid with ix flag */ -+ ix = 1; -+ break; -+ case AA_EXEC_UNCONFINED: -+ /* only valid without ix flag */ -+ ix = 0; -+ break; -+ case AA_EXEC_PROFILE: -+ new_profile = aa_register_find(profile, NULL, filename, !ix, -+ complain, sa); -+ break; -+ case AA_EXEC_CHILD: -+ *child = new_compound_name(profile->name, filename); -+ sa->name2 = *child; -+ if (!*child) { -+ sa->info = "Failed name resolution - exec failed"; -+ sa->error_code = -ENOMEM; -+ new_profile = ERR_PTR(-ENOMEM); -+ } else { -+ new_profile = aa_register_find(profile, NULL, *child, -+ !ix, complain, sa); -+ } -+ break; -+ default: -+ /* all other indexes are named transitions */ -+ index = AA_EXEC_INDEX(xmode); -+ if (index - 4 >= profile->exec_table_size) { -+ sa->info = "invalid named transition - exec failed"; -+ sa->error_code = -EACCES; -+ new_profile = ERR_PTR(-EACCES); -+ } else { -+ char *ns_name = NULL; -+ char *name = profile->exec_table[index - 4]; -+ if (*name == ':') { -+ ns_name = name + 1; -+ name = ns_name + strlen(ns_name) + 1; -+ } -+ sa->name2 = name; -+ sa->name3 = ns_name; -+ new_profile = -+ aa_register_find(profile, ns_name, name, -+ !ix, complain, sa); -+ } -+ } -+ if (IS_ERR(new_profile)) -+ /* all these failures must be audited - no quieting */ -+ return ERR_PTR(aa_audit_reject(profile, sa)); -+ return new_profile; -+} -+ -+/** -+ * aa_register - register a new program -+ * @bprm: binprm of program being registered -+ * -+ * Try to register a new program during execve(). This should give the -+ * new program a valid aa_task_context if confined. -+ */ -+int aa_register(struct linux_binprm *bprm) -+{ -+ const char *filename; -+ char *buffer = NULL, *child = NULL; -+ struct file *filp = bprm->file; -+ struct aa_profile *profile, *old_profile, *new_profile = NULL; -+ int exec_mode, complain = 0, shift; -+ struct aa_audit sa; -+ -+ AA_DEBUG("%s\n", __FUNCTION__); -+ -+ profile = aa_get_profile(current); -+ -+ shift = aa_inode_mode(filp->f_dentry->d_inode); -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "exec"; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.request_mask = MAY_EXEC << shift; -+ -+ filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer, 0); -+ if (IS_ERR(filename)) { -+ if (profile) { -+ sa.info = "Failed name resolution - exec failed"; -+ sa.error_code = PTR_ERR(filename); -+ aa_audit_file(profile, &sa); -+ return sa.error_code; -+ } else -+ return 0; -+ } -+ sa.name = filename; -+ -+ exec_mode = AA_EXEC_UNSAFE << shift; -+ -+repeat: -+ if (profile) { -+ complain = PROFILE_COMPLAIN(profile); -+ -+ /* Confined task, determine what mode inherit, unconfined or -+ * mandatory to load new profile -+ */ -+ exec_mode = aa_match(profile->file_rules, filename, -+ &sa.audit_mask); -+ -+ -+ if (exec_mode & sa.request_mask) { -+ int xm = exec_mode >> shift; -+ new_profile = aa_x_to_profile(profile, filename, -+ xm, &sa, &child); -+ -+ if (!new_profile && (xm & AA_EXEC_INHERIT)) -+ /* (p|c|n|)ix - don't change profile */ -+ goto cleanup; -+ /* error case caught below */ -+ -+ } else if (sa.request_mask & AUDIT_QUIET_MASK(sa.audit_mask)) { -+ /* quiet failed exit */ -+ new_profile = ERR_PTR(-EACCES); -+ } else if (complain) { -+ /* There was no entry in calling profile -+ * describing mode to execute image in. -+ * Drop into null-profile (disabling secure exec). -+ */ -+ new_profile = -+ aa_dup_profile(profile->ns->null_complain_profile); -+ exec_mode |= AA_EXEC_UNSAFE << shift; -+ } else { -+ sa.denied_mask = sa.request_mask; -+ sa.error_code = -EACCES; -+ new_profile = ERR_PTR(aa_audit_file(profile, &sa)); -+ } -+ } else { -+ /* Unconfined task, load profile if it exists */ -+ new_profile = aa_register_find(NULL, NULL, filename, 0, 0, &sa); -+ if (new_profile == NULL) -+ goto cleanup; -+ } -+ -+ if (IS_ERR(new_profile)) -+ goto cleanup; -+ -+ old_profile = __aa_replace_profile(current, new_profile); -+ if (IS_ERR(old_profile)) { -+ aa_put_profile(new_profile); -+ aa_put_profile(profile); -+ if (PTR_ERR(old_profile) == -ESTALE) { -+ profile = aa_get_profile(current); -+ goto repeat; -+ } -+ if (PTR_ERR(old_profile) == -EPERM) { -+ sa.denied_mask = sa.request_mask; -+ sa.info = "unable to set profile due to ptrace"; -+ sa.task = current->parent->pid; -+ aa_audit_reject(profile, &sa); -+ } -+ new_profile = old_profile; -+ goto cleanup; -+ } -+ aa_put_profile(old_profile); -+ aa_put_profile(profile); -+ -+ /* Handle confined exec. -+ * Can be at this point for the following reasons: -+ * 1. unconfined switching to confined -+ * 2. confined switching to different confinement -+ * 3. confined switching to unconfined -+ * -+ * Cases 2 and 3 are marked as requiring secure exec -+ * (unless policy specified "unsafe exec") -+ */ -+ if (!(exec_mode & (AA_EXEC_UNSAFE << shift))) { -+ unsigned long bprm_flags; -+ -+ bprm_flags = AA_SECURE_EXEC_NEEDED; -+ bprm->security = (void*) -+ ((unsigned long)bprm->security | bprm_flags); -+ } -+ -+ if (complain && new_profile && -+ new_profile == new_profile->ns->null_complain_profile) { -+ sa.request_mask = 0; -+ sa.name = NULL; -+ sa.info = "set profile"; -+ aa_audit_hint(new_profile, &sa); -+ } -+ -+cleanup: -+ aa_put_name_buffer(child); -+ aa_put_name_buffer(buffer); -+ if (IS_ERR(new_profile)) -+ return PTR_ERR(new_profile); -+ aa_put_profile(new_profile); -+ return 0; -+} -+ -+/** -+ * aa_release - release a task context -+ * @task: task being released -+ * -+ * This is called after a task has exited and the parent has reaped it. -+ */ -+void aa_release(struct task_struct *task) -+{ -+ struct aa_task_context *cxt; -+ struct aa_profile *profile; -+ /* -+ * While the task context is still on a profile's task context -+ * list, another process could replace the profile under us, -+ * leaving us with a locked profile that is no longer attached -+ * to this task. So after locking the profile, we check that -+ * the profile is still attached. The profile lock is -+ * sufficient to prevent the replacement race so we do not lock -+ * the task. -+ * -+ * Use lock subtyping to avoid lockdep reporting a false irq -+ * possible inversion between the task_lock and profile_lock -+ * -+ * We also avoid taking the task_lock here because lock_dep -+ * would report another false {softirq-on-W} potential irq_lock -+ * inversion. -+ * -+ * If the task does not have a profile attached we are safe; -+ * nothing can race with us at this point. -+ */ -+ -+repeat: -+ profile = aa_get_profile(task); -+ if (profile) { -+ lock_profile_nested(profile, aa_lock_task_release); -+ cxt = aa_task_context(task); -+ if (unlikely(!cxt || cxt->profile != profile)) { -+ unlock_profile(profile); -+ aa_put_profile(profile); -+ goto repeat; -+ } -+ aa_change_task_context(task, NULL, NULL, 0, NULL); -+ unlock_profile(profile); -+ aa_put_profile(profile); -+ } -+} -+ -+static int do_change_profile(struct aa_profile *expected, -+ struct aa_namespace *ns, const char *name, -+ u64 cookie, int restore, struct aa_audit *sa) -+{ -+ struct aa_profile *new_profile = NULL, *old_profile = NULL, -+ *previous_profile = NULL; -+ struct aa_task_context *new_cxt, *cxt; -+ int error = 0; -+ -+ sa->name = name; -+ -+ new_cxt = aa_alloc_task_context(GFP_KERNEL); -+ if (!new_cxt) -+ return -ENOMEM; -+ -+ new_profile = aa_find_profile(ns, name); -+ if (!new_profile && !restore) { -+ if (!PROFILE_COMPLAIN(expected)) -+ return -ENOENT; -+ new_profile = aa_dup_profile(ns->null_complain_profile); -+ } -+ -+ cxt = lock_task_and_profiles(current, new_profile); -+ if (!cxt) { -+ error = -EPERM; -+ goto out; -+ } -+ old_profile = cxt->profile; -+ -+ if (cxt->profile != expected || (new_profile && new_profile->isstale)) { -+ error = -ESTALE; -+ goto out; -+ } -+ -+ if (cxt->previous_profile) { -+ if (cxt->cookie != cookie) { -+ error = -EACCES; -+ sa->info = "killing process"; -+ aa_audit_reject(cxt->profile, sa); -+ /* terminate process */ -+ (void)send_sig_info(SIGKILL, NULL, current); -+ goto out; -+ } -+ -+ if (!restore) -+ previous_profile = cxt->previous_profile; -+ } else -+ previous_profile = cxt->profile; -+ -+ if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, new_profile)) { -+ error = -EACCES; -+ goto out; -+ } -+ -+ if (new_profile == ns->null_complain_profile) -+ aa_audit_hint(cxt->profile, sa); -+ -+ if (APPARMOR_AUDIT(cxt)) -+ aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT); -+ -+ if (!restore && cookie) -+ aa_change_task_context(current, new_cxt, new_profile, cookie, -+ previous_profile); -+ else -+ /* either return to previous_profile, or a permanent change */ -+ aa_change_task_context(current, new_cxt, new_profile, 0, NULL); -+ -+out: -+ if (aa_task_context(current) != new_cxt) -+ aa_free_task_context(new_cxt); -+ task_unlock(current); -+ unlock_both_profiles(old_profile, new_profile); -+ aa_put_profile(new_profile); -+ return error; -+} -+ -+/** -+ * aa_change_profile - perform a one-way profile transition -+ * @ns_name: name of the profile namespace to change to -+ * @name: name of profile to change to -+ * Change to new profile @name. Unlike with hats, there is no way -+ * to change back. -+ * -+ * Returns %0 on success, error otherwise. -+ */ -+int aa_change_profile(const char *ns_name, const char *name) -+{ -+ struct aa_task_context *cxt; -+ struct aa_profile *profile = NULL; -+ struct aa_namespace *ns = NULL; -+ struct aa_audit sa; -+ unsigned int state; -+ int error = -EINVAL; -+ -+ if (!name) -+ return -EINVAL; -+ -+ memset(&sa, 0, sizeof(sa)); -+ sa.gfp_mask = GFP_ATOMIC; -+ sa.operation = "change_profile"; -+ -+repeat: -+ task_lock(current); -+ cxt = aa_task_context(current); -+ if (cxt) -+ profile = aa_dup_profile(cxt->profile); -+ task_unlock(current); -+ -+ if (ns_name) -+ ns = aa_find_namespace(ns_name); -+ else if (profile) -+ ns = aa_get_namespace(profile->ns); -+ else -+ ns = aa_get_namespace(default_namespace); -+ -+ if (!ns) { -+ aa_put_profile(profile); -+ return -ENOENT; -+ } -+ -+ if (!profile || PROFILE_COMPLAIN(profile) || -+ (ns == profile->ns && -+ (aa_match(profile->file_rules, name, NULL) & AA_CHANGE_PROFILE))) -+ error = do_change_profile(profile, ns, name, 0, 0, &sa); -+ else { -+ /* check for a rule with a namespace prepended */ -+ aa_match_state(profile->file_rules, DFA_START, ns->name, -+ &state); -+ state = aa_dfa_null_transition(profile->file_rules, state); -+ if ((aa_match_state(profile->file_rules, state, name, NULL) & -+ AA_CHANGE_PROFILE)) -+ error = do_change_profile(profile, ns, name, 0, 0, -+ &sa); -+ else -+ /* no permission to transition to profile @name */ -+ error = -EACCES; -+ } -+ -+ aa_put_namespace(ns); -+ aa_put_profile(profile); -+ if (error == -ESTALE) -+ goto repeat; -+ -+ return error; -+} -+ -+/** -+ * aa_change_hat - change hat to/from subprofile -+ * @hat_name: hat to change to -+ * @cookie: magic value to validate the hat change -+ * -+ * Change to new @hat_name, and store the @hat_magic in the current task -+ * context. If the new @hat_name is %NULL and the @cookie matches that -+ * stored in the current task context and is not 0, return to the top level -+ * profile. -+ * Returns %0 on success, error otherwise. -+ */ -+int aa_change_hat(const char *hat_name, u64 cookie) -+{ -+ struct aa_task_context *cxt; -+ struct aa_profile *profile, *previous_profile; -+ struct aa_audit sa; -+ int error = 0; -+ -+ memset(&sa, 0, sizeof(sa)); -+ sa.gfp_mask = GFP_ATOMIC; -+ sa.operation = "change_hat"; -+ -+repeat: -+ task_lock(current); -+ cxt = aa_task_context(current); -+ if (!cxt) { -+ task_unlock(current); -+ return -EPERM; -+ } -+ profile = aa_dup_profile(cxt->profile); -+ previous_profile = aa_dup_profile(cxt->previous_profile); -+ task_unlock(current); -+ -+ if (hat_name) { -+ char *name, *profile_name; -+ if (!PROFILE_COMPLAIN(profile) && -+ !(aa_match(profile->file_rules, hat_name, NULL) -+ & AA_CHANGE_HAT)) { -+ /* missing permission to change_hat is treated the -+ * same as a failed hat search */ -+ error = -ENOENT; -+ goto out; -+ } -+ -+ if (previous_profile) -+ profile_name = previous_profile->name; -+ else -+ profile_name = profile->name; -+ -+ name = new_compound_name(profile_name, hat_name); -+ if (!name) { -+ error = -ENOMEM; -+ goto out; -+ } -+ error = do_change_profile(profile, profile->ns, name, cookie, -+ 0, &sa); -+ aa_put_name_buffer(name); -+ } else if (previous_profile) -+ error = do_change_profile(profile, profile->ns, -+ previous_profile->name, cookie, 1, -+ &sa); -+ /* else ignore restores when there is no saved profile */ -+ -+out: -+ aa_put_profile(previous_profile); -+ aa_put_profile(profile); -+ if (error == -ESTALE) -+ goto repeat; -+ -+ return error; -+} -+ -+/** -+ * __aa_replace_profile - replace a task's profile -+ * @task: task to switch the profile of -+ * @profile: profile to switch to -+ * -+ * Returns a handle to the previous profile upon success, or else an -+ * error code. -+ */ -+struct aa_profile *__aa_replace_profile(struct task_struct *task, -+ struct aa_profile *profile) -+{ -+ struct aa_task_context *cxt, *new_cxt = NULL; -+ struct aa_profile *old_profile = NULL; -+ -+ if (profile) { -+ new_cxt = aa_alloc_task_context(GFP_KERNEL); -+ if (!new_cxt) -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ cxt = lock_task_and_profiles(task, profile); -+ if (unlikely(profile && profile->isstale)) { -+ task_unlock(task); -+ unlock_both_profiles(profile, cxt ? cxt->profile : NULL); -+ aa_free_task_context(new_cxt); -+ return ERR_PTR(-ESTALE); -+ } -+ -+ if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) { -+ task_unlock(task); -+ unlock_both_profiles(profile, cxt ? cxt->profile : NULL); -+ aa_free_task_context(new_cxt); -+ return ERR_PTR(-EPERM); -+ } -+ -+ if (cxt) -+ old_profile = aa_dup_profile(cxt->profile); -+ aa_change_task_context(task, new_cxt, profile, 0, NULL); -+ -+ task_unlock(task); -+ unlock_both_profiles(profile, old_profile); -+ return old_profile; -+} -+ -+/** -+ * lock_task_and_profiles - lock the task and confining profiles and @profile -+ * @task: task to lock -+ * @profile: extra profile to lock in addition to the current profile -+ * -+ * Handle the spinning on locking to make sure the task context and -+ * profile are consistent once all locks are aquired. -+ * -+ * return the aa_task_context currently confining the task. The task lock -+ * will be held whether or not the task is confined. -+ */ -+struct aa_task_context * -+lock_task_and_profiles(struct task_struct *task, struct aa_profile *profile) -+{ -+ struct aa_task_context *cxt; -+ struct aa_profile *old_profile = NULL; -+ -+ rcu_read_lock(); -+repeat: -+ cxt = aa_task_context(task); -+ if (cxt) -+ old_profile = cxt->profile; -+ -+ lock_both_profiles(profile, old_profile); -+ task_lock(task); -+ -+ /* check for race with profile transition, replacement or removal */ -+ if (unlikely(cxt != aa_task_context(task))) { -+ task_unlock(task); -+ unlock_both_profiles(profile, old_profile); -+ old_profile = NULL; -+ goto repeat; -+ } -+ rcu_read_unlock(); -+ return cxt; -+} -+ -+static void free_aa_task_context_rcu_callback(struct rcu_head *head) -+{ -+ struct aa_task_context *cxt; -+ -+ cxt = container_of(head, struct aa_task_context, rcu); -+ aa_free_task_context(cxt); -+} -+ -+/** -+ * aa_change_task_context - switch a task to use a new context and profile -+ * @task: task that is having its task context changed -+ * @new_cxt: new task context to use after the switch -+ * @profile: new profile to use after the switch -+ * @cookie: magic value to switch to -+ * @previous_profile: profile the task can return to -+ */ -+void aa_change_task_context(struct task_struct *task, -+ struct aa_task_context *new_cxt, -+ struct aa_profile *profile, u64 cookie, -+ struct aa_profile *previous_profile) -+{ -+ struct aa_task_context *old_cxt = aa_task_context(task); -+ -+ if (old_cxt) { -+ list_del_init(&old_cxt->list); -+ call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback); -+ } -+ if (new_cxt) { -+ /* set the caps_logged cache to the quiet_caps mask -+ * this has the effect of quieting caps that are not -+ * supposed to be logged -+ */ -+ new_cxt->caps_logged = profile->quiet_caps; -+ new_cxt->cookie = cookie; -+ new_cxt->task = task; -+ new_cxt->profile = aa_dup_profile(profile); -+ new_cxt->previous_profile = aa_dup_profile(previous_profile); -+ list_move(&new_cxt->list, &profile->task_contexts); -+ } -+ rcu_assign_pointer(task->security, new_cxt); -+} diff --git a/kernel-patches/for-mainline/apparmor-misc.diff b/kernel-patches/for-mainline/apparmor-misc.diff deleted file mode 100644 index 34c963b08..000000000 --- a/kernel-patches/for-mainline/apparmor-misc.diff +++ /dev/null @@ -1,1418 +0,0 @@ -From: John Johansen -Subject: AppArmor: all the rest - -All the things that didn't nicely fit in a category on their own: kbuild -code, declararions and inline functions, /sys/kernel/security/apparmor -filesystem for controlling apparmor from user space, profile list -functions, locking documentation, /proc/$pid/task/$tid/attr/current -access. - -Signed-off-by: John Johansen -Signed-off-by: Andreas Gruenbacher - ---- - security/apparmor/Kconfig | 42 ++++ - security/apparmor/Makefile | 13 + - security/apparmor/apparmor.h | 367 +++++++++++++++++++++++++++++++++++++++++ - security/apparmor/apparmorfs.c | 280 +++++++++++++++++++++++++++++++ - security/apparmor/inline.h | 250 +++++++++++++++++++++++++++ - security/apparmor/list.c | 156 +++++++++++++++++ - security/apparmor/locking.txt | 68 +++++++ - security/apparmor/procattr.c | 195 +++++++++++++++++++++ - 8 files changed, 1371 insertions(+) - ---- /dev/null -+++ b/security/apparmor/Kconfig -@@ -0,0 +1,42 @@ -+config SECURITY_APPARMOR -+ bool "AppArmor support" -+ depends on SECURITY -+ select AUDIT -+ help -+ This enables the AppArmor security module. -+ Required userspace tools (if they are not included in your -+ distribution) and further information may be found at -+ -+ -+ If you are unsure how to answer this question, answer N. -+ -+config SECURITY_APPARMOR_BOOTPARAM_VALUE -+ int "AppArmor boot parameter default value" -+ depends on SECURITY_APPARMOR -+ range 0 1 -+ default 1 -+ help -+ This option sets the default value for the kernel parameter -+ 'apparmor', which allows AppArmor to be enabled or disabled -+ at boot. If this option is set to 0 (zero), the AppArmor -+ kernel parameter will default to 0, disabling AppArmor at -+ bootup. If this option is set to 1 (one), the AppArmor -+ kernel parameter will default to 1, enabling AppArmor at -+ bootup. -+ -+ If you are unsure how to answer this question, answer 1. -+ -+config SECURITY_APPARMOR_DISABLE -+ bool "AppArmor runtime disable" -+ depends on SECURITY_APPARMOR -+ default n -+ help -+ This option enables writing to a apparmorfs node 'disable', which -+ allows AppArmor to be disabled at runtime prior to the policy load. -+ AppArmor will then remain disabled until the next boot. -+ This option is similar to the apparmor.enabled=0 boot parameter, -+ but is to support runtime disabling of AppArmor, e.g. from -+ /sbin/init, for portability across platforms where boot -+ parameters are difficult to employ. -+ -+ If you are unsure how to answer this question, answer N. ---- /dev/null -+++ b/security/apparmor/Makefile -@@ -0,0 +1,13 @@ -+# Makefile for AppArmor Linux Security Module -+# -+obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o -+ -+apparmor-y := main.o list.o procattr.o lsm.o apparmorfs.o \ -+ module_interface.o match.o -+ -+quiet_cmd_make-caps = GEN $@ -+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 > $@ -+ -+$(obj)/main.o : $(obj)/capability_names.h -+$(obj)/capability_names.h : $(srctree)/include/linux/capability.h -+ $(call cmd,make-caps) ---- /dev/null -+++ b/security/apparmor/apparmor.h -@@ -0,0 +1,367 @@ -+/* -+ * Copyright (C) 1998-2007 Novell/SUSE -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation, version 2 of the -+ * License. -+ * -+ * AppArmor internal prototypes -+ */ -+ -+#ifndef __APPARMOR_H -+#define __APPARMOR_H -+ -+#include -+#include -+#include -+#include -+ -+/* -+ * We use MAY_READ, MAY_WRITE, MAY_EXEC, MAY_APPEND and the following flags -+ * for profile permissions -+ */ -+#define AA_MAY_LINK 0x0010 -+#define AA_MAY_LOCK 0x0020 -+#define AA_EXEC_MMAP 0x0040 -+#define AA_MAY_MOUNT 0x0080 /* no direct audit mapping */ -+#define AA_EXEC_UNSAFE 0x0100 -+#define AA_EXEC_INHERIT 0x0200 -+#define AA_EXEC_MOD_0 0x0400 -+#define AA_EXEC_MOD_1 0x0800 -+#define AA_EXEC_MOD_2 0x1000 -+#define AA_EXEC_MOD_3 0x2000 -+ -+#define AA_BASE_PERMS (MAY_READ | MAY_WRITE | MAY_EXEC | \ -+ MAY_APPEND | AA_MAY_LINK | \ -+ AA_MAY_LOCK | AA_EXEC_MMAP | \ -+ AA_MAY_MOUNT | AA_EXEC_UNSAFE | \ -+ AA_EXEC_INHERIT | AA_EXEC_MOD_0 | \ -+ AA_EXEC_MOD_1 | AA_EXEC_MOD_2 | \ -+ AA_EXEC_MOD_3) -+ -+#define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \ -+ AA_EXEC_MOD_2 | AA_EXEC_MOD_3) -+ -+#define AA_EXEC_TYPE (AA_EXEC_UNSAFE | AA_EXEC_INHERIT | \ -+ AA_EXEC_MODIFIERS) -+ -+#define AA_EXEC_UNCONFINED AA_EXEC_MOD_0 -+#define AA_EXEC_PROFILE AA_EXEC_MOD_1 -+#define AA_EXEC_CHILD (AA_EXEC_MOD_0 | AA_EXEC_MOD_1) -+/* remaining exec modes are index into profile name table */ -+#define AA_EXEC_INDEX(mode) ((mode & AA_EXEC_MODIFIERS) >> 10) -+ -+#define AA_USER_SHIFT 0 -+#define AA_OTHER_SHIFT 14 -+ -+#define AA_USER_PERMS (AA_BASE_PERMS << AA_USER_SHIFT) -+#define AA_OTHER_PERMS (AA_BASE_PERMS << AA_OTHER_SHIFT) -+ -+#define AA_FILE_PERMS (AA_USER_PERMS | AA_OTHER_PERMS) -+ -+#define AA_LINK_BITS ((AA_MAY_LINK << AA_USER_SHIFT) | \ -+ (AA_MAY_LINK << AA_OTHER_SHIFT)) -+ -+#define AA_USER_EXEC (MAY_EXEC << AA_USER_SHIFT) -+#define AA_OTHER_EXEC (MAY_EXEC << AA_OTHER_SHIFT) -+ -+#define AA_USER_EXEC_TYPE (AA_EXEC_TYPE << AA_USER_SHIFT) -+#define AA_OTHER_EXEC_TYPE (AA_EXEC_TYPE << AA_OTHER_SHIFT) -+ -+#define AA_EXEC_BITS (AA_USER_EXEC | AA_OTHER_EXEC) -+ -+#define ALL_AA_EXEC_UNSAFE ((AA_EXEC_UNSAFE << AA_USER_SHIFT) | \ -+ (AA_EXEC_UNSAFE << AA_OTHER_SHIFT)) -+ -+#define ALL_AA_EXEC_TYPE (AA_USER_EXEC_TYPE | AA_OTHER_EXEC_TYPE) -+ -+/* overloaded permissions for link pairs */ -+#define AA_LINK_SUBSET_TEST 0x0020 -+ -+#define AA_USER_PTRACE 0x10000000 -+#define AA_OTHER_PTRACE 0x20000000 -+#define AA_PTRACE_PERMS (AA_USER_PTRACE | AA_OTHER_PTRACE) -+ -+/* shared permissions that are not duplicated in user::other */ -+#define AA_CHANGE_HAT 0x40000000 -+#define AA_CHANGE_PROFILE 0x80000000 -+ -+#define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE) -+ -+#define AA_VALID_PERM_MASK (AA_FILE_PERMS | AA_PTRACE_PERMS | \ -+ AA_SHARED_PERMS) -+ -+/* audit bits for the second accept field */ -+#define AUDIT_FILE_MASK 0x1fc07f -+#define AUDIT_QUIET_MASK(mask) ((mask >> 7) & AUDIT_FILE_MASK) -+#define AA_VALID_PERM2_MASK 0x0fffffff -+ -+#define AA_SECURE_EXEC_NEEDED 1 -+ -+/* Control parameters (0 or 1), settable thru module/boot flags or -+ * via /sys/kernel/security/apparmor/control */ -+extern int apparmor_complain; -+extern int apparmor_debug; -+extern int apparmor_audit; -+extern int apparmor_logsyscall; -+extern unsigned int apparmor_path_max; -+ -+#define PROFILE_COMPLAIN(_profile) \ -+ (apparmor_complain == 1 || ((_profile) && (_profile)->flags.complain)) -+ -+#define APPARMOR_COMPLAIN(_cxt) \ -+ (apparmor_complain == 1 || \ -+ ((_cxt) && (_cxt)->profile && (_cxt)->profile->flags.complain)) -+ -+#define PROFILE_AUDIT(_profile) \ -+ (apparmor_audit == 1 || ((_profile) && (_profile)->flags.audit)) -+ -+#define APPARMOR_AUDIT(_cxt) \ -+ (apparmor_audit == 1 || \ -+ ((_cxt) && (_cxt)->profile && (_cxt)->profile->flags.audit)) -+ -+/* -+ * DEBUG remains global (no per profile flag) since it is mostly used in sysctl -+ * which is not related to profile accesses. -+ */ -+ -+#define AA_DEBUG(fmt, args...) \ -+ do { \ -+ if (apparmor_debug) \ -+ printk(KERN_DEBUG "AppArmor: " fmt, ##args); \ -+ } while (0) -+ -+#define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args) -+ -+struct aa_profile; -+ -+/* struct aa_namespace - namespace for a set of profiles -+ * @name: the name of the namespace -+ * @list: list the namespace is on -+ * @profiles: list of profile in the namespace -+ * @profile_count: the number of profiles in the namespace -+ * @null_complain_profile: special profile used for learning in this namespace -+ * @count: reference count on the namespace -+ * @lock: lock for adding/removing profile to the namespace -+ */ -+struct aa_namespace { -+ char *name; -+ struct list_head list; -+ struct list_head profiles; -+ int profile_count; -+ struct aa_profile *null_complain_profile; -+ -+ struct kref count; -+ rwlock_t lock; -+}; -+ -+/* struct aa_profile - basic confinement data -+ * @name: the profiles name -+ * @list: list this profile is on -+ * @ns: namespace the profile is in -+ * @file_rules: dfa containing the profiles file rules -+ * @flags: flags controlling profile behavior -+ * @isstale: flag indicating if profile is stale -+ * @set_caps: capabilities that are being set -+ * @capabilities: capabilities mask -+ * @audit_caps: caps that are to be audited -+ * @quiet_caps: caps that should not be audited -+ * @capabilities: capabilities granted by the process -+ * @count: reference count of the profile -+ * @task_contexts: list of tasks confined by profile -+ * @lock: lock for the task_contexts list -+ * @network_families: basic network permissions -+ * @audit_network: which network permissions to force audit -+ * @quiet_network: which network permissions to quiet rejects -+ * -+ * The AppArmor profile contains the basic confinement data. Each profile -+ * has a name, and all nonstale profile are in a profile namespace. -+ * -+ * The task_contexts list and the isstale flag are protected by the -+ * profile lock. -+ * -+ * If a task context is moved between two profiles, we first need to grab -+ * both profile locks. lock_both_profiles() does that in a deadlock-safe -+ * way. -+ */ -+struct aa_profile { -+ char *name; -+ struct list_head list; -+ struct aa_namespace *ns; -+ -+ int exec_table_size; -+ char **exec_table; -+ struct aa_dfa *file_rules; -+ struct { -+ int complain; -+ int audit; -+ } flags; -+ int isstale; -+ -+ kernel_cap_t set_caps; -+ kernel_cap_t capabilities; -+ kernel_cap_t audit_caps; -+ kernel_cap_t quiet_caps; -+ -+ struct kref count; -+ struct list_head task_contexts; -+ spinlock_t lock; -+ unsigned long int_flags; -+}; -+ -+extern struct list_head profile_ns_list; -+extern rwlock_t profile_ns_list_lock; -+extern struct mutex aa_interface_lock; -+ -+/** -+ * struct aa_task_context - primary label for confined tasks -+ * @profile: the current profile -+ * @previous_profile: profile the task may return to -+ * @cookie: magic value the task must know for returning to @previous_profile -+ * @list: list this aa_task_context is on -+ * @task: task that the aa_task_context confines -+ * @rcu: rcu head used when freeing the aa_task_context -+ * @caps_logged: caps that have previously generated log entries -+ * -+ * Contains the task's current profile (which could change due to -+ * change_hat). Plus the hat_magic needed during change_hat. -+ */ -+struct aa_task_context { -+ struct aa_profile *profile; -+ struct aa_profile *previous_profile; -+ u64 cookie; -+ struct list_head list; -+ struct task_struct *task; -+ struct rcu_head rcu; -+ kernel_cap_t caps_logged; -+}; -+ -+extern struct aa_namespace *default_namespace; -+ -+/* aa_audit - AppArmor auditing structure -+ * Structure is populated by access control code and passed to aa_audit which -+ * provides for a single point of logging. -+ */ -+ -+struct aa_audit { -+ const char *operation; -+ gfp_t gfp_mask; -+ const char *info; -+ const char *name; -+ const char *name2; -+ const char *name3; -+ int request_mask, denied_mask, audit_mask; -+ struct iattr *iattr; -+ pid_t task, parent; -+ int error_code; -+}; -+ -+/* Flags for the permission check functions */ -+#define AA_CHECK_FD 1 /* coming from a file descriptor */ -+#define AA_CHECK_DIR 2 /* file type is directory */ -+ -+/* lock subtypes so lockdep does not raise false dependencies */ -+enum aa_lock_class { -+ aa_lock_normal, -+ aa_lock_nested, -+ aa_lock_task_release -+}; -+ -+/* main.c */ -+extern int alloc_default_namespace(void); -+extern void free_default_namespace(void); -+extern int aa_audit_message(struct aa_profile *profile, struct aa_audit *sa, -+ int type); -+void aa_audit_hint(struct aa_profile *profile, struct aa_audit *sa); -+void aa_audit_status(struct aa_profile *profile, struct aa_audit *sa); -+int aa_audit_reject(struct aa_profile *profile, struct aa_audit *sa); -+extern int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp, -+ const char *); -+extern int aa_audit(struct aa_profile *profile, struct aa_audit *); -+ -+extern int aa_attr(struct aa_profile *profile, struct dentry *dentry, -+ struct vfsmount *mnt, struct iattr *iattr); -+extern int aa_perm_xattr(struct aa_profile *profile, const char *operation, -+ struct dentry *dentry, struct vfsmount *mnt, -+ int mask, int check); -+extern int aa_capability(struct aa_task_context *cxt, int cap); -+extern int aa_perm(struct aa_profile *profile, const char *operation, -+ struct dentry *dentry, struct vfsmount *mnt, int mask, -+ int check); -+extern int aa_perm_dir(struct aa_profile *profile, const char *operation, -+ struct dentry *dentry, struct vfsmount *mnt, -+ int mask); -+extern int aa_perm_path(struct aa_profile *, const char *operation, -+ const char *name, int mask, uid_t uid); -+extern int aa_link(struct aa_profile *profile, -+ struct dentry *link, struct vfsmount *link_mnt, -+ struct dentry *target, struct vfsmount *target_mnt); -+extern int aa_clone(struct task_struct *task); -+extern int aa_register(struct linux_binprm *bprm); -+extern void aa_release(struct task_struct *task); -+extern int aa_change_hat(const char *id, u64 hat_magic); -+extern int aa_change_profile(const char *ns_name, const char *name); -+extern struct aa_profile *__aa_replace_profile(struct task_struct *task, -+ struct aa_profile *profile); -+extern struct aa_task_context *lock_task_and_profiles(struct task_struct *task, -+ struct aa_profile *profile); -+extern void unlock_task_and_profiles(struct task_struct *task, -+ struct aa_task_context *cxt, -+ struct aa_profile *profile); -+extern void aa_change_task_context(struct task_struct *task, -+ struct aa_task_context *new_cxt, -+ struct aa_profile *profile, u64 cookie, -+ struct aa_profile *previous_profile); -+extern int aa_may_ptrace(struct aa_task_context *cxt, -+ struct aa_profile *tracee); -+ -+/* lsm.c */ -+extern int apparmor_initialized; -+extern void info_message(const char *str); -+extern void apparmor_disable(void); -+ -+/* list.c */ -+extern struct aa_namespace *__aa_find_namespace(const char *name, -+ struct list_head *list); -+extern struct aa_profile *__aa_find_profile(const char *name, -+ struct list_head *list); -+extern void aa_profile_ns_list_release(void); -+ -+/* module_interface.c */ -+extern ssize_t aa_add_profile(void *, size_t); -+extern ssize_t aa_replace_profile(void *, size_t); -+extern ssize_t aa_remove_profile(char *, size_t); -+extern struct aa_namespace *alloc_aa_namespace(char *name); -+extern void free_aa_namespace(struct aa_namespace *ns); -+extern void free_aa_namespace_kref(struct kref *kref); -+extern struct aa_profile *alloc_aa_profile(void); -+extern void free_aa_profile(struct aa_profile *profile); -+extern void free_aa_profile_kref(struct kref *kref); -+extern void aa_unconfine_tasks(struct aa_profile *profile); -+ -+/* procattr.c */ -+extern int aa_getprocattr(struct aa_profile *profile, char **string, -+ unsigned *len); -+extern int aa_setprocattr_changehat(char *args); -+extern int aa_setprocattr_changeprofile(char *args); -+extern int aa_setprocattr_setprofile(struct task_struct *task, char *args); -+ -+/* apparmorfs.c */ -+extern int create_apparmorfs(void); -+extern void destroy_apparmorfs(void); -+ -+/* match.c */ -+extern struct aa_dfa *aa_match_alloc(void); -+extern void aa_match_free(struct aa_dfa *dfa); -+extern int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size); -+extern int verify_dfa(struct aa_dfa *dfa); -+extern unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str, int *); -+extern unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start, -+ const char *str); -+extern unsigned int aa_match_state(struct aa_dfa *dfa, unsigned int start, -+ const char *str, unsigned int *final); -+extern unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, -+ unsigned int start); -+ -+#endif /* __APPARMOR_H */ ---- /dev/null -+++ b/security/apparmor/apparmorfs.c -@@ -0,0 +1,280 @@ -+/* -+ * Copyright (C) 1998-2007 Novell/SUSE -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation, version 2 of the -+ * License. -+ * -+ * AppArmor filesystem (part of securityfs) -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "apparmor.h" -+#include "inline.h" -+ -+static char *aa_simple_write_to_buffer(const char __user *userbuf, -+ size_t alloc_size, size_t copy_size, -+ loff_t *pos, const char *operation) -+{ -+ struct aa_profile *profile; -+ char *data; -+ -+ if (*pos != 0) { -+ /* only writes from pos 0, that is complete writes */ -+ data = ERR_PTR(-ESPIPE); -+ goto out; -+ } -+ -+ /* -+ * Don't allow confined processes to load/replace/remove profiles. -+ * No sane person would add rules allowing this to a profile -+ * but we enforce the restriction anyways. -+ */ -+ profile = aa_get_profile(current); -+ if (profile) { -+ struct aa_audit sa; -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = operation; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.error_code = -EACCES; -+ data = ERR_PTR(aa_audit_reject(profile, &sa)); -+ aa_put_profile(profile); -+ goto out; -+ } -+ -+ data = vmalloc(alloc_size); -+ if (data == NULL) { -+ data = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ if (copy_from_user(data, userbuf, copy_size)) { -+ vfree(data); -+ data = ERR_PTR(-EFAULT); -+ goto out; -+ } -+ -+out: -+ return data; -+} -+ -+/* apparmor/profiles */ -+extern struct seq_operations apparmorfs_profiles_op; -+ -+static int aa_profiles_open(struct inode *inode, struct file *file) -+{ -+ return seq_open(file, &apparmorfs_profiles_op); -+} -+ -+ -+static int aa_profiles_release(struct inode *inode, struct file *file) -+{ -+ return seq_release(inode, file); -+} -+ -+static struct file_operations apparmorfs_profiles_fops = { -+ .open = aa_profiles_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = aa_profiles_release, -+}; -+ -+/* apparmor/matching */ -+static ssize_t aa_matching_read(struct file *file, char __user *buf, -+ size_t size, loff_t *ppos) -+{ -+ const char *matching = "pattern=aadfa audit perms=rwxamlk/ user::other"; -+ -+ return simple_read_from_buffer(buf, size, ppos, matching, -+ strlen(matching)); -+} -+ -+static struct file_operations apparmorfs_matching_fops = { -+ .read = aa_matching_read, -+}; -+ -+/* apparmor/features */ -+static ssize_t aa_features_read(struct file *file, char __user *buf, -+ size_t size, loff_t *ppos) -+{ -+ const char *features = "file=3.0 capability=2.0 network=1.0 " -+ "change_hat=1.4 change_profile=1.0 " -+ "aanamespaces=1.0"; -+ -+ return simple_read_from_buffer(buf, size, ppos, features, -+ strlen(features)); -+} -+ -+static struct file_operations apparmorfs_features_fops = { -+ .read = aa_features_read, -+}; -+ -+/* apparmor/.load */ -+static ssize_t aa_profile_load(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos) -+{ -+ char *data; -+ ssize_t error; -+ -+ data = aa_simple_write_to_buffer(buf, size, size, pos, "profile_load"); -+ -+ error = PTR_ERR(data); -+ if (!IS_ERR(data)) { -+ error = aa_add_profile(data, size); -+ vfree(data); -+ } -+ -+ return error; -+} -+ -+ -+static struct file_operations apparmorfs_profile_load = { -+ .write = aa_profile_load -+}; -+ -+/* apparmor/.replace */ -+static ssize_t aa_profile_replace(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos) -+{ -+ char *data; -+ ssize_t error; -+ -+ data = aa_simple_write_to_buffer(buf, size, size, pos, -+ "profile_replace"); -+ -+ error = PTR_ERR(data); -+ if (!IS_ERR(data)) { -+ error = aa_replace_profile(data, size); -+ vfree(data); -+ } -+ -+ return error; -+} -+ -+ -+static struct file_operations apparmorfs_profile_replace = { -+ .write = aa_profile_replace -+}; -+ -+/* apparmor/.remove */ -+static ssize_t aa_profile_remove(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos) -+{ -+ char *data; -+ ssize_t error; -+ -+ /* -+ * aa_remove_profile needs a null terminated string so 1 extra -+ * byte is allocated and the copied data is null terminated. -+ */ -+ data = aa_simple_write_to_buffer(buf, size + 1, size, pos, -+ "profile_remove"); -+ -+ error = PTR_ERR(data); -+ if (!IS_ERR(data)) { -+ data[size] = 0; -+ error = aa_remove_profile(data, size); -+ vfree(data); -+ } -+ -+ return error; -+} -+ -+static struct file_operations apparmorfs_profile_remove = { -+ .write = aa_profile_remove -+}; -+ -+static struct dentry *apparmor_dentry; -+ -+static void aafs_remove(const char *name) -+{ -+ struct dentry *dentry; -+ -+ dentry = lookup_one_len(name, apparmor_dentry, strlen(name)); -+ if (!IS_ERR(dentry)) { -+ securityfs_remove(dentry); -+ dput(dentry); -+ } -+} -+ -+static int aafs_create(const char *name, int mask, struct file_operations *fops) -+{ -+ struct dentry *dentry; -+ -+ dentry = securityfs_create_file(name, S_IFREG | mask, apparmor_dentry, -+ NULL, fops); -+ -+ return IS_ERR(dentry) ? PTR_ERR(dentry) : 0; -+} -+ -+void destroy_apparmorfs(void) -+{ -+ if (apparmor_dentry) { -+ aafs_remove(".remove"); -+ aafs_remove(".replace"); -+ aafs_remove(".load"); -+ aafs_remove("matching"); -+ aafs_remove("features"); -+ aafs_remove("profiles"); -+ securityfs_remove(apparmor_dentry); -+ apparmor_dentry = NULL; -+ } -+} -+ -+int create_apparmorfs(void) -+{ -+ int error; -+ -+ if (!apparmor_initialized) -+ return 0; -+ -+ if (apparmor_dentry) { -+ AA_ERROR("%s: AppArmor securityfs already exists\n", -+ __FUNCTION__); -+ return -EEXIST; -+ } -+ -+ apparmor_dentry = securityfs_create_dir("apparmor", NULL); -+ if (IS_ERR(apparmor_dentry)) { -+ error = PTR_ERR(apparmor_dentry); -+ apparmor_dentry = NULL; -+ goto error; -+ } -+ error = aafs_create("profiles", 0440, &apparmorfs_profiles_fops); -+ if (error) -+ goto error; -+ error = aafs_create("matching", 0444, &apparmorfs_matching_fops); -+ if (error) -+ goto error; -+ error = aafs_create("features", 0444, &apparmorfs_features_fops); -+ if (error) -+ goto error; -+ error = aafs_create(".load", 0640, &apparmorfs_profile_load); -+ if (error) -+ goto error; -+ error = aafs_create(".replace", 0640, &apparmorfs_profile_replace); -+ if (error) -+ goto error; -+ error = aafs_create(".remove", 0640, &apparmorfs_profile_remove); -+ if (error) -+ goto error; -+ -+ /* Report that AppArmor fs is enabled */ -+ info_message("AppArmor Filesystem Enabled"); -+ return 0; -+ -+error: -+ destroy_apparmorfs(); -+ AA_ERROR("Error creating AppArmor securityfs\n"); -+ apparmor_disable(); -+ return error; -+} -+ -+fs_initcall(create_apparmorfs); -+ ---- /dev/null -+++ b/security/apparmor/inline.h -@@ -0,0 +1,250 @@ -+/* -+ * Copyright (C) 1998-2007 Novell/SUSE -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation, version 2 of the -+ * License. -+ */ -+ -+#ifndef __INLINE_H -+#define __INLINE_H -+ -+#include -+ -+#include "match.h" -+ -+static inline int mediated_filesystem(struct inode *inode) -+{ -+ return !(inode->i_sb->s_flags & MS_NOUSER); -+} -+ -+static inline struct aa_task_context *aa_task_context(struct task_struct *task) -+{ -+ return (struct aa_task_context *) rcu_dereference(task->security); -+} -+ -+static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns) -+{ -+ if (ns) -+ kref_get(&(ns->count)); -+ -+ return ns; -+} -+ -+static inline void aa_put_namespace(struct aa_namespace *ns) -+{ -+ if (ns) -+ kref_put(&ns->count, free_aa_namespace_kref); -+} -+ -+ -+static inline struct aa_namespace *aa_find_namespace(const char *name) -+{ -+ struct aa_namespace *ns = NULL; -+ -+ read_lock(&profile_ns_list_lock); -+ ns = aa_get_namespace(__aa_find_namespace(name, &profile_ns_list)); -+ read_unlock(&profile_ns_list_lock); -+ -+ return ns; -+} -+ -+/** -+ * aa_dup_profile - increment refcount on profile @p -+ * @p: profile -+ */ -+static inline struct aa_profile *aa_dup_profile(struct aa_profile *p) -+{ -+ if (p) -+ kref_get(&(p->count)); -+ -+ return p; -+} -+ -+/** -+ * aa_put_profile - decrement refcount on profile @p -+ * @p: profile -+ */ -+static inline void aa_put_profile(struct aa_profile *p) -+{ -+ if (p) -+ kref_put(&p->count, free_aa_profile_kref); -+} -+ -+static inline struct aa_profile *aa_get_profile(struct task_struct *task) -+{ -+ struct aa_task_context *cxt; -+ struct aa_profile *profile = NULL; -+ -+ rcu_read_lock(); -+ cxt = aa_task_context(task); -+ if (cxt) { -+ profile = cxt->profile; -+ aa_dup_profile(profile); -+ } -+ rcu_read_unlock(); -+ -+ return profile; -+} -+ -+static inline struct aa_profile *aa_find_profile(struct aa_namespace *ns, -+ const char *name) -+{ -+ struct aa_profile *profile = NULL; -+ -+ read_lock(&ns->lock); -+ profile = aa_dup_profile(__aa_find_profile(name, &ns->profiles)); -+ read_unlock(&ns->lock); -+ -+ return profile; -+} -+ -+static inline struct aa_task_context *aa_alloc_task_context(gfp_t flags) -+{ -+ struct aa_task_context *cxt; -+ -+ cxt = kzalloc(sizeof(*cxt), flags); -+ if (cxt) { -+ INIT_LIST_HEAD(&cxt->list); -+ INIT_RCU_HEAD(&cxt->rcu); -+ } -+ -+ return cxt; -+} -+ -+static inline void aa_free_task_context(struct aa_task_context *cxt) -+{ -+ if (cxt) { -+ aa_put_profile(cxt->profile); -+ aa_put_profile(cxt->previous_profile); -+ kfree(cxt); -+ } -+} -+ -+/** -+ * lock_profile - lock a profile -+ * @profile: the profile to lock -+ * -+ * While the profile is locked, local interrupts are disabled. This also -+ * gives us RCU reader safety. -+ */ -+static inline void lock_profile_nested(struct aa_profile *profile, -+ enum aa_lock_class lock_class) -+{ -+ /* -+ * Lock the profile. -+ * -+ * Need to disable interrupts here because this lock is used in -+ * the task_free_security hook, which may run in RCU context. -+ */ -+ if (profile) -+ spin_lock_irqsave_nested(&profile->lock, profile->int_flags, -+ lock_class); -+} -+ -+static inline void lock_profile(struct aa_profile *profile) -+{ -+ lock_profile_nested(profile, aa_lock_normal); -+} -+ -+/** -+ * unlock_profile - unlock a profile -+ * @profile: the profile to unlock -+ */ -+static inline void unlock_profile(struct aa_profile *profile) -+{ -+ /* Unlock the profile. */ -+ if (profile) -+ spin_unlock_irqrestore(&profile->lock, profile->int_flags); -+} -+ -+/** -+ * lock_both_profiles - lock two profiles in a deadlock-free way -+ * @profile1: profile to lock (may be NULL) -+ * @profile2: profile to lock (may be NULL) -+ * -+ * The order in which profiles are passed into lock_both_profiles() / -+ * unlock_both_profiles() does not matter. -+ * While the profile is locked, local interrupts are disabled. This also -+ * gives us RCU reader safety. -+ */ -+static inline void lock_both_profiles(struct aa_profile *profile1, -+ struct aa_profile *profile2) -+{ -+ /* -+ * Lock the two profiles. -+ * -+ * We need to disable interrupts because the profile locks are -+ * used in the task_free_security hook, which may run in RCU -+ * context. -+ * -+ * Do not nest spin_lock_irqsave()/spin_unlock_irqresore(): -+ * interrupts only need to be turned off once. -+ */ -+ if (!profile1 || profile1 == profile2) { -+ if (profile2) -+ spin_lock_irqsave_nested(&profile2->lock, -+ profile2->int_flags, -+ aa_lock_normal); -+ } else if (profile1 > profile2) { -+ /* profile1 cannot be NULL here. */ -+ spin_lock_irqsave_nested(&profile1->lock, profile1->int_flags, -+ aa_lock_normal); -+ if (profile2) -+ spin_lock_nested(&profile2->lock, aa_lock_nested); -+ -+ } else { -+ /* profile2 cannot be NULL here. */ -+ spin_lock_irqsave_nested(&profile2->lock, profile2->int_flags, -+ aa_lock_normal); -+ spin_lock_nested(&profile1->lock, aa_lock_nested); -+ } -+} -+ -+/** -+ * unlock_both_profiles - unlock two profiles in a deadlock-free way -+ * @profile1: profile to unlock (may be NULL) -+ * @profile2: profile to unlock (may be NULL) -+ * -+ * The order in which profiles are passed into lock_both_profiles() / -+ * unlock_both_profiles() does not matter. -+ * While the profile is locked, local interrupts are disabled. This also -+ * gives us RCU reader safety. -+ */ -+static inline void unlock_both_profiles(struct aa_profile *profile1, -+ struct aa_profile *profile2) -+{ -+ /* Unlock the two profiles. */ -+ if (!profile1 || profile1 == profile2) { -+ if (profile2) -+ spin_unlock_irqrestore(&profile2->lock, -+ profile2->int_flags); -+ } else if (profile1 > profile2) { -+ /* profile1 cannot be NULL here. */ -+ if (profile2) -+ spin_unlock(&profile2->lock); -+ spin_unlock_irqrestore(&profile1->lock, profile1->int_flags); -+ } else { -+ /* profile2 cannot be NULL here. */ -+ spin_unlock(&profile1->lock); -+ spin_unlock_irqrestore(&profile2->lock, profile2->int_flags); -+ } -+} -+ -+static inline unsigned int aa_match(struct aa_dfa *dfa, const char *pathname, -+ int *audit_mask) -+{ -+ if (dfa) -+ return aa_dfa_match(dfa, pathname, audit_mask); -+ if (audit_mask) -+ *audit_mask = 0; -+ return 0; -+} -+ -+static inline int dfa_audit_mask(struct aa_dfa *dfa, unsigned int state) -+{ -+ return ACCEPT_TABLE2(dfa)[state]; -+} -+ -+#endif /* __INLINE_H__ */ ---- /dev/null -+++ b/security/apparmor/list.c -@@ -0,0 +1,156 @@ -+/* -+ * Copyright (C) 1998-2007 Novell/SUSE -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation, version 2 of the -+ * License. -+ * -+ * AppArmor Profile List Management -+ */ -+ -+#include -+#include "apparmor.h" -+#include "inline.h" -+ -+/* list of profile namespaces and lock */ -+LIST_HEAD(profile_ns_list); -+rwlock_t profile_ns_list_lock = RW_LOCK_UNLOCKED; -+ -+/** -+ * __aa_find_namespace - look up a profile namespace on the namespace list -+ * @name: name of namespace to find -+ * @head: list to search -+ * -+ * Returns a pointer to the namespace on the list, or NULL if no namespace -+ * called @name exists. The caller must hold the profile_ns_list_lock. -+ */ -+struct aa_namespace *__aa_find_namespace(const char *name, -+ struct list_head *head) -+{ -+ struct aa_namespace *ns; -+ -+ list_for_each_entry(ns, head, list) { -+ if (!strcmp(ns->name, name)) -+ return ns; -+ } -+ -+ return NULL; -+} -+ -+/** -+ * __aa_find_profile - look up a profile on the profile list -+ * @name: name of profile to find -+ * @head: list to search -+ * -+ * Returns a pointer to the profile on the list, or NULL if no profile -+ * called @name exists. The caller must hold the profile_list_lock. -+ */ -+struct aa_profile *__aa_find_profile(const char *name, struct list_head *head) -+{ -+ struct aa_profile *profile; -+ -+ list_for_each_entry(profile, head, list) { -+ if (!strcmp(profile->name, name)) -+ return profile; -+ } -+ -+ return NULL; -+} -+ -+static void aa_profile_list_release(struct list_head *head) -+{ -+ struct aa_profile *profile, *tmp; -+ list_for_each_entry_safe(profile, tmp, head, list) { -+ /* Remove the profile from each task context it is on. */ -+ lock_profile(profile); -+ profile->isstale = 1; -+ aa_unconfine_tasks(profile); -+ list_del_init(&profile->list); -+ unlock_profile(profile); -+ aa_put_profile(profile); -+ } -+} -+ -+/** -+ * aa_profilelist_release - Remove all profiles from profile_list -+ */ -+void aa_profile_ns_list_release(void) -+{ -+ struct aa_namespace *ns, *tmp; -+ -+ /* Remove and release all the profiles on namespace profile lists. */ -+ write_lock(&profile_ns_list_lock); -+ list_for_each_entry_safe(ns, tmp, &profile_ns_list, list) { -+ write_lock(&ns->lock); -+ aa_profile_list_release(&ns->profiles); -+ list_del_init(&ns->list); -+ write_unlock(&ns->lock); -+ aa_put_namespace(ns); -+ } -+ write_unlock(&profile_ns_list_lock); -+} -+ -+static void *p_start(struct seq_file *f, loff_t *pos) -+{ -+ struct aa_namespace *ns; -+ struct aa_profile *profile; -+ loff_t l = *pos; -+ read_lock(&profile_ns_list_lock); -+ if (l--) -+ return NULL; -+ list_for_each_entry(ns, &profile_ns_list, list) { -+ read_lock(&ns->lock); -+ list_for_each_entry(profile, &ns->profiles, list) -+ return profile; -+ read_unlock(&ns->lock); -+ } -+ return NULL; -+} -+ -+static void *p_next(struct seq_file *f, void *p, loff_t *pos) -+{ -+ struct aa_profile *profile = (struct aa_profile *) p; -+ struct list_head *lh = profile->list.next; -+ struct aa_namespace *ns; -+ (*pos)++; -+ if (lh != &profile->ns->profiles) -+ return list_entry(lh, struct aa_profile, list); -+ -+ lh = profile->ns->list.next; -+ read_unlock(&profile->ns->lock); -+ while (lh != &profile_ns_list) { -+ ns = list_entry(lh, struct aa_namespace, list); -+ read_lock(&ns->lock); -+ list_for_each_entry(profile, &ns->profiles, list) -+ return profile; -+ read_unlock(&ns->lock); -+ lh = ns->list.next; -+ } -+ return NULL; -+} -+ -+static void p_stop(struct seq_file *f, void *v) -+{ -+ read_unlock(&profile_ns_list_lock); -+} -+ -+static int seq_show_profile(struct seq_file *f, void *v) -+{ -+ struct aa_profile *profile = (struct aa_profile *)v; -+ if (profile->ns == default_namespace) -+ seq_printf(f, "%s (%s)\n", profile->name, -+ PROFILE_COMPLAIN(profile) ? "complain" : "enforce"); -+ else -+ seq_printf(f, ":%s:%s (%s)\n", profile->ns->name, profile->name, -+ PROFILE_COMPLAIN(profile) ? "complain" : "enforce"); -+ return 0; -+} -+ -+/* Used in apparmorfs.c */ -+struct seq_operations apparmorfs_profiles_op = { -+ .start = p_start, -+ .next = p_next, -+ .stop = p_stop, -+ .show = seq_show_profile, -+}; ---- /dev/null -+++ b/security/apparmor/locking.txt -@@ -0,0 +1,68 @@ -+Locking in AppArmor -+=================== -+ -+Lock hierarchy: -+ -+ aa_interface_lock -+ profile_list_lock -+ aa_profile->lock -+ task_lock() -+ -+ -+Which lock protects what? -+ -+ /-----------------------+-------------------------------\ -+ | Variable | Lock | -+ >-----------------------+-------------------------------< -+ | profile_list | profile_list_lock | -+ +-----------------------+-------------------------------+ -+ | aa_profile | (reference count) | -+ +-----------------------+-------------------------------+ -+ | aa_profile-> | aa_profile->lock | -+ | isstale, | | -+ | task_contexts | | -+ +-----------------------+-------------------------------+ -+ | task_struct->security | read: RCU | -+ | | write: task_lock() | -+ +-----------------------+-------------------------------+ -+ | aa_profile->sub | handle on the profile (list | -+ | | is never modified) | -+ \-----------------------+-------------------------------/ -+ -+(Obviously, the list_heads embedded in data structures are always -+protected with the lock that also protects the list.) -+ -+When moving a task context from one profile to another, we grab both -+profile locks with lock_both_profiles(). This ensures that both locks -+are always taken in the same order, and so we won't deadlock. -+ -+Since task_struct->security is RCU protected the aa_task_struct it -+references is only guarenteed to exist for the rcu cycle. Where -+aa_task_context->profile is needed in blocking operations the -+profile's reference count is incremented and the profile reference -+is used. -+ -+Profiles on profile_list are never stale: when a profile becomes stale, -+it is removed from profile_list at the same time (under profile_list_lock -+and aa_profile->lock). -+ -+The aa_interface_lock is taken whenever user-space modifies the profile -+list, and can sleep. This ensures that profile loading/replacement/removal -+won't race with itself. We release the profile_list_lock as soon as -+possible to avoid stalling exec during profile loading/replacement/removal. -+ -+AppArmor uses lock subtyping to avoid false positives from lockdep. The -+profile lock is often taken nested, but it is guaranteed to be in a lock -+safe order and not the same lock when done, so it is safe. -+ -+A third lock type (aa_lock_task_release) is given to the profile lock -+when it is taken in soft irq context during task release (aa_release). -+This is to avoid a false positive between the task lock and the profile -+lock. In task context the profile lock wraps the task lock with irqs -+off, but the kernel takes the task lock with irqs enabled. This won't -+result in a deadlock because for a deadlock to occur the kernel must -+take dead task A's lock (irqs on), the rcu callback hook freeing -+dead task A must be run and AppArmor must be changing the profile on -+dead task A. The kernel should not be taking a dead task's task_lock -+at the same time the task is being freed by task rcu cleanup other wise -+the task would not be out of its quiescent period. ---- /dev/null -+++ b/security/apparmor/procattr.c -@@ -0,0 +1,195 @@ -+/* -+ * Copyright (C) 1998-2007 Novell/SUSE -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation, version 2 of the -+ * License. -+ * -+ * AppArmor /proc/pid/attr handling -+ */ -+ -+#include "apparmor.h" -+#include "inline.h" -+ -+int aa_getprocattr(struct aa_profile *profile, char **string, unsigned *len) -+{ -+ char *str; -+ -+ if (profile) { -+ const char *mode_str = PROFILE_COMPLAIN(profile) ? -+ " (complain)" : " (enforce)"; -+ int mode_len, name_len, ns_len = 0; -+ -+ mode_len = strlen(mode_str); -+ name_len = strlen(profile->name); -+ if (profile->ns != default_namespace) -+ ns_len = strlen(profile->ns->name) + 2; -+ *len = mode_len + ns_len + name_len + 1; -+ str = kmalloc(*len, GFP_ATOMIC); -+ if (!str) -+ return -ENOMEM; -+ -+ if (ns_len) { -+ *str++ = ':'; -+ memcpy(str, profile->ns->name, ns_len - 2); -+ str += ns_len - 2; -+ *str++ = ':'; -+ } -+ memcpy(str, profile->name, name_len); -+ str += name_len; -+ memcpy(str, mode_str, mode_len); -+ str += mode_len; -+ *str++ = '\n'; -+ str -= *len; -+ } else { -+ const char *unconfined_str = "unconfined\n"; -+ -+ *len = strlen(unconfined_str); -+ str = kmalloc(*len, GFP_ATOMIC); -+ if (!str) -+ return -ENOMEM; -+ -+ memcpy(str, unconfined_str, *len); -+ } -+ *string = str; -+ -+ return 0; -+} -+ -+static char *split_token_from_name(const char *op, char *args, u64 *cookie) -+{ -+ char *name; -+ -+ *cookie = simple_strtoull(args, &name, 16); -+ if ((name == args) || *name != '^') { -+ AA_ERROR("%s: Invalid input '%s'", op, args); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ name++; /* skip ^ */ -+ if (!*name) -+ name = NULL; -+ return name; -+} -+ -+int aa_setprocattr_changehat(char *args) -+{ -+ char *hat; -+ u64 cookie; -+ -+ hat = split_token_from_name("change_hat", args, &cookie); -+ if (IS_ERR(hat)) -+ return PTR_ERR(hat); -+ -+ if (!hat && !cookie) { -+ AA_ERROR("change_hat: Invalid input, NULL hat and NULL magic"); -+ return -EINVAL; -+ } -+ -+ AA_DEBUG("%s: Magic 0x%llx Hat '%s'\n", -+ __FUNCTION__, cookie, hat ? hat : NULL); -+ -+ return aa_change_hat(hat, cookie); -+} -+ -+int aa_setprocattr_changeprofile(char *args) -+{ -+ char *name = args, *ns_name = NULL; -+ -+ if (name[0] == ':') { -+ char *split = strchr(&name[1], ':'); -+ if (split) { -+ *split = 0; -+ ns_name = &name[1]; -+ name = split + 1; -+ } -+ } -+ -+ return aa_change_profile(ns_name, name); -+} -+ -+int aa_setprocattr_setprofile(struct task_struct *task, char *args) -+{ -+ struct aa_profile *old_profile, *new_profile; -+ struct aa_namespace *ns; -+ struct aa_audit sa; -+ char *name, *ns_name = NULL; -+ -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "profile_set"; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.task = task->pid; -+ -+ AA_DEBUG("%s: current %d\n", -+ __FUNCTION__, current->pid); -+ -+ name = args; -+ if (args[0] != '/') { -+ char *split = strchr(args, ':'); -+ if (split) { -+ *split = 0; -+ ns_name = args; -+ name = split + 1; -+ } -+ } -+ if (ns_name) -+ ns = aa_find_namespace(ns_name); -+ else -+ ns = aa_get_namespace(default_namespace); -+ if (!ns) { -+ sa.name = ns_name; -+ sa.info = "unknown namespace"; -+ aa_audit_reject(NULL, &sa); -+ aa_put_namespace(ns); -+ return -EINVAL; -+ } -+ -+repeat: -+ if (strcmp(name, "unconfined") == 0) -+ new_profile = NULL; -+ else { -+ new_profile = aa_find_profile(ns, name); -+ if (!new_profile) { -+ sa.name = ns_name; -+ sa.name2 = name; -+ sa.info = "unknown profile"; -+ aa_audit_reject(NULL, &sa); -+ aa_put_namespace(ns); -+ return -EINVAL; -+ } -+ } -+ -+ old_profile = __aa_replace_profile(task, new_profile); -+ if (IS_ERR(old_profile)) { -+ int error; -+ -+ aa_put_profile(new_profile); -+ error = PTR_ERR(old_profile); -+ if (error == -ESTALE) -+ goto repeat; -+ aa_put_namespace(ns); -+ return error; -+ } -+ -+ if (new_profile) { -+ sa.name = ns_name; -+ sa.name2 = name; -+ sa.name3 = old_profile ? old_profile->name : -+ "unconfined"; -+ aa_audit_status(NULL, &sa); -+ } else { -+ if (old_profile) { -+ sa.name = "unconfined"; -+ sa.name2 = old_profile->name; -+ aa_audit_status(NULL, &sa); -+ } else { -+ sa.info = "task is unconfined"; -+ aa_audit_status(NULL, &sa); -+ } -+ } -+ aa_put_namespace(ns); -+ aa_put_profile(old_profile); -+ aa_put_profile(new_profile); -+ return 0; -+} diff --git a/kernel-patches/for-mainline/apparmor-module_interface.diff b/kernel-patches/for-mainline/apparmor-module_interface.diff deleted file mode 100644 index 39b9f1bb1..000000000 --- a/kernel-patches/for-mainline/apparmor-module_interface.diff +++ /dev/null @@ -1,1350 +0,0 @@ -From: John Johansen -Subject: AppArmor: Profile loading and manipulation, pathname matching - -Pathname matching, transition table loading, profile loading and -manipulation. - -Signed-off-by: John Johansen -Signed-off-by: Andreas Gruenbacher - ---- - security/apparmor/match.c | 364 ++++++++++++++ - security/apparmor/match.h | 87 +++ - security/apparmor/module_interface.c | 875 +++++++++++++++++++++++++++++++++++ - 3 files changed, 1326 insertions(+) - ---- /dev/null -+++ b/security/apparmor/match.c -@@ -0,0 +1,364 @@ -+/* -+ * Copyright (C) 2007 Novell/SUSE -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation, version 2 of the -+ * License. -+ * -+ * Regular expression transition table matching -+ */ -+ -+#include -+#include -+#include -+#include "apparmor.h" -+#include "match.h" -+#include "inline.h" -+ -+static struct table_header *unpack_table(void *blob, size_t bsize) -+{ -+ struct table_header *table = NULL; -+ struct table_header th; -+ size_t tsize; -+ -+ if (bsize < sizeof(struct table_header)) -+ goto out; -+ -+ th.td_id = be16_to_cpu(*(u16 *) (blob)); -+ th.td_flags = be16_to_cpu(*(u16 *) (blob + 2)); -+ th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8)); -+ blob += sizeof(struct table_header); -+ -+ if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 || -+ th.td_flags == YYTD_DATA8)) -+ goto out; -+ -+ tsize = table_size(th.td_lolen, th.td_flags); -+ if (bsize < tsize) -+ goto out; -+ -+ table = kmalloc(tsize, GFP_KERNEL); -+ if (table) { -+ *table = th; -+ if (th.td_flags == YYTD_DATA8) -+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen, -+ u8, byte_to_byte); -+ else if (th.td_flags == YYTD_DATA16) -+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen, -+ u16, be16_to_cpu); -+ else -+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen, -+ u32, be32_to_cpu); -+ } -+ -+out: -+ return table; -+} -+ -+int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size) -+{ -+ int hsize, i; -+ int error = -ENOMEM; -+ -+ /* get dfa table set header */ -+ if (size < sizeof(struct table_set_header)) -+ goto fail; -+ -+ if (ntohl(*(u32 *)blob) != YYTH_MAGIC) -+ goto fail; -+ -+ hsize = ntohl(*(u32 *)(blob + 4)); -+ if (size < hsize) -+ goto fail; -+ -+ blob += hsize; -+ size -= hsize; -+ -+ error = -EPROTO; -+ while (size > 0) { -+ struct table_header *table; -+ table = unpack_table(blob, size); -+ if (!table) -+ goto fail; -+ -+ switch(table->td_id) { -+ case YYTD_ID_ACCEPT: -+ case YYTD_ID_ACCEPT2: -+ case YYTD_ID_BASE: -+ dfa->tables[table->td_id - 1] = table; -+ if (table->td_flags != YYTD_DATA32) -+ goto fail; -+ break; -+ case YYTD_ID_DEF: -+ case YYTD_ID_NXT: -+ case YYTD_ID_CHK: -+ dfa->tables[table->td_id - 1] = table; -+ if (table->td_flags != YYTD_DATA16) -+ goto fail; -+ break; -+ case YYTD_ID_EC: -+ dfa->tables[table->td_id - 1] = table; -+ if (table->td_flags != YYTD_DATA8) -+ goto fail; -+ break; -+ default: -+ kfree(table); -+ goto fail; -+ } -+ -+ blob += table_size(table->td_lolen, table->td_flags); -+ size -= table_size(table->td_lolen, table->td_flags); -+ } -+ -+ return 0; -+ -+fail: -+ for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) { -+ if (dfa->tables[i]) { -+ kfree(dfa->tables[i]); -+ dfa->tables[i] = NULL; -+ } -+ } -+ return error; -+} -+ -+/** -+ * verify_dfa - verify that all the transitions and states in the dfa tables -+ * are in bounds. -+ * @dfa: dfa to test -+ * -+ * assumes dfa has gone through the verification done by unpacking -+ */ -+int verify_dfa(struct aa_dfa *dfa) -+{ -+ size_t i, state_count, trans_count; -+ int error = -EPROTO; -+ -+ /* check that required tables exist */ -+ if (!(dfa->tables[YYTD_ID_ACCEPT - 1] && -+ dfa->tables[YYTD_ID_ACCEPT2 - 1] && -+ dfa->tables[YYTD_ID_DEF - 1] && -+ dfa->tables[YYTD_ID_BASE - 1] && -+ dfa->tables[YYTD_ID_NXT - 1] && -+ dfa->tables[YYTD_ID_CHK - 1])) -+ goto out; -+ -+ /* accept.size == default.size == base.size */ -+ state_count = dfa->tables[YYTD_ID_BASE - 1]->td_lolen; -+ if (!(state_count == dfa->tables[YYTD_ID_DEF - 1]->td_lolen && -+ state_count == dfa->tables[YYTD_ID_ACCEPT - 1]->td_lolen && -+ state_count == dfa->tables[YYTD_ID_ACCEPT2 - 1]->td_lolen)) -+ goto out; -+ -+ /* next.size == chk.size */ -+ trans_count = dfa->tables[YYTD_ID_NXT - 1]->td_lolen; -+ if (trans_count != dfa->tables[YYTD_ID_CHK - 1]->td_lolen) -+ goto out; -+ -+ /* if equivalence classes then its table size must be 256 */ -+ if (dfa->tables[YYTD_ID_EC - 1] && -+ dfa->tables[YYTD_ID_EC - 1]->td_lolen != 256) -+ goto out; -+ -+ for (i = 0; i < state_count; i++) { -+ if (DEFAULT_TABLE(dfa)[i] >= state_count) -+ goto out; -+ if (BASE_TABLE(dfa)[i] >= trans_count + 256) -+ goto out; -+ } -+ -+ for (i = 0; i < trans_count ; i++) { -+ if (NEXT_TABLE(dfa)[i] >= state_count) -+ goto out; -+ if (CHECK_TABLE(dfa)[i] >= state_count) -+ goto out; -+ } -+ -+ /* verify accept permissions */ -+ for (i = 0; i < state_count; i++) { -+ int mode = ACCEPT_TABLE(dfa)[i]; -+ -+ if (mode & ~AA_VALID_PERM_MASK) -+ goto out; -+ if (ACCEPT_TABLE2(dfa)[i] & ~AA_VALID_PERM2_MASK) -+ goto out; -+ -+ /* if any exec modifier is set MAY_EXEC must be set */ -+ if ((mode & AA_USER_EXEC_TYPE) && !(mode & AA_USER_EXEC)) -+ goto out; -+ if ((mode & AA_OTHER_EXEC_TYPE) && !(mode & AA_OTHER_EXEC)) -+ goto out; -+ } -+ -+ error = 0; -+out: -+ return error; -+} -+ -+struct aa_dfa *aa_match_alloc(void) -+{ -+ return kzalloc(sizeof(struct aa_dfa), GFP_KERNEL); -+} -+ -+void aa_match_free(struct aa_dfa *dfa) -+{ -+ if (dfa) { -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) -+ kfree(dfa->tables[i]); -+ } -+ kfree(dfa); -+} -+ -+/** -+ * aa_dfa_next_state_len - traverse @dfa to find state @str stops at -+ * @dfa: the dfa to match @str against -+ * @start: the state of the dfa to start matching in -+ * @str: the string of bytes to match against the dfa -+ * @len: length of the string of bytes to match -+ * -+ * aa_dfa_next_state will match @str against the dfa and return the state it -+ * finished matching in. The final state can be used to look up the accepting -+ * label, or as the start state of a continuing match. -+ * -+ * aa_dfa_next_state could be implement using this function by doing -+ * return aa_dfa_next_state_len(dfa, start, str, strlen(str)); -+ * but that would require traversing the string twice and be slightly -+ * slower. -+ */ -+unsigned int aa_dfa_next_state_len(struct aa_dfa *dfa, unsigned int start, -+ const char *str, int len) -+{ -+ u16 *def = DEFAULT_TABLE(dfa); -+ u32 *base = BASE_TABLE(dfa); -+ u16 *next = NEXT_TABLE(dfa); -+ u16 *check = CHECK_TABLE(dfa); -+ unsigned int state = start, pos; -+ -+ if (state == 0) -+ return 0; -+ -+ /* current state is , matching character *str */ -+ if (dfa->tables[YYTD_ID_EC - 1]) { -+ u8 *equiv = EQUIV_TABLE(dfa); -+ for (; len; len--) { -+ pos = base[state] + equiv[(u8)*str++]; -+ if (check[pos] == state) -+ state = next[pos]; -+ else -+ state = def[state]; -+ } -+ } else { -+ for (; len; len--) { -+ pos = base[state] + (u8)*str++; -+ if (check[pos] == state) -+ state = next[pos]; -+ else -+ state = def[state]; -+ } -+ } -+ return state; -+} -+ -+/** -+ * aa_dfa_next_state - traverse @dfa to find state @str stops at -+ * @dfa: the dfa to match @str against -+ * @start: the state of the dfa to start matching in -+ * @str: the null terminated string of bytes to match against the dfa -+ * -+ * aa_dfa_next_state will match @str against the dfa and return the state it -+ * finished matching in. The final state can be used to look up the accepting -+ * label, or as the start state of a continuing match. -+ */ -+unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start, -+ const char *str) -+{ -+ u16 *def = DEFAULT_TABLE(dfa); -+ u32 *base = BASE_TABLE(dfa); -+ u16 *next = NEXT_TABLE(dfa); -+ u16 *check = CHECK_TABLE(dfa); -+ unsigned int state = start, pos; -+ -+ if (state == 0) -+ return 0; -+ -+ /* current state is , matching character *str */ -+ if (dfa->tables[YYTD_ID_EC - 1]) { -+ u8 *equiv = EQUIV_TABLE(dfa); -+ while (*str) { -+ pos = base[state] + equiv[(u8)*str++]; -+ if (check[pos] == state) -+ state = next[pos]; -+ else -+ state = def[state]; -+ } -+ } else { -+ while (*str) { -+ pos = base[state] + (u8)*str++; -+ if (check[pos] == state) -+ state = next[pos]; -+ else -+ state = def[state]; -+ } -+ } -+ return state; -+} -+ -+/** -+ * aa_dfa_null_transition - step to next state after null character -+ * @dfa: the dfa to match against -+ * @start: the state of the dfa to start matching in -+ * -+ * aa_dfa_null_transition transitions to the next state after a null -+ * character which is not used in standard matching and is only -+ * used to seperate pairs. -+ */ -+unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start) -+{ -+ return aa_dfa_next_state_len(dfa, start, "", 1); -+} -+ -+/** -+ * aa_dfa_match - find accept perm for @str in @dfa -+ * @dfa: the dfa to match @str against -+ * @str: the string to match against the dfa -+ * @audit_mask: the audit_mask for the final state -+ * -+ * aa_dfa_match will match @str and return the accept perms for the -+ * final state. -+ */ -+unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str, int *audit_mask) -+{ -+ int state = aa_dfa_next_state(dfa, DFA_START, str); -+ if (audit_mask) -+ *audit_mask = dfa_audit_mask(dfa, state); -+ return ACCEPT_TABLE(dfa)[state]; -+} -+ -+/** -+ * aa_match_state - find accept perm and state for @str in @dfa -+ * @dfa: the dfa to match @str against -+ * @start: the state to start the match from -+ * @str: the string to match against the dfa -+ * @final: the state that the match finished in -+ * -+ * aa_match_state will match @str and return the accept perms, and @final -+ * state, the match occured in. -+ */ -+unsigned int aa_match_state(struct aa_dfa *dfa, unsigned int start, -+ const char *str, unsigned int *final) -+{ -+ unsigned int state; -+ if (dfa) { -+ state = aa_dfa_next_state(dfa, start, str); -+ if (final) -+ *final = state; -+ return ACCEPT_TABLE(dfa)[state]; -+ } -+ if (final) -+ *final = 0; -+ return 0; -+} -+ ---- /dev/null -+++ b/security/apparmor/match.h -@@ -0,0 +1,87 @@ -+/* -+ * Copyright (C) 2007 Novell/SUSE -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation, version 2 of the -+ * License. -+ * -+ * AppArmor submodule (match) prototypes -+ */ -+ -+#ifndef __MATCH_H -+#define __MATCH_H -+ -+#define DFA_START 1 -+ -+/** -+ * The format used for transition tables is based on the GNU flex table -+ * file format (--tables-file option; see Table File Format in the flex -+ * info pages and the flex sources for documentation). The magic number -+ * used in the header is 0x1B5E783D insted of 0xF13C57B1 though, because -+ * the YY_ID_CHK (check) and YY_ID_DEF (default) tables are used -+ * slightly differently (see the apparmor-parser package). -+ */ -+ -+#define YYTH_MAGIC 0x1B5E783D -+ -+struct table_set_header { -+ u32 th_magic; /* YYTH_MAGIC */ -+ u32 th_hsize; -+ u32 th_ssize; -+ u16 th_flags; -+ char th_version[]; -+}; -+ -+#define YYTD_ID_ACCEPT 1 -+#define YYTD_ID_BASE 2 -+#define YYTD_ID_CHK 3 -+#define YYTD_ID_DEF 4 -+#define YYTD_ID_EC 5 -+#define YYTD_ID_META 6 -+#define YYTD_ID_ACCEPT2 7 -+#define YYTD_ID_NXT 8 -+ -+ -+#define YYTD_DATA8 1 -+#define YYTD_DATA16 2 -+#define YYTD_DATA32 4 -+ -+struct table_header { -+ u16 td_id; -+ u16 td_flags; -+ u32 td_hilen; -+ u32 td_lolen; -+ char td_data[]; -+}; -+ -+#define DEFAULT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_DEF - 1]->td_data)) -+#define BASE_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_BASE - 1]->td_data)) -+#define NEXT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_NXT - 1]->td_data)) -+#define CHECK_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_CHK - 1]->td_data)) -+#define EQUIV_TABLE(DFA) ((u8 *)((DFA)->tables[YYTD_ID_EC - 1]->td_data)) -+#define ACCEPT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT - 1]->td_data)) -+#define ACCEPT_TABLE2(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT2 -1]->td_data)) -+ -+struct aa_dfa { -+ struct table_header *tables[YYTD_ID_NXT]; -+}; -+ -+#define byte_to_byte(X) (X) -+ -+#define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \ -+ do { \ -+ typeof(LEN) __i; \ -+ TYPE *__t = (TYPE *) TABLE; \ -+ TYPE *__b = (TYPE *) BLOB; \ -+ for (__i = 0; __i < LEN; __i++) { \ -+ __t[__i] = NTOHX(__b[__i]); \ -+ } \ -+ } while (0) -+ -+static inline size_t table_size(size_t len, size_t el_size) -+{ -+ return ALIGN(sizeof(struct table_header) + len * el_size, 8); -+} -+ -+#endif /* __MATCH_H */ ---- /dev/null -+++ b/security/apparmor/module_interface.c -@@ -0,0 +1,875 @@ -+/* -+ * Copyright (C) 1998-2007 Novell/SUSE -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation, version 2 of the -+ * License. -+ * -+ * AppArmor userspace policy interface -+ */ -+ -+#include -+ -+#include "apparmor.h" -+#include "inline.h" -+ -+/* -+ * This mutex is used to synchronize profile adds, replacements, and -+ * removals: we only allow one of these operations at a time. -+ * We do not use the profile list lock here in order to avoid blocking -+ * exec during those operations. (Exec involves a profile list lookup -+ * for named-profile transitions.) -+ */ -+DEFINE_MUTEX(aa_interface_lock); -+ -+/* -+ * The AppArmor interface treats data as a type byte followed by the -+ * actual data. The interface has the notion of a a named entry -+ * which has a name (AA_NAME typecode followed by name string) followed by -+ * the entries typecode and data. Named types allow for optional -+ * elements and extensions to be added and tested for without breaking -+ * backwards compatability. -+ */ -+ -+enum aa_code { -+ AA_U8, -+ AA_U16, -+ AA_U32, -+ AA_U64, -+ AA_NAME, /* same as string except it is items name */ -+ AA_STRING, -+ AA_BLOB, -+ AA_STRUCT, -+ AA_STRUCTEND, -+ AA_LIST, -+ AA_LISTEND, -+ AA_ARRAY, -+ AA_ARRAYEND, -+}; -+ -+/* -+ * aa_ext is the read of the buffer containing the serialized profile. The -+ * data is copied into a kernel buffer in apparmorfs and then handed off to -+ * the unpack routines. -+ */ -+struct aa_ext { -+ void *start; -+ void *end; -+ void *pos; /* pointer to current position in the buffer */ -+ u32 version; -+ char *ns_name; -+}; -+ -+static inline int aa_inbounds(struct aa_ext *e, size_t size) -+{ -+ return (size <= e->end - e->pos); -+} -+ -+/** -+ * aa_u16_chunck - test and do bounds checking for a u16 size based chunk -+ * @e: serialized data read head -+ * @chunk: start address for chunk of data -+ * -+ * return the size of chunk found with the read head at the end of -+ * the chunk. -+ */ -+static size_t aa_is_u16_chunk(struct aa_ext *e, char **chunk) -+{ -+ void *pos = e->pos; -+ size_t size = 0; -+ -+ if (!aa_inbounds(e, sizeof(u16))) -+ goto fail; -+ size = le16_to_cpu(get_unaligned((u16 *)e->pos)); -+ e->pos += sizeof(u16); -+ if (!aa_inbounds(e, size)) -+ goto fail; -+ *chunk = e->pos; -+ e->pos += size; -+ return size; -+ -+fail: -+ e->pos = pos; -+ return 0; -+} -+ -+static inline int aa_is_X(struct aa_ext *e, enum aa_code code) -+{ -+ if (!aa_inbounds(e, 1)) -+ return 0; -+ if (*(u8 *) e->pos != code) -+ return 0; -+ e->pos++; -+ return 1; -+} -+ -+/** -+ * aa_is_nameX - check is the next element is of type X with a name of @name -+ * @e: serialized data extent information -+ * @code: type code -+ * @name: name to match to the serialized element. -+ * -+ * check that the next serialized data element is of type X and has a tag -+ * name @name. If @name is specified then there must be a matching -+ * name element in the stream. If @name is NULL any name element will be -+ * skipped and only the typecode will be tested. -+ * returns 1 on success (both type code and name tests match) and the read -+ * head is advanced past the headers -+ * returns %0 if either match failes, the read head does not move -+ */ -+static int aa_is_nameX(struct aa_ext *e, enum aa_code code, const char *name) -+{ -+ void *pos = e->pos; -+ /* -+ * Check for presence of a tagname, and if present name size -+ * AA_NAME tag value is a u16. -+ */ -+ if (aa_is_X(e, AA_NAME)) { -+ char *tag; -+ size_t size = aa_is_u16_chunk(e, &tag); -+ /* if a name is specified it must match. otherwise skip tag */ -+ if (name && (!size || strcmp(name, tag))) -+ goto fail; -+ } else if (name) { -+ /* if a name is specified and there is no name tag fail */ -+ goto fail; -+ } -+ -+ /* now check if type code matches */ -+ if (aa_is_X(e, code)) -+ return 1; -+ -+fail: -+ e->pos = pos; -+ return 0; -+} -+ -+static int aa_is_u16(struct aa_ext *e, u16 *data, const char *name) -+{ -+ void *pos = e->pos; -+ if (aa_is_nameX(e, AA_U16, name)) { -+ if (!aa_inbounds(e, sizeof(u16))) -+ goto fail; -+ if (data) -+ *data = le16_to_cpu(get_unaligned((u16 *)e->pos)); -+ e->pos += sizeof(u16); -+ return 1; -+ } -+fail: -+ e->pos = pos; -+ return 0; -+} -+ -+static int aa_is_u32(struct aa_ext *e, u32 *data, const char *name) -+{ -+ void *pos = e->pos; -+ if (aa_is_nameX(e, AA_U32, name)) { -+ if (!aa_inbounds(e, sizeof(u32))) -+ goto fail; -+ if (data) -+ *data = le32_to_cpu(get_unaligned((u32 *)e->pos)); -+ e->pos += sizeof(u32); -+ return 1; -+ } -+fail: -+ e->pos = pos; -+ return 0; -+} -+ -+static size_t aa_is_array(struct aa_ext *e, const char *name) -+{ -+ void *pos = e->pos; -+ if (aa_is_nameX(e, AA_ARRAY, name)) { -+ int size; -+ if (!aa_inbounds(e, sizeof(u16))) -+ goto fail; -+ size = (int) le16_to_cpu(get_unaligned((u16 *)e->pos)); -+ e->pos += sizeof(u16); -+ return size; -+ } -+fail: -+ e->pos = pos; -+ return 0; -+} -+ -+static size_t aa_is_blob(struct aa_ext *e, char **blob, const char *name) -+{ -+ void *pos = e->pos; -+ if (aa_is_nameX(e, AA_BLOB, name)) { -+ u32 size; -+ if (!aa_inbounds(e, sizeof(u32))) -+ goto fail; -+ size = le32_to_cpu(get_unaligned((u32 *)e->pos)); -+ e->pos += sizeof(u32); -+ if (aa_inbounds(e, (size_t) size)) { -+ * blob = e->pos; -+ e->pos += size; -+ return size; -+ } -+ } -+fail: -+ e->pos = pos; -+ return 0; -+} -+ -+static int aa_is_dynstring(struct aa_ext *e, char **string, const char *name) -+{ -+ char *src_str; -+ size_t size = 0; -+ void *pos = e->pos; -+ *string = NULL; -+ if (aa_is_nameX(e, AA_STRING, name) && -+ (size = aa_is_u16_chunk(e, &src_str))) { -+ char *str; -+ if (!(str = kmalloc(size, GFP_KERNEL))) -+ goto fail; -+ memcpy(str, src_str, size); -+ *string = str; -+ } -+ -+ return size; -+ -+fail: -+ e->pos = pos; -+ return 0; -+} -+ -+/** -+ * aa_unpack_dfa - unpack a file rule dfa -+ * @e: serialized data extent information -+ * -+ * returns dfa or ERR_PTR -+ */ -+static struct aa_dfa *aa_unpack_dfa(struct aa_ext *e) -+{ -+ char *blob = NULL; -+ size_t size, error = 0; -+ struct aa_dfa *dfa = NULL; -+ -+ size = aa_is_blob(e, &blob, "aadfa"); -+ if (size) { -+ dfa = aa_match_alloc(); -+ if (dfa) { -+ /* -+ * The dfa is aligned with in the blob to 8 bytes -+ * from the beginning of the stream. -+ */ -+ size_t sz = blob - (char *) e->start; -+ size_t pad = ALIGN(sz, 8) - sz; -+ error = unpack_dfa(dfa, blob + pad, size - pad); -+ if (!error) -+ error = verify_dfa(dfa); -+ } else { -+ error = -ENOMEM; -+ } -+ -+ if (error) { -+ aa_match_free(dfa); -+ dfa = ERR_PTR(error); -+ } -+ } -+ -+ return dfa; -+} -+ -+static int aa_unpack_exec_table(struct aa_ext *e, struct aa_profile *profile) -+{ -+ void *pos = e->pos; -+ -+ /* exec table is optional */ -+ if (aa_is_nameX(e, AA_STRUCT, "xtable")) { -+ int i, size; -+ -+ size = aa_is_array(e, NULL); -+ /* currently 4 exec bits and entries 0-3 are reserved iupcx */ -+ if (size > 16 - 4) -+ goto fail; -+ profile->exec_table = kzalloc(sizeof(char *) * size, -+ GFP_KERNEL); -+ if (!profile->exec_table) -+ goto fail; -+ -+ for (i = 0; i < size; i++) { -+ char *tmp; -+ if (!aa_is_dynstring(e, &tmp, NULL)) -+ goto fail; -+ /* note: strings beginning with a : have an embedded -+ \0 seperating the profile ns name from the profile -+ name */ -+ profile->exec_table[i] = tmp; -+ } -+ if (!aa_is_nameX(e, AA_ARRAYEND, NULL)) -+ goto fail; -+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) -+ goto fail; -+ profile->exec_table_size = size; -+ } -+ return 1; -+ -+fail: -+ e->pos = pos; -+ return 0; -+} -+ -+/** -+ * aa_unpack_profile - unpack a serialized profile -+ * @e: serialized data extent information -+ * @sa: audit struct for the operation -+ */ -+static struct aa_profile *aa_unpack_profile(struct aa_ext *e, -+ struct aa_audit *sa) -+{ -+ struct aa_profile *profile = NULL; -+ -+ int error = -EPROTO; -+ -+ profile = alloc_aa_profile(); -+ if (!profile) -+ return ERR_PTR(-ENOMEM); -+ -+ /* check that we have the right struct being passed */ -+ if (!aa_is_nameX(e, AA_STRUCT, "profile")) -+ goto fail; -+ if (!aa_is_dynstring(e, &profile->name, NULL)) -+ goto fail; -+ -+ /* per profile debug flags (complain, audit) */ -+ if (!aa_is_nameX(e, AA_STRUCT, "flags")) -+ goto fail; -+ if (!aa_is_u32(e, NULL, NULL)) -+ goto fail; -+ if (!aa_is_u32(e, &(profile->flags.complain), NULL)) -+ goto fail; -+ if (!aa_is_u32(e, &(profile->flags.audit), NULL)) -+ goto fail; -+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) -+ goto fail; -+ -+ if (!aa_is_u32(e, &(profile->capabilities), NULL)) -+ goto fail; -+ if (!aa_is_u32(e, &(profile->audit_caps), NULL)) -+ goto fail; -+ if (!aa_is_u32(e, &(profile->quiet_caps), NULL)) -+ goto fail; -+ if (!aa_is_u32(e, &(profile->set_caps), NULL)) -+ goto fail; -+ -+ /* get file rules */ -+ profile->file_rules = aa_unpack_dfa(e); -+ if (IS_ERR(profile->file_rules)) { -+ error = PTR_ERR(profile->file_rules); -+ profile->file_rules = NULL; -+ goto fail; -+ } -+ -+ if (!aa_unpack_exec_table(e, profile)) -+ goto fail; -+ -+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) -+ goto fail; -+ -+ return profile; -+ -+fail: -+ sa->name = profile && profile->name ? profile->name : "unknown"; -+ if (!sa->info) -+ sa->info = "failed to unpack profile"; -+ aa_audit_status(NULL, sa); -+ -+ if (profile) -+ free_aa_profile(profile); -+ -+ return ERR_PTR(error); -+} -+ -+/** -+ * aa_verify_head - unpack serialized stream header -+ * @e: serialized data read head -+ * @operation: operation header is being verified for -+ * -+ * returns error or 0 if header is good -+ */ -+static int aa_verify_header(struct aa_ext *e, struct aa_audit *sa) -+{ -+ /* get the interface version */ -+ if (!aa_is_u32(e, &e->version, "version")) { -+ sa->info = "invalid profile format"; -+ aa_audit_status(NULL, sa); -+ return -EPROTONOSUPPORT; -+ } -+ -+ /* check that the interface version is currently supported */ -+ if (e->version != 5) { -+ sa->info = "unsupported interface version"; -+ aa_audit_status(NULL, sa); -+ return -EPROTONOSUPPORT; -+ } -+ -+ /* read the namespace if present */ -+ if (!aa_is_dynstring(e, &e->ns_name, "namespace")) { -+ e->ns_name = NULL; -+ } -+ -+ return 0; -+} -+ -+/** -+ * aa_add_profile - Unpack and add a new profile to the profile list -+ * @data: serialized data stream -+ * @size: size of the serialized data stream -+ */ -+ssize_t aa_add_profile(void *data, size_t size) -+{ -+ struct aa_profile *profile = NULL; -+ struct aa_namespace *ns = NULL; -+ struct aa_ext e = { -+ .start = data, -+ .end = data + size, -+ .pos = data, -+ .ns_name = NULL -+ }; -+ ssize_t error; -+ struct aa_audit sa; -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "profile_load"; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ error = aa_verify_header(&e, &sa); -+ if (error) -+ return error; -+ -+ profile = aa_unpack_profile(&e, &sa); -+ if (IS_ERR(profile)) -+ return PTR_ERR(profile); -+ -+ mutex_lock(&aa_interface_lock); -+ write_lock(&profile_ns_list_lock); -+ if (e.ns_name) -+ ns = __aa_find_namespace(e.ns_name, &profile_ns_list); -+ else -+ ns = default_namespace; -+ if (!ns) { -+ struct aa_namespace *new_ns; -+ write_unlock(&profile_ns_list_lock); -+ new_ns = alloc_aa_namespace(e.ns_name); -+ if (!new_ns) { -+ mutex_unlock(&aa_interface_lock); -+ return -ENOMEM; -+ } -+ write_lock(&profile_ns_list_lock); -+ ns = __aa_find_namespace(e.ns_name, &profile_ns_list); -+ if (!ns) { -+ list_add(&new_ns->list, &profile_ns_list); -+ ns = new_ns; -+ } else -+ free_aa_namespace(new_ns); -+ } -+ -+ write_lock(&ns->lock); -+ if (__aa_find_profile(profile->name, &ns->profiles)) { -+ /* A profile with this name exists already. */ -+ write_unlock(&ns->lock); -+ write_unlock(&profile_ns_list_lock); -+ sa.name = profile->name; -+ sa.name2 = ns->name; -+ sa.info = "failed: profile already loaded"; -+ aa_audit_status(NULL, &sa); -+ mutex_unlock(&aa_interface_lock); -+ aa_put_profile(profile); -+ return -EEXIST; -+ } -+ profile->ns = aa_get_namespace(ns); -+ ns->profile_count++; -+ list_add(&profile->list, &ns->profiles); -+ write_unlock(&ns->lock); -+ write_unlock(&profile_ns_list_lock); -+ -+ sa.name = profile->name; -+ sa.name2 = ns->name; -+ aa_audit_status(NULL, &sa); -+ mutex_unlock(&aa_interface_lock); -+ return size; -+} -+ -+/** -+ * task_replace - replace a task's profile -+ * @task: task to replace profile on -+ * @new_cxt: new aa_task_context to do replacement with -+ * @new_profile: new profile -+ */ -+static inline void task_replace(struct task_struct *task, -+ struct aa_task_context *new_cxt, -+ struct aa_profile *new_profile) -+{ -+ struct aa_task_context *cxt = aa_task_context(task); -+ -+ AA_DEBUG("%s: replacing profile for task %d " -+ "profile=%s (%p)\n", -+ __FUNCTION__, -+ cxt->task->pid, -+ cxt->profile->name, cxt->profile); -+ -+ aa_change_task_context(task, new_cxt, new_profile, cxt->cookie, -+ cxt->previous_profile); -+} -+ -+/** -+ * aa_replace_profile - replace a profile on the profile list -+ * @udata: serialized data stream -+ * @size: size of the serialized data stream -+ * -+ * unpack and replace a profile on the profile list and uses of that profile -+ * by any aa_task_context. If the profile does not exist on the profile list -+ * it is added. Return %0 or error. -+ */ -+ssize_t aa_replace_profile(void *udata, size_t size) -+{ -+ struct aa_profile *old_profile, *new_profile; -+ struct aa_namespace *ns; -+ struct aa_task_context *new_cxt; -+ struct aa_ext e = { -+ .start = udata, -+ .end = udata + size, -+ .pos = udata, -+ .ns_name = NULL -+ }; -+ ssize_t error; -+ struct aa_audit sa; -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "profile_replace"; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ error = aa_verify_header(&e, &sa); -+ if (error) -+ return error; -+ -+ new_profile = aa_unpack_profile(&e, &sa); -+ if (IS_ERR(new_profile)) -+ return PTR_ERR(new_profile); -+ -+ mutex_lock(&aa_interface_lock); -+ write_lock(&profile_ns_list_lock); -+ if (e.ns_name) -+ ns = __aa_find_namespace(e.ns_name, &profile_ns_list); -+ else -+ ns = default_namespace; -+ if (!ns) { -+ struct aa_namespace *new_ns; -+ write_unlock(&profile_ns_list_lock); -+ new_ns = alloc_aa_namespace(e.ns_name); -+ if (!new_ns) { -+ mutex_unlock(&aa_interface_lock); -+ return -ENOMEM; -+ } -+ write_lock(&profile_ns_list_lock); -+ ns = __aa_find_namespace(e.ns_name, &profile_ns_list); -+ if (!ns) { -+ list_add(&new_ns->list, &profile_ns_list); -+ ns = new_ns; -+ } else -+ free_aa_namespace(new_ns); -+ } -+ -+ write_lock(&ns->lock); -+ old_profile = __aa_find_profile(new_profile->name, &ns->profiles); -+ if (old_profile) { -+ lock_profile(old_profile); -+ old_profile->isstale = 1; -+ list_del_init(&old_profile->list); -+ unlock_profile(old_profile); -+ ns->profile_count--; -+ } -+ new_profile->ns = aa_get_namespace(ns); -+ ns->profile_count++; -+ /* not don't need an extra ref count to keep new_profile as -+ * it is protect by the interface mutex */ -+ list_add(&new_profile->list, &ns->profiles); -+ write_unlock(&ns->lock); -+ write_unlock(&profile_ns_list_lock); -+ -+ if (!old_profile) { -+ sa.operation = "profile_load"; -+ goto out; -+ } -+ /* -+ * Replacement needs to allocate a new aa_task_context for each -+ * task confined by old_profile. To do this the profile locks -+ * are only held when the actual switch is done per task. While -+ * looping to allocate a new aa_task_context the old_task list -+ * may get shorter if tasks exit/change their profile but will -+ * not get longer as new task will not use old_profile detecting -+ * that is stale. -+ */ -+ do { -+ new_cxt = aa_alloc_task_context(GFP_KERNEL | __GFP_NOFAIL); -+ -+ lock_both_profiles(old_profile, new_profile); -+ if (!list_empty(&old_profile->task_contexts)) { -+ struct task_struct *task = -+ list_entry(old_profile->task_contexts.next, -+ struct aa_task_context, list)->task; -+ task_lock(task); -+ task_replace(task, new_cxt, new_profile); -+ task_unlock(task); -+ new_cxt = NULL; -+ } -+ unlock_both_profiles(old_profile, new_profile); -+ } while (!new_cxt); -+ aa_free_task_context(new_cxt); -+ aa_put_profile(old_profile); -+ -+out: -+ sa.name = new_profile->name; -+ sa.name2 = ns->name; -+ aa_audit_status(NULL, &sa); -+ mutex_unlock(&aa_interface_lock); -+ return size; -+} -+ -+/** -+ * aa_remove_profile - remove a profile from the system -+ * @name: name of the profile to remove -+ * @size: size of the name -+ * -+ * remove a profile from the profile list and all aa_task_context references -+ * to said profile. -+ */ -+ssize_t aa_remove_profile(char *name, size_t size) -+{ -+ struct aa_namespace *ns; -+ struct aa_profile *profile; -+ struct aa_audit sa; -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "profile_remove"; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ mutex_lock(&aa_interface_lock); -+ write_lock(&profile_ns_list_lock); -+ -+ if (name[0] == ':') { -+ char *split = strchr(name + 1, ':'); -+ if (!split) -+ goto noent; -+ *split = 0; -+ ns = __aa_find_namespace(name + 1, &profile_ns_list); -+ name = split + 1; -+ } else { -+ ns = default_namespace; -+ } -+ -+ if (!ns) -+ goto noent; -+ sa.name2 = ns->name; -+ write_lock(&ns->lock); -+ profile = __aa_find_profile(name, &ns->profiles); -+ if (!profile) { -+ write_unlock(&ns->lock); -+ goto noent; -+ } -+ sa.name = profile->name; -+ -+ /* Remove the profile from each task context it is on. */ -+ lock_profile(profile); -+ profile->isstale = 1; -+ aa_unconfine_tasks(profile); -+ list_del_init(&profile->list); -+ ns->profile_count--; -+ unlock_profile(profile); -+ /* Release the profile itself. */ -+ write_unlock(&ns->lock); -+ /* check to see if the namespace has become stale */ -+ if (ns != default_namespace && ns->profile_count == 0) { -+ list_del_init(&ns->list); -+ aa_put_namespace(ns); -+ } -+ write_unlock(&profile_ns_list_lock); -+ -+ aa_audit_status(NULL, &sa); -+ mutex_unlock(&aa_interface_lock); -+ aa_put_profile(profile); -+ -+ return size; -+ -+noent: -+ write_unlock(&profile_ns_list_lock); -+ sa.info = "failed: profile does not exist"; -+ aa_audit_status(NULL, &sa); -+ mutex_unlock(&aa_interface_lock); -+ return -ENOENT; -+} -+ -+/** -+ * free_aa_namespace_kref - free aa_namespace by kref (see aa_put_namespace) -+ * @kr: kref callback for freeing of a namespace -+ */ -+void free_aa_namespace_kref(struct kref *kref) -+{ -+ struct aa_namespace *ns=container_of(kref, struct aa_namespace, count); -+ -+ free_aa_namespace(ns); -+} -+ -+/** -+ * alloc_aa_namespace - allocate, initialize and return a new namespace -+ * @name: a preallocated name -+ * Returns NULL on failure. -+ */ -+struct aa_namespace *alloc_aa_namespace(char *name) -+{ -+ struct aa_namespace *ns; -+ -+ ns = kzalloc(sizeof(*ns), GFP_KERNEL); -+ AA_DEBUG("%s(%p)\n", __FUNCTION__, ns); -+ if (ns) { -+ ns->name = name; -+ INIT_LIST_HEAD(&ns->list); -+ INIT_LIST_HEAD(&ns->profiles); -+ kref_init(&ns->count); -+ rwlock_init(&ns->lock); -+ -+ ns->null_complain_profile = alloc_aa_profile(); -+ if (!ns->null_complain_profile) { -+ if (!name) -+ kfree(ns->name); -+ kfree(ns); -+ return NULL; -+ } -+ ns->null_complain_profile->name = -+ kstrdup("null-complain-profile", GFP_KERNEL); -+ if (!ns->null_complain_profile->name) { -+ free_aa_profile(ns->null_complain_profile); -+ if (!name) -+ kfree(ns->name); -+ kfree(ns); -+ return NULL; -+ } -+ ns->null_complain_profile->flags.complain = 1; -+ /* null_complain_profile doesn't contribute to ns ref count */ -+ ns->null_complain_profile->ns = ns; -+ } -+ return ns; -+} -+ -+/** -+ * free_aa_namespace - free a profile namespace -+ * @namespace: the namespace to free -+ * -+ * Free a namespace. All references to the namespace must have been put. -+ * If the namespace was referenced by a profile confining a task, -+ * free_aa_namespace will be called indirectly (through free_aa_profile) -+ * from an rcu callback routine, so we must not sleep here. -+ */ -+void free_aa_namespace(struct aa_namespace *ns) -+{ -+ AA_DEBUG("%s(%p)\n", __FUNCTION__, ns); -+ -+ if (!ns) -+ return; -+ -+ /* namespace still contains profiles -- invalid */ -+ if (!list_empty(&ns->profiles)) { -+ AA_ERROR("%s: internal error, " -+ "namespace '%s' still contains profiles\n", -+ __FUNCTION__, -+ ns->name); -+ BUG(); -+ } -+ if (!list_empty(&ns->list)) { -+ AA_ERROR("%s: internal error, " -+ "namespace '%s' still on list\n", -+ __FUNCTION__, -+ ns->name); -+ BUG(); -+ } -+ /* null_complain_profile doesn't contribute to ns ref counting */ -+ ns->null_complain_profile->ns = NULL; -+ aa_put_profile(ns->null_complain_profile); -+ kfree(ns->name); -+ kfree(ns); -+} -+ -+/** -+ * free_aa_profile_kref - free aa_profile by kref (called by aa_put_profile) -+ * @kr: kref callback for freeing of a profile -+ */ -+void free_aa_profile_kref(struct kref *kref) -+{ -+ struct aa_profile *p=container_of(kref, struct aa_profile, count); -+ -+ free_aa_profile(p); -+} -+ -+/** -+ * alloc_aa_profile - allocate, initialize and return a new profile -+ * Returns NULL on failure. -+ */ -+struct aa_profile *alloc_aa_profile(void) -+{ -+ struct aa_profile *profile; -+ -+ profile = kzalloc(sizeof(*profile), GFP_KERNEL); -+ AA_DEBUG("%s(%p)\n", __FUNCTION__, profile); -+ if (profile) { -+ INIT_LIST_HEAD(&profile->list); -+ kref_init(&profile->count); -+ INIT_LIST_HEAD(&profile->task_contexts); -+ spin_lock_init(&profile->lock); -+ } -+ return profile; -+} -+ -+/** -+ * free_aa_profile - free a profile -+ * @profile: the profile to free -+ * -+ * Free a profile, its hats and null_profile. All references to the profile, -+ * its hats and null_profile must have been put. -+ * -+ * If the profile was referenced from a task context, free_aa_profile() will -+ * be called from an rcu callback routine, so we must not sleep here. -+ */ -+void free_aa_profile(struct aa_profile *profile) -+{ -+ AA_DEBUG("%s(%p)\n", __FUNCTION__, profile); -+ -+ if (!profile) -+ return; -+ -+ /* profile is still on profile namespace list -- invalid */ -+ if (!list_empty(&profile->list)) { -+ AA_ERROR("%s: internal error, " -+ "profile '%s' still on global list\n", -+ __FUNCTION__, -+ profile->name); -+ BUG(); -+ } -+ aa_put_namespace(profile->ns); -+ -+ aa_match_free(profile->file_rules); -+ -+ if (profile->name) { -+ AA_DEBUG("%s: %s\n", __FUNCTION__, profile->name); -+ kfree(profile->name); -+ } -+ -+ kfree(profile); -+} -+ -+/** -+ * aa_unconfine_tasks - remove tasks on a profile's task context list -+ * @profile: profile to remove tasks from -+ * -+ * Assumes that @profile lock is held. -+ */ -+void aa_unconfine_tasks(struct aa_profile *profile) -+{ -+ while (!list_empty(&profile->task_contexts)) { -+ struct task_struct *task = -+ list_entry(profile->task_contexts.next, -+ struct aa_task_context, list)->task; -+ task_lock(task); -+ aa_change_task_context(task, NULL, NULL, 0, NULL); -+ task_unlock(task); -+ } -+} diff --git a/kernel-patches/for-mainline/apparmor-network.diff b/kernel-patches/for-mainline/apparmor-network.diff deleted file mode 100644 index dc860b951..000000000 --- a/kernel-patches/for-mainline/apparmor-network.diff +++ /dev/null @@ -1,408 +0,0 @@ -From: John Johansen -Subject: AppArmor: Simplified network controls for AppArmor - -Simple network control determining which network families a confined -application has access to. - -Signed-off-by: John Johansen - ---- - security/apparmor/Makefile | 7 + - security/apparmor/apparmor.h | 9 ++ - security/apparmor/lsm.c | 129 ++++++++++++++++++++++++++++++++++- - security/apparmor/main.c | 107 ++++++++++++++++++++++++++++- - security/apparmor/module_interface.c | 26 ++++++- - 5 files changed, 271 insertions(+), 7 deletions(-) - ---- a/security/apparmor/Makefile -+++ b/security/apparmor/Makefile -@@ -8,6 +8,11 @@ apparmor-y := main.o list.o procattr.o l - quiet_cmd_make-caps = GEN $@ - 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 > $@ - --$(obj)/main.o : $(obj)/capability_names.h -+quiet_cmd_make-af = GEN $@ -+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 > $@ -+ -+$(obj)/main.o : $(obj)/capability_names.h $(obj)/af_names.h - $(obj)/capability_names.h : $(srctree)/include/linux/capability.h - $(call cmd,make-caps) -+$(obj)/af_names.h : $(srctree)/include/linux/socket.h -+ $(call cmd,make-af) ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -16,6 +16,8 @@ - #include - #include - #include -+#include -+#include - - /* - * We use MAY_READ, MAY_WRITE, MAY_EXEC, MAY_APPEND and the following flags -@@ -208,6 +210,9 @@ struct aa_profile { - struct list_head task_contexts; - spinlock_t lock; - unsigned long int_flags; -+ u16 network_families[AF_MAX]; -+ u16 audit_network[AF_MAX]; -+ u16 quiet_network[AF_MAX]; - }; - - extern struct list_head profile_ns_list; -@@ -254,6 +259,7 @@ struct aa_audit { - int request_mask, denied_mask, audit_mask; - struct iattr *iattr; - pid_t task, parent; -+ int family, type, protocol; - int error_code; - }; - -@@ -315,6 +321,9 @@ extern void aa_change_task_context(struc - struct aa_profile *previous_profile); - extern int aa_may_ptrace(struct aa_task_context *cxt, - struct aa_profile *tracee); -+extern int aa_net_perm(struct aa_profile *profile, char *operation, -+ int family, int type, int protocol); -+extern int aa_revalidate_sk(struct sock *sk, char *operation); - - /* lsm.c */ - extern int apparmor_initialized; ---- a/security/apparmor/lsm.c -+++ b/security/apparmor/lsm.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - - #include "apparmor.h" - #include "inline.h" -@@ -663,6 +664,117 @@ static void apparmor_task_free_security( - aa_release(task); - } - -+static int apparmor_socket_create(int family, int type, int protocol, int kern) -+{ -+ struct aa_profile *profile; -+ int error = 0; -+ -+ if (kern) -+ return 0; -+ -+ profile = aa_get_profile(current); -+ if (profile) -+ error = aa_net_perm(profile, "socket_create", family, -+ type, protocol); -+ aa_put_profile(profile); -+ -+ return error; -+} -+ -+static int apparmor_socket_post_create(struct socket *sock, int family, -+ int type, int protocol, int kern) -+{ -+ struct sock *sk = sock->sk; -+ -+ if (kern) -+ return 0; -+ -+ return aa_revalidate_sk(sk, "socket_post_create"); -+} -+ -+static int apparmor_socket_bind(struct socket *sock, -+ struct sockaddr *address, int addrlen) -+{ -+ struct sock *sk = sock->sk; -+ -+ return aa_revalidate_sk(sk, "socket_bind"); -+} -+ -+static int apparmor_socket_connect(struct socket *sock, -+ struct sockaddr *address, int addrlen) -+{ -+ struct sock *sk = sock->sk; -+ -+ return aa_revalidate_sk(sk, "socket_connect"); -+} -+ -+static int apparmor_socket_listen(struct socket *sock, int backlog) -+{ -+ struct sock *sk = sock->sk; -+ -+ return aa_revalidate_sk(sk, "socket_listen"); -+} -+ -+static int apparmor_socket_accept(struct socket *sock, struct socket *newsock) -+{ -+ struct sock *sk = sock->sk; -+ -+ return aa_revalidate_sk(sk, "socket_accept"); -+} -+ -+static int apparmor_socket_sendmsg(struct socket *sock, -+ struct msghdr *msg, int size) -+{ -+ struct sock *sk = sock->sk; -+ -+ return aa_revalidate_sk(sk, "socket_sendmsg"); -+} -+ -+static int apparmor_socket_recvmsg(struct socket *sock, -+ struct msghdr *msg, int size, int flags) -+{ -+ struct sock *sk = sock->sk; -+ -+ return aa_revalidate_sk(sk, "socket_recvmsg"); -+} -+ -+static int apparmor_socket_getsockname(struct socket *sock) -+{ -+ struct sock *sk = sock->sk; -+ -+ return aa_revalidate_sk(sk, "socket_getsockname"); -+} -+ -+static int apparmor_socket_getpeername(struct socket *sock) -+{ -+ struct sock *sk = sock->sk; -+ -+ return aa_revalidate_sk(sk, "socket_getpeername"); -+} -+ -+static int apparmor_socket_getsockopt(struct socket *sock, int level, -+ int optname) -+{ -+ struct sock *sk = sock->sk; -+ -+ return aa_revalidate_sk(sk, "socket_getsockopt"); -+} -+ -+static int apparmor_socket_setsockopt(struct socket *sock, int level, -+ int optname) -+{ -+ struct sock *sk = sock->sk; -+ -+ return aa_revalidate_sk(sk, "socket_setsockopt"); -+} -+ -+static int apparmor_socket_shutdown(struct socket *sock, int how) -+{ -+ struct sock *sk = sock->sk; -+ -+ return aa_revalidate_sk(sk, "socket_shutdown"); -+} -+ - static int apparmor_getprocattr(struct task_struct *task, char *name, - char **value) - { -@@ -763,9 +875,6 @@ struct security_operations apparmor_ops - .capable = apparmor_capable, - .syslog = cap_syslog, - -- .netlink_send = cap_netlink_send, -- .netlink_recv = cap_netlink_recv, -- - .bprm_apply_creds = cap_bprm_apply_creds, - .bprm_set_security = apparmor_bprm_set_security, - .bprm_secureexec = apparmor_bprm_secureexec, -@@ -801,6 +910,20 @@ struct security_operations apparmor_ops - - .getprocattr = apparmor_getprocattr, - .setprocattr = apparmor_setprocattr, -+ -+ .socket_create = apparmor_socket_create, -+ .socket_post_create = apparmor_socket_post_create, -+ .socket_bind = apparmor_socket_bind, -+ .socket_connect = apparmor_socket_connect, -+ .socket_listen = apparmor_socket_listen, -+ .socket_accept = apparmor_socket_accept, -+ .socket_sendmsg = apparmor_socket_sendmsg, -+ .socket_recvmsg = apparmor_socket_recvmsg, -+ .socket_getsockname = apparmor_socket_getsockname, -+ .socket_getpeername = apparmor_socket_getpeername, -+ .socket_getsockopt = apparmor_socket_getsockopt, -+ .socket_setsockopt = apparmor_socket_setsockopt, -+ .socket_shutdown = apparmor_socket_shutdown, - }; - - void info_message(const char *str) ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -14,6 +14,9 @@ - #include - #include - #include -+#include -+#include -+#include - - #include "apparmor.h" - -@@ -116,6 +119,24 @@ static void aa_audit_file_mask(struct au - audit_log_format(ab, " %s=\"%s::%s\"", name, user, other); - } - -+static const char *address_families[] = { -+#include "af_names.h" -+}; -+ -+static const char *sock_types[] = { -+ "unknown(0)", -+ "stream", -+ "dgram", -+ "raw", -+ "rdm", -+ "seqpacket", -+ "dccp", -+ "unknown(7)", -+ "unknown(8)", -+ "unknown(9)", -+ "packet", -+}; -+ - /** - * aa_audit - Log an audit event to the audit subsystem - * @profile: profile to check against -@@ -187,7 +208,25 @@ static int aa_audit_base(struct aa_profi - audit_log_untrustedstring(ab, sa->name2); - } - -- audit_log_format(ab, " pid=%d", current->pid); -+ if (sa->family || sa->type) { -+ if (address_families[sa->family]) -+ audit_log_format(ab, " family=\"%s\"", -+ address_families[sa->family]); -+ else -+ audit_log_format(ab, " family=\"unknown(%d)\"", -+ sa->family); -+ -+ if (sock_types[sa->type]) -+ audit_log_format(ab, " sock_type=\"%s\"", -+ sock_types[sa->type]); -+ else -+ audit_log_format(ab, " sock_type=\"unknown(%d)\"", -+ sa->type); -+ -+ audit_log_format(ab, " protocol=%d", sa->protocol); -+ } -+ -+ audit_log_format(ab, " pid=%d", current->pid); - - if (profile) { - audit_log_format(ab, " profile="); -@@ -768,6 +807,72 @@ int aa_link(struct aa_profile *profile, - return error; - } - -+int aa_net_perm(struct aa_profile *profile, char *operation, -+ int family, int type, int protocol) -+{ -+ struct aa_audit sa; -+ int error = 0; -+ u16 family_mask, audit_mask, quiet_mask; -+ -+ if ((family < 0) || (family >= AF_MAX)) -+ return -EINVAL; -+ -+ if ((type < 0) || (type >= SOCK_MAX)) -+ return -EINVAL; -+ -+ /* unix domain and netlink sockets are handled by ipc */ -+ if (family == AF_UNIX || family == AF_NETLINK) -+ return 0; -+ -+ family_mask = profile->network_families[family]; -+ audit_mask = profile->audit_network[family]; -+ quiet_mask = profile->quiet_network[family]; -+ -+ error = (family_mask & (1 << type)) ? 0 : -EACCES; -+ -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = operation; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.family = family; -+ sa.type = type; -+ sa.protocol = protocol; -+ sa.error_code = error; -+ -+ if (likely(!error)) { -+ if (!PROFILE_AUDIT(profile) && !(family_mask & audit_mask)) -+ return 0; -+ } else if (!((1 << type) & ~quiet_mask)) { -+ return error; -+ } -+ -+ error = aa_audit(profile, &sa); -+ -+ return error; -+} -+ -+int aa_revalidate_sk(struct sock *sk, char *operation) -+{ -+ struct aa_profile *profile; -+ int error = 0; -+ -+ /* this is some debugging code to flush out the network hooks that -+ that are called in interrupt context */ -+ if (in_interrupt()) { -+ printk("AppArmor Debug: Hook being called from interrupt context\n"); -+ dump_stack(); -+ return 0; -+ } -+ -+ profile = aa_get_profile(current); -+ if (profile) -+ error = aa_net_perm(profile, operation, -+ sk->sk_family, sk->sk_type, -+ sk->sk_protocol); -+ aa_put_profile(profile); -+ -+ return error; -+} -+ - /******************************* - * Global task related functions - *******************************/ ---- a/security/apparmor/module_interface.c -+++ b/security/apparmor/module_interface.c -@@ -320,8 +320,8 @@ static struct aa_profile *aa_unpack_prof - struct aa_audit *sa) - { - struct aa_profile *profile = NULL; -- -- int error = -EPROTO; -+ size_t size = 0; -+ int i, error = -EPROTO; - - profile = alloc_aa_profile(); - if (!profile) -@@ -354,6 +354,28 @@ static struct aa_profile *aa_unpack_prof - if (!aa_is_u32(e, &(profile->set_caps), NULL)) - goto fail; - -+ size = aa_is_array(e, "net_allowed_af"); -+ if (size) { -+ if (size > AF_MAX) -+ goto fail; -+ -+ for (i = 0; i < size; i++) { -+ if (!aa_is_u16(e, &profile->network_families[i], NULL)) -+ goto fail; -+ if (!aa_is_u16(e, &profile->audit_network[i], NULL)) -+ goto fail; -+ if (!aa_is_u16(e, &profile->quiet_network[i], NULL)) -+ goto fail; -+ } -+ if (!aa_is_nameX(e, AA_ARRAYEND, NULL)) -+ goto fail; -+ /* allow unix domain and netlink sockets they are handled -+ * by IPC -+ */ -+ } -+ profile->network_families[AF_UNIX] = 0xffff; -+ profile->network_families[AF_NETLINK] = 0xffff; -+ - /* get file rules */ - profile->file_rules = aa_unpack_dfa(e); - if (IS_ERR(profile->file_rules)) { diff --git a/kernel-patches/for-mainline/apparmor-rlimits.diff b/kernel-patches/for-mainline/apparmor-rlimits.diff deleted file mode 100644 index 5895479c4..000000000 --- a/kernel-patches/for-mainline/apparmor-rlimits.diff +++ /dev/null @@ -1,461 +0,0 @@ -From: John Johansen -Subject: AppArmor: per profile controls for system rlimits - -Provide contol of rlimits on a per profile basis. Each profile provides -a per limit contol and corresponding hard limit value, such that when a -profile becomes attached to a task it sets the tasks limits to be <= to -the profiles specified limits. Note: the profile limit value will not -raise a tasks limit if it is already less than the profile mandates. - -In addition to setting a tasks limits, the ability to set limits on -a confined task are controlled. AppArmor only controls the raising -of a tasks limits Tasks with CAP_SYS_RESOURCE can have their hard limits -raised up to the value specified by the profile. AppArmor does not -prevent a task for lowering its hard limits, nor does it provide -additional control on soft limits. - -AppArmor only controls the limits specified in a profile so that -any limit not specified is free to be modified subject to standard -linux limitations. - ---- - security/apparmor/apparmor.h | 23 ++++++ - security/apparmor/apparmorfs.c | 2 - security/apparmor/lsm.c | 16 ++++ - security/apparmor/main.c | 132 +++++++++++++++++++++++++++++++---- - security/apparmor/module_interface.c | 56 ++++++++++++++ - 5 files changed, 215 insertions(+), 14 deletions(-) - ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -136,6 +137,18 @@ extern unsigned int apparmor_path_max; - - #define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args) - -+/* struct aa_rlimit - rlimits settings for the profile -+ * @mask: which hard limits to set -+ * @limits: rlimit values that override task limits -+ * -+ * AppArmor rlimits are used to set confined task rlimits. Only the -+ * limits specified in @mask will be controlled by apparmor. -+ */ -+struct aa_rlimit { -+ unsigned int mask; -+ struct rlimit limits[RLIM_NLIMITS]; -+}; -+ - struct aa_profile; - - /* struct aa_namespace - namespace for a set of profiles -@@ -170,6 +183,8 @@ struct aa_namespace { - * @audit_caps: caps that are to be audited - * @quiet_caps: caps that should not be audited - * @capabilities: capabilities granted by the process -+ * @rlimits: rlimits for the profile -+ * @task_count: how many tasks the profile is attached to - * @count: reference count of the profile - * @task_contexts: list of tasks confined by profile - * @lock: lock for the task_contexts list -@@ -206,6 +221,9 @@ struct aa_profile { - kernel_cap_t audit_caps; - kernel_cap_t quiet_caps; - -+ struct aa_rlimit rlimits; -+ unsigned int task_count; -+ - struct kref count; - struct list_head task_contexts; - spinlock_t lock; -@@ -257,6 +275,7 @@ struct aa_audit { - const char *name2; - const char *name3; - int request_mask, denied_mask, audit_mask; -+ int rlimit; - struct iattr *iattr; - pid_t task, parent; - int family, type, protocol; -@@ -324,6 +343,10 @@ extern int aa_may_ptrace(struct aa_task_ - extern int aa_net_perm(struct aa_profile *profile, char *operation, - int family, int type, int protocol); - extern int aa_revalidate_sk(struct sock *sk, char *operation); -+extern int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource, -+ struct rlimit *new_rlim); -+extern void aa_set_rlimits(struct task_struct *task, struct aa_profile *profile); -+ - - /* lsm.c */ - extern int apparmor_initialized; ---- a/security/apparmor/apparmorfs.c -+++ b/security/apparmor/apparmorfs.c -@@ -105,7 +105,7 @@ static ssize_t aa_features_read(struct f - { - const char *features = "file=3.0 capability=2.0 network=1.0 " - "change_hat=1.4 change_profile=1.0 " -- "aanamespaces=1.0"; -+ "aanamespaces=1.0 rlimit=1.0"; - - return simple_read_from_buffer(buf, size, ppos, features, - strlen(features)); ---- a/security/apparmor/lsm.c -+++ b/security/apparmor/lsm.c -@@ -866,6 +866,21 @@ static int apparmor_setprocattr(struct t - return error; - } - -+static int apparmor_task_setrlimit(unsigned int resource, -+ struct rlimit *new_rlim) -+{ -+ struct aa_profile *profile; -+ int error = 0; -+ -+ profile = aa_get_profile(current); -+ if (profile) { -+ error = aa_task_setrlimit(profile, resource, new_rlim); -+ } -+ aa_put_profile(profile); -+ -+ return error; -+} -+ - struct security_operations apparmor_ops = { - .ptrace = apparmor_ptrace, - .capget = cap_capget, -@@ -907,6 +922,7 @@ struct security_operations apparmor_ops - .task_free_security = apparmor_task_free_security, - .task_post_setuid = cap_task_post_setuid, - .task_reparent_to_init = cap_task_reparent_to_init, -+ .task_setrlimit = apparmor_task_setrlimit, - - .getprocattr = apparmor_getprocattr, - .setprocattr = apparmor_setprocattr, ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -177,6 +177,9 @@ static int aa_audit_base(struct aa_profi - if (sa->request_mask) - audit_log_format(ab, " fsuid=%d", current->fsuid); - -+ if (sa->rlimit) -+ audit_log_format(ab, " rlimit=%d", sa->rlimit - 1); -+ - if (sa->iattr) { - struct iattr *iattr = sa->iattr; - -@@ -872,6 +875,79 @@ int aa_revalidate_sk(struct sock *sk, ch - - return error; - } -+/** -+ * aa_task_setrlimit - test permission to set an rlimit -+ * @profile - profile confining the task -+ * @resource - the resource being set -+ * @new_rlim - the new resource limit -+ * -+ * Control raising the processes hard limit. -+ */ -+int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource, -+ struct rlimit *new_rlim) -+{ -+ struct aa_audit sa; -+ int error = 0; -+ -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "setrlimit"; -+ sa.gfp_mask = GFP_KERNEL; -+ sa.rlimit = resource + 1; -+ -+ if (profile->rlimits.mask & (1 << resource) && -+ new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max) { -+ sa.error_code = -EACCES; -+ -+ error = aa_audit(profile, &sa); -+ } -+ -+ return error; -+} -+ -+static int aa_rlimit_nproc(struct aa_profile *profile) { -+ if (profile && (profile->rlimits.mask & (1 << RLIMIT_NPROC)) && -+ profile->task_count >= profile->rlimits.limits[RLIMIT_NPROC].rlim_max) -+ return -EAGAIN; -+ return 0; -+} -+ -+void aa_set_rlimits(struct task_struct *task, struct aa_profile *profile) -+{ -+ int i, mask; -+ -+ if (!profile) -+ return; -+ -+ if (!profile->rlimits.mask) -+ return; -+ -+ task_lock(task->group_leader); -+ mask = 1; -+ for (i = 0; i < RLIM_NLIMITS; i++, mask <<= 1) { -+ struct rlimit new_rlim, *old_rlim; -+ -+ /* check to see if NPROC which is per profile and handled -+ * in clone/exec or whether this is a limit to be set -+ * can't set cpu limit either right now -+ */ -+ if (i == RLIMIT_NPROC || i == RLIMIT_CPU) -+ continue; -+ -+ old_rlim = task->signal->rlim + i; -+ new_rlim = *old_rlim; -+ -+ if (mask & profile->rlimits.mask && -+ profile->rlimits.limits[i].rlim_max < new_rlim.rlim_max) { -+ new_rlim.rlim_max = profile->rlimits.limits[i].rlim_max; -+ /* soft limit should not exceed hard limit */ -+ if (new_rlim.rlim_cur > new_rlim.rlim_max) -+ new_rlim.rlim_cur = new_rlim.rlim_max; -+ } -+ -+ *old_rlim = new_rlim; -+ } -+ task_unlock(task->group_leader); -+} - - /******************************* - * Global task related functions -@@ -885,6 +961,7 @@ int aa_revalidate_sk(struct sock *sk, ch - */ - int aa_clone(struct task_struct *child) - { -+ struct aa_audit sa; - struct aa_task_context *cxt, *child_cxt; - struct aa_profile *profile; - -@@ -894,6 +971,11 @@ int aa_clone(struct task_struct *child) - if (!child_cxt) - return -ENOMEM; - -+ memset(&sa, 0, sizeof(sa)); -+ sa.operation = "clone"; -+ sa.task = child->pid; -+ sa.gfp_mask = GFP_KERNEL; -+ - repeat: - profile = aa_get_profile(current); - if (profile) { -@@ -910,18 +992,22 @@ repeat: - goto repeat; - } - -+ if (aa_rlimit_nproc(profile)) { -+ sa.info = "rlimit nproc limit exceeded"; -+ unlock_profile(profile); -+ aa_audit_reject(profile, &sa); -+ aa_put_profile(profile); -+ return -EAGAIN; -+ } -+ - /* No need to grab the child's task lock here. */ - aa_change_task_context(child, child_cxt, profile, - cxt->cookie, cxt->previous_profile); -+ - unlock_profile(profile); - - if (APPARMOR_COMPLAIN(child_cxt) && - profile == profile->ns->null_complain_profile) { -- struct aa_audit sa; -- memset(&sa, 0, sizeof(sa)); -- sa.operation = "clone"; -- sa.gfp_mask = GFP_KERNEL; -- sa.task = child->pid; - aa_audit_hint(profile, &sa); - } - aa_put_profile(profile); -@@ -1156,6 +1242,10 @@ repeat: - sa.task = current->parent->pid; - aa_audit_reject(profile, &sa); - } -+ if (PTR_ERR(old_profile) == -EAGAIN) { -+ sa.info = "rlimit nproc limit exceeded"; -+ aa_audit_reject(profile, &sa); -+ } - new_profile = old_profile; - goto cleanup; - } -@@ -1296,6 +1386,12 @@ static int do_change_profile(struct aa_p - goto out; - } - -+ if ((error = aa_rlimit_nproc(new_profile))) { -+ sa->info = "rlimit nproc limit exceeded"; -+ aa_audit_reject(cxt->profile, sa); -+ goto out; -+ } -+ - if (new_profile == ns->null_complain_profile) - aa_audit_hint(cxt->profile, sa); - -@@ -1482,17 +1578,18 @@ struct aa_profile *__aa_replace_profile( - - cxt = lock_task_and_profiles(task, profile); - if (unlikely(profile && profile->isstale)) { -- task_unlock(task); -- unlock_both_profiles(profile, cxt ? cxt->profile : NULL); -- aa_free_task_context(new_cxt); -- return ERR_PTR(-ESTALE); -+ old_profile = ERR_PTR(-ESTALE); -+ goto error; - } - - if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) { -- task_unlock(task); -- unlock_both_profiles(profile, cxt ? cxt->profile : NULL); -- aa_free_task_context(new_cxt); -- return ERR_PTR(-EPERM); -+ old_profile = ERR_PTR(-EPERM); -+ goto error; -+ } -+ -+ if (aa_rlimit_nproc(profile)) { -+ old_profile = ERR_PTR(-EAGAIN); -+ goto error; - } - - if (cxt) -@@ -1500,8 +1597,15 @@ struct aa_profile *__aa_replace_profile( - aa_change_task_context(task, new_cxt, profile, 0, NULL); - - task_unlock(task); -+ aa_set_rlimits(task, profile); - unlock_both_profiles(profile, old_profile); - return old_profile; -+ -+error: -+ task_unlock(task); -+ unlock_both_profiles(profile, cxt ? cxt->profile : NULL); -+ aa_free_task_context(new_cxt); -+ return old_profile; - } - - /** -@@ -1566,6 +1670,7 @@ void aa_change_task_context(struct task_ - - if (old_cxt) { - list_del_init(&old_cxt->list); -+ old_cxt->profile->task_count--; - call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback); - } - if (new_cxt) { -@@ -1577,6 +1682,7 @@ void aa_change_task_context(struct task_ - new_cxt->cookie = cookie; - new_cxt->task = task; - new_cxt->profile = aa_dup_profile(profile); -+ profile->task_count++; - new_cxt->previous_profile = aa_dup_profile(previous_profile); - list_move(&new_cxt->list, &profile->task_contexts); - } ---- a/security/apparmor/module_interface.c -+++ b/security/apparmor/module_interface.c -@@ -177,6 +177,22 @@ fail: - return 0; - } - -+static int aa_is_u64(struct aa_ext *e, u64 *data, const char *name) -+{ -+ void *pos = e->pos; -+ if (aa_is_nameX(e, AA_U64, name)) { -+ if (!aa_inbounds(e, sizeof(u64))) -+ goto fail; -+ if (data) -+ *data = le64_to_cpu(get_unaligned((u64 *)e->pos)); -+ e->pos += sizeof(u64); -+ return 1; -+ } -+fail: -+ e->pos = pos; -+ return 0; -+} -+ - static size_t aa_is_array(struct aa_ext *e, const char *name) - { - void *pos = e->pos; -@@ -311,6 +327,39 @@ fail: - return 0; - } - -+int aa_unpack_rlimits(struct aa_ext *e, struct aa_profile *profile) -+{ -+ void *pos = e->pos; -+ -+ /* rlimits are optional */ -+ if (aa_is_nameX(e, AA_STRUCT, "rlimits")) { -+ int i, size; -+ u32 tmp = 0; -+ if (!aa_is_u32(e, &tmp, NULL)) -+ goto fail; -+ profile->rlimits.mask = tmp; -+ -+ size = aa_is_array(e, NULL); -+ if (size != RLIM_NLIMITS) -+ goto fail; -+ for (i = 0; i < size; i++) { -+ u64 tmp = 0; -+ if (!aa_is_u64(e, &tmp, NULL)) -+ goto fail; -+ profile->rlimits.limits[i].rlim_max = tmp; -+ } -+ if (!aa_is_nameX(e, AA_ARRAYEND, NULL)) -+ goto fail; -+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) -+ goto fail; -+ } -+ return 1; -+ -+fail: -+ e->pos = pos; -+ return 0; -+} -+ - /** - * aa_unpack_profile - unpack a serialized profile - * @e: serialized data extent information -@@ -354,6 +403,9 @@ static struct aa_profile *aa_unpack_prof - if (!aa_is_u32(e, &(profile->set_caps), NULL)) - goto fail; - -+ if (!aa_unpack_rlimits(e, profile)) -+ goto fail; -+ - size = aa_is_array(e, "net_allowed_af"); - if (size) { - if (size > AF_MAX) -@@ -613,6 +665,8 @@ ssize_t aa_replace_profile(void *udata, - sa.operation = "profile_load"; - goto out; - } -+ /* do not fail replacement based off of profile's NPROC rlimit */ -+ - /* - * Replacement needs to allocate a new aa_task_context for each - * task confined by old_profile. To do this the profile locks -@@ -633,6 +687,7 @@ ssize_t aa_replace_profile(void *udata, - task_lock(task); - task_replace(task, new_cxt, new_profile); - task_unlock(task); -+ aa_set_rlimits(task, new_profile); - new_cxt = NULL; - } - unlock_both_profiles(old_profile, new_profile); -@@ -655,6 +710,7 @@ out: - * - * remove a profile from the profile list and all aa_task_context references - * to said profile. -+ * NOTE: removing confinement does not restore rlimits to preconfinemnet values - */ - ssize_t aa_remove_profile(char *name, size_t size) - { diff --git a/kernel-patches/for-mainline/apparmor-secondary-accept.diff b/kernel-patches/for-mainline/apparmor-secondary-accept.diff deleted file mode 100644 index 194302c2f..000000000 --- a/kernel-patches/for-mainline/apparmor-secondary-accept.diff +++ /dev/null @@ -1,73 +0,0 @@ ---- - security/apparmor/apparmor.h | 1 + - security/apparmor/match.c | 9 +++++++-- - security/apparmor/match.h | 2 ++ - 3 files changed, 10 insertions(+), 2 deletions(-) - ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -87,6 +87,7 @@ - AA_AUDIT_FIELD) - - #define AA_VALID_PERM_MASK (AA_FILE_PERMS | AA_SHARED_PERMS) -+#define AA_VALID_PERM2_MASK 0x0fffffff - - #define AA_SECURE_EXEC_NEEDED 1 - ---- a/security/apparmor/match.c -+++ b/security/apparmor/match.c -@@ -83,6 +83,7 @@ int unpack_dfa(struct aa_dfa *dfa, void - - switch(table->td_id) { - case YYTD_ID_ACCEPT: -+ case YYTD_ID_ACCEPT2: - case YYTD_ID_BASE: - dfa->tables[table->td_id - 1] = table; - if (table->td_flags != YYTD_DATA32) -@@ -134,7 +135,8 @@ int verify_dfa(struct aa_dfa *dfa) - int error = -EPROTO; - - /* check that required tables exist */ -- if (!(dfa->tables[YYTD_ID_ACCEPT -1 ] && -+ if (!(dfa->tables[YYTD_ID_ACCEPT - 1] && -+ dfa->tables[YYTD_ID_ACCEPT2 - 1] && - dfa->tables[YYTD_ID_DEF - 1] && - dfa->tables[YYTD_ID_BASE - 1] && - dfa->tables[YYTD_ID_NXT - 1] && -@@ -144,7 +146,8 @@ int verify_dfa(struct aa_dfa *dfa) - /* accept.size == default.size == base.size */ - state_count = dfa->tables[YYTD_ID_BASE - 1]->td_lolen; - if (!(state_count == dfa->tables[YYTD_ID_DEF - 1]->td_lolen && -- state_count == dfa->tables[YYTD_ID_ACCEPT - 1]->td_lolen)) -+ state_count == dfa->tables[YYTD_ID_ACCEPT - 1]->td_lolen && -+ state_count == dfa->tables[YYTD_ID_ACCEPT2 - 1]->td_lolen)) - goto out; - - /* next.size == chk.size */ -@@ -177,6 +180,8 @@ int verify_dfa(struct aa_dfa *dfa) - - if (mode & ~AA_VALID_PERM_MASK) - goto out; -+ if (ACCEPT_TABLE2(dfa)[i] & ~AA_VALID_PERM2_MASK) -+ goto out; - - /* if any exec modifier is set MAY_EXEC must be set */ - if ((mode & AA_USER_EXEC_TYPE) && !(mode & AA_USER_EXEC)) ---- a/security/apparmor/match.h -+++ b/security/apparmor/match.h -@@ -39,6 +39,7 @@ struct table_set_header { - #define YYTD_ID_DEF 4 - #define YYTD_ID_EC 5 - #define YYTD_ID_META 6 -+#define YYTD_ID_ACCEPT2 7 - #define YYTD_ID_NXT 8 - - -@@ -60,6 +61,7 @@ struct table_header { - #define CHECK_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_CHK - 1]->td_data)) - #define EQUIV_TABLE(DFA) ((u8 *)((DFA)->tables[YYTD_ID_EC - 1]->td_data)) - #define ACCEPT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT - 1]->td_data)) -+#define ACCEPT_TABLE2(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT2 -1]->td_data)) - - struct aa_dfa { - struct table_header *tables[YYTD_ID_NXT]; diff --git a/kernel-patches/for-mainline/apparmor-security-goal.diff b/kernel-patches/for-mainline/apparmor-security-goal.diff deleted file mode 100644 index 9205f67d6..000000000 --- a/kernel-patches/for-mainline/apparmor-security-goal.diff +++ /dev/null @@ -1,141 +0,0 @@ ---- - Documentation/lsm/AppArmor-Security-Goal.txt | 134 +++++++++++++++++++++++++++ - 1 file changed, 134 insertions(+) - ---- /dev/null -+++ b/Documentation/lsm/AppArmor-Security-Goal.txt -@@ -0,0 +1,134 @@ -+AppArmor Security Goal -+Crispin Cowan, PhD -+MercenaryLinux.com -+ -+This document specifies the security goal that AppArmor is intended to -+achieve, so that users can evaluate whether AppArmor will meet their -+needs, and kernel developers can evaluate whether AppArmor is living up -+to its claims. This document is *not* a general purpose explanation of -+how AppArmor works, nor is it an explanation for why one might want to -+use AppArmor rather than some other system. -+ -+AppArmor is intended to limit system damage from attackers exploiting -+vulnerabilities in applications that the system hosts. The threat is -+that an attacker can cause a vulnerable application to do something -+unexpected and undesirable. AppArmor addresses this threat by confining -+the application to access only the resources it needs to access to -+execute properly, effectively imposing "least privilege" execution on -+the application. -+ -+Applications interact with the rest of the system via resources -+including files, interprocess communication, networking, capabilities, -+and execution of other applications. The purpose of least privilege is -+to bound the damage that a malicious user or code can do by removing -+access to resources that the application does not need for its intended -+function. This is true for all access control systems, including AppArmor. -+ -+The "attacker" is someone trying to gain the privileges of a process for -+themselves. For instance, a policy for a web server might grant read -+only access to most web documents, preventing an attacker who can -+corrupt the web server from defacing the web pages. A web server has -+access to the web server's local file system, and a network attacker -+trying to hack the web server does not have such file access. An e-mail -+attacker attempting to infect the recipient of the e-mail does not have -+access to the files that the victim user's mail client does. By limiting -+the scope of access for an application, AppArmor can limit the damage an -+attacker can do by exploiting vulnerabilities in applications. -+ -+An "application" is one or more related processes performing a function, -+e.g. the gang of processes that constitute an Apache web server, or a -+Postfix mail server. AppArmor *only* confines processes that the -+AppArmor policy says it should confine, and other processes are -+permitted to do anything that DAC permits. This is sometimes known as a -+targeted security policy. -+ -+AppArmor does not provide a "default" policy that applies to all -+processes. So to defend an entire host, you have to piece-wise confine -+each process that is exposed to potential attack. For instance, to -+defend a system against network attack, place AppArmor profiles around -+every application that accesses the network. This limits the damage a -+network attacker can do to the file system to only those files granted -+by the profiles for the network-available applications. Similarly, to -+defend a system against attack from the console, place AppArmor profiles -+around every application that accessed the keyboard and mouse. The -+system is "defended" in that the worst the attacker can do to corrupt -+the system is limited to the transitive closure of what the confined -+processes are allowed to access. -+ -+AppArmor currently mediates access to files, ability to use POSIX.1e -+Capabilities, and coarse-grained control on network access. This is -+sufficient to prevent a confined process from *directly* corrupting the -+file system. It is not sufficient to prevent a confined process from -+*indirectly* corrupting the system by influencing some other process to -+do the dirty deed. But to do so requires a complicit process that can be -+manipulated through another channel such as IPC. A "complicit" process -+is either a malicious process the attacker somehow got control of, or is -+a process that is actively listening to IPC of some kind and can be -+corrupted via IPC. -+ -+The only IPC that AppArmor mediates is access to named sockets, FIFOs, -+etc. that appear in the file system name space, a side effect of -+AppArmor's file access mediation. Future versions of AppArmor will -+mediate more resources, including finer grained network access controls, -+and controls on various forms of IPC. -+ -+AppArmor specifies the programs to be confined and the resources they -+can access in a syntax similar to how users are accustomed to accessing -+those resources. So file access controls are specified using absolute -+paths with respect to the name space the process is in. POSIX.1e -+capabilities are specified by name. Network access controls currently -+are specified by simply naming the protocol that can be used e.g. tcp, -+udp, and in the future will be more general, resembling firewall rules. -+ -+Thus the AppArmor security goal should be considered piecewise from the -+point of view of a single confined process: that process should only be -+able to access the resources specified in its profile: -+ -+ * can only access files that are reachable in its name space by path -+ names matching its profile, and only with the permitted modes: -+ read, append, write, memory map, execute, and link -+ * can only use the POSIX.1e capabilities listed in the profile -+ * can only perform the network operations listed in the profile -+ -+Security issues that AppArmor explicitly does *not* address: -+ -+ * Processes that are not confined by AppArmor are not restricted in -+ any way by AppArmor. If an unconfined process is considered an -+ unacceptable threat, then confine additional applications until -+ adequate security is achieved. -+ * A process that is not permitted to directly access a resource can -+ influence some other process that does have access to the resource -+ may do so, if the "influence" is a permitted action. -+ * A confined process may only access a file if it has at least one -+ of the files aliases specified in its profile. If a file alias is -+ not specified in the profile then it can not be accessed by that -+ path. The creation of aliases needs to be tightly controlled in -+ confined applications, hard links creation should be limited to -+ provide adequate security. -+ * A confined process can operate on a file descriptor passed to it -+ by an unconfined process, even if it manipulates a file not in the -+ confined process's profile. To block this attack, confine the -+ process that passed the file descriptor. -+ * Process activities not currently mediated by AppArmor are -+ permitted, e.g. confined processes can perform any IPC that DAC -+ permits, other than signals as mediated by CAP_KILL. -+ * Manipulating AppArmor policy requires being both root privileged -+ and not being confined by AppArmor, thus there is explicitly no -+ capability for non-privileged users to change AppArmor policy. -+ * AppArmor confines processes if they are children of a confined -+ process, or if the name of the exec'd child matches the name of an -+ AppArmor profile. Another process could copy a program to a -+ different path name and then execute it without confinement, but -+ the other process would have to have permission to do so in the -+ first place. To prevent this, confine the other process and -+ additional applications until adequate security is achieved. -+ * Mount and namespace manipulations can be used to arbitrarily -+ change the pathnames that files appear at, and thus completely -+ bypass AppArmor policy. To prevent this, processes confined by -+ AppArmor are currently not permitted to call mount or manipulate -+ name spaces at all. A future development may provide more granular -+ controls on mount and namespace manipulations. -+ * AppArmor does not slice bread, cure cancer, bring world peace, or -+ provide perfect security. This list may be expanded :-) -+ -+ diff --git a/kernel-patches/for-mainline/audit-log-type-in-syslog.diff b/kernel-patches/for-mainline/audit-log-type-in-syslog.diff deleted file mode 100644 index 518ca74c3..000000000 --- a/kernel-patches/for-mainline/audit-log-type-in-syslog.diff +++ /dev/null @@ -1,18 +0,0 @@ ---- - security/apparmor/main.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -159,8 +159,10 @@ static int aa_audit_base(struct aa_profi - return type == AUDIT_APPARMOR_ALLOWED ? 0 : -ENOMEM; - } - -+ audit_log_format(ab, " type=%d", type); -+ - if (sa->operation) -- audit_log_format(ab, "operation=\"%s\"", sa->operation); -+ audit_log_format(ab, " operation=\"%s\"", sa->operation); - - if (sa->info) { - audit_log_format(ab, " info=\"%s\"", sa->info); diff --git a/kernel-patches/for-mainline/audit-uid.diff b/kernel-patches/for-mainline/audit-uid.diff deleted file mode 100644 index d46110fe6..000000000 --- a/kernel-patches/for-mainline/audit-uid.diff +++ /dev/null @@ -1,16 +0,0 @@ ---- - security/apparmor/main.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -405,6 +405,9 @@ static int aa_audit_base(struct aa_profi - if (sa->denied_mask) - aa_audit_file_mask(ab, "denied_mask", sa->denied_mask); - -+ if (sa->request_mask) -+ audit_log_format(ab, " fsuid=%d", current->fsuid); -+ - if (sa->iattr) { - struct iattr *iattr = sa->iattr; - diff --git a/kernel-patches/for-mainline/cap-set.diff b/kernel-patches/for-mainline/cap-set.diff deleted file mode 100644 index 855bd5158..000000000 --- a/kernel-patches/for-mainline/cap-set.diff +++ /dev/null @@ -1,87 +0,0 @@ ---- - security/apparmor/apparmor.h | 10 ++++++++++ - security/apparmor/apparmorfs.c | 4 ++-- - security/apparmor/lsm.c | 15 ++++++--------- - security/apparmor/module_interface.c | 2 ++ - 4 files changed, 20 insertions(+), 11 deletions(-) - ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -158,8 +158,17 @@ struct aa_namespace { - * @file_rules: dfa containing the profiles file rules - * @flags: flags controlling profile behavior - * @isstale: flag indicating if profile is stale -+ * @set_caps: capabilities that are being set -+ * @capabilities: capabilities mask -+ * @audit_caps: caps that are to be audited -+ * @quiet_caps: caps that should not be audited - * @capabilities: capabilities granted by the process - * @count: reference count of the profile -+ * @task_contexts: list of tasks confined by profile -+ * @lock: lock for the task_contexts list -+ * @network_families: basic network permissions -+ * @audit_network: which network permissions to force audit -+ * @quiet_network: which network permissions to quiet rejects - * - * The AppArmor profile contains the basic confinement data. Each profile - * has a name, and all nonstale profile are in a profile namespace. -@@ -183,6 +192,7 @@ struct aa_profile { - } flags; - int isstale; - -+ kernel_cap_t set_caps; - kernel_cap_t capabilities; - kernel_cap_t audit_caps; - kernel_cap_t quiet_caps; ---- a/security/apparmor/apparmorfs.c -+++ b/security/apparmor/apparmorfs.c -@@ -103,8 +103,8 @@ static struct file_operations apparmorfs - static ssize_t aa_features_read(struct file *file, char __user *buf, - size_t size, loff_t *ppos) - { -- const char *features = "file=3.0 capability=1.0 network=1.0 " -- "change_hat=1.3 change_profile=1.0 " -+ const char *features = "file=3.0 capability=2.0 network=1.0 " -+ "change_hat=1.4 change_profile=1.0 " - "aanamespaces=1.0"; - - return simple_read_from_buffer(buf, size, ppos, features, ---- a/security/apparmor/lsm.c -+++ b/security/apparmor/lsm.c -@@ -210,19 +210,16 @@ static int apparmor_ptrace(struct task_s - static int apparmor_capable(struct task_struct *task, int cap) - { - int error; -+ struct aa_task_context *cxt; - - /* cap_capable returns 0 on success, else -EPERM */ - error = cap_capable(task, cap); - -- if (!error) { -- struct aa_task_context *cxt; -- -- rcu_read_lock(); -- cxt = aa_task_context(task); -- if (cxt) -- error = aa_capability(cxt, cap); -- rcu_read_unlock(); -- } -+ rcu_read_lock(); -+ cxt = aa_task_context(task); -+ if (cxt && (!error || cap_raised(cxt->profile->set_caps, cap))) -+ error = aa_capability(cxt, cap); -+ rcu_read_unlock(); - - return error; - } ---- a/security/apparmor/module_interface.c -+++ b/security/apparmor/module_interface.c -@@ -316,6 +316,8 @@ static struct aa_profile *aa_unpack_prof - goto fail; - if (!aa_is_u32(e, &(profile->quiet_caps), NULL)) - goto fail; -+ if (!aa_is_u32(e, &(profile->set_caps), NULL)) -+ goto fail; - - size = aa_is_array(e, "net_allowed_af"); - if (size) { diff --git a/kernel-patches/for-mainline/change-profile-kernel-v2.diff b/kernel-patches/for-mainline/change-profile-kernel-v2.diff deleted file mode 100644 index 4fdba982f..000000000 --- a/kernel-patches/for-mainline/change-profile-kernel-v2.diff +++ /dev/null @@ -1,95 +0,0 @@ -This patch removes magic cookies from the aa_change_profile interface, making -it a true one-way transition. - -It also fixes a refcounting bug with previous_profile by virtue of removing -the broken code entirely. - -Signed-off-by: Kenny Graunke -Signed-off-by: Seth Arnold - ---- - security/apparmor/apparmor.h | 2 +- - security/apparmor/main.c | 21 +++++++-------------- - security/apparmor/procattr.c | 9 +-------- - 3 files changed, 9 insertions(+), 23 deletions(-) ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -211,7 +211,7 @@ extern int aa_clone(struct task_struct * - extern int aa_register(struct linux_binprm *bprm); - extern void aa_release(struct task_struct *task); - extern int aa_change_hat(const char *id, u64 hat_magic); --extern int aa_change_profile(const char *name, u64 cookie); -+extern int aa_change_profile(const char *name); - extern struct aa_profile *__aa_find_profile(const char *name, - struct list_head *list); - extern struct aa_profile *__aa_replace_profile(struct task_struct *task, ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -1110,20 +1110,18 @@ out: - } - - /** -- * aa_change_profile - change profile to/from previous stored profile -+ * aa_change_profile - perform a one-way profile transition - * @name: name of profile to change to -- * @cookie: magic value to validate the profile change - * -- * Change to new profile @name, and store the @cookie in the current task -- * context. If the new @name is %NULL and the @cookie matches that -- * stored in the current task context, return to the previous profile. -+ * Change to new profile @name. Unlike with hats, there is no way -+ * to change back. - * - * Returns %0 on success, error otherwise. - */ --int aa_change_profile(const char *name, u64 cookie) -+int aa_change_profile(const char *name) - { - struct aa_task_context *cxt; -- struct aa_profile *profile, *previous_profile; -+ struct aa_profile *profile; - struct aa_audit sa; - int error = 0; - -@@ -1139,7 +1137,6 @@ repeat: - return -EPERM; - } - profile = aa_dup_profile(cxt->profile); -- previous_profile = aa_dup_profile(cxt->previous_profile); - task_unlock(current); - - if (name) { -@@ -1150,13 +1147,9 @@ repeat: - aa_put_profile(profile); - return -EACCES; - } -- error = do_change_profile(profile, name, cookie, 0, &sa); -- } else if (previous_profile) -- error = do_change_profile(profile, previous_profile->name, -- cookie, 1, &sa); -- /* else ignore restores when there is no saved profile */ -+ error = do_change_profile(profile, name, 0, 0, &sa); -+ } - -- aa_put_profile(previous_profile); - aa_put_profile(profile); - if (error == -ESTALE) - goto repeat; ---- a/security/apparmor/procattr.c -+++ b/security/apparmor/procattr.c -@@ -87,14 +87,7 @@ int aa_setprocattr_changehat(char *args) - - int aa_setprocattr_changeprofile(char *args) - { -- char *name; -- u64 cookie; -- -- name = split_token_from_name("change_profile", args, &cookie); -- if (IS_ERR(name)) -- return PTR_ERR(name); -- -- return aa_change_profile(name, cookie); -+ return aa_change_profile(args); - } - - int aa_setprocattr_setprofile(struct task_struct *task, char *args) diff --git a/kernel-patches/for-mainline/d_namespace_path.diff b/kernel-patches/for-mainline/d_namespace_path.diff deleted file mode 100644 index 92af69212..000000000 --- a/kernel-patches/for-mainline/d_namespace_path.diff +++ /dev/null @@ -1,86 +0,0 @@ -From: Andreas Gruenbacher -Subject: Add d_namespace_path() to compute namespace relative pathnames - -In AppArmor, we are interested in pathnames relative to the namespace root. -This is the same as d_path() except for the root where the search ends. Add -a function for computing the namespace-relative path. - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/dcache.c | 6 +++--- - fs/namespace.c | 27 +++++++++++++++++++++++++++ - include/linux/dcache.h | 2 ++ - include/linux/mount.h | 2 ++ - 4 files changed, 34 insertions(+), 3 deletions(-) - ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -1782,9 +1782,9 @@ shouldnt_be_hashed: - * - * Returns the buffer or an error code. - */ --static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt, -- struct dentry *root, struct vfsmount *rootmnt, -- char *buffer, int buflen, int fail_deleted) -+char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt, -+ struct dentry *root, struct vfsmount *rootmnt, -+ char *buffer, int buflen, int fail_deleted) - { - int namelen, is_slash, vfsmount_locked = 0; - ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -1883,3 +1883,30 @@ void __put_mnt_ns(struct mnt_namespace * - release_mounts(&umount_list); - kfree(ns); - } -+ -+char *d_namespace_path(struct dentry *dentry, struct vfsmount *vfsmnt, -+ char *buf, int buflen) -+{ -+ struct vfsmount *rootmnt, *nsrootmnt = NULL; -+ struct dentry *root = NULL; -+ char *res; -+ -+ read_lock(¤t->fs->lock); -+ rootmnt = mntget(current->fs->rootmnt); -+ read_unlock(¤t->fs->lock); -+ spin_lock(&vfsmount_lock); -+ if (rootmnt->mnt_ns) -+ nsrootmnt = mntget(rootmnt->mnt_ns->root); -+ spin_unlock(&vfsmount_lock); -+ mntput(rootmnt); -+ if (nsrootmnt) -+ root = dget(nsrootmnt->mnt_root); -+ res = __d_path(dentry, vfsmnt, root, nsrootmnt, buf, buflen, 1); -+ dput(root); -+ mntput(nsrootmnt); -+ /* Prevent empty path for lazily unmounted filesystems. */ -+ if (!IS_ERR(res) && *res == '\0') -+ *--res = '.'; -+ return res; -+} -+EXPORT_SYMBOL(d_namespace_path); ---- a/include/linux/dcache.h -+++ b/include/linux/dcache.h -@@ -300,6 +300,8 @@ extern int d_validate(struct dentry *, s - */ - extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); - -+extern char *__d_path(struct dentry *, struct vfsmount *, struct dentry *, -+ struct vfsmount *, char *, int, int); - extern char * d_path(struct dentry *, struct vfsmount *, char *, int); - - /* Allocation counts.. */ ---- a/include/linux/mount.h -+++ b/include/linux/mount.h -@@ -103,5 +103,7 @@ extern void shrink_submounts(struct vfsm - extern spinlock_t vfsmount_lock; - extern dev_t name_to_dev_t(char *name); - -+extern char *d_namespace_path(struct dentry *, struct vfsmount *, char *, int); -+ - #endif - #endif /* _LINUX_MOUNT_H */ diff --git a/kernel-patches/for-mainline/do_path_lookup-nameidata.diff b/kernel-patches/for-mainline/do_path_lookup-nameidata.diff deleted file mode 100644 index b797d741c..000000000 --- a/kernel-patches/for-mainline/do_path_lookup-nameidata.diff +++ /dev/null @@ -1,47 +0,0 @@ -From: Andreas Gruenbacher -Subject: Switch to vfs_permission() in do_path_lookup() - -Switch from file_permission() to vfs_permission() in do_path_lookup(): -this avoids calling permission() with a NULL nameidata here. - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/namei.c | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -1147,25 +1147,24 @@ static int fastcall do_path_lookup(int d - nd->dentry = dget(fs->pwd); - read_unlock(&fs->lock); - } else { -- struct dentry *dentry; -- - file = fget_light(dfd, &fput_needed); - retval = -EBADF; - if (!file) - goto out_fail; - -- dentry = file->f_path.dentry; -+ nd->dentry = file->f_path.dentry; -+ nd->mnt = file->f_path.mnt; - - retval = -ENOTDIR; -- if (!S_ISDIR(dentry->d_inode->i_mode)) -+ if (!S_ISDIR(nd->dentry->d_inode->i_mode)) - goto fput_fail; - -- retval = file_permission(file, MAY_EXEC); -+ retval = vfs_permission(nd, MAY_EXEC); - if (retval) - goto fput_fail; - -- nd->mnt = mntget(file->f_path.mnt); -- nd->dentry = dget(dentry); -+ mntget(nd->mnt); -+ dget(nd->dentry); - - fput_light(file, fput_needed); - } diff --git a/kernel-patches/for-mainline/ecryptfs-d_revalidate.diff b/kernel-patches/for-mainline/ecryptfs-d_revalidate.diff deleted file mode 100644 index cc79e5770..000000000 --- a/kernel-patches/for-mainline/ecryptfs-d_revalidate.diff +++ /dev/null @@ -1,42 +0,0 @@ -From: Andreas Gruenbacher -Subject: Check for NULL nameidata in ecryptfs_d_revalidate - -Some filesystems like nfsd and ecryptfs use lookup_one_len() on other -filesystems. This causes d_revalidate() calls with nd == NULL through -__lookup_hash() and cached_lookup(), so we need to check for NULL -nameidata. - -Signed-off-by: Andreas Gruenbacher -Cc: Mike Halcrow -Cc: Phillip Hellewell - ---- - fs/ecryptfs/dentry.c | 16 ++++++++++------ - 1 file changed, 10 insertions(+), 6 deletions(-) - ---- a/fs/ecryptfs/dentry.c -+++ b/fs/ecryptfs/dentry.c -@@ -51,13 +51,17 @@ static int ecryptfs_d_revalidate(struct - - if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate) - goto out; -- dentry_save = nd->dentry; -- vfsmount_save = nd->mnt; -- nd->dentry = lower_dentry; -- nd->mnt = lower_mnt; -+ if (nd) { -+ dentry_save = nd->dentry; -+ vfsmount_save = nd->mnt; -+ nd->dentry = lower_dentry; -+ nd->mnt = lower_mnt; -+ } - rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd); -- nd->dentry = dentry_save; -- nd->mnt = vfsmount_save; -+ if (nd) { -+ nd->dentry = dentry_save; -+ nd->mnt = vfsmount_save; -+ } - if (dentry->d_inode) { - struct inode *lower_inode = - ecryptfs_inode_to_lower(dentry->d_inode); diff --git a/kernel-patches/for-mainline/expand-dfa.diff b/kernel-patches/for-mainline/expand-dfa.diff deleted file mode 100644 index 0a40006fe..000000000 --- a/kernel-patches/for-mainline/expand-dfa.diff +++ /dev/null @@ -1,173 +0,0 @@ -Allow the dfa to return its state, which will allow for pair matches. - ---- - security/apparmor/apparmor.h | 7 ++- - security/apparmor/inline.h | 2 - security/apparmor/match.c | 99 ++++++++++++++++++++++++++++++++++++++----- - security/apparmor/match.h | 2 - 4 files changed, 99 insertions(+), 11 deletions(-) - ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -45,7 +45,6 @@ - - #define AA_SECURE_EXEC_NEEDED 1 - -- - /* Control parameters (0 or 1), settable thru module/boot flags or - * via /sys/kernel/security/apparmor/control */ - extern int apparmor_complain; -@@ -260,5 +259,11 @@ extern void aa_match_free(struct aa_dfa - extern int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size); - extern int verify_dfa(struct aa_dfa *dfa); - extern unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str); -+extern unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start, -+ const char *str); -+extern unsigned int aa_match_state(struct aa_dfa *dfa, unsigned int start, -+ const char *str, unsigned int *final); -+extern unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, -+ unsigned int start); - - #endif /* __APPARMOR_H */ ---- a/security/apparmor/inline.h -+++ b/security/apparmor/inline.h -@@ -12,6 +12,8 @@ - - #include - -+#include "match.h" -+ - static inline int mediated_filesystem(struct inode *inode) - { - return !(inode->i_sb->s_flags & MS_NOUSER); ---- a/security/apparmor/match.c -+++ b/security/apparmor/match.c -@@ -208,22 +208,26 @@ void aa_match_free(struct aa_dfa *dfa) - } - - /** -- * aa_dfa_match - match @path against @dfa starting in @state -- * @dfa: the dfa to match @path against -- * @state: the state to start matching in -- * @path: the path to match against the dfa -+ * aa_dfa_next_state - traverse @dfa to find state @str stops at -+ * @dfa: the dfa to match @str against -+ * @start: the state of the dfa to start matching in -+ * @str: the string to match against the dfa - * -- * aa_dfa_match will match the full path length and return the state it -- * finished matching in. The final state is used to look up the accepting -- * label. -+ * aa_dfa_next_state will match @str against the dfa and return the state it -+ * finished matching in. The final state can be used to look up the accepting -+ * label, or as the start state of a continuing match. - */ --unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str) -+unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start, -+ const char *str) - { - u16 *def = DEFAULT_TABLE(dfa); - u32 *base = BASE_TABLE(dfa); - u16 *next = NEXT_TABLE(dfa); - u16 *check = CHECK_TABLE(dfa); -- unsigned int state = 1, pos; -+ unsigned int state = start, pos; -+ -+ if (state == 0) -+ return 0; - - /* current state is , matching character *str */ - if (dfa->tables[YYTD_ID_EC - 1]) { -@@ -244,5 +248,80 @@ unsigned int aa_dfa_match(struct aa_dfa - state = def[state]; - } - } -- return ACCEPT_TABLE(dfa)[state]; -+ return state; -+} -+ -+/** -+ * aa_dfa_null_transition - step to next state after null character -+ * @dfa: the dfa to match against -+ * @start: the state of the dfa to start matching in -+ * -+ * aa_dfa_null_transition transitions to the next state after a null -+ * character which is not used in standard matching and is only -+ * used to seperate pairs. -+ */ -+unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start) -+{ -+ u16 *def = DEFAULT_TABLE(dfa); -+ u32 *base = BASE_TABLE(dfa); -+ u16 *next = NEXT_TABLE(dfa); -+ u16 *check = CHECK_TABLE(dfa); -+ unsigned int state = start, pos; -+ -+ /* current state is , matching character *str */ -+ if (dfa->tables[YYTD_ID_EC - 1]) { -+ u8 *equiv = EQUIV_TABLE(dfa); -+ pos = base[state] + equiv[0]; -+ if (check[pos] == state) -+ state = next[pos]; -+ else -+ state = def[state]; -+ } else { -+ pos = base[state] + 0; -+ if (check[pos] == state) -+ state = next[pos]; -+ else -+ state = def[state]; -+ } -+ -+ return state; -+} -+ -+/** -+ * aa_dfa_match - find accept perm for @str in @dfa -+ * @dfa: the dfa to match @str against -+ * @str: the string to match against the dfa -+ * -+ * aa_dfa_match will match @str and return the accept perms for the -+ * final state. -+ */ -+unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str) -+{ -+ return ACCEPT_TABLE(dfa)[aa_dfa_next_state(dfa, DFA_START, str)]; - } -+ -+/** -+ * aa_match_state - find accept perm and state for @str in @dfa -+ * @dfa: the dfa to match @str against -+ * @start: the state to start the match from -+ * @str: the string to match against the dfa -+ * @final: the state that the match finished in -+ * -+ * aa_match_state will match @str and return the accept perms, and @final -+ * state, the match occured in. -+ */ -+unsigned int aa_match_state(struct aa_dfa *dfa, unsigned int start, -+ const char *str, unsigned int *final) -+{ -+ unsigned int state; -+ if (dfa) { -+ state = aa_dfa_next_state(dfa, start, str); -+ if (final) -+ *final = state; -+ return ACCEPT_TABLE(dfa)[state]; -+ } -+ if (final) -+ *final = 0; -+ return 0; -+} -+ ---- a/security/apparmor/match.h -+++ b/security/apparmor/match.h -@@ -12,6 +12,8 @@ - #ifndef __MATCH_H - #define __MATCH_H - -+#define DFA_START 1 -+ - /** - * The format used for transition tables is based on the GNU flex table - * file format (--tables-file option; see Table File Format in the flex diff --git a/kernel-patches/for-mainline/extend-x-mods.diff b/kernel-patches/for-mainline/extend-x-mods.diff deleted file mode 100644 index 6efb542a8..000000000 --- a/kernel-patches/for-mainline/extend-x-mods.diff +++ /dev/null @@ -1,72 +0,0 @@ ---- - security/apparmor/apparmor.h | 43 ++++++++++++++++++++++++++++--------------- - 1 file changed, 28 insertions(+), 15 deletions(-) - ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -26,25 +26,33 @@ - #define AA_MAY_LINK 0x0010 - #define AA_MAY_LOCK 0x0020 - #define AA_EXEC_MMAP 0x0040 --#define AA_EXEC_UNSAFE 0x0080 --#define AA_EXEC_MOD_0 0x0100 --#define AA_EXEC_MOD_1 0x0200 -+#define AA_MAY_MOUNT 0x0080 /* no direct audit mapping */ -+#define AA_EXEC_UNSAFE 0x0100 -+#define AA_EXEC_MOD_0 0x0200 -+#define AA_EXEC_MOD_1 0x0400 -+#define AA_EXEC_MOD_2 0x0800 -+#define AA_EXEC_MOD_3 0x1000 -+#define AA_EXEC_MOD_4 0x2000 -+ - #define AA_BASE_PERMS (MAY_READ | MAY_WRITE | MAY_EXEC | \ - MAY_APPEND | AA_MAY_LINK | \ - AA_MAY_LOCK | AA_EXEC_MMAP | \ -- AA_EXEC_UNSAFE | AA_EXEC_MOD_0 | \ -- AA_EXEC_MOD_1) --#define AA_LINK_SUBSET_TEST 0x0020 -- --#define AA_EXEC_UNCONFINED 0 --#define AA_EXEC_INHERIT AA_EXEC_MOD_0 --#define AA_EXEC_PROFILE AA_EXEC_MOD_1 --#define AA_EXEC_PIX (AA_EXEC_MOD_0 | AA_EXEC_MOD_1) -- --#define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1) -+ AA_MAY_MOUNT | AA_EXEC_UNSAFE | \ -+ AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \ -+ AA_EXEC_MOD_2 | AA_EXEC_MOD_3 | \ -+ AA_EXEC_MOD_4) -+ -+#define AA_EXEC_UNCONFINED AA_EXEC_MOD_0 -+#define AA_EXEC_INHERIT AA_EXEC_MOD_1 -+#define AA_EXEC_PROFILE (AA_EXEC_MOD_0 | AA_EXEC_MOD_1) -+#define AA_EXEC_PIX AA_EXEC_MOD_2 -+ -+#define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \ -+ AA_EXEC_MOD_2 | AA_EXEC_MOD_3 | \ -+ AA_EXEC_MOD_4) - - #define AA_USER_SHIFT 0 --#define AA_OTHER_SHIFT 10 -+#define AA_OTHER_SHIFT 14 - - #define AA_USER_PERMS (AA_BASE_PERMS << AA_USER_SHIFT) - #define AA_OTHER_PERMS (AA_BASE_PERMS << AA_OTHER_SHIFT) -@@ -68,11 +76,16 @@ - #define AA_ALL_EXEC_MODS (AA_USER_EXEC_MODS | \ - AA_OTHER_EXEC_MODS) - -+/* overloaded permissions for link pairs */ -+#define AA_LINK_SUBSET_TEST 0x0020 -+ - /* shared permissions that are not duplicated in user::other */ -+#define AA_AUDIT_FIELD 0x10000000 - #define AA_CHANGE_HAT 0x20000000 - #define AA_CHANGE_PROFILE 0x40000000 - --#define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE) -+#define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE | \ -+ AA_AUDIT_FIELD) - - #define AA_VALID_PERM_MASK (AA_FILE_PERMS | AA_SHARED_PERMS) - diff --git a/kernel-patches/for-mainline/fgetattr.diff b/kernel-patches/for-mainline/fgetattr.diff deleted file mode 100644 index 92a69396b..000000000 --- a/kernel-patches/for-mainline/fgetattr.diff +++ /dev/null @@ -1,130 +0,0 @@ -From: Miklos Szeredi - -Add a new file operation: f_op->fgetattr(), that is invoked by -fstat(). Fall back to i_op->getattr() if it is not defined. - -We need this because fstat() semantics can in some cases be better -implemented if the filesystem has the open file available. - -Let's take the following example: we have a network filesystem, with -the server implemented as an unprivileged userspace process running on -a UNIX system (this is basically what sshfs does). - -We want the filesystem to follow the familiar UNIX file semantics as -closely as possible. If for example we have this sequence of events, -we still would like fstat to work correctly: - - 1) file X is opened on client - 2) file X is renamed to Y on server - 3) fstat() is performed on open file descriptor on client - -This is only possible if the filesystem server acutally uses fstat() -on a file descriptor obtained when the file was opened. Which means, -the filesystem client needs a way to get this information from the -VFS. - -Even if we assume, that the remote filesystem never changes, it is -difficult to implement open-unlink-fstat semantics correctly in the -client, without having this information. - -Signed-off-by: Miklos Szeredi -Signed-off-by: John Johansen ---- - ---- - fs/fuse/file.c | 13 +++++++++++++ - fs/stat.c | 29 ++++++++++++++++++++++++++++- - include/linux/fs.h | 1 + - 3 files changed, 42 insertions(+), 1 deletion(-) - ---- a/fs/fuse/file.c -+++ b/fs/fuse/file.c -@@ -871,6 +871,17 @@ static int fuse_file_flock(struct file * - return err; - } - -+static int fuse_file_fgetattr(struct file *file, struct kstat *stat) -+{ -+ struct inode *inode = file->f_dentry->d_inode; -+ struct fuse_conn *fc = get_fuse_conn(inode); -+ -+ if (!fuse_allow_task(fc, current)) -+ return -EACCES; -+ -+ return fuse_update_attributes(inode, stat, file, NULL); -+} -+ - static sector_t fuse_bmap(struct address_space *mapping, sector_t block) - { - struct inode *inode = mapping->host; -@@ -920,6 +931,7 @@ static const struct file_operations fuse - .fsync = fuse_fsync, - .lock = fuse_file_lock, - .flock = fuse_file_flock, -+ .fgetattr = fuse_file_fgetattr, - .splice_read = generic_file_splice_read, - }; - -@@ -933,6 +945,7 @@ static const struct file_operations fuse - .fsync = fuse_fsync, - .lock = fuse_file_lock, - .flock = fuse_file_flock, -+ .fgetattr = fuse_file_fgetattr, - /* no mmap and splice_read */ - }; - ---- a/fs/stat.c -+++ b/fs/stat.c -@@ -55,6 +55,33 @@ int vfs_getattr(struct vfsmount *mnt, st - - EXPORT_SYMBOL(vfs_getattr); - -+/* -+ * Perform getattr on an open file -+ * -+ * Fall back to i_op->getattr (or generic_fillattr) if the filesystem -+ * doesn't define an f_op->fgetattr operation. -+ */ -+static int vfs_fgetattr(struct file *file, struct kstat *stat) -+{ -+ struct vfsmount *mnt = file->f_path.mnt; -+ struct dentry *dentry = file->f_path.dentry; -+ struct inode *inode = dentry->d_inode; -+ int retval; -+ -+ retval = security_inode_getattr(mnt, dentry); -+ if (retval) -+ return retval; -+ -+ if (file->f_op && file->f_op->fgetattr) { -+ return file->f_op->fgetattr(file, stat); -+ } else if (inode->i_op->getattr) { -+ return inode->i_op->getattr(mnt, dentry, stat); -+ } else { -+ generic_fillattr(inode, stat); -+ return 0; -+ } -+} -+ - int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat) - { - struct nameidata nd; -@@ -101,7 +128,7 @@ int vfs_fstat(unsigned int fd, struct ks - int error = -EBADF; - - if (f) { -- error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat); -+ error = vfs_fgetattr(f, stat); - fput(f); - } - return error; ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1188,6 +1188,7 @@ struct file_operations { - ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); - ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); - int (*setlease)(struct file *, long, struct file_lock **); -+ int (*fgetattr)(struct file *, struct kstat *); - }; - - struct inode_operations { diff --git a/kernel-patches/for-mainline/file-handle-ops.diff b/kernel-patches/for-mainline/file-handle-ops.diff deleted file mode 100644 index d4da03f1f..000000000 --- a/kernel-patches/for-mainline/file-handle-ops.diff +++ /dev/null @@ -1,83 +0,0 @@ -From: Andreas Gruenbacher -Subject: Enable LSM hooks to distinguish operations on file descriptors from operations on pathnames - -Struct iattr already contains ia_file since commit cc4e69de from -Miklos (which is related to commit befc649c). Use this to pass -struct file down the setattr hooks. This allows LSMs to distinguish -operations on file descriptors from operations on paths. - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen -Cc: Miklos Szeredi - ---- - fs/nfsd/vfs.c | 12 +++++++----- - fs/open.c | 4 +++- - 2 files changed, 10 insertions(+), 6 deletions(-) - ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -413,7 +413,7 @@ static ssize_t nfsd_getxattr(struct dent - { - ssize_t buflen; - -- buflen = vfs_getxattr(dentry, mnt, key, NULL, 0); -+ buflen = vfs_getxattr(dentry, mnt, key, NULL, 0, NULL); - if (buflen <= 0) - return buflen; - -@@ -421,7 +421,7 @@ static ssize_t nfsd_getxattr(struct dent - if (!*buf) - return -ENOMEM; - -- return vfs_getxattr(dentry, mnt, key, *buf, buflen); -+ return vfs_getxattr(dentry, mnt, key, *buf, buflen, NULL); - } - #endif - -@@ -447,7 +447,7 @@ set_nfsv4_acl_one(struct dentry *dentry, - goto out; - } - -- error = vfs_setxattr(dentry, mnt, key, buf, len, 0); -+ error = vfs_setxattr(dentry, mnt, key, buf, len, 0, NULL); - out: - kfree(buf); - return error; -@@ -2051,12 +2051,14 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i - - mnt = fhp->fh_export->ex_mnt; - if (size) -- error = vfs_setxattr(fhp->fh_dentry, mnt, name, value, size,0); -+ error = vfs_setxattr(fhp->fh_dentry, mnt, name, value, size, 0, -+ NULL); - else { - if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT) - error = 0; - else { -- error = vfs_removexattr(fhp->fh_dentry, mnt, name); -+ error = vfs_removexattr(fhp->fh_dentry, mnt, name, -+ NULL); - if (error == -ENODATA) - error = 0; - } ---- a/fs/open.c -+++ b/fs/open.c -@@ -581,7 +581,7 @@ asmlinkage long sys_fchmod(unsigned int - if (mode == (mode_t) -1) - mode = inode->i_mode; - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); -- newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -+ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME | ATTR_FILE; - err = fnotify_change(dentry, file->f_path.mnt, &newattrs, file); - mutex_unlock(&inode->i_mutex); - -@@ -661,6 +661,8 @@ static int chown_common(struct dentry * - if (!S_ISDIR(inode->i_mode)) - newattrs.ia_valid |= - ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; -+ if (file) -+ newattrs.ia_valid |= ATTR_FILE; - mutex_lock(&inode->i_mutex); - error = fnotify_change(dentry, mnt, &newattrs, file); - mutex_unlock(&inode->i_mutex); diff --git a/kernel-patches/for-mainline/file_permission-nameidata.diff b/kernel-patches/for-mainline/file_permission-nameidata.diff deleted file mode 100644 index 4c0d7d72b..000000000 --- a/kernel-patches/for-mainline/file_permission-nameidata.diff +++ /dev/null @@ -1,31 +0,0 @@ -From: Andreas Gruenbacher -Subject: Fix file_permission() - -We cannot easily switch from file_permission() to vfs_permission() -everywhere, so fix file_permission() to not use a NULL nameidata -for the remaining users. - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/namei.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -313,7 +313,13 @@ int vfs_permission(struct nameidata *nd, - */ - int file_permission(struct file *file, int mask) - { -- return permission(file->f_path.dentry->d_inode, mask, NULL); -+ struct nameidata nd; -+ -+ nd.dentry = file->f_path.dentry; -+ nd.mnt = file->f_path.mnt; -+ nd.flags = LOOKUP_ACCESS; -+ -+ return permission(nd.dentry->d_inode, mask, &nd); - } - - /* diff --git a/kernel-patches/for-mainline/fix-change_profile-namespace.diff b/kernel-patches/for-mainline/fix-change_profile-namespace.diff deleted file mode 100644 index 605a9029f..000000000 --- a/kernel-patches/for-mainline/fix-change_profile-namespace.diff +++ /dev/null @@ -1,17 +0,0 @@ ---- - security/apparmor/main.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -1239,9 +1239,7 @@ repeat: - return -ENOENT; - } - -- if (PROFILE_COMPLAIN(profile) || -- (ns == profile->ns && -- (aa_match(profile->file_rules, name) & AA_CHANGE_PROFILE))) -+ if (PROFILE_COMPLAIN(profile)) - error = do_change_profile(profile, ns, name, 0, 0, &sa); - else { - /* check for a rule with a namespace prepended */ diff --git a/kernel-patches/for-mainline/fix-d_path.diff b/kernel-patches/for-mainline/fix-d_path.diff deleted file mode 100644 index 91bd6949c..000000000 --- a/kernel-patches/for-mainline/fix-d_path.diff +++ /dev/null @@ -1,68 +0,0 @@ -From: Andreas Gruenbacher -Subject: Distinguish between connected and disconnected paths in d_path() - -Change d_path() so that it will never return a path starting with '/' if -the path doesn't lead up to the chroot directory. Also ensure that the -path returned never is the empty string: this would only occur with a lazily unmounted file system; return "." in that case instead. - -Signed-off-by: Andreas Gruenbacher - ---- - fs/dcache.c | 18 ++++-------------- - fs/namespace.c | 3 --- - 2 files changed, 4 insertions(+), 17 deletions(-) - ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -1829,8 +1829,11 @@ global_root: - buffer++; - buflen++; - } -- if (is_slash) -+ if (is_slash) { -+ if (*buffer == '\0') -+ *--buffer = '.'; - goto out; -+ } - } - if (buflen < namelen) - goto Elong; -@@ -1843,18 +1846,6 @@ Elong: - goto out; - } - --static char *__connect_d_path(char *path, char *buffer) --{ -- if (!IS_ERR(path) && *path != '/') { -- /* Pretend that disconnected paths are hanging off the root. */ -- if (path == buffer) -- path = ERR_PTR(-ENAMETOOLONG); -- else -- *--path = '/'; -- } -- return path; --} -- - /* write full pathname into buffer and return start of pathname */ - char *d_path(struct dentry *dentry, struct vfsmount *vfsmnt, char *buf, - int buflen) -@@ -1868,7 +1859,6 @@ char *d_path(struct dentry *dentry, stru - root = dget(current->fs->root); - read_unlock(¤t->fs->lock); - res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, 0); -- res = __connect_d_path(res, buf); - dput(root); - mntput(rootmnt); - return res; ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -1917,9 +1917,6 @@ char *d_namespace_path(struct dentry *de - res = __d_path(dentry, vfsmnt, root, nsrootmnt, buf, buflen, 1); - dput(root); - mntput(nsrootmnt); -- /* Prevent empty path for lazily unmounted filesystems. */ -- if (!IS_ERR(res) && *res == '\0') -- *--res = '.'; - return res; - } - EXPORT_SYMBOL(d_namespace_path); diff --git a/kernel-patches/for-mainline/fix-dfa.diff b/kernel-patches/for-mainline/fix-dfa.diff deleted file mode 100644 index 6c0a18d4c..000000000 --- a/kernel-patches/for-mainline/fix-dfa.diff +++ /dev/null @@ -1,134 +0,0 @@ ---- - security/apparmor/match.c | 74 +++++++++++++++++++++++++++++++--------------- - 1 file changed, 51 insertions(+), 23 deletions(-) - ---- a/security/apparmor/match.c -+++ b/security/apparmor/match.c -@@ -213,17 +213,23 @@ void aa_match_free(struct aa_dfa *dfa) - } - - /** -- * aa_dfa_next_state - traverse @dfa to find state @str stops at -+ * aa_dfa_next_state_len - traverse @dfa to find state @str stops at - * @dfa: the dfa to match @str against - * @start: the state of the dfa to start matching in -- * @str: the string to match against the dfa -+ * @str: the string of bytes to match against the dfa -+ * @len: length of the string of bytes to match - * - * aa_dfa_next_state will match @str against the dfa and return the state it - * finished matching in. The final state can be used to look up the accepting - * label, or as the start state of a continuing match. -+ * -+ * aa_dfa_next_state could be implement using this function by doing -+ * return aa_dfa_next_state_len(dfa, start, str, strlen(str)); -+ * but that would require traversing the string twice and be slightly -+ * slower. - */ --unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start, -- const char *str) -+unsigned int aa_dfa_next_state_len(struct aa_dfa *dfa, unsigned int start, -+ const char *str, int len) - { - u16 *def = DEFAULT_TABLE(dfa); - u32 *base = BASE_TABLE(dfa); -@@ -237,7 +243,7 @@ unsigned int aa_dfa_next_state(struct aa - /* current state is , matching character *str */ - if (dfa->tables[YYTD_ID_EC - 1]) { - u8 *equiv = EQUIV_TABLE(dfa); -- while (*str) { -+ for (; len; len--) { - pos = base[state] + equiv[(u8)*str++]; - if (check[pos] == state) - state = next[pos]; -@@ -245,7 +251,7 @@ unsigned int aa_dfa_next_state(struct aa - state = def[state]; - } - } else { -- while (*str) { -+ for (; len; len--) { - pos = base[state] + (u8)*str++; - if (check[pos] == state) - state = next[pos]; -@@ -257,15 +263,17 @@ unsigned int aa_dfa_next_state(struct aa - } - - /** -- * aa_dfa_null_transition - step to next state after null character -- * @dfa: the dfa to match against -+ * aa_dfa_next_state - traverse @dfa to find state @str stops at -+ * @dfa: the dfa to match @str against - * @start: the state of the dfa to start matching in -+ * @str: the null terminated string of bytes to match against the dfa - * -- * aa_dfa_null_transition transitions to the next state after a null -- * character which is not used in standard matching and is only -- * used to seperate pairs. -+ * aa_dfa_next_state will match @str against the dfa and return the state it -+ * finished matching in. The final state can be used to look up the accepting -+ * label, or as the start state of a continuing match. - */ --unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start) -+unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start, -+ const char *str) - { - u16 *def = DEFAULT_TABLE(dfa); - u32 *base = BASE_TABLE(dfa); -@@ -273,26 +281,46 @@ unsigned int aa_dfa_null_transition(stru - u16 *check = CHECK_TABLE(dfa); - unsigned int state = start, pos; - -+ if (state == 0) -+ return 0; -+ - /* current state is , matching character *str */ - if (dfa->tables[YYTD_ID_EC - 1]) { - u8 *equiv = EQUIV_TABLE(dfa); -- pos = base[state] + equiv[0]; -- if (check[pos] == state) -- state = next[pos]; -- else -- state = def[state]; -+ while (*str) { -+ pos = base[state] + equiv[(u8)*str++]; -+ if (check[pos] == state) -+ state = next[pos]; -+ else -+ state = def[state]; -+ } - } else { -- pos = base[state] + 0; -- if (check[pos] == state) -- state = next[pos]; -- else -- state = def[state]; -+ while (*str) { -+ pos = base[state] + (u8)*str++; -+ if (check[pos] == state) -+ state = next[pos]; -+ else -+ state = def[state]; -+ } - } -- - return state; - } - - /** -+ * aa_dfa_null_transition - step to next state after null character -+ * @dfa: the dfa to match against -+ * @start: the state of the dfa to start matching in -+ * -+ * aa_dfa_null_transition transitions to the next state after a null -+ * character which is not used in standard matching and is only -+ * used to seperate pairs. -+ */ -+unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start) -+{ -+ return aa_dfa_next_state_len(dfa, start, "", 1); -+} -+ -+/** - * aa_dfa_match - find accept perm for @str in @dfa - * @dfa: the dfa to match @str against - * @str: the string to match against the dfa diff --git a/kernel-patches/for-mainline/fix-fuse.diff b/kernel-patches/for-mainline/fix-fuse.diff deleted file mode 100644 index b3920af6d..000000000 --- a/kernel-patches/for-mainline/fix-fuse.diff +++ /dev/null @@ -1,37 +0,0 @@ ---- - fs/fuse/dir.c | 2 +- - fs/fuse/file.c | 2 +- - fs/fuse/fuse_i.h | 3 +++ - 3 files changed, 5 insertions(+), 2 deletions(-) - ---- a/fs/fuse/dir.c -+++ b/fs/fuse/dir.c -@@ -1167,7 +1167,7 @@ static int fuse_setattr(struct dentry *e - return fuse_do_setattr(entry, attr, NULL); - } - --static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, -+int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, - struct kstat *stat) - { - struct inode *inode = entry->d_inode; ---- a/fs/fuse/file.c -+++ b/fs/fuse/file.c -@@ -855,7 +855,7 @@ static int fuse_file_fgetattr(struct fil - if (!fuse_allow_task(fc, current)) - return -EACCES; - -- return fuse_update_attributes(inode, stat, file, NULL); -+ return fuse_getattr(file->f_vfsmnt, file->f_dentry, stat); - } - - static sector_t fuse_bmap(struct address_space *mapping, sector_t block) ---- a/fs/fuse/fuse_i.h -+++ b/fs/fuse/fuse_i.h -@@ -597,3 +597,6 @@ int fuse_valid_type(int m); - int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task); - - u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id); -+ -+int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, -+ struct kstat *stat); diff --git a/kernel-patches/for-mainline/fix-getcwd.diff b/kernel-patches/for-mainline/fix-getcwd.diff deleted file mode 100644 index dae09bc24..000000000 --- a/kernel-patches/for-mainline/fix-getcwd.diff +++ /dev/null @@ -1,30 +0,0 @@ -From: Andreas Gruenbacher -Subject: Make getcwd() only return valid paths - -Make getcwd() fail with -ENOENT if the current working directory is -disconnected: the process is not asking for some previous name of that -directory but for the current name; returning a path meaningless in the -context of that process makes no sense. - -Signed-off-by: Andreas Gruenbacher - ---- - fs/dcache.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -1910,10 +1910,12 @@ asmlinkage long sys_getcwd(char __user * - read_unlock(¤t->fs->lock); - - cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1); -- cwd = __connect_d_path(cwd, page); - error = PTR_ERR(cwd); - if (IS_ERR(cwd)) - goto out; -+ error = -ENOENT; -+ if (*cwd != '/') -+ goto out; - - error = -ERANGE; - len = PAGE_SIZE + page - cwd; diff --git a/kernel-patches/for-mainline/fix-link-subset.diff b/kernel-patches/for-mainline/fix-link-subset.diff deleted file mode 100644 index 5ca853212..000000000 --- a/kernel-patches/for-mainline/fix-link-subset.diff +++ /dev/null @@ -1,76 +0,0 @@ ---- - security/apparmor/main.c | 37 ++++++++++++++++++++----------------- - 1 file changed, 20 insertions(+), 17 deletions(-) - ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -68,7 +68,7 @@ static int aa_link_denied(struct aa_prof - int *request_mask) - { - unsigned int state; -- int l_mode, t_mode, denied_mask = 0; -+ int l_mode, t_mode, l_subset, denied_mask = 0; - int link_mask = AA_MAY_LINK << target_mode; - - *request_mask = link_mask; -@@ -83,31 +83,35 @@ static int aa_link_denied(struct aa_prof - - if (!(mode & link_mask)) - denied_mask |= link_mask; -+ /* return if link subset test is not required */ - if (!(mode & (AA_LINK_SUBSET_TEST << target_mode))) - return denied_mask; - } - -- /* do link perm subset test */ -- t_mode = aa_match(profile->file_rules, target); -- -- /* Ignore valid-profile-transition flags. */ -- l_mode &= ~AA_SHARED_PERMS; -- t_mode &= ~AA_SHARED_PERMS; -- -- *request_mask = l_mode | link_mask; -- -- /* Link always requires 'l' on the link for both parts of the pair. -+ /* Do link perm subset test - * If a subset test is required a permission subset test of the - * perms for the link are done against the user:group:other of the - * target's 'r', 'w', 'x', 'a', 'k', and 'm' permissions. - * - * If the link has 'x', an exact match of all the execute flags -- * ('i', 'u', 'p'). safe exec is treated as a subset of unsafe exec -+ * must match. - */ --#define SUBSET_PERMS (AA_FILE_PERMS & ~AA_LINK_BITS) - denied_mask |= ~l_mode & link_mask; -- if (l_mode & SUBSET_PERMS) { -- denied_mask |= (l_mode & SUBSET_PERMS) & ~t_mode; -+ -+ t_mode = aa_match(profile->file_rules, target); -+ -+ -+ /* For actual subset test ignore valid-profile-transition flags, -+ * and link bits -+ */ -+ l_mode &= ~(AA_SHARED_PERMS | AA_LINK_BITS); -+ t_mode &= ~(AA_SHARED_PERMS | AA_LINK_BITS); -+ l_subset = l_mode & AA_FILE_PERMS; -+ -+ *request_mask = l_mode | link_mask; -+ -+ if (l_subset) { -+ denied_mask |= (l_subset) & ~t_mode; - if (denied_mask & AA_EXEC_BITS) - denied_mask |= l_mode & AA_ALL_EXEC_MODS; - else if (l_mode & AA_EXEC_BITS) { -@@ -126,9 +130,8 @@ static int aa_link_denied(struct aa_prof - denied_mask |= AA_OTHER_EXEC | - (l_mode & AA_OTHER_EXEC_MODS); - } -- } else -+ } else if (t_mode & AA_FILE_PERMS) - denied_mask |= t_mode | link_mask; --#undef SUBSET_PERMS - - return denied_mask; - } diff --git a/kernel-patches/for-mainline/fix-name-errorpath.diff b/kernel-patches/for-mainline/fix-name-errorpath.diff deleted file mode 100644 index a50277a44..000000000 --- a/kernel-patches/for-mainline/fix-name-errorpath.diff +++ /dev/null @@ -1,22 +0,0 @@ -fix bug where the error code and mask are not being set correctly -when pathname lookup fails. - ---- - security/apparmor/main.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -191,8 +191,10 @@ static int aa_perm_dentry(struct aa_prof - */ - if (PTR_ERR(sa->name) == -ENOENT && (check & AA_CHECK_FD)) - sa->denied_mask = 0; -- else -- sa->denied_mask = PTR_ERR(sa->name); -+ else { -+ sa->denied_mask = sa->requested_mask; -+ sa->error_code = PTR_ERR(sa->name); -+ } - sa->name = NULL; - } else - sa->denied_mask = aa_file_denied(profile, sa->name, diff --git a/kernel-patches/for-mainline/fix-named-transitions.diff b/kernel-patches/for-mainline/fix-named-transitions.diff deleted file mode 100644 index 725624e1d..000000000 --- a/kernel-patches/for-mainline/fix-named-transitions.diff +++ /dev/null @@ -1,26 +0,0 @@ ---- - security/apparmor/main.c | 2 +- - security/apparmor/module_interface.c | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -1119,7 +1119,7 @@ aa_x_to_profile(struct aa_profile *profi - default: - /* all other indexes are named transitions */ - index = AA_EXEC_INDEX(xmode); -- if (index - 4 > profile->exec_table_size) { -+ if (index - 4 >= profile->exec_table_size) { - sa->info = "invalid named transition - exec failed"; - sa->error_code = -EACCES; - new_profile = ERR_PTR(-EACCES); ---- a/security/apparmor/module_interface.c -+++ b/security/apparmor/module_interface.c -@@ -319,6 +319,7 @@ static int aa_unpack_exec_table(struct a - goto fail; - if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) - goto fail; -+ profile->exec_table_size = size; - } - return 1; - diff --git a/kernel-patches/for-mainline/fix-net.diff b/kernel-patches/for-mainline/fix-net.diff deleted file mode 100644 index ac13414a5..000000000 --- a/kernel-patches/for-mainline/fix-net.diff +++ /dev/null @@ -1,38 +0,0 @@ ---- - security/apparmor/lsm.c | 18 ------------------ - 1 file changed, 18 deletions(-) - ---- a/security/apparmor/lsm.c -+++ b/security/apparmor/lsm.c -@@ -717,22 +717,6 @@ static int apparmor_socket_shutdown(stru - return aa_revalidate_sk(sk, "socket_shutdown"); - } - --static int apparmor_socket_getpeersec_stream(struct socket *sock, -- char __user *optval, int __user *optlen, unsigned len) --{ -- struct sock *sk = sock->sk; -- -- return aa_revalidate_sk(sk, "socket_getpeersec_stream"); --} -- --static int apparmor_socket_getpeersec_dgram(struct socket *sock, -- struct sk_buff *skb, u32 *secid) --{ -- struct sock *sk = sock->sk; -- -- return aa_revalidate_sk(sk, "socket_getpeersec_dgram"); --} -- - static int apparmor_getprocattr(struct task_struct *task, char *name, - char **value) - { -@@ -882,8 +866,6 @@ struct security_operations apparmor_ops - .socket_getsockopt = apparmor_socket_getsockopt, - .socket_setsockopt = apparmor_socket_setsockopt, - .socket_shutdown = apparmor_socket_shutdown, -- .socket_getpeersec_stream = apparmor_socket_getpeersec_stream, -- .socket_getpeersec_dgram = apparmor_socket_getpeersec_dgram, - }; - - static void info_message(const char *str) diff --git a/kernel-patches/for-mainline/fix-profile-namespaces.diff b/kernel-patches/for-mainline/fix-profile-namespaces.diff deleted file mode 100644 index 0da22b79b..000000000 --- a/kernel-patches/for-mainline/fix-profile-namespaces.diff +++ /dev/null @@ -1,92 +0,0 @@ ---- - security/apparmor/list.c | 2 +- - security/apparmor/main.c | 20 +++++++++++--------- - security/apparmor/procattr.c | 13 +++++++------ - 3 files changed, 19 insertions(+), 16 deletions(-) - ---- a/security/apparmor/list.c -+++ b/security/apparmor/list.c -@@ -142,7 +142,7 @@ static int seq_show_profile(struct seq_f - seq_printf(f, "%s (%s)\n", profile->name, - PROFILE_COMPLAIN(profile) ? "complain" : "enforce"); - else -- seq_printf(f, "%s:%s (%s)\n", profile->ns->name, profile->name, -+ seq_printf(f, ":%s:%s (%s)\n", profile->ns->name, profile->name, - PROFILE_COMPLAIN(profile) ? "complain" : "enforce"); - return 0; - } ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -251,8 +251,10 @@ static int aa_audit_base(struct aa_profi - audit_log_format(ab, " profile="); - audit_log_untrustedstring(ab, profile->name); - -- audit_log_format(ab, " namespace="); -- audit_log_untrustedstring(ab, profile->ns->name); -+ if (profile->ns != default_namespace) { -+ audit_log_format(ab, " namespace="); -+ audit_log_untrustedstring(ab, profile->ns->name); -+ } - } - - audit_log_end(ab); -@@ -1364,15 +1366,15 @@ repeat: - - if (hat_name) { - char *name, *profile_name; -- /* Not Yet. This perm check is currently done by searching -- for the hat profile. When hat style profile names -- become more generic then this will be needed. -- if (!(aa_match(profile->file_rules, hat_name) & -- AA_CHANGE_PROFILE)) { -- error = -EACCES; -+ if (!PROFILE_COMPLAIN(profile) && -+ !(aa_match(profile->file_rules, hat_name, NULL) -+ & AA_CHANGE_HAT)) { -+ /* missing permission to change_hat is treated the -+ * same as a failed hat search */ -+ error = -ENOENT; - goto out; - } -- */ -+ - if (previous_profile) - profile_name = previous_profile->name; - else ---- a/security/apparmor/procattr.c -+++ b/security/apparmor/procattr.c -@@ -24,15 +24,16 @@ int aa_getprocattr(struct aa_profile *pr - mode_len = strlen(mode_str); - name_len = strlen(profile->name); - if (profile->ns != default_namespace) -- ns_len = strlen(profile->ns->name) + 1; -+ ns_len = strlen(profile->ns->name) + 2; - *len = mode_len + ns_len + name_len + 1; - str = kmalloc(*len, GFP_ATOMIC); - if (!str) - return -ENOMEM; - - if (ns_len) { -- memcpy(str, profile->ns->name, ns_len - 1); -- str += ns_len - 1; -+ *str++ = ':'; -+ memcpy(str, profile->ns->name, ns_len - 2); -+ str += ns_len - 2; - *str++ = ':'; - } - memcpy(str, profile->name, name_len); -@@ -96,11 +97,11 @@ int aa_setprocattr_changeprofile(char *a - { - char *name = args, *ns_name = NULL; - -- if (name[0] != '/') { -- char *split = strchr(name, ':'); -+ if (name[0] == ':') { -+ char *split = strchr(&name[1], ':'); - if (split) { - *split = 0; -- ns_name = name; -+ ns_name = &name[1]; - name = split + 1; - } - } diff --git a/kernel-patches/for-mainline/fix-rcu-deref.diff b/kernel-patches/for-mainline/fix-rcu-deref.diff deleted file mode 100644 index 795a54697..000000000 --- a/kernel-patches/for-mainline/fix-rcu-deref.diff +++ /dev/null @@ -1,18 +0,0 @@ -The old style of casting in the rcu_dereference fails to compile with -the newer rcu_dereference macro. - ---- - security/apparmor/inline.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/security/apparmor/inline.h -+++ b/security/apparmor/inline.h -@@ -19,7 +19,7 @@ static inline int mediated_filesystem(st - - static inline struct aa_task_context *aa_task_context(struct task_struct *task) - { -- return rcu_dereference((struct aa_task_context *)task->security); -+ return (struct aa_task_context *) rcu_dereference(task->security); - } - - /** diff --git a/kernel-patches/for-mainline/fix-user-audit.diff b/kernel-patches/for-mainline/fix-user-audit.diff deleted file mode 100644 index 1b464c6ed..000000000 --- a/kernel-patches/for-mainline/fix-user-audit.diff +++ /dev/null @@ -1,15 +0,0 @@ ---- - security/apparmor/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -338,7 +338,7 @@ static void aa_audit_file_mask(struct au - aa_audit_file_sub_mask(ab, other, - (mask & AA_OTHER_PERMS) >> AA_OTHER_SHIFT); - -- audit_log_format(ab, " %s=\"%s::%s\"", name, user, other); -+ audit_log_format(ab, " %s=\"%s:%s\"", name, user, other); - } - - static const char *address_families[] = { diff --git a/kernel-patches/for-mainline/fix-vfs_rmdir.diff b/kernel-patches/for-mainline/fix-vfs_rmdir.diff deleted file mode 100644 index b8e66c80b..000000000 --- a/kernel-patches/for-mainline/fix-vfs_rmdir.diff +++ /dev/null @@ -1,44 +0,0 @@ -From: John Johansen -Subject: Call lsm hook before unhashing dentry in vfs_rmdir() - -If we unhash the dentry before calling the security_inode_rmdir hook, -we cannot compute the file's pathname in the hook anymore. AppArmor -needs to know the filename in order to decide whether a file may be -deleted, though. - -Signed-off-by: John Johansen -Signed-off-by: Andreas Gruenbacher - ---- - fs/namei.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2097,6 +2097,10 @@ int vfs_rmdir(struct inode *dir, struct - if (!dir->i_op || !dir->i_op->rmdir) - return -EPERM; - -+ error = security_inode_rmdir(dir, dentry, mnt); -+ if (error) -+ return error; -+ - DQUOT_INIT(dir); - - mutex_lock(&dentry->d_inode->i_mutex); -@@ -2104,12 +2108,9 @@ int vfs_rmdir(struct inode *dir, struct - if (d_mountpoint(dentry)) - error = -EBUSY; - else { -- error = security_inode_rmdir(dir, dentry, mnt); -- if (!error) { -- error = dir->i_op->rmdir(dir, dentry); -- if (!error) -- dentry->d_inode->i_flags |= S_DEAD; -- } -+ error = dir->i_op->rmdir(dir, dentry); -+ if (!error) -+ dentry->d_inode->i_flags |= S_DEAD; - } - mutex_unlock(&dentry->d_inode->i_mutex); - if (!error) { diff --git a/kernel-patches/for-mainline/foobar.diff b/kernel-patches/for-mainline/foobar.diff deleted file mode 100644 index 94ea97aeb..000000000 --- a/kernel-patches/for-mainline/foobar.diff +++ /dev/null @@ -1,278 +0,0 @@ ---- - security/Makefile | 2 - security/foobar/Makefile | 1 - security/foobar/foobar.c | 257 +++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 260 insertions(+) - ---- a/security/Makefile -+++ b/security/Makefile -@@ -16,3 +16,5 @@ obj-$(CONFIG_SECURITY) += security.o d - obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o - obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o - obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o -+ -+subdir-$(CONFIG_SECURITY) += foobar ---- /dev/null -+++ b/security/foobar/Makefile -@@ -0,0 +1 @@ -+obj-m += foobar.o ---- /dev/null -+++ b/security/foobar/foobar.c -@@ -0,0 +1,257 @@ -+#include -+#include -+#include -+ -+#define log_path(dentry, mnt, fmt...) \ -+ __log_path(__FUNCTION__, dentry, mnt, NULL, ##fmt) -+ -+#define log_path_inode(inode, fmt...) \ -+ __log_path(__FUNCTION__, NULL, NULL, inode, ##fmt) -+ -+static int show_traversals; -+module_param(show_traversals, bool, 0644); -+ -+static void __log_path(const char *op, struct dentry *dentry, -+ struct vfsmount *mnt, struct inode *inode, -+ char *fmt, ...) -+{ -+ va_list ap; -+ char *page = NULL, *name = ""; -+ -+ page = (char *)__get_free_page(GFP_KERNEL); -+ if (!page) -+ name = ""; -+ else if (mnt) { -+ name = d_path(dentry, mnt, page + 1, PAGE_SIZE - 2); -+ if (IS_ERR(name)) { -+ snprintf(page, PAGE_SIZE, "<%ld>", PTR_ERR(name)); -+ name = page; -+ } else { -+ page[PAGE_SIZE - 2] = '"'; -+ page[PAGE_SIZE - 1] = '\0'; -+ *--name = '"'; -+ } -+ } else if (dentry) { -+ snprintf(page, PAGE_SIZE, "<%s>", dentry->d_name.name); -+ name = page; -+ } else if (inode) { -+ snprintf(page, PAGE_SIZE, "<%s:%ld>", -+ inode->i_sb->s_type->name, -+ inode->i_ino); -+ name = page; -+ } -+ -+ if (fmt) { -+ char *buffer = (char *)__get_free_page(GFP_KERNEL); -+ -+ if (buffer) { -+ int n; -+ -+ n = snprintf(buffer, PAGE_SIZE, KERN_INFO "%s(%s, ", -+ op, name); -+ va_start(ap, fmt); -+ n += vsnprintf(buffer + n, PAGE_SIZE - n, fmt, ap); -+ va_end(ap); -+ snprintf(buffer + n, PAGE_SIZE - n, ")\n"); -+ printk("%s", buffer); -+ -+ free_page((unsigned long)buffer); -+ } else -+ printk("%s: Out of memory\n", __FUNCTION__); -+ } else -+ printk(KERN_INFO "%s(%s)\n", op, name); -+ -+ free_page((unsigned long)page); -+} -+ -+static int foobar_inode_mkdir(struct inode *inode, struct dentry *dentry, -+ struct vfsmount *mnt, int mask) -+{ -+ log_path(dentry, mnt, NULL); -+ -+ return 0; -+} -+ -+static int foobar_inode_rmdir(struct inode *inode, struct dentry *dentry, -+ struct vfsmount *mnt) -+{ -+ log_path(dentry, mnt, NULL); -+ -+ return 0; -+} -+ -+static int foobar_inode_create(struct inode *inode, struct dentry *dentry, -+ struct vfsmount *mnt, int mask) -+{ -+ log_path(dentry, mnt, NULL); -+ -+ return 0; -+} -+ -+static int foobar_inode_link(struct dentry *old_dentry, -+ struct vfsmount *old_mnt, -+ struct inode *inode, -+ struct dentry *new_dentry, -+ struct vfsmount *new_mnt) -+{ -+ log_path(old_dentry, old_mnt, ""); -+ log_path(new_dentry, new_mnt, ""); -+ -+ return 0; -+} -+ -+static int foobar_inode_unlink(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt) -+{ -+ log_path(dentry, mnt, NULL); -+ -+ return 0; -+} -+ -+static int foobar_inode_mknod(struct inode *inode, struct dentry *dentry, -+ struct vfsmount *mnt, int mode, dev_t dev) -+{ -+ log_path(dentry, mnt, NULL); -+ -+ return 0; -+} -+ -+static int foobar_inode_rename(struct inode *old_inode, -+ struct dentry *old_dentry, -+ struct vfsmount *old_mnt, -+ struct inode *new_inode, -+ struct dentry *new_dentry, -+ struct vfsmount *new_mnt) -+{ -+ log_path(old_dentry, old_mnt, ""); -+ log_path(new_dentry, new_mnt, ""); -+ -+ return 0; -+} -+ -+static int foobar_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, -+ struct iattr *iattr) -+{ -+ log_path(dentry, mnt, NULL); -+ -+ return 0; -+} -+ -+static int foobar_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *name, void *value, size_t size, -+ int flags, struct file *file) -+{ -+ log_path(dentry, mnt, NULL); -+ -+ return 0; -+} -+ -+static int foobar_inode_getxattr(struct dentry *dentry, -+ struct vfsmount *mnt, char *name, struct file *file) -+{ -+ log_path(dentry, mnt, NULL); -+ -+ return 0; -+} -+ -+static int foobar_inode_listxattr(struct dentry *dentry, -+ struct vfsmount *mnt, struct file *file) -+{ -+ log_path(dentry, mnt, NULL); -+ -+ return 0; -+} -+ -+static int foobar_inode_removexattr(struct dentry *dentry, -+ struct vfsmount *mnt, char *name, struct file *file) -+{ -+ log_path(dentry, mnt, NULL); -+ -+ return 0; -+} -+ -+static int foobar_inode_symlink(struct inode *dir, -+ struct dentry *dentry, struct vfsmount *mnt, -+ const char *old_name) -+{ -+ log_path(dentry, mnt, NULL); -+ -+ return 0; -+} -+ -+static int foobar_inode_permission(struct inode *inode, int mask, -+ struct nameidata *nd) -+{ -+ if (nd && (nd->flags & (LOOKUP_PARENT | LOOKUP_CONTINUE)) && -+ !show_traversals) -+ return 0; -+ -+ if (nd) { -+ char *parent = "", *sep="", *cont = ""; -+ -+ if (nd->flags & LOOKUP_PARENT) -+ parent = "LOOKUP_PARENT"; -+ if (nd->flags & LOOKUP_CONTINUE) -+ cont = "LOOKUP_CONTINUE"; -+ if ((nd->flags & (LOOKUP_PARENT | LOOKUP_CONTINUE)) == -+ (LOOKUP_PARENT | LOOKUP_CONTINUE)) -+ sep = ", "; -+ else if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_CONTINUE))) -+ sep = "0"; -+ -+ log_path(nd->dentry, nd->mnt, "%c%c%c%c, %s%s%s", -+ mask & MAY_READ ? 'r' : '-', -+ mask & MAY_WRITE ? 'w' : '-', -+ mask & MAY_EXEC ? 'x' : '-', -+ mask & MAY_APPEND ? 'a' : '-', -+ parent, sep, cont); -+ } else { -+ log_path_inode(inode, "%c%c%c%c, 0", -+ mask & MAY_READ ? 'r' : '-', -+ mask & MAY_WRITE ? 'w' : '-', -+ mask & MAY_EXEC ? 'x' : '-', -+ mask & MAY_APPEND ? 'a' : '-'); -+ } -+ -+ return 0; -+} -+ -+struct security_operations foobar_ops = { -+ .inode_create = foobar_inode_create, -+ .inode_link = foobar_inode_link, -+ .inode_unlink = foobar_inode_unlink, -+ .inode_mkdir = foobar_inode_mkdir, -+ .inode_rmdir = foobar_inode_rmdir, -+ .inode_mknod = foobar_inode_mknod, -+ .inode_rename = foobar_inode_rename, -+ .inode_setattr = foobar_inode_setattr, -+ .inode_setxattr = foobar_inode_setxattr, -+ .inode_getxattr = foobar_inode_getxattr, -+ .inode_listxattr = foobar_inode_listxattr, -+ .inode_removexattr = foobar_inode_removexattr, -+ .inode_symlink = foobar_inode_symlink, -+ .inode_permission = foobar_inode_permission, -+}; -+ -+static int __init foobar_init(void) -+{ -+ int error; -+ -+ error = register_security(&foobar_ops); -+ if (error) -+ printk(KERN_ERR "Unable to load foobar lsm\n"); -+ -+ return error; -+} -+ -+static void __exit foobar_exit(void) -+{ -+ if (unregister_security(&foobar_ops)) -+ printk(KERN_ERR "Unable to properly unregister foobar lsm\n"); -+} -+ -+module_init(foobar_init); -+module_exit(foobar_exit); -+ -+MODULE_DESCRIPTION("lsm module logging to syslog"); -+MODULE_LICENSE("GPL"); diff --git a/kernel-patches/for-mainline/fsetattr-reintro-ATTR_FILE.diff b/kernel-patches/for-mainline/fsetattr-reintro-ATTR_FILE.diff deleted file mode 100644 index 745dab65c..000000000 --- a/kernel-patches/for-mainline/fsetattr-reintro-ATTR_FILE.diff +++ /dev/null @@ -1,27 +0,0 @@ ---- - fs/open.c | 3 +++ - include/linux/fs.h | 1 + - 2 files changed, 4 insertions(+) - ---- a/fs/open.c -+++ b/fs/open.c -@@ -207,6 +207,9 @@ int do_truncate(struct dentry *dentry, s - newattrs.ia_size = length; - newattrs.ia_valid = ATTR_SIZE | time_attrs; - -+ if (filp) -+ newattrs.ia_valid |= ATTR_FILE; -+ - /* Remove suid/sgid on truncate too */ - newattrs.ia_valid |= should_remove_suid(dentry); - ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -329,6 +329,7 @@ typedef void (dio_iodone_t)(struct kiocb - #define ATTR_ATTR_FLAG 1024 - #define ATTR_KILL_SUID 2048 - #define ATTR_KILL_SGID 4096 -+#define ATTR_FILE 8192 - #define ATTR_KILL_PRIV 16384 - #define ATTR_OPEN 32768 /* Truncating from open(O_TRUNC) */ - diff --git a/kernel-patches/for-mainline/fsetattr.diff b/kernel-patches/for-mainline/fsetattr.diff deleted file mode 100644 index 1ec84054e..000000000 --- a/kernel-patches/for-mainline/fsetattr.diff +++ /dev/null @@ -1,392 +0,0 @@ -Subject: VFS: new fsetattr() file operation - -From: Miklos Szeredi - -Add a new file operation: f_op->fsetattr(), that is invoked by -ftruncate, fchmod, fchown and utimensat. Fall back to i_op->setattr() -if it is not defined. - -For the reasons why we need this, see patch adding fgetattr(). - -ftruncate() already passed the open file to the filesystem via the -ia_file member of struct iattr. However it is cleaner to have a -separate file operation for this, so remove ia_file, ATTR_FILE and -convert existing users: fuse and AFS. - -Signed-off-by: Miklos Szeredi --- -Signed-off-by: John Johansen --- - ---- - fs/afs/dir.c | 1 + - fs/afs/file.c | 1 + - fs/afs/inode.c | 19 +++++++++++++++---- - fs/afs/internal.h | 1 + - fs/attr.c | 18 ++++++++++++++---- - fs/fuse/dir.c | 20 +++++++++----------- - fs/fuse/file.c | 7 +++++++ - fs/fuse/fuse_i.h | 4 ++++ - fs/open.c | 20 ++++++++------------ - fs/utimes.c | 2 +- - include/linux/fs.h | 10 ++-------- - 11 files changed, 63 insertions(+), 40 deletions(-) - ---- a/fs/afs/dir.c -+++ b/fs/afs/dir.c -@@ -45,6 +45,7 @@ const struct file_operations afs_dir_fil - .release = afs_release, - .readdir = afs_readdir, - .lock = afs_lock, -+ .fsetattr = afs_fsetattr, - }; - - const struct inode_operations afs_dir_inode_operations = { ---- a/fs/afs/file.c -+++ b/fs/afs/file.c -@@ -36,6 +36,7 @@ const struct file_operations afs_file_op - .fsync = afs_fsync, - .lock = afs_lock, - .flock = afs_flock, -+ .fsetattr = afs_fsetattr, - }; - - const struct inode_operations afs_file_inode_operations = { ---- a/fs/afs/inode.c -+++ b/fs/afs/inode.c -@@ -360,7 +360,8 @@ void afs_clear_inode(struct inode *inode - /* - * set the attributes of an inode - */ --int afs_setattr(struct dentry *dentry, struct iattr *attr) -+static int afs_do_setattr(struct dentry *dentry, struct iattr *attr, -+ struct file *file) - { - struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode); - struct key *key; -@@ -382,8 +383,8 @@ int afs_setattr(struct dentry *dentry, s - afs_writeback_all(vnode); - } - -- if (attr->ia_valid & ATTR_FILE) { -- key = attr->ia_file->private_data; -+ if (file) { -+ key = file->private_data; - } else { - key = afs_request_key(vnode->volume->cell); - if (IS_ERR(key)) { -@@ -393,10 +394,20 @@ int afs_setattr(struct dentry *dentry, s - } - - ret = afs_vnode_setattr(vnode, key, attr); -- if (!(attr->ia_valid & ATTR_FILE)) -+ if (!file) - key_put(key); - - error: - _leave(" = %d", ret); - return ret; - } -+ -+int afs_setattr(struct dentry *dentry, struct iattr *attr) -+{ -+ return afs_do_setattr(dentry, attr, NULL); -+} -+ -+int afs_fsetattr(struct file *file, struct iattr *attr) -+{ -+ return afs_do_setattr(file->f_path.dentry, attr, file); -+} ---- a/fs/afs/internal.h -+++ b/fs/afs/internal.h -@@ -550,6 +550,7 @@ extern void afs_zap_data(struct afs_vnod - extern int afs_validate(struct afs_vnode *, struct key *); - extern int afs_getattr(struct vfsmount *, struct dentry *, struct kstat *); - extern int afs_setattr(struct dentry *, struct iattr *); -+extern int afs_fsetattr(struct file *, struct iattr *); - extern void afs_clear_inode(struct inode *); - - /* ---- a/fs/attr.c -+++ b/fs/attr.c -@@ -100,8 +100,8 @@ int inode_setattr(struct inode * inode, - } - EXPORT_SYMBOL(inode_setattr); - --int notify_change(struct dentry *dentry, struct vfsmount *mnt, -- struct iattr *attr) -+int fnotify_change(struct dentry *dentry, struct vfsmount *mnt, -+ struct iattr *attr, struct file *file) - { - struct inode *inode = dentry->d_inode; - mode_t mode = inode->i_mode; -@@ -160,8 +160,12 @@ int notify_change(struct dentry *dentry, - - if (inode->i_op && inode->i_op->setattr) { - error = security_inode_setattr(dentry, mnt, attr); -- if (!error) -- error = inode->i_op->setattr(dentry, attr); -+ if (!error) { -+ if (file && file->f_op && file->f_op->fsetattr) -+ error = file->f_op->fsetattr(file, attr); -+ else -+ error = inode->i_op->setattr(dentry, attr); -+ } - } else { - error = inode_change_ok(inode, attr); - if (!error) -@@ -184,4 +188,10 @@ int notify_change(struct dentry *dentry, - return error; - } - -+int notify_change(struct dentry *dentry, struct vfsmount *mnt, -+ struct iattr *attr) -+{ -+ return fnotify_change(dentry, mnt, attr, NULL); -+} -+ - EXPORT_SYMBOL(notify_change); ---- a/fs/fuse/dir.c -+++ b/fs/fuse/dir.c -@@ -1063,21 +1063,22 @@ static int fuse_dir_fsync(struct file *f - return file ? fuse_fsync_common(file, de, datasync, 1) : 0; - } - --static bool update_mtime(unsigned ivalid) -+static bool update_mtime(unsigned ivalid, bool have_file) - { - /* Always update if mtime is explicitly set */ - if (ivalid & ATTR_MTIME_SET) - return true; - - /* If it's an open(O_TRUNC) or an ftruncate(), don't update */ -- if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE))) -+ if ((ivalid & ATTR_SIZE) && ((ivalid & ATTR_OPEN) || have_file)) - return false; - - /* In all other cases update */ - return true; - } - --static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) -+static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg, -+ bool have_file) - { - unsigned ivalid = iattr->ia_valid; - -@@ -1096,7 +1097,7 @@ static void iattr_to_fattr(struct iattr - if (!(ivalid & ATTR_ATIME_SET)) - arg->valid |= FATTR_ATIME_NOW; - } -- if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) { -+ if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, have_file)) { - arg->valid |= FATTR_MTIME; - arg->mtime = iattr->ia_mtime.tv_sec; - arg->mtimensec = iattr->ia_mtime.tv_nsec; -@@ -1113,8 +1114,8 @@ static void iattr_to_fattr(struct iattr - * vmtruncate() doesn't allow for this case, so do the rlimit checking - * and the actual truncation by hand. - */ --static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, -- struct file *file) -+int fuse_do_setattr(struct dentry *entry, struct iattr *attr, -+ struct file *file) - { - struct inode *inode = entry->d_inode; - struct fuse_conn *fc = get_fuse_conn(inode); -@@ -1152,7 +1153,7 @@ static int fuse_do_setattr(struct dentry - - memset(&inarg, 0, sizeof(inarg)); - memset(&outarg, 0, sizeof(outarg)); -- iattr_to_fattr(attr, &inarg); -+ iattr_to_fattr(attr, &inarg, file != NULL); - if (file) { - struct fuse_file *ff = file->private_data; - inarg.valid |= FATTR_FH; -@@ -1194,10 +1195,7 @@ static int fuse_do_setattr(struct dentry - - static int fuse_setattr(struct dentry *entry, struct iattr *attr) - { -- if (attr->ia_valid & ATTR_FILE) -- return fuse_do_setattr(entry, attr, attr->ia_file); -- else -- return fuse_do_setattr(entry, attr, NULL); -+ return fuse_do_setattr(entry, attr, NULL); - } - - static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, ---- a/fs/fuse/file.c -+++ b/fs/fuse/file.c -@@ -907,6 +907,11 @@ static sector_t fuse_bmap(struct address - return err ? 0 : outarg.block; - } - -+static int fuse_fsetattr(struct file *file, struct iattr *attr) -+{ -+ return fuse_do_setattr(file->f_path.dentry, attr, file); -+} -+ - static const struct file_operations fuse_file_operations = { - .llseek = generic_file_llseek, - .read = do_sync_read, -@@ -920,6 +925,7 @@ static const struct file_operations fuse - .fsync = fuse_fsync, - .lock = fuse_file_lock, - .flock = fuse_file_flock, -+ .fsetattr = fuse_fsetattr, - .splice_read = generic_file_splice_read, - }; - -@@ -933,6 +939,7 @@ static const struct file_operations fuse - .fsync = fuse_fsync, - .lock = fuse_file_lock, - .flock = fuse_file_flock, -+ .fsetattr = fuse_fsetattr, - /* no mmap and splice_read */ - }; - ---- a/fs/fuse/fuse_i.h -+++ b/fs/fuse/fuse_i.h -@@ -505,6 +505,10 @@ void fuse_change_attributes(struct inode - */ - int fuse_dev_init(void); - -+ -+int fuse_do_setattr(struct dentry *entry, struct iattr *attr, -+ struct file *file); -+ - /** - * Cleanup the client device - */ ---- a/fs/open.c -+++ b/fs/open.c -@@ -206,16 +206,12 @@ int do_truncate(struct dentry *dentry, s - - newattrs.ia_size = length; - newattrs.ia_valid = ATTR_SIZE | time_attrs; -- if (filp) { -- newattrs.ia_file = filp; -- newattrs.ia_valid |= ATTR_FILE; -- } - - /* Remove suid/sgid on truncate too */ - newattrs.ia_valid |= should_remove_suid(dentry); - - mutex_lock(&dentry->d_inode->i_mutex); -- err = notify_change(dentry, mnt, &newattrs); -+ err = fnotify_change(dentry, mnt, &newattrs, filp); - mutex_unlock(&dentry->d_inode->i_mutex); - return err; - } -@@ -583,7 +579,7 @@ asmlinkage long sys_fchmod(unsigned int - mode = inode->i_mode; - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -- err = notify_change(dentry, file->f_path.mnt, &newattrs); -+ err = fnotify_change(dentry, file->f_path.mnt, &newattrs, file); - mutex_unlock(&inode->i_mutex); - - out_putf: -@@ -633,7 +629,7 @@ asmlinkage long sys_chmod(const char __u - } - - static int chown_common(struct dentry * dentry, struct vfsmount *mnt, -- uid_t user, gid_t group) -+ uid_t user, gid_t group, struct file *file) - { - struct inode * inode; - int error; -@@ -663,7 +659,7 @@ static int chown_common(struct dentry * - newattrs.ia_valid |= - ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; - mutex_lock(&inode->i_mutex); -- error = notify_change(dentry, mnt, &newattrs); -+ error = fnotify_change(dentry, mnt, &newattrs, file); - mutex_unlock(&inode->i_mutex); - out: - return error; -@@ -677,7 +673,7 @@ asmlinkage long sys_chown(const char __u - error = user_path_walk(filename, &nd); - if (error) - goto out; -- error = chown_common(nd.dentry, nd.mnt, user, group); -+ error = chown_common(nd.dentry, nd.mnt, user, group, NULL); - path_release(&nd); - out: - return error; -@@ -697,7 +693,7 @@ asmlinkage long sys_fchownat(int dfd, co - error = __user_walk_fd(dfd, filename, follow, &nd); - if (error) - goto out; -- error = chown_common(nd.dentry, nd.mnt, user, group); -+ error = chown_common(nd.dentry, nd.mnt, user, group, NULL); - path_release(&nd); - out: - return error; -@@ -711,7 +707,7 @@ asmlinkage long sys_lchown(const char __ - error = user_path_walk_link(filename, &nd); - if (error) - goto out; -- error = chown_common(nd.dentry, nd.mnt, user, group); -+ error = chown_common(nd.dentry, nd.mnt, user, group, NULL); - path_release(&nd); - out: - return error; -@@ -730,7 +726,7 @@ asmlinkage long sys_fchown(unsigned int - - dentry = file->f_path.dentry; - audit_inode(NULL, dentry); -- error = chown_common(dentry, file->f_path.mnt, user, group); -+ error = chown_common(dentry, file->f_path.mnt, user, group, file); - fput(file); - out: - return error; ---- a/fs/utimes.c -+++ b/fs/utimes.c -@@ -132,7 +132,7 @@ long do_utimes(int dfd, char __user *fil - } - } - mutex_lock(&inode->i_mutex); -- error = notify_change(path.dentry, path.mnt, &newattrs); -+ error = fnotify_change(path.dentry, path.mnt, &newattrs, f); - mutex_unlock(&inode->i_mutex); - dput_and_out: - if (f) ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -329,7 +329,6 @@ typedef void (dio_iodone_t)(struct kiocb - #define ATTR_ATTR_FLAG 1024 - #define ATTR_KILL_SUID 2048 - #define ATTR_KILL_SGID 4096 --#define ATTR_FILE 8192 - #define ATTR_KILL_PRIV 16384 - #define ATTR_OPEN 32768 /* Truncating from open(O_TRUNC) */ - -@@ -351,13 +350,6 @@ struct iattr { - struct timespec ia_atime; - struct timespec ia_mtime; - struct timespec ia_ctime; -- -- /* -- * Not an attribute, but an auxilary info for filesystems wanting to -- * implement an ftruncate() like method. NOTE: filesystem should -- * check for (ia_valid & ATTR_FILE), and not for (ia_file != NULL). -- */ -- struct file *ia_file; - }; - - /* -@@ -1188,6 +1180,7 @@ struct file_operations { - ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); - ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); - int (*setlease)(struct file *, long, struct file_lock **); -+ int (*fsetattr)(struct file *, struct iattr *); - }; - - struct inode_operations { -@@ -1694,6 +1687,7 @@ extern int do_remount_sb(struct super_bl - extern sector_t bmap(struct inode *, sector_t); - #endif - extern int notify_change(struct dentry *, struct vfsmount *, struct iattr *); -+extern int fnotify_change(struct dentry *, struct vfsmount *, struct iattr *, struct file *); - extern int permission(struct inode *, int, struct nameidata *); - extern int generic_permission(struct inode *, int, - int (*check_acl)(struct inode *, int)); diff --git a/kernel-patches/for-mainline/hat_perm.diff b/kernel-patches/for-mainline/hat_perm.diff deleted file mode 100644 index a718ee749..000000000 --- a/kernel-patches/for-mainline/hat_perm.diff +++ /dev/null @@ -1,39 +0,0 @@ ---- - security/apparmor/apparmor.h | 5 +++-- - security/apparmor/main.c | 9 +++++++++ - 2 files changed, 12 insertions(+), 2 deletions(-) - ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -68,10 +68,11 @@ - #define AA_ALL_EXEC_MODS (AA_USER_EXEC_MODS | \ - AA_OTHER_EXEC_MODS) - --/* shared permissions that are not duplicated in user:group:other */ -+/* shared permissions that are not duplicated in user::other */ -+#define AA_CHANGE_HAT 0x20000000 - #define AA_CHANGE_PROFILE 0x40000000 - --#define AA_SHARED_PERMS (AA_CHANGE_PROFILE) -+#define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE) - - #define AA_VALID_PERM_MASK (AA_FILE_PERMS | AA_SHARED_PERMS) - ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -1300,6 +1300,15 @@ repeat: - - if (hat_name) { - char *name, *profile_name; -+ /* Not Yet. This perm check is currently done by searching -+ for the hat profile. When hat style profile names -+ become more generic then this will be needed. -+ if (!(aa_match(profile->file_rules, hat_name) & -+ AA_CHANGE_PROFILE)) { -+ error = -EACCES; -+ goto out; -+ } -+ */ - if (previous_profile) - profile_name = previous_profile->name; - else diff --git a/kernel-patches/for-mainline/may_create-args.diff b/kernel-patches/for-mainline/may_create-args.diff deleted file mode 100644 index 5f02d842f..000000000 --- a/kernel-patches/for-mainline/may_create-args.diff +++ /dev/null @@ -1,86 +0,0 @@ -From: Andreas Gruenbacher -Subject: Remove redundant may_create() argument - -Signed-off-by: Andreas Gruenbacher - ---- - fs/namei.c | 22 ++++++++++------------ - 1 file changed, 10 insertions(+), 12 deletions(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -1462,16 +1462,14 @@ static int may_delete(struct inode *dir, - * 3. We should have write and exec permissions on dir - * 4. We can't do it if dir is immutable (done in permission()) - */ --static inline int may_create(struct inode *dir, struct dentry *child, -- struct nameidata2 *nd) -+static inline int may_create(struct nameidata2 *nd, struct dentry *child) - { - if (child->d_inode) - return -EEXIST; -- if (IS_DEADDIR(dir)) -+ if (IS_DEADDIR(nd->dentry->d_inode)) - return -ENOENT; -- if (nd) -- nd->flags |= LOOKUP_CONTINUE; -- return permission(dir,MAY_WRITE | MAY_EXEC, nd); -+ nd->flags |= LOOKUP_CONTINUE; -+ return permission(nd->dentry->d_inode, MAY_WRITE | MAY_EXEC, nd); - } - - /* -@@ -1537,7 +1535,7 @@ void unlock_rename(struct dentry *p1, st - int vfs_create(struct nameidata2 *nd, struct dentry *dentry, int mode) - { - struct inode *dir = nd->dentry->d_inode; -- int error = may_create(dir, dentry, nd); -+ int error = may_create(nd, dentry); - - if (error) - return error; -@@ -1883,7 +1881,7 @@ EXPORT_SYMBOL_GPL(lookup_create); - int vfs_mknod(struct nameidata2 *nd, struct dentry *dentry, int mode, dev_t dev) - { - struct inode *dir = nd->dentry->d_inode; -- int error = may_create(dir, dentry, nd); -+ int error = may_create(nd, dentry); - - if (error) - return error; -@@ -1963,7 +1961,7 @@ asmlinkage long sys_mknod(const char __u - int vfs_mkdir(struct nameidata2 *nd, struct dentry *dentry, int mode) - { - struct inode *dir = nd->dentry->d_inode; -- int error = may_create(dir, dentry, nd); -+ int error = may_create(nd, dentry); - - if (error) - return error; -@@ -2232,7 +2230,7 @@ int vfs_symlink(struct nameidata2 *nd, s - const char *oldname, int mode) - { - struct inode *dir = nd->dentry->d_inode; -- int error = may_create(dir, dentry, nd); -+ int error = may_create(nd, dentry); - - if (error) - return error; -@@ -2304,7 +2302,7 @@ int vfs_link(struct nameidata2 *old_nd, - if (!inode) - return -ENOENT; - -- error = may_create(dir, new_dentry, new_parent); -+ error = may_create(new_parent, new_dentry); - if (error) - return error; - -@@ -2522,7 +2520,7 @@ int vfs_rename(struct nameidata2 *old_nd - return error; - - if (!new_dentry->d_inode) -- error = may_create(new_dir, new_dentry, new_nd); -+ error = may_create(new_nd, new_dentry); - else - error = may_delete(new_dir, new_dentry, is_dir); - if (error) diff --git a/kernel-patches/for-mainline/may_delete-args.diff b/kernel-patches/for-mainline/may_delete-args.diff deleted file mode 100644 index 75ba37309..000000000 --- a/kernel-patches/for-mainline/may_delete-args.diff +++ /dev/null @@ -1,74 +0,0 @@ -From: Andreas Gruenbacher -Subject: Pass nameidata2 to may_delete() - -Pass the nameidata through to may_delete(), and pass it on to the -permission() call. - -Signed-off-by: Andreas Gruenbacher - ---- - fs/namei.c | 18 ++++++++---------- - 1 file changed, 8 insertions(+), 10 deletions(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -1418,8 +1418,9 @@ static inline int check_sticky(struct in - * 10. We don't allow removal of NFS sillyrenamed files; it's handled by - * nfs_async_unlink(). - */ --static int may_delete(struct inode *dir,struct dentry *victim,int isdir) -+static int may_delete(struct nameidata2 *nd, struct dentry *victim, int isdir) - { -+ struct inode *dir = nd->dentry->d_inode; - int error; - - if (!victim->d_inode) -@@ -1428,11 +1429,8 @@ static int may_delete(struct inode *dir, - BUG_ON(victim->d_parent->d_inode != dir); - audit_inode_child(victim->d_name.name, victim->d_inode, dir); - --#if 0 -- if (nd) -- nd->flags |= LOOKUP_CONTINUE; --#endif -- error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); -+ nd->flags |= LOOKUP_CONTINUE; -+ error = permission(dir,MAY_WRITE | MAY_EXEC, nd); - if (error) - return error; - if (IS_APPEND(dir)) -@@ -2049,7 +2047,7 @@ void dentry_unhash(struct dentry *dentry - int vfs_rmdir(struct nameidata2 *nd, struct dentry *dentry) - { - struct inode *dir = nd->dentry->d_inode; -- int error = may_delete(dir, dentry, 1); -+ int error = may_delete(nd, dentry, 1); - - if (error) - return error; -@@ -2131,7 +2129,7 @@ asmlinkage long sys_rmdir(const char __u - int vfs_unlink(struct nameidata2 *nd, struct dentry *dentry) - { - struct inode *dir = nd->dentry->d_inode; -- int error = may_delete(dir, dentry, 0); -+ int error = may_delete(nd, dentry, 0); - - if (error) - return error; -@@ -2517,14 +2515,14 @@ int vfs_rename(struct nameidata2 *old_nd - if (old_dentry->d_inode == new_dentry->d_inode) - return 0; - -- error = may_delete(old_dir, old_dentry, is_dir); -+ error = may_delete(old_nd, old_dentry, is_dir); - if (error) - return error; - - if (!new_dentry->d_inode) - error = may_create(new_nd, new_dentry); - else -- error = may_delete(new_dir, new_dentry, is_dir); -+ error = may_delete(new_nd, new_dentry, is_dir); - if (error) - return error; - diff --git a/kernel-patches/for-mainline/mount-consistent-__d_path.diff b/kernel-patches/for-mainline/mount-consistent-__d_path.diff deleted file mode 100644 index 4c6e5bffd..000000000 --- a/kernel-patches/for-mainline/mount-consistent-__d_path.diff +++ /dev/null @@ -1,60 +0,0 @@ -From: Andreas Gruenbacher -Subject: Make d_path() consistent across mount operations - -The path that __d_path() computes can become slightly inconsistent when it -races with mount operations: it grabs the vfsmount_lock when traversing mount -points but immediately drops it again, only to re-grab it when it reaches the -next mount point. The result is that the filename computed is not always -consisent, and the file may never have had that name. (This is unlikely, but -still possible.) - -Fix this by grabbing the vfsmount_lock when the first mount point is reached, -and holding onto it until the d_cache lookup is completed. - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/dcache.c | 14 ++++++++------ - 1 file changed, 8 insertions(+), 6 deletions(-) - ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -1786,7 +1786,7 @@ static char *__d_path(struct dentry *den - struct dentry *root, struct vfsmount *rootmnt, - char *buffer, int buflen, int fail_deleted) - { -- int namelen, is_slash; -+ int namelen, is_slash, vfsmount_locked = 0; - - if (buflen < 2) - return ERR_PTR(-ENAMETOOLONG); -@@ -1809,14 +1809,14 @@ static char *__d_path(struct dentry *den - struct dentry * parent; - - if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { -- spin_lock(&vfsmount_lock); -- if (vfsmnt->mnt_parent == vfsmnt) { -- spin_unlock(&vfsmount_lock); -- goto global_root; -+ if (!vfsmount_locked) { -+ spin_lock(&vfsmount_lock); -+ vfsmount_locked = 1; - } -+ if (vfsmnt->mnt_parent == vfsmnt) -+ goto global_root; - dentry = vfsmnt->mnt_mountpoint; - vfsmnt = vfsmnt->mnt_parent; -- spin_unlock(&vfsmount_lock); - continue; - } - parent = dentry->d_parent; -@@ -1835,6 +1835,8 @@ static char *__d_path(struct dentry *den - *--buffer = '/'; - - out: -+ if (vfsmount_locked) -+ spin_unlock(&vfsmount_lock); - spin_unlock(&dcache_lock); - return buffer; - diff --git a/kernel-patches/for-mainline/nfs-nameidata-check.diff b/kernel-patches/for-mainline/nfs-nameidata-check.diff deleted file mode 100644 index d16b74848..000000000 --- a/kernel-patches/for-mainline/nfs-nameidata-check.diff +++ /dev/null @@ -1,47 +0,0 @@ -From: Andreas Gruenbacher -Subject: nfs NULL nameidata check? - -nfs_lookup() checks for NULL nameidata in one place, but not in another. In -nfs_sillyrename() it calls lookup_one_len() -> __lookup_hash(), which passes -in a NULL nameidata to nfs_lookup(). Unless I'm overlooking something, -fs/nfs/dir.c:923 will dereference this NULL pointer if the sillyrenamed file -exists? - -Signed-off-by: Andreas Gruenbacher - ---- - fs/nfs/dir.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/fs/nfs/dir.c -+++ b/fs/nfs/dir.c -@@ -896,15 +896,15 @@ int nfs_is_exclusive_create(struct inode - return (nd->intent.open.flags & O_EXCL) != 0; - } - --static inline int nfs_reval_fsid(struct vfsmount *mnt, struct inode *dir, -+static inline int nfs_reval_fsid(struct nameidata *nd, struct inode *dir, - struct nfs_fh *fh, struct nfs_fattr *fattr) - { - struct nfs_server *server = NFS_SERVER(dir); - -- if (!nfs_fsid_equal(&server->fsid, &fattr->fsid)) -- /* Revalidate fsid on root dir */ -- return __nfs_revalidate_inode(server, mnt->mnt_root->d_inode); -- return 0; -+ if (nd == NULL || nfs_fsid_equal(&server->fsid, &fattr->fsid)) -+ return 0; -+ /* Revalidate fsid on root dir */ -+ return __nfs_revalidate_inode(server, nd->mnt->mnt_root->d_inode); - } - - static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata2 *nd) -@@ -945,7 +945,7 @@ static struct dentry *nfs_lookup(struct - res = ERR_PTR(error); - goto out_unlock; - } -- error = nfs_reval_fsid(nd->mnt, dir, &fhandle, &fattr); -+ error = nfs_reval_fsid(nd, dir, &fhandle, &fattr); - if (error < 0) { - res = ERR_PTR(error); - goto out_unlock; diff --git a/kernel-patches/for-mainline/nfsd_permission-nameidata.diff b/kernel-patches/for-mainline/nfsd_permission-nameidata.diff deleted file mode 100644 index a586e97a4..000000000 --- a/kernel-patches/for-mainline/nfsd_permission-nameidata.diff +++ /dev/null @@ -1,45 +0,0 @@ -From: Andreas Gruenbacher -Subject: Pass nameidata2 to permission() from nfsd_permission() - -Construct a nameidata object and pass it down to permission(), so -that we can do the proper mount flag checks there. - -Note that confining nfsd with AppArmor makes no sense, and so this -patch is not necessary for AppArmor alone. - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/nfsd/vfs.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1804,6 +1804,7 @@ nfsd_statfs(struct svc_rqst *rqstp, stru - __be32 - nfsd_permission(struct svc_export *exp, struct dentry *dentry, int acc) - { -+ struct nameidata2 nd; - struct inode *inode = dentry->d_inode; - int err; - -@@ -1869,12 +1870,16 @@ nfsd_permission(struct svc_export *exp, - inode->i_uid == current->fsuid) - return 0; - -- err = permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC), NULL); -+ nd.dentry = dentry; -+ nd.mnt = exp->ex_mnt; -+ nd.flags = LOOKUP_ACCESS; -+ -+ err = permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC), &nd); - - /* Allow read access to binaries even when mode 111 */ - if (err == -EACCES && S_ISREG(inode->i_mode) && - acc == (MAY_READ | MAY_OWNER_OVERRIDE)) -- err = permission(inode, MAY_EXEC, NULL); -+ err = permission(inode, MAY_EXEC, &nd); - - return err? nfserrno(err) : 0; - } diff --git a/kernel-patches/for-mainline/no-safex-link-subset.diff b/kernel-patches/for-mainline/no-safex-link-subset.diff deleted file mode 100644 index 5f9682ded..000000000 --- a/kernel-patches/for-mainline/no-safex-link-subset.diff +++ /dev/null @@ -1,139 +0,0 @@ ---- - security/apparmor/apparmor.h | 21 ++++++++++----------- - security/apparmor/main.c | 40 ++++++++++++---------------------------- - security/apparmor/match.c | 9 +++++++-- - 3 files changed, 29 insertions(+), 41 deletions(-) - ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -42,15 +42,18 @@ - AA_EXEC_MOD_2 | AA_EXEC_MOD_3 | \ - AA_EXEC_MOD_4) - -+#define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \ -+ AA_EXEC_MOD_2 | AA_EXEC_MOD_3 | \ -+ AA_EXEC_MOD_4) -+ -+#define AA_EXEC_TYPE (MAY_EXEC | AA_EXEC_UNSAFE | \ -+ AA_EXEC_MODIFIERS) -+ - #define AA_EXEC_UNCONFINED AA_EXEC_MOD_0 - #define AA_EXEC_INHERIT AA_EXEC_MOD_1 - #define AA_EXEC_PROFILE (AA_EXEC_MOD_0 | AA_EXEC_MOD_1) - #define AA_EXEC_PIX AA_EXEC_MOD_2 - --#define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \ -- AA_EXEC_MOD_2 | AA_EXEC_MOD_3 | \ -- AA_EXEC_MOD_4) -- - #define AA_USER_SHIFT 0 - #define AA_OTHER_SHIFT 14 - -@@ -65,16 +68,12 @@ - #define AA_USER_EXEC (MAY_EXEC << AA_USER_SHIFT) - #define AA_OTHER_EXEC (MAY_EXEC << AA_OTHER_SHIFT) - --#define AA_USER_EXEC_MODS (AA_EXEC_MODIFIERS << AA_USER_SHIFT) --#define AA_OTHER_EXEC_MODS (AA_EXEC_MODIFIERS << AA_OTHER_SHIFT) -- --#define AA_USER_EXEC_UNSAFE (AA_EXEC_UNSAFE << AA_USER_SHIFT) --#define AA_OTHER_EXEC_UNSAFE (AA_EXEC_UNSAFE << AA_OTHER_SHIFT) -+#define AA_USER_EXEC_TYPE (AA_EXEC_TYPE << AA_USER_SHIFT) -+#define AA_OTHER_EXEC_TYPE (AA_EXEC_TYPE << AA_OTHER_SHIFT) - - #define AA_EXEC_BITS (AA_USER_EXEC | AA_OTHER_EXEC) - --#define AA_ALL_EXEC_MODS (AA_USER_EXEC_MODS | \ -- AA_OTHER_EXEC_MODS) -+#define ALL_AA_EXEC_TYPE (AA_USER_EXEC_TYPE | AA_OTHER_EXEC_TYPE) - - /* overloaded permissions for link pairs */ - #define AA_LINK_SUBSET_TEST 0x0020 ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -68,7 +68,7 @@ static int aa_link_denied(struct aa_prof - int *request_mask) - { - unsigned int state; -- int l_mode, t_mode, l_subset, denied_mask = 0; -+ int l_mode, t_mode, denied_mask = 0; - int link_mask = AA_MAY_LINK << target_mode; - - *request_mask = link_mask; -@@ -90,7 +90,7 @@ static int aa_link_denied(struct aa_prof - - /* Do link perm subset test - * If a subset test is required a permission subset test of the -- * perms for the link are done against the user:group:other of the -+ * perms for the link are done against the user::other of the - * target's 'r', 'w', 'x', 'a', 'k', and 'm' permissions. - * - * If the link has 'x', an exact match of all the execute flags -@@ -100,38 +100,22 @@ static int aa_link_denied(struct aa_prof - - t_mode = aa_match(profile->file_rules, target); - -- - /* For actual subset test ignore valid-profile-transition flags, - * and link bits - */ -- l_mode &= ~(AA_SHARED_PERMS | AA_LINK_BITS); -- t_mode &= ~(AA_SHARED_PERMS | AA_LINK_BITS); -- l_subset = l_mode & AA_FILE_PERMS; -+ l_mode &= AA_FILE_PERMS & ~AA_LINK_BITS; -+ t_mode &= AA_FILE_PERMS & ~AA_LINK_BITS; - - *request_mask = l_mode | link_mask; - -- if (l_subset) { -- denied_mask |= (l_subset) & ~t_mode; -- if (denied_mask & AA_EXEC_BITS) -- denied_mask |= l_mode & AA_ALL_EXEC_MODS; -- else if (l_mode & AA_EXEC_BITS) { -- if (!(l_mode & AA_USER_EXEC_UNSAFE)) -- l_mode |= t_mode & AA_USER_EXEC_UNSAFE; -- if (l_mode & AA_USER_EXEC && -- (l_mode & AA_USER_EXEC_MODS) != -- (t_mode & AA_USER_EXEC_MODS)) -- denied_mask |= AA_USER_EXEC | -- (l_mode & AA_USER_EXEC_MODS); -- if (!(l_mode & AA_OTHER_EXEC_UNSAFE)) -- l_mode |= t_mode & AA_OTHER_EXEC_UNSAFE; -- if (l_mode & AA_OTHER_EXEC && -- (l_mode & AA_OTHER_EXEC_MODS) != -- (t_mode & AA_OTHER_EXEC_MODS)) -- denied_mask |= AA_OTHER_EXEC | -- (l_mode & AA_OTHER_EXEC_MODS); -- } -- } else if (t_mode & AA_FILE_PERMS) -- denied_mask |= t_mode | link_mask; -+ if (l_mode) { -+ denied_mask |= l_mode & ~t_mode; -+ if ((l_mode & AA_EXEC_BITS) && -+ (l_mode & ALL_AA_EXEC_TYPE) != -+ (t_mode & ALL_AA_EXEC_TYPE)) -+ denied_mask = (denied_mask & ~ALL_AA_EXEC_TYPE) | -+ (l_mode & ALL_AA_EXEC_TYPE); -+ } - - return denied_mask; - } ---- a/security/apparmor/match.c -+++ b/security/apparmor/match.c -@@ -175,9 +175,14 @@ int verify_dfa(struct aa_dfa *dfa) - for (i = 0; i < state_count; i++) { - int mode = ACCEPT_TABLE(dfa)[i]; - -- if (mode & ~AA_VALID_PERM_MASK) { -+ if (mode & ~AA_VALID_PERM_MASK) -+ goto out; -+ -+ /* if any exec modifier is set MAY_EXEC must be set */ -+ if ((mode & AA_USER_EXEC_TYPE) && !(mode & AA_USER_EXEC)) -+ goto out; -+ if ((mode & AA_OTHER_EXEC_TYPE) && !(mode & AA_OTHER_EXEC)) - goto out; -- } - } - - error = 0; diff --git a/kernel-patches/for-mainline/null_module/Kbuild b/kernel-patches/for-mainline/null_module/Kbuild deleted file mode 100644 index 56dbee73b..000000000 --- a/kernel-patches/for-mainline/null_module/Kbuild +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_SECURITY_FOOBAR) += foobar.o - -foobar-y := foobar-lsm.o diff --git a/kernel-patches/for-mainline/null_module/Makefile b/kernel-patches/for-mainline/null_module/Makefile deleted file mode 100644 index e07fe1097..000000000 --- a/kernel-patches/for-mainline/null_module/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-m += foobar.o diff --git a/kernel-patches/for-mainline/null_module/foobar-lsm.c b/kernel-patches/for-mainline/null_module/foobar-lsm.c deleted file mode 100644 index 1fee05226..000000000 --- a/kernel-patches/for-mainline/null_module/foobar-lsm.c +++ /dev/null @@ -1,197 +0,0 @@ -#include -#include -#include - -static void log_path(char *op, struct dentry *dentry, struct vfsmount *mnt) -{ - char *page, *name; - - if (!mnt) { - printk(KERN_INFO "foobar(%s): %p NULL vfsmnt\n", op, dentry); - return; - } - - page = (char *)__get_free_page(GFP_KERNEL); - if (!page) { - printk(KERN_ERR "foobar(%s): Unable to get page for path %p/%p\n", - op, mnt, dentry); - goto out; - } - - name=d_path(dentry, mnt, page, PAGE_SIZE); - if (IS_ERR(name)){ - printk(KERN_ERR "foobar(%s): Error path %p/%p overflowed buffer\n", - op, mnt, dentry); - goto out; - } - - printk(KERN_INFO "foobar(%s): %p/%p->'%s'\n", - op, mnt, dentry, name); - -out: - if (page) - free_page((unsigned long)page); -} - -static int foobar_inode_mkdir(struct inode *inode, struct dentry *dentry, - struct vfsmount *mnt, int mask) -{ - log_path("inode_mkdir", dentry, mnt); - - return 0; -} - -static int foobar_inode_rmdir(struct inode *inode, struct dentry *dentry, - struct vfsmount *mnt) -{ - log_path("inode_rmdir", dentry, mnt); - - return 0; -} - -static int foobar_inode_create(struct inode *inode, struct dentry *dentry, - struct vfsmount *mnt, int mask) -{ - log_path("inode_create", dentry, mnt); - - return 0; -} - -static int foobar_inode_link(struct dentry *old_dentry, - struct vfsmount *old_mnt, - struct inode *inode, - struct dentry *new_dentry, - struct vfsmount *new_mnt) -{ - log_path("inode_link (old)", old_dentry, old_mnt); - log_path("inode_link (new)", new_dentry, new_mnt); - - return 0; -} - -static int foobar_inode_unlink(struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt) -{ - log_path("inode_unlink", dentry, mnt); - - return 0; -} - -static int foobar_inode_mknod(struct inode *inode, struct dentry *dentry, - struct vfsmount *mnt, int mode, dev_t dev) -{ - log_path("inode_mknod", dentry, mnt); - - return 0; -} - -static int foobar_inode_rename(struct inode *old_inode, - struct dentry *old_dentry, - struct vfsmount *old_mnt, - struct inode *new_inode, - struct dentry *new_dentry, - struct vfsmount *new_mnt) -{ - log_path("inode_rename (old)", old_dentry, old_mnt); - log_path("inode_rename (new)", new_dentry, new_mnt); - - return 0; -} - -static int foobar_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, - struct iattr *iattr) -{ - log_path("inode_setattr", dentry, mnt); - - return 0; -} - -static int foobar_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, - char *name, void *value, size_t size, - int flags) -{ - log_path("inode_setxattr", dentry, mnt); - - return 0; -} - -static int foobar_inode_getxattr(struct dentry *dentry, - struct vfsmount *mnt, char *name) -{ - log_path("inode_getxattr", dentry, mnt); - - return 0; -} - -static int foobar_inode_listxattr(struct dentry *dentry, - struct vfsmount *mnt) -{ - log_path("inode_listxattr", dentry, mnt); - - return 0; -} - -static int foobar_inode_removexattr(struct dentry *dentry, - struct vfsmount *mnt, char *name) -{ - log_path("inode_removexattr", dentry, mnt); - - return 0; -} - -static int foobar_inode_symlink(struct inode *dir, - struct dentry *dentry, struct vfsmount *mnt, - const char *old_name) -{ - log_path("inode_symlink", dentry, mnt); - - return 0; -} - -static int foobar_inode_permission(struct inode *inode, int mask, - struct nameidata *nd) -{ - log_path("inode_permission", nd->dentry, nd->mnt); - - return 0; -} - -struct security_operations foobar_ops = { - .inode_create = foobar_inode_create, - .inode_link = foobar_inode_link, - .inode_unlink = foobar_inode_unlink, - .inode_mkdir = foobar_inode_mkdir, - .inode_rmdir = foobar_inode_rmdir, - .inode_mknod = foobar_inode_mknod, - .inode_rename = foobar_inode_rename, - .inode_setattr = foobar_inode_setattr, - .inode_setxattr = foobar_inode_setxattr, - .inode_getxattr = foobar_inode_getxattr, - .inode_listxattr = foobar_inode_listxattr, - .inode_removexattr = foobar_inode_removexattr, - .inode_symlink = foobar_inode_symlink, -// .inode_permission = foobar_inode_permission, -}; - -static int __init foobar_init(void) -{ -int error; - - if ((error = register_security(&foobar_ops))) { - printk(KERN_ERR "Unable to load dummy module\n"); - } - - return error; -} - -static void __exit foobar_exit(void) -{ - if (unregister_security(&foobar_ops)) - printk(KERN_ERR "Unable to properly unregister module\n"); -} - -module_init(foobar_init); -module_exit(foobar_exit); - -MODULE_DESCRIPTION("Test module"); -MODULE_LICENSE("GPL"); diff --git a/kernel-patches/for-mainline/owner-perm-set.diff b/kernel-patches/for-mainline/owner-perm-set.diff deleted file mode 100644 index 9a440b5e0..000000000 --- a/kernel-patches/for-mainline/owner-perm-set.diff +++ /dev/null @@ -1,561 +0,0 @@ ---- - security/apparmor/apparmor.h | 60 +++++++--- - security/apparmor/apparmorfs.c | 2 - security/apparmor/lsm.c | 2 - security/apparmor/main.c | 193 +++++++++++++++++++++++------------ - security/apparmor/match.c | 8 - - security/apparmor/module_interface.c | 3 - 6 files changed, 179 insertions(+), 89 deletions(-) - ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -26,22 +26,50 @@ - #define AA_MAY_LINK 0x0010 - #define AA_MAY_LOCK 0x0020 - #define AA_EXEC_MMAP 0x0040 -+#define AA_EXEC_UNSAFE 0x0080 -+#define AA_EXEC_MOD_0 0x0100 -+#define AA_EXEC_MOD_1 0x0200 -+#define AA_BASE_PERMS (MAY_READ | MAY_WRITE | MAY_EXEC | \ -+ MAY_APPEND | AA_MAY_LINK | \ -+ AA_MAY_LOCK | AA_EXEC_MMAP | \ -+ AA_EXEC_UNSAFE | AA_EXEC_MOD_0 | \ -+ AA_EXEC_MOD_1) - --#define AA_CHANGE_PROFILE 0x04000000 --#define AA_EXEC_INHERIT 0x08000000 --#define AA_EXEC_UNCONFINED 0x10000000 --#define AA_EXEC_PROFILE 0x20000000 --#define AA_EXEC_UNSAFE 0x40000000 -- --#define AA_EXEC_MODIFIERS (AA_EXEC_INHERIT | \ -- AA_EXEC_UNCONFINED | \ -- AA_EXEC_PROFILE) -+#define AA_EXEC_UNCONFINED 0 -+#define AA_EXEC_INHERIT AA_EXEC_MOD_0 -+#define AA_EXEC_PROFILE AA_EXEC_MOD_1 -+#define AA_EXEC_PIX (AA_EXEC_MOD_0 | AA_EXEC_MOD_1) - --#define AA_VALID_PERM_MASK (MAY_READ | MAY_WRITE | MAY_EXEC | \ -- MAY_APPEND | AA_MAY_LINK | \ -- AA_MAY_LOCK | \ -- AA_EXEC_MODIFIERS | AA_EXEC_MMAP | \ -- AA_EXEC_UNSAFE | AA_CHANGE_PROFILE) -+#define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1) -+ -+#define AA_USER_SHIFT 0 -+#define AA_OTHER_SHIFT 10 -+ -+#define AA_USER_PERMS (AA_BASE_PERMS << AA_USER_SHIFT) -+#define AA_OTHER_PERMS (AA_BASE_PERMS << AA_OTHER_SHIFT) -+ -+#define AA_FILE_PERMS (AA_USER_PERMS | AA_OTHER_PERMS) -+ -+#define AA_LINK_BITS ((AA_MAY_LINK << AA_USER_SHIFT) | \ -+ (AA_MAY_LINK << AA_OTHER_SHIFT)) -+ -+#define AA_USER_EXEC (MAY_EXEC << AA_USER_SHIFT) -+#define AA_OTHER_EXEC (MAY_EXEC << AA_OTHER_SHIFT) -+ -+#define AA_USER_EXEC_MODS (AA_EXEC_MODIFIERS << AA_USER_SHIFT) -+#define AA_OTHER_EXEC_MODS (AA_EXEC_MODIFIERS << AA_OTHER_SHIFT) -+ -+#define AA_EXEC_BITS (AA_USER_EXEC | AA_OTHER_EXEC) -+ -+#define AA_ALL_EXEC_MODS (AA_USER_EXEC_MODS | \ -+ AA_OTHER_EXEC_MODS) -+ -+/* shared permissions that are not duplicated in user:group:other */ -+#define AA_CHANGE_PROFILE 0x40000000 -+ -+#define AA_SHARED_PERMS (AA_CHANGE_PROFILE) -+ -+#define AA_VALID_PERM_MASK (AA_FILE_PERMS | AA_SHARED_PERMS) - - #define AA_SECURE_EXEC_NEEDED 1 - -@@ -183,7 +211,7 @@ struct aa_audit { - const char *name; - const char *name2; - const char *name3; -- int requested_mask, denied_mask; -+ int request_mask, denied_mask; - struct iattr *iattr; - pid_t task, parent; - int family, type, protocol; -@@ -226,7 +254,7 @@ extern int aa_perm_dir(struct aa_profile - struct dentry *dentry, struct vfsmount *mnt, - int mask); - extern int aa_perm_path(struct aa_profile *, const char *operation, -- const char *name, int); -+ const char *name, int mask, uid_t uid); - extern int aa_link(struct aa_profile *profile, - struct dentry *link, struct vfsmount *link_mnt, - struct dentry *target, struct vfsmount *target_mnt); ---- a/security/apparmor/apparmorfs.c -+++ b/security/apparmor/apparmorfs.c -@@ -89,7 +89,7 @@ static struct file_operations apparmorfs - static ssize_t aa_matching_read(struct file *file, char __user *buf, - size_t size, loff_t *ppos) - { -- const char *matching = "pattern=aadfa perms=rwxamlz"; -+ const char *matching = "pattern=aadfa perms=rwxamlz user:other"; - - return simple_read_from_buffer(buf, size, ppos, matching, - strlen(matching)); ---- a/security/apparmor/lsm.c -+++ b/security/apparmor/lsm.c -@@ -199,7 +199,7 @@ static int apparmor_sysctl(struct ctl_ta - if (name && name - buffer >= 5) { - name -= 5; - memcpy(name, "/proc", 5); -- error = aa_perm_path(profile, "sysctl", name, mask); -+ error = aa_perm_path(profile, "sysctl", name, mask, 0); - } - free_page((unsigned long)buffer); - } ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -31,6 +31,14 @@ static const char *capability_names[] = - - struct aa_namespace *default_namespace; - -+static int aa_inode_mode(struct inode *inode) -+{ -+ /* if the inode doesn't exist the user is creating it */ -+ if (!inode || current->fsuid == inode->i_uid) -+ return AA_USER_SHIFT; -+ return AA_OTHER_SHIFT; -+} -+ - /** - * aa_file_denied - check for @mask access on a file - * @profile: profile to check against -@@ -51,39 +59,52 @@ static int aa_file_denied(struct aa_prof - * @profile: profile to check against - * @link: pathname of link being created - * @target: pathname of target to be linked to -+ * @target_mode: UGO shift for target inode - * @request_mask: the permissions subset valid only if link succeeds - * Return %0 on success, or else the permissions that the profile denies. - */ - static int aa_link_denied(struct aa_profile *profile, const char *link, -- const char *target, int *request_mask) -+ const char *target, int target_mode, -+ int *request_mask) - { - int l_mode, t_mode, denied_mask; -+ int link_mask = AA_MAY_LINK << target_mode; - - l_mode = aa_match(profile->file_rules, link); - t_mode = aa_match(profile->file_rules, target); - - /* Ignore valid-profile-transition flags. */ -- l_mode &= ~AA_CHANGE_PROFILE; -- t_mode &= ~AA_CHANGE_PROFILE; -+ l_mode &= ~AA_SHARED_PERMS; -+ t_mode &= ~AA_SHARED_PERMS; - -- *request_mask = l_mode | AA_MAY_LINK; -- -- /* Link always requires 'l' on the link, a subset of the -- * target's 'r', 'w', 'x', 'a', 'z', and 'm' permissions on the link, -- * and if the link has 'x', an exact match of all the execute flags -- * ('i', 'u', 'U', 'p', 'P'). -- */ --#define RWXAZM (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND | AA_MAY_LOCK | \ -- AA_EXEC_MMAP) -- denied_mask = ~l_mode & AA_MAY_LINK; -- if (l_mode & RWXAZM) -- denied_mask |= (l_mode & ~ AA_MAY_LINK) & ~t_mode; -- else -- denied_mask |= t_mode | AA_MAY_LINK; -- if (denied_mask & AA_EXEC_MODIFIERS) -- denied_mask |= MAY_EXEC; -+ *request_mask = l_mode | link_mask; - --#undef RWXAZM -+ /* Link always requires 'l' on the link, a subset for user:other -+ * of the target's 'r', 'w', 'x', 'a', 'z', and 'm' permissions on -+ * the link, and if the link has 'x', an exact match of all the -+ * execute flags ('i', 'u', 'U', 'p', 'P'). -+ */ -+#define SUBSET_PERMS (AA_FILE_PERMS & ~AA_LINK_BITS) -+ denied_mask = ~l_mode & link_mask; -+ if (l_mode & SUBSET_PERMS) { -+ denied_mask |= (l_mode & SUBSET_PERMS) & ~t_mode; -+ if (denied_mask & AA_EXEC_BITS) -+ denied_mask |= l_mode & AA_ALL_EXEC_MODS; -+ else if (l_mode & AA_EXEC_BITS) { -+ if (l_mode & AA_USER_EXEC && -+ (l_mode & AA_USER_EXEC_MODS) != -+ (t_mode & AA_USER_EXEC_MODS)) -+ denied_mask |= AA_USER_EXEC | -+ (l_mode & AA_USER_EXEC_MODS); -+ if (l_mode & AA_OTHER_EXEC && -+ (l_mode & AA_OTHER_EXEC_MODS) != -+ (t_mode & AA_OTHER_EXEC_MODS)) -+ denied_mask |= AA_OTHER_EXEC | -+ (l_mode & AA_OTHER_EXEC_MODS); -+ } -+ } else -+ denied_mask |= t_mode | link_mask; -+#undef SUBSET_PERMS - - return denied_mask; - } -@@ -173,7 +194,7 @@ static int aa_perm_dentry(struct aa_prof - char *buffer = NULL; - - sa->name = aa_get_name(dentry, mnt, &buffer, check); -- -+ sa->request_mask <<= aa_inode_mode(dentry->d_inode); - if (IS_ERR(sa->name)) { - /* - * deleted files are given a pass on permission checks when -@@ -182,13 +203,13 @@ static int aa_perm_dentry(struct aa_prof - if (PTR_ERR(sa->name) == -ENOENT && (check & AA_CHECK_FD)) - sa->denied_mask = 0; - else { -- sa->denied_mask = sa->requested_mask; -+ sa->denied_mask = sa->request_mask; - sa->error_code = PTR_ERR(sa->name); - } - sa->name = NULL; - } else - sa->denied_mask = aa_file_denied(profile, sa->name, -- sa->requested_mask); -+ sa->request_mask); - - if (!sa->denied_mask) - sa->error_code = 0; -@@ -229,10 +250,10 @@ void free_default_namespace(void) - default_namespace = NULL; - } - --static void aa_audit_file_mask(struct audit_buffer *ab, const char *name, -- int mask) -+static void aa_audit_file_sub_mask(struct audit_buffer *ab, char *buffer, -+ int mask) - { -- char mask_str[10], *m = mask_str; -+ char *m = buffer; - - if (mask & AA_EXEC_MMAP) - *m++ = 'm'; -@@ -242,32 +263,58 @@ static void aa_audit_file_mask(struct au - *m++ = 'w'; - else if (mask & MAY_APPEND) - *m++ = 'a'; -- if (mask & (MAY_EXEC | AA_EXEC_MODIFIERS)) { -+ if (mask & MAY_EXEC) { - if (mask & AA_EXEC_UNSAFE) { -- if (mask & AA_EXEC_INHERIT) -- *m++ = 'i'; -- if (mask & AA_EXEC_UNCONFINED) -+ switch(mask & AA_EXEC_MODIFIERS) { -+ case AA_EXEC_UNCONFINED: - *m++ = 'u'; -- if (mask & AA_EXEC_PROFILE) -+ break; -+ case AA_EXEC_PIX: -+ *m++ = 'p'; -+ /* fall through */ -+ case AA_EXEC_INHERIT: -+ *m++ = 'i'; -+ break; -+ case AA_EXEC_PROFILE: - *m++ = 'p'; -+ break; -+ } - } else { -- if (mask & AA_EXEC_INHERIT) -- *m++ = 'I'; -- if (mask & AA_EXEC_UNCONFINED) -+ switch(mask & AA_EXEC_MODIFIERS) { -+ case AA_EXEC_UNCONFINED: - *m++ = 'U'; -- if (mask & AA_EXEC_PROFILE) -+ break; -+ case AA_EXEC_PIX: - *m++ = 'P'; -+ /* fall through */ -+ case AA_EXEC_INHERIT: -+ *m++ = 'I'; -+ break; -+ case AA_EXEC_PROFILE: -+ *m++ = 'P'; -+ break; -+ } - } -- if (mask & MAY_EXEC) -- *m++ = 'x'; -+ *m++ = 'x'; - } - if (mask & AA_MAY_LINK) - *m++ = 'l'; - if (mask & AA_MAY_LOCK) - *m++ = 'k'; - *m++ = '\0'; -+} -+ -+static void aa_audit_file_mask(struct audit_buffer *ab, const char *name, -+ int mask) -+{ -+ char user[10], other[10]; - -- audit_log_format(ab, " %s=\"%s\"", name, mask_str); -+ aa_audit_file_sub_mask(ab, user, -+ (mask & AA_USER_PERMS) >> AA_USER_SHIFT); -+ aa_audit_file_sub_mask(ab, other, -+ (mask & AA_OTHER_PERMS) >> AA_OTHER_SHIFT); -+ -+ audit_log_format(ab, " %s=\"%s::%s\"", name, user, other); - } - - static const char *address_families[] = { -@@ -316,8 +363,8 @@ static int aa_audit_base(struct aa_profi - if (sa->info) - audit_log_format(ab, " info=\"%s\"", sa->info); - -- if (sa->requested_mask) -- aa_audit_file_mask(ab, "requested_mask", sa->requested_mask); -+ if (sa->request_mask) -+ aa_audit_file_mask(ab, "request_mask", sa->request_mask); - - if (sa->denied_mask) - aa_audit_file_mask(ab, "denied_mask", sa->denied_mask); -@@ -472,7 +519,7 @@ int aa_attr(struct aa_profile *profile, - sa.operation = "setattr"; - sa.gfp_mask = GFP_KERNEL; - sa.iattr = iattr; -- sa.requested_mask = MAY_WRITE; -+ sa.request_mask = MAY_WRITE; - sa.error_code = -EACCES; - - check = 0; -@@ -506,7 +553,7 @@ int aa_perm_xattr(struct aa_profile *pro - memset(&sa, 0, sizeof(sa)); - sa.operation = operation; - sa.gfp_mask = GFP_KERNEL; -- sa.requested_mask = mask; -+ sa.request_mask = mask; - sa.error_code = -EACCES; - - if (inode && S_ISDIR(inode->i_mode)) -@@ -540,7 +587,7 @@ int aa_perm(struct aa_profile *profile, - memset(&sa, 0, sizeof(sa)); - sa.operation = operation; - sa.gfp_mask = GFP_KERNEL; -- sa.requested_mask = mask; -+ sa.request_mask = mask; - sa.error_code = -EACCES; - - error = aa_perm_dentry(profile, dentry, mnt, &sa, check); -@@ -569,24 +616,28 @@ int aa_perm_dir(struct aa_profile *profi - memset(&sa, 0, sizeof(sa)); - sa.operation = operation; - sa.gfp_mask = GFP_KERNEL; -- sa.requested_mask = mask; -+ sa.request_mask = mask; - sa.error_code = -EACCES; - - return aa_perm_dentry(profile, dentry, mnt, &sa, AA_CHECK_DIR); - } - - int aa_perm_path(struct aa_profile *profile, const char *operation, -- const char *name, int mask) -+ const char *name, int mask, uid_t uid) - { - struct aa_audit sa; - - memset(&sa, 0, sizeof(sa)); - sa.operation = operation; - sa.gfp_mask = GFP_KERNEL; -- sa.requested_mask = mask; -+ sa.request_mask = mask; - sa.name = name; -+ if (current->fsuid == uid) -+ sa.request_mask = mask << AA_USER_SHIFT; -+ else -+ sa.request_mask = mask << AA_OTHER_SHIFT; - -- sa.denied_mask = aa_file_denied(profile, name, mask); -+ sa.denied_mask = aa_file_denied(profile, name, sa.request_mask) ; - sa.error_code = sa.denied_mask ? -EACCES : 0; - - return aa_audit(profile, &sa); -@@ -672,9 +723,10 @@ int aa_link(struct aa_profile *profile, - } - - if (sa.name && sa.name2) { -- sa.requested_mask = AA_MAY_LINK; -+ sa.request_mask = AA_MAY_LINK; - sa.denied_mask = aa_link_denied(profile, sa.name, sa.name2, -- &sa.requested_mask); -+ aa_inode_mode(target->d_inode), -+ &sa.request_mask); - sa.error_code = sa.denied_mask ? -EACCES : 0; - } - -@@ -818,7 +870,7 @@ aa_register_find(struct aa_profile *prof - __FUNCTION__, new_profile->name); - } else if (mandatory && profile) { - sa->info = "mandatory profile missing"; -- sa->denied_mask = MAY_EXEC; -+ sa->denied_mask = sa->request_mask; /* shifted MAY_EXEC */ - if (complain) { - aa_audit_hint(profile, sa); - new_profile = -@@ -829,7 +881,7 @@ aa_register_find(struct aa_profile *prof - } - } else { - /* Only way we can get into this code is if task -- * is unconfined. -+ * is unconfined, or pix. - */ - AA_DEBUG("%s: No profile found for exec image '%s'\n", - __FUNCTION__, -@@ -851,7 +903,7 @@ int aa_register(struct linux_binprm *bpr - char *buffer = NULL; - struct file *filp = bprm->file; - struct aa_profile *profile, *old_profile, *new_profile = NULL; -- int exec_mode = AA_EXEC_UNSAFE, complain = 0; -+ int exec_mode, complain = 0, shift; - struct aa_audit sa; - - AA_DEBUG("%s\n", __FUNCTION__); -@@ -862,11 +914,14 @@ int aa_register(struct linux_binprm *bpr - return -ENOENT; - } - -+ shift = aa_inode_mode(filp->f_dentry->d_inode); -+ exec_mode = AA_EXEC_UNSAFE << shift; -+ - memset(&sa, 0, sizeof(sa)); - sa.operation = "exec"; - sa.gfp_mask = GFP_KERNEL; - sa.name = filename; -- sa.requested_mask = MAY_EXEC; -+ sa.request_mask = MAY_EXEC << shift; - - repeat: - profile = aa_get_profile(current); -@@ -878,16 +933,16 @@ repeat: - */ - exec_mode = aa_match(profile->file_rules, filename); - -- if (exec_mode & (MAY_EXEC | AA_EXEC_MODIFIERS)) { -- switch (exec_mode & (MAY_EXEC | AA_EXEC_MODIFIERS)) { -- case MAY_EXEC | AA_EXEC_INHERIT: -+ if (exec_mode & sa.request_mask) { -+ switch ((exec_mode >> shift) & AA_EXEC_MODIFIERS) { -+ case AA_EXEC_INHERIT: - AA_DEBUG("%s: INHERIT %s\n", - __FUNCTION__, - filename); - /* nothing to be done here */ - goto cleanup; - -- case MAY_EXEC | AA_EXEC_UNCONFINED: -+ case AA_EXEC_UNCONFINED: - AA_DEBUG("%s: UNCONFINED %s\n", - __FUNCTION__, - filename); -@@ -896,7 +951,7 @@ repeat: - new_profile = NULL; - break; - -- case MAY_EXEC | AA_EXEC_PROFILE: -+ case AA_EXEC_PROFILE: - AA_DEBUG("%s: PROFILE %s\n", - __FUNCTION__, - filename); -@@ -905,6 +960,18 @@ repeat: - 1, complain, - &sa); - break; -+ case AA_EXEC_PIX: -+ AA_DEBUG("%s: PROFILE %s\n", -+ __FUNCTION__, -+ filename); -+ new_profile = aa_register_find(profile, -+ filename, -+ 0, complain, -+ &sa); -+ if (!new_profile) -+ /* inherit - nothing to be done here */ -+ goto cleanup; -+ break; - } - - } else if (complain) { -@@ -914,9 +981,9 @@ repeat: - */ - new_profile = - aa_dup_profile(profile->ns->null_complain_profile); -- exec_mode |= AA_EXEC_UNSAFE; -+ exec_mode |= AA_EXEC_UNSAFE << shift; - } else { -- sa.denied_mask = MAY_EXEC; -+ sa.denied_mask = sa.request_mask; - aa_audit_reject(profile, &sa); - new_profile = ERR_PTR(-EPERM); - } -@@ -937,7 +1004,7 @@ repeat: - if (PTR_ERR(old_profile) == -ESTALE) - goto repeat; - if (PTR_ERR(old_profile) == -EPERM) { -- sa.denied_mask = MAY_EXEC; -+ sa.denied_mask = sa.request_mask; - sa.info = "unable to set profile due to ptrace"; - sa.task = current->parent->pid; - aa_audit_reject(profile, &sa); -@@ -957,7 +1024,7 @@ repeat: - * Cases 2 and 3 are marked as requiring secure exec - * (unless policy specified "unsafe exec") - */ -- if (!(exec_mode & AA_EXEC_UNSAFE)) { -+ if (!(exec_mode & (AA_EXEC_UNSAFE << shift))) { - unsigned long bprm_flags; - - bprm_flags = AA_SECURE_EXEC_NEEDED; -@@ -967,7 +1034,7 @@ repeat: - - if (complain && new_profile && - new_profile == new_profile->ns->null_complain_profile) { -- sa.requested_mask = 0; -+ sa.request_mask = 0; - sa.name = NULL; - sa.info = "set profile"; - aa_audit_hint(new_profile, &sa); ---- a/security/apparmor/match.c -+++ b/security/apparmor/match.c -@@ -175,14 +175,8 @@ int verify_dfa(struct aa_dfa *dfa) - for (i = 0; i < state_count; i++) { - int mode = ACCEPT_TABLE(dfa)[i]; - -- if (mode & ~AA_VALID_PERM_MASK) -+ if (mode & ~AA_VALID_PERM_MASK) { - goto out; -- -- /* if MAY_EXEC, exactly one exec modifier must be set */ -- if (mode & MAY_EXEC) { -- mode &= AA_EXEC_MODIFIERS; -- if (mode & (mode - 1)) -- goto out; - } - } - ---- a/security/apparmor/module_interface.c -+++ b/security/apparmor/module_interface.c -@@ -349,7 +349,8 @@ fail: - sa.operation = operation; - sa.gfp_mask = GFP_KERNEL; - sa.name = profile && profile->name ? profile->name : "unknown"; -- sa.info = "failed to unpack profile"; -+ if (!sa.info) -+ sa.info = "failed to unpack profile"; - aa_audit_status(NULL, &sa); - - if (profile) diff --git a/kernel-patches/for-mainline/parent-permission.diff b/kernel-patches/for-mainline/parent-permission.diff deleted file mode 100644 index 1852ed377..000000000 --- a/kernel-patches/for-mainline/parent-permission.diff +++ /dev/null @@ -1,24 +0,0 @@ -From: Andreas Gruenbacher -Subject: Allow permission functions to tell between parent and leaf checks - -Set the LOOKUP_CONTINUE flag when checking parent permissions. This allows -permission functions to tell between parent and leaf checks. - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/namei.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -1508,6 +1508,8 @@ static inline int may_create(struct inod - return -EEXIST; - if (IS_DEADDIR(dir)) - return -ENOENT; -+ if (nd) -+ nd->flags |= LOOKUP_CONTINUE; - return permission(dir,MAY_WRITE | MAY_EXEC, nd); - } - diff --git a/kernel-patches/for-mainline/proc-mounts-check-d_path-result.diff b/kernel-patches/for-mainline/proc-mounts-check-d_path-result.diff deleted file mode 100644 index a1ef265a1..000000000 --- a/kernel-patches/for-mainline/proc-mounts-check-d_path-result.diff +++ /dev/null @@ -1,129 +0,0 @@ -From: Andreas Gruenbacher -Subject: Filter out disconnected paths from /proc/mounts - -Use d_path() instead of seq_path when generating /proc/mounts and -/proc/$id/mountstats, reuse the same buffer for all mounts, and filter out -disconnected paths. - -This path has no net effect in itself because d_path() so far doesn't -distinguish sconnected and disconnected paths yet. The next patch fixes that -though; without this patch, the next patch would break /proc/mounts and -/proc/$id/mountstats. - -There is some disagreement what /proc/mounts should include. Currently it -reports all mounts from the current namespace and doesn't include lazy -unmounts. This leads to ambiguities with the rootfs (which is an internal mount -irrelevant to user-space except in the initrd), and in chroots. - -With this and the next patch, /proc/mounts only reports the mounts reachable -for the current process, which makes a lot more sense IMO. If the current -process is rooted in the namespace root (which it usually is), it will see all -mounts except for the rootfs. - -Signed-off-by: Andreas Gruenbacher - ---- - fs/namespace.c | 23 +++++++++++++++++++++-- - fs/proc/base.c | 10 +++++++++- - 2 files changed, 30 insertions(+), 3 deletions(-) - ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -348,8 +348,16 @@ static inline void mangle(struct seq_fil - seq_escape(m, s, " \t\n\\"); - } - -+/* Keep in sync with fs/proc/base.c! */ -+struct proc_mounts { -+ struct seq_file m; -+ void *page; -+ int event; -+}; -+ - static int show_vfsmnt(struct seq_file *m, void *v) - { -+ void *page = container_of(m, struct proc_mounts, m)->page; - struct vfsmount *mnt = v; - int err = 0; - static struct proc_fs_info { -@@ -371,10 +379,15 @@ static int show_vfsmnt(struct seq_file * - { 0, NULL } - }; - struct proc_fs_info *fs_infop; -+ char *path; -+ -+ path = d_path(mnt->mnt_root, mnt, page, PAGE_SIZE); -+ if (IS_ERR(path) || *path != '/') -+ return err; - - mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); - seq_putc(m, ' '); -- seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); -+ mangle(m, path); - seq_putc(m, ' '); - mangle(m, mnt->mnt_sb->s_type->name); - seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw"); -@@ -401,8 +414,14 @@ struct seq_operations mounts_op = { - - static int show_vfsstat(struct seq_file *m, void *v) - { -+ void *page = container_of(m, struct proc_mounts, m)->page; - struct vfsmount *mnt = v; - int err = 0; -+ char *path; -+ -+ path = d_path(mnt->mnt_root, mnt, page, PAGE_SIZE); -+ if (IS_ERR(path) || *path != '/') -+ return err; /* error or path unreachable from chroot */ - - /* device */ - if (mnt->mnt_devname) { -@@ -413,7 +432,7 @@ static int show_vfsstat(struct seq_file - - /* mount point */ - seq_puts(m, " mounted on "); -- seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); -+ mangle(m, path); - seq_putc(m, ' '); - - /* file system type */ ---- a/fs/proc/base.c -+++ b/fs/proc/base.c -@@ -354,8 +354,11 @@ static const struct inode_operations pro - }; - - extern struct seq_operations mounts_op; -+ -+/* Keep in sync with fs/namespace.c! */ - struct proc_mounts { - struct seq_file m; -+ void *page; - int event; - }; - -@@ -383,12 +386,16 @@ static int __mounts_open(struct inode *i - p = kmalloc(sizeof(struct proc_mounts), GFP_KERNEL); - if (p) { - file->private_data = &p->m; -- ret = seq_open(file, seq_ops); -+ p->page = (void *)__get_free_page(GFP_KERNEL); -+ if (p->page) -+ ret = seq_open(file, seq_ops); - if (!ret) { - p->m.private = ns; - p->event = ns->event; - return 0; - } -+ if (p->page) -+ free_page((unsigned long)p->page); - kfree(p); - } - put_mnt_ns(ns); -@@ -407,6 +414,7 @@ static int mounts_release(struct inode * - container_of(file->private_data, struct proc_mounts, m); - struct mnt_namespace *ns = p->m.private; - -+ free_page((unsigned long)p->page); - put_mnt_ns(ns); - return seq_release(inode, file); - } diff --git a/kernel-patches/for-mainline/proc-mounts-cleanup.diff b/kernel-patches/for-mainline/proc-mounts-cleanup.diff deleted file mode 100644 index a52fb02da..000000000 --- a/kernel-patches/for-mainline/proc-mounts-cleanup.diff +++ /dev/null @@ -1,98 +0,0 @@ -From: Andreas Gruenbacher -Subject: Remove duplicate proc code - -Remove some duplicate code in generating the contents of /proc/mounts and -/proc/$pid/mountstats. - -Signed-off-by: Andreas Gruenbacher - ---- - -This patch is optional, and does not affect the rest of this series. - - fs/proc/base.c | 45 +++++++++++++++------------------------------ - 1 file changed, 15 insertions(+), 30 deletions(-) - ---- a/fs/proc/base.c -+++ b/fs/proc/base.c -@@ -359,7 +359,8 @@ struct proc_mounts { - int event; - }; - --static int mounts_open(struct inode *inode, struct file *file) -+static int __mounts_open(struct inode *inode, struct file *file, -+ struct seq_operations *seq_ops) - { - struct task_struct *task = get_proc_task(inode); - struct mnt_namespace *ns = NULL; -@@ -382,7 +383,7 @@ static int mounts_open(struct inode *ino - p = kmalloc(sizeof(struct proc_mounts), GFP_KERNEL); - if (p) { - file->private_data = &p->m; -- ret = seq_open(file, &mounts_op); -+ ret = seq_open(file, seq_ops); - if (!ret) { - p->m.private = ns; - p->event = ns->event; -@@ -395,17 +396,25 @@ static int mounts_open(struct inode *ino - return ret; - } - -+static int mounts_open(struct inode *inode, struct file *file) -+{ -+ return __mounts_open(inode, file, &mounts_op); -+} -+ - static int mounts_release(struct inode *inode, struct file *file) - { -- struct seq_file *m = file->private_data; -- struct mnt_namespace *ns = m->private; -+ struct proc_mounts *p = -+ container_of(file->private_data, struct proc_mounts, m); -+ struct mnt_namespace *ns = p->m.private; -+ - put_mnt_ns(ns); - return seq_release(inode, file); - } - - static unsigned mounts_poll(struct file *file, poll_table *wait) - { -- struct proc_mounts *p = file->private_data; -+ struct proc_mounts *p = -+ container_of(file->private_data, struct proc_mounts, m); - struct mnt_namespace *ns = p->m.private; - unsigned res = 0; - -@@ -432,31 +441,7 @@ static const struct file_operations proc - extern struct seq_operations mountstats_op; - static int mountstats_open(struct inode *inode, struct file *file) - { -- int ret = seq_open(file, &mountstats_op); -- -- if (!ret) { -- struct seq_file *m = file->private_data; -- struct mnt_namespace *mnt_ns = NULL; -- struct task_struct *task = get_proc_task(inode); -- -- if (task) { -- task_lock(task); -- if (task->nsproxy) -- mnt_ns = task->nsproxy->mnt_ns; -- if (mnt_ns) -- get_mnt_ns(mnt_ns); -- task_unlock(task); -- put_task_struct(task); -- } -- -- if (mnt_ns) -- m->private = mnt_ns; -- else { -- seq_release(inode, file); -- ret = -EINVAL; -- } -- } -- return ret; -+ return __mounts_open(inode, file, &mountstats_op); - } - - static const struct file_operations proc_mountstats_operations = { diff --git a/kernel-patches/for-mainline/profile-namespaces.diff b/kernel-patches/for-mainline/profile-namespaces.diff deleted file mode 100644 index 00c051d8a..000000000 --- a/kernel-patches/for-mainline/profile-namespaces.diff +++ /dev/null @@ -1,1158 +0,0 @@ -Add profile namespace's to AppArmor. - -Each namespace defines are set of profiles that will be searched when -looking up profiles. This allows for seperate /bin/foo profiles per -namespace allowing, for different confinement of users, etc. - -When profiles are reported it is now in a namespace:profile pair. -User side profiles that begin with / (old style) are assumed to be -in the namespace specified on the command line or fall back to the -"default" namespace. - -profile namespace names can be [alpha]([[:alnum:]_]* - - -currently - -- the parser allows setting the namespace a profile should go in using - --namespace name option. This will override the namespace specified - for a profile. -- the parser will accept profiles using a namespace:/profile/name syntax - the specified namespace will be used unless it is overriden by - the -namespace name command line option -- the only way to change names spaces is the use of change_profile and - set_profile. change_profile will allow for pam style change_profile - that drops, users into different "roles". - -The goal with namespaces is to provide a generic mechanism for: -- roles -- chroot & fsnames profile sets -- confinement of users (partial default policy) -- user profile sets (requires a little more and user side support) - -namespaces will be better supported with policy based transitions when -the named transition patch is finished (sorry I didn't get time to -finish it in hack week, but I may do it one of these weekends). - -The best way to play with namespaces current is setprofile -echo "setprofile namespace:/profile" >/proc//attr/current - ---- - security/apparmor/apparmor.h | 59 ++++++--- - security/apparmor/inline.h | 35 ++++- - security/apparmor/list.c | 106 ++++++++++++---- - security/apparmor/lsm.c | 30 +--- - security/apparmor/main.c | 143 ++++++++++++---------- - security/apparmor/module_interface.c | 227 +++++++++++++++++++++++++++++++---- - security/apparmor/procattr.c | 62 ++++++++- - 7 files changed, 504 insertions(+), 158 deletions(-) - ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -80,18 +80,40 @@ extern unsigned int apparmor_path_max; - - #define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args) - -+struct aa_profile; -+ -+/* struct aa_namespace - namespace for a set of profiles -+ * @name: the name of the namespace -+ * @list: list the namespace is on -+ * @profiles: list of profile in the namespace -+ * @profile_count: the number of profiles in the namespace -+ * @null_complain_profile: special profile used for learning in this namespace -+ * @count: reference count on the namespace -+ * @lock: lock for adding/removing profile to the namespace -+ */ -+struct aa_namespace { -+ char *name; -+ struct list_head list; -+ struct list_head profiles; -+ int profile_count; -+ struct aa_profile *null_complain_profile; -+ -+ struct kref count; -+ rwlock_t lock; -+}; -+ - /* struct aa_profile - basic confinement data - * @name: the profiles name -- * @file_rules: dfa containing the profiles file rules - * @list: list this profile is on -+ * @ns: namespace the profile is in -+ * @file_rules: dfa containing the profiles file rules - * @flags: flags controlling profile behavior - * @isstale: flag indicating if profile is stale - * @capabilities: capabilities granted by the process - * @count: reference count of the profile - * - * The AppArmor profile contains the basic confinement data. Each profile -- * has a name and potentially a list of sub profile entries. All non stale -- * profiles are on the profile_list. -+ * has a name, and all nonstale profile are in a profile namespace. - * - * The task_contexts list and the isstale flag are protected by the - * profile lock. -@@ -102,8 +124,10 @@ extern unsigned int apparmor_path_max; - */ - struct aa_profile { - char *name; -- struct aa_dfa *file_rules; - struct list_head list; -+ struct aa_namespace *ns; -+ -+ struct aa_dfa *file_rules; - struct { - int complain; - int audit; -@@ -118,8 +142,8 @@ struct aa_profile { - u16 network_families[AF_MAX]; - }; - --extern struct list_head profile_list; --extern rwlock_t profile_list_lock; -+extern struct list_head profile_ns_list; -+extern rwlock_t profile_ns_list_lock; - extern struct mutex aa_interface_lock; - - /** -@@ -145,7 +169,7 @@ struct aa_task_context { - kernel_cap_t caps_logged; - }; - --extern struct aa_profile *null_complain_profile; -+extern struct aa_namespace *default_namespace; - - /* aa_audit - AppArmor auditing structure - * Structure is populated by access control code and passed to aa_audit which -@@ -158,6 +182,7 @@ struct aa_audit { - const char *info; - const char *name; - const char *name2; -+ const char *name3; - int requested_mask, denied_mask; - struct iattr *iattr; - pid_t task, parent; -@@ -177,9 +202,8 @@ enum aa_lock_class { - }; - - /* main.c */ --extern int alloc_null_complain_profile(void); --extern void free_null_complain_profile(void); --extern int attach_nullprofile(struct aa_profile *profile); -+extern int alloc_default_namespace(void); -+extern void free_default_namespace(void); - extern int aa_audit_message(struct aa_profile *profile, struct aa_audit *sa, - int type); - void aa_audit_hint(struct aa_profile *profile, struct aa_audit *sa); -@@ -210,9 +234,7 @@ extern int aa_clone(struct task_struct * - extern int aa_register(struct linux_binprm *bprm); - extern void aa_release(struct task_struct *task); - extern int aa_change_hat(const char *id, u64 hat_magic); --extern int aa_change_profile(const char *name); --extern struct aa_profile *__aa_find_profile(const char *name, -- struct list_head *list); -+extern int aa_change_profile(const char *ns_name, const char *name); - extern struct aa_profile *__aa_replace_profile(struct task_struct *task, - struct aa_profile *profile); - extern struct aa_task_context *lock_task_and_profiles(struct task_struct *task, -@@ -231,12 +253,19 @@ extern int aa_net_perm(struct aa_profile - extern int aa_revalidate_sk(struct sock *sk, char *operation); - - /* list.c */ --extern void aa_profilelist_release(void); -+extern struct aa_namespace *__aa_find_namespace(const char *name, -+ struct list_head *list); -+extern struct aa_profile *__aa_find_profile(const char *name, -+ struct list_head *list); -+extern void aa_profile_ns_list_release(void); - - /* module_interface.c */ - extern ssize_t aa_add_profile(void *, size_t); - extern ssize_t aa_replace_profile(void *, size_t); --extern ssize_t aa_remove_profile(const char *, size_t); -+extern ssize_t aa_remove_profile(char *, size_t); -+extern struct aa_namespace *alloc_aa_namespace(char *name); -+extern void free_aa_namespace(struct aa_namespace *ns); -+extern void free_aa_namespace_kref(struct kref *kref); - extern struct aa_profile *alloc_aa_profile(void); - extern void free_aa_profile(struct aa_profile *profile); - extern void free_aa_profile_kref(struct kref *kref); ---- a/security/apparmor/inline.h -+++ b/security/apparmor/inline.h -@@ -24,6 +24,32 @@ static inline struct aa_task_context *aa - return (struct aa_task_context *) rcu_dereference(task->security); - } - -+static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns) -+{ -+ if (ns) -+ kref_get(&(ns->count)); -+ -+ return ns; -+} -+ -+static inline void aa_put_namespace(struct aa_namespace *ns) -+{ -+ if (ns) -+ kref_put(&ns->count, free_aa_namespace_kref); -+} -+ -+ -+static inline struct aa_namespace *aa_find_namespace(const char *name) -+{ -+ struct aa_namespace *ns = NULL; -+ -+ read_lock(&profile_ns_list_lock); -+ ns = aa_get_namespace(__aa_find_namespace(name, &profile_ns_list)); -+ read_unlock(&profile_ns_list_lock); -+ -+ return ns; -+} -+ - /** - * aa_dup_profile - increment refcount on profile @p - * @p: profile -@@ -62,13 +88,14 @@ static inline struct aa_profile *aa_get_ - return profile; - } - --static inline struct aa_profile *aa_find_profile(const char *name) -+static inline struct aa_profile *aa_find_profile(struct aa_namespace *ns, -+ const char *name) - { - struct aa_profile *profile = NULL; - -- read_lock(&profile_list_lock); -- profile = aa_dup_profile(__aa_find_profile(name, &profile_list)); -- read_unlock(&profile_list_lock); -+ read_lock(&ns->lock); -+ profile = aa_dup_profile(__aa_find_profile(name, &ns->profiles)); -+ read_unlock(&ns->lock); - - return profile; - } ---- a/security/apparmor/list.c -+++ b/security/apparmor/list.c -@@ -13,9 +13,30 @@ - #include "apparmor.h" - #include "inline.h" - --/* list of all profiles and lock */ --LIST_HEAD(profile_list); --rwlock_t profile_list_lock = RW_LOCK_UNLOCKED; -+/* list of profile namespaces and lock */ -+LIST_HEAD(profile_ns_list); -+rwlock_t profile_ns_list_lock = RW_LOCK_UNLOCKED; -+ -+/** -+ * __aa_find_namespace - look up a profile namespace on the namespace list -+ * @name: name of namespace to find -+ * @head: list to search -+ * -+ * Returns a pointer to the namespace on the list, or NULL if no namespace -+ * called @name exists. The caller must hold the profile_ns_list_lock. -+ */ -+struct aa_namespace *__aa_find_namespace(const char *name, -+ struct list_head *head) -+{ -+ struct aa_namespace *ns; -+ -+ list_for_each_entry(ns, head, list) { -+ if (!strcmp(ns->name, name)) -+ return ns; -+ } -+ -+ return NULL; -+} - - /** - * __aa_find_profile - look up a profile on the profile list -@@ -37,51 +58,92 @@ struct aa_profile *__aa_find_profile(con - return NULL; - } - -+static void aa_profile_list_release(struct list_head *head) -+{ -+ struct aa_profile *profile, *tmp; -+ list_for_each_entry_safe(profile, tmp, head, list) { -+ /* Remove the profile from each task context it is on. */ -+ lock_profile(profile); -+ profile->isstale = 1; -+ aa_unconfine_tasks(profile); -+ list_del_init(&profile->list); -+ unlock_profile(profile); -+ aa_put_profile(profile); -+ } -+} -+ - /** - * aa_profilelist_release - Remove all profiles from profile_list - */ --void aa_profilelist_release(void) -+void aa_profile_ns_list_release(void) - { -- struct aa_profile *p, *tmp; -+ struct aa_namespace *ns, *tmp; - -- write_lock(&profile_list_lock); -- list_for_each_entry_safe(p, tmp, &profile_list, list) { -- list_del_init(&p->list); -- aa_put_profile(p); -+ /* Remove and release all the profiles on namespace profile lists. */ -+ write_lock(&profile_ns_list_lock); -+ list_for_each_entry_safe(ns, tmp, &profile_ns_list, list) { -+ write_lock(&ns->lock); -+ aa_profile_list_release(&ns->profiles); -+ list_del_init(&ns->list); -+ write_unlock(&ns->lock); -+ aa_put_namespace(ns); - } -- write_unlock(&profile_list_lock); -+ write_unlock(&profile_ns_list_lock); - } - - static void *p_start(struct seq_file *f, loff_t *pos) - { -- struct aa_profile *node; -+ struct aa_namespace *ns; -+ struct aa_profile *profile; - loff_t l = *pos; -- -- read_lock(&profile_list_lock); -- list_for_each_entry(node, &profile_list, list) -- if (!l--) -- return node; -+ read_lock(&profile_ns_list_lock); -+ if (l--) -+ return NULL; -+ list_for_each_entry(ns, &profile_ns_list, list) { -+ read_lock(&ns->lock); -+ list_for_each_entry(profile, &ns->profiles, list) -+ return profile; -+ read_unlock(&ns->lock); -+ } - return NULL; - } - - static void *p_next(struct seq_file *f, void *p, loff_t *pos) - { -- struct list_head *lh = ((struct aa_profile *)p)->list.next; -+ struct aa_profile *profile = (struct aa_profile *) p; -+ struct list_head *lh = profile->list.next; -+ struct aa_namespace *ns; - (*pos)++; -- return lh == &profile_list ? -- NULL : list_entry(lh, struct aa_profile, list); -+ if (lh != &profile->ns->profiles) -+ return list_entry(lh, struct aa_profile, list); -+ -+ lh = profile->ns->list.next; -+ read_unlock(&profile->ns->lock); -+ while (lh != &profile_ns_list) { -+ ns = list_entry(lh, struct aa_namespace, list); -+ read_lock(&ns->lock); -+ list_for_each_entry(profile, &ns->profiles, list) -+ return profile; -+ read_unlock(&ns->lock); -+ lh = ns->list.next; -+ } -+ return NULL; - } - - static void p_stop(struct seq_file *f, void *v) - { -- read_unlock(&profile_list_lock); -+ read_unlock(&profile_ns_list_lock); - } - - static int seq_show_profile(struct seq_file *f, void *v) - { - struct aa_profile *profile = (struct aa_profile *)v; -- seq_printf(f, "%s (%s)\n", profile->name, -- PROFILE_COMPLAIN(profile) ? "complain" : "enforce"); -+ if (profile->ns == default_namespace) -+ seq_printf(f, "%s (%s)\n", profile->name, -+ PROFILE_COMPLAIN(profile) ? "complain" : "enforce"); -+ else -+ seq_printf(f, "%s:%s (%s)\n", profile->ns->name, profile->name, -+ PROFILE_COMPLAIN(profile) ? "complain" : "enforce"); - return 0; - } - ---- a/security/apparmor/lsm.c -+++ b/security/apparmor/lsm.c -@@ -887,12 +887,12 @@ static int __init apparmor_init(void) - goto createfs_out; - } - -- if ((error = alloc_null_complain_profile())){ -- AA_ERROR("Unable to allocate null complain profile\n"); -+ if ((error = alloc_default_namespace())){ -+ AA_ERROR("Unable to allocate default profile namespace\n"); - goto alloc_out; - } - -- if ((error = register_security(&apparmor_ops))) { -+ if ((error = register_security(&apparmor_ops))) { - AA_ERROR("Unable to register AppArmor\n"); - goto register_security_out; - } -@@ -905,10 +905,10 @@ static int __init apparmor_init(void) - return error; - - register_security_out: -- free_null_complain_profile(); -+ free_default_namespace(); - - alloc_out: -- destroy_apparmorfs(); -+ destroy_apparmorfs(); - - createfs_out: - return error; -@@ -919,26 +919,10 @@ static void __exit apparmor_exit(void) - { - /* Remove and release all the profiles on the profile list. */ - mutex_lock(&aa_interface_lock); -- write_lock(&profile_list_lock); -- while (!list_empty(&profile_list)) { -- struct aa_profile *profile = -- list_entry(profile_list.next, struct aa_profile, list); -- -- /* Remove the profile from each task context it is on. */ -- lock_profile(profile); -- profile->isstale = 1; -- aa_unconfine_tasks(profile); -- unlock_profile(profile); -- -- /* Release the profile itself. */ -- list_del_init(&profile->list); -- aa_put_profile(profile); -- } -- write_unlock(&profile_list_lock); -+ aa_profile_ns_list_release(); - - /* FIXME: cleanup profiles references on files */ -- -- free_null_complain_profile(); -+ free_default_namespace(); - - /* - * Delay for an rcu cycle to make sure that all active task ---- a/security/apparmor/main.c -+++ b/security/apparmor/main.c -@@ -29,17 +29,7 @@ static const char *capability_names[] = - #include "capability_names.h" - }; - --/* NULL complain profile -- * -- * Used when in complain mode, to emit Permitting messages for non-existant -- * profiles and hats. This is necessary because of selective mode, in which -- * case we need a complain null_profile and enforce null_profile -- * -- * The null_complain_profile cannot be statically allocated, because it -- * can be associated to files which keep their reference even if apparmor is -- * unloaded -- */ --struct aa_profile *null_complain_profile; -+struct aa_namespace *default_namespace; - - /** - * aa_file_denied - check for @mask access on a file -@@ -209,42 +199,34 @@ static int aa_perm_dentry(struct aa_prof - return error; - } - --/** -- * alloc_null_complain_profile - Allocate the global null_complain_profile. -- * -- * Return %0 (success) or error (-%ENOMEM) -- */ --int alloc_null_complain_profile(void) -+int alloc_default_namespace(void) - { -- null_complain_profile = alloc_aa_profile(); -- if (!null_complain_profile) -- goto fail; -- -- null_complain_profile->name = -- kstrdup("null-complain-profile", GFP_KERNEL); -- -- if (!null_complain_profile->name) -- goto fail; -+ struct aa_namespace *ns; -+ char *name = kstrdup("default", GFP_KERNEL); -+ if (!name) -+ return -ENOMEM; -+ ns = alloc_aa_namespace(name); -+ if (!ns) { -+ kfree(name); -+ return -ENOMEM; -+ } - -- null_complain_profile->flags.complain = 1; -+ write_lock(&profile_ns_list_lock); -+ default_namespace = ns; -+ aa_get_namespace(ns); -+ list_add(&ns->list, &profile_ns_list); -+ write_unlock(&profile_ns_list_lock); - - return 0; -- --fail: -- /* free_aa_profile is safe for freeing partially constructed objects */ -- free_aa_profile(null_complain_profile); -- null_complain_profile = NULL; -- -- return -ENOMEM; - } - --/** -- * free_null_complain_profile - Free null profiles -- */ --void free_null_complain_profile(void) -+void free_default_namespace(void) - { -- aa_put_profile(null_complain_profile); -- null_complain_profile = NULL; -+ write_lock(&profile_ns_list_lock); -+ list_del_init(&default_namespace->list); -+ write_unlock(&profile_ns_list_lock); -+ aa_put_namespace(default_namespace); -+ default_namespace = NULL; - } - - static void aa_audit_file_mask(struct audit_buffer *ab, const char *name, -@@ -394,6 +376,9 @@ static int aa_audit_base(struct aa_profi - if (profile) { - audit_log_format(ab, " profile="); - audit_log_untrustedstring(ab, profile->name); -+ -+ audit_log_format(ab, " namespace="); -+ audit_log_untrustedstring(ab, profile->ns->name); - } - - audit_log_end(ab); -@@ -801,7 +786,7 @@ repeat: - unlock_profile(profile); - - if (APPARMOR_COMPLAIN(child_cxt) && -- profile == null_complain_profile) { -+ profile == profile->ns->null_complain_profile) { - struct aa_audit sa; - memset(&sa, 0, sizeof(sa)); - sa.operation = "clone"; -@@ -823,7 +808,11 @@ aa_register_find(struct aa_profile *prof - struct aa_profile *new_profile; - - /* Locate new profile */ -- new_profile = aa_find_profile(name); -+ if (profile) -+ new_profile = aa_find_profile(profile->ns, name); -+ else -+ new_profile = aa_find_profile(default_namespace, name); -+ - if (new_profile) { - AA_DEBUG("%s: setting profile %s\n", - __FUNCTION__, new_profile->name); -@@ -832,7 +821,8 @@ aa_register_find(struct aa_profile *prof - sa->denied_mask = MAY_EXEC; - if (complain) { - aa_audit_hint(profile, sa); -- new_profile = aa_dup_profile(null_complain_profile); -+ new_profile = -+ aa_dup_profile(profile->ns->null_complain_profile); - } else { - aa_audit_reject(profile, sa); - return ERR_PTR(-EACCES); /* was -EPERM */ -@@ -922,7 +912,8 @@ repeat: - * describing mode to execute image in. - * Drop into null-profile (disabling secure exec). - */ -- new_profile = aa_dup_profile(null_complain_profile); -+ new_profile = -+ aa_dup_profile(profile->ns->null_complain_profile); - exec_mode |= AA_EXEC_UNSAFE; - } else { - sa.denied_mask = MAY_EXEC; -@@ -974,7 +965,8 @@ repeat: - ((unsigned long)bprm->security | bprm_flags); - } - -- if (complain && new_profile == null_complain_profile) { -+ if (complain && new_profile && -+ new_profile == new_profile->ns->null_complain_profile) { - sa.requested_mask = 0; - sa.name = NULL; - sa.info = "set profile"; -@@ -1034,7 +1026,8 @@ repeat: - } - } - --static int do_change_profile(struct aa_profile *expected, const char *name, -+static int do_change_profile(struct aa_profile *expected, -+ struct aa_namespace *ns, const char *name, - u64 cookie, int restore, struct aa_audit *sa) - { - struct aa_profile *new_profile = NULL, *old_profile = NULL, -@@ -1048,11 +1041,11 @@ static int do_change_profile(struct aa_p - if (!new_cxt) - return -ENOMEM; - -- new_profile = aa_find_profile(name); -+ new_profile = aa_find_profile(ns, name); - if (!new_profile && !restore) { - if (!PROFILE_COMPLAIN(expected)) - return -ENOENT; -- new_profile = aa_dup_profile(null_complain_profile); -+ new_profile = aa_dup_profile(ns->null_complain_profile); - } - - cxt = lock_task_and_profiles(current, new_profile); -@@ -1087,7 +1080,7 @@ static int do_change_profile(struct aa_p - goto out; - } - -- if (new_profile == null_complain_profile) -+ if (new_profile == ns->null_complain_profile) - aa_audit_hint(cxt->profile, sa); - - if (APPARMOR_AUDIT(cxt)) -@@ -1111,19 +1104,24 @@ out: - - /** - * aa_change_profile - perform a one-way profile transition -+ * @ns_name: name of the profile namespace to change to - * @name: name of profile to change to -- * - * Change to new profile @name. Unlike with hats, there is no way - * to change back. - * - * Returns %0 on success, error otherwise. - */ --int aa_change_profile(const char *name) -+int aa_change_profile(const char *ns_name, const char *name) - { - struct aa_task_context *cxt; - struct aa_profile *profile; -+ struct aa_namespace *ns = NULL; - struct aa_audit sa; -- int error = 0; -+ unsigned int state; -+ int error = -EINVAL; -+ -+ if (!name) -+ return -EINVAL; - - memset(&sa, 0, sizeof(sa)); - sa.gfp_mask = GFP_ATOMIC; -@@ -1139,17 +1137,34 @@ repeat: - profile = aa_dup_profile(cxt->profile); - task_unlock(current); - -- if (name) { -- if (profile != null_complain_profile && -- !(aa_match(profile->file_rules, name) & -- AA_CHANGE_PROFILE)) { -+ if (ns_name) -+ ns = aa_find_namespace(ns_name); -+ else -+ ns = aa_get_namespace(profile->ns); -+ if (!ns) { -+ aa_put_profile(profile); -+ return -ENOENT; -+ } -+ -+ if (PROFILE_COMPLAIN(profile) || -+ (ns == profile->ns && -+ (aa_match(profile->file_rules, name) & AA_CHANGE_PROFILE))) -+ error = do_change_profile(profile, ns, name, 0, 0, &sa); -+ else { -+ /* check for a rule with a namespace prepended */ -+ aa_match_state(profile->file_rules, DFA_START, ns->name, -+ &state); -+ state = aa_dfa_null_transition(profile->file_rules, state); -+ if ((aa_match_state(profile->file_rules, state, name, NULL) & -+ AA_CHANGE_PROFILE)) -+ error = do_change_profile(profile, ns, name, 0, 0, -+ &sa); -+ else - /* no permission to transition to profile @name */ -- aa_put_profile(profile); -- return -EACCES; -- } -- error = do_change_profile(profile, name, 0, 0, &sa); -+ error = -EACCES; - } - -+ aa_put_namespace(ns); - aa_put_profile(profile); - if (error == -ESTALE) - goto repeat; -@@ -1204,11 +1219,13 @@ repeat: - goto out; - } - sprintf(name, "%s//%s", profile_name, hat_name); -- error = do_change_profile(profile, name, cookie, 0, &sa); -+ error = do_change_profile(profile, profile->ns, name, cookie, -+ 0, &sa); - kfree(name); - } else if (previous_profile) -- error = do_change_profile(profile, previous_profile->name, -- cookie, 1, &sa); -+ error = do_change_profile(profile, profile->ns, -+ previous_profile->name, cookie, 1, -+ &sa); - /* else ignore restores when there is no saved profile */ - - out: ---- a/security/apparmor/module_interface.c -+++ b/security/apparmor/module_interface.c -@@ -58,6 +58,7 @@ struct aa_ext { - void *end; - void *pos; /* pointer to current position in the buffer */ - u32 version; -+ char *ns_name; - }; - - static inline int aa_inbounds(struct aa_ext *e, size_t size) -@@ -387,6 +388,12 @@ static int aa_verify_header(struct aa_ex - aa_audit_status(NULL, &sa); - return -EPROTONOSUPPORT; - } -+ -+ /* read the namespace if present */ -+ if (!aa_is_dynstring(e, &e->ns_name, "namespace")) { -+ e->ns_name = NULL; -+ } -+ - return 0; - } - -@@ -398,10 +405,12 @@ static int aa_verify_header(struct aa_ex - ssize_t aa_add_profile(void *data, size_t size) - { - struct aa_profile *profile = NULL; -+ struct aa_namespace *ns = NULL; - struct aa_ext e = { - .start = data, - .end = data + size, -- .pos = data -+ .pos = data, -+ .ns_name = NULL - }; - ssize_t error = aa_verify_header(&e, "profile_load"); - if (error) -@@ -412,16 +421,42 @@ ssize_t aa_add_profile(void *data, size_ - return PTR_ERR(profile); - - mutex_lock(&aa_interface_lock); -- write_lock(&profile_list_lock); -- if (__aa_find_profile(profile->name, &profile_list)) { -+ write_lock(&profile_ns_list_lock); -+ if (e.ns_name) -+ ns = __aa_find_namespace(e.ns_name, &profile_ns_list); -+ else -+ ns = default_namespace; -+ if (!ns) { -+ struct aa_namespace *new_ns; -+ write_unlock(&profile_ns_list_lock); -+ new_ns = alloc_aa_namespace(e.ns_name); -+ if (!new_ns) { -+ mutex_unlock(&aa_interface_lock); -+ return -ENOMEM; -+ } -+ write_lock(&profile_ns_list_lock); -+ ns = __aa_find_namespace(e.ns_name, &profile_ns_list); -+ if (!ns) { -+ list_add(&new_ns->list, &profile_ns_list); -+ ns = new_ns; -+ } else -+ free_aa_namespace(new_ns); -+ } -+ -+ write_lock(&ns->lock); -+ if (__aa_find_profile(profile->name, &ns->profiles)) { - /* A profile with this name exists already. */ -- write_unlock(&profile_list_lock); -+ write_unlock(&ns->lock); -+ write_unlock(&profile_ns_list_lock); - mutex_unlock(&aa_interface_lock); - aa_put_profile(profile); - return -EEXIST; - } -- list_add(&profile->list, &profile_list); -- write_unlock(&profile_list_lock); -+ profile->ns = aa_get_namespace(ns); -+ ns->profile_count++; -+ list_add(&profile->list, &ns->profiles); -+ write_unlock(&ns->lock); -+ write_unlock(&profile_ns_list_lock); - mutex_unlock(&aa_interface_lock); - - return size; -@@ -461,12 +496,15 @@ static inline void task_replace(struct t - ssize_t aa_replace_profile(void *udata, size_t size) - { - struct aa_profile *old_profile, *new_profile; -+ struct aa_namespace *ns; - struct aa_task_context *new_cxt; - struct aa_ext e = { - .start = udata, - .end = udata + size, -- .pos = udata -+ .pos = udata, -+ .ns_name = NULL - }; -+ - ssize_t error = aa_verify_header(&e, "profile_replace"); - if (error) - return error; -@@ -476,16 +514,42 @@ ssize_t aa_replace_profile(void *udata, - return PTR_ERR(new_profile); - - mutex_lock(&aa_interface_lock); -- write_lock(&profile_list_lock); -- old_profile = __aa_find_profile(new_profile->name, &profile_list); -+ write_lock(&profile_ns_list_lock); -+ if (e.ns_name) -+ ns = __aa_find_namespace(e.ns_name, &profile_ns_list); -+ else -+ ns = default_namespace; -+ if (!ns) { -+ struct aa_namespace *new_ns; -+ write_unlock(&profile_ns_list_lock); -+ new_ns = alloc_aa_namespace(e.ns_name); -+ if (!new_ns) { -+ mutex_unlock(&aa_interface_lock); -+ return -ENOMEM; -+ } -+ write_lock(&profile_ns_list_lock); -+ ns = __aa_find_namespace(e.ns_name, &profile_ns_list); -+ if (!ns) { -+ list_add(&new_ns->list, &profile_ns_list); -+ ns = new_ns; -+ } else -+ free_aa_namespace(new_ns); -+ } -+ -+ write_lock(&ns->lock); -+ old_profile = __aa_find_profile(new_profile->name, &ns->profiles); - if (old_profile) { - lock_profile(old_profile); - old_profile->isstale = 1; -- unlock_profile(old_profile); - list_del_init(&old_profile->list); -+ unlock_profile(old_profile); -+ ns->profile_count--; - } -- list_add(&new_profile->list, &profile_list); -- write_unlock(&profile_list_lock); -+ new_profile->ns = aa_get_namespace(ns); -+ ns->profile_count++; -+ list_add(&new_profile->list, &ns->profiles); -+ write_unlock(&ns->lock); -+ write_unlock(&profile_ns_list_lock); - - if (!old_profile) - goto out; -@@ -530,32 +594,148 @@ out: - * remove a profile from the profile list and all aa_task_context references - * to said profile. - */ --ssize_t aa_remove_profile(const char *name, size_t size) -+ssize_t aa_remove_profile(char *name, size_t size) - { -+ struct aa_namespace *ns; - struct aa_profile *profile; - - mutex_lock(&aa_interface_lock); -- write_lock(&profile_list_lock); -- profile = __aa_find_profile(name, &profile_list); -+ write_lock(&profile_ns_list_lock); -+ -+ if (name[0] == '/') { -+ ns = default_namespace; -+ } else { -+ char *split = strchr(name, ':'); -+ if (!split) -+ goto noent; -+ *split = 0; -+ ns = __aa_find_namespace(name, &profile_ns_list); -+ name = split + 1; -+ } -+ -+ if (!ns) -+ goto noent; -+ write_lock(&ns->lock); -+ profile = __aa_find_profile(name, &ns->profiles); - if (!profile) { -- write_unlock(&profile_list_lock); -- mutex_unlock(&aa_interface_lock); -- return -ENOENT; -+ write_unlock(&ns->lock); -+ goto noent; - } - - /* Remove the profile from each task context it is on. */ - lock_profile(profile); - profile->isstale = 1; - aa_unconfine_tasks(profile); -+ list_del_init(&profile->list); -+ ns->profile_count--; - unlock_profile(profile); -- - /* Release the profile itself. */ -- list_del_init(&profile->list); -- aa_put_profile(profile); -- write_unlock(&profile_list_lock); -+ write_unlock(&ns->lock); -+ /* check to see if the namespace has become stale */ -+ if (ns != default_namespace && ns->profile_count == 0) { -+ list_del_init(&ns->list); -+ aa_put_namespace(ns); -+ } -+ write_unlock(&profile_ns_list_lock); - mutex_unlock(&aa_interface_lock); -+ aa_put_profile(profile); - - return size; -+ -+noent: -+ write_unlock(&profile_ns_list_lock); -+ mutex_unlock(&aa_interface_lock); -+ return -ENOENT; -+} -+ -+/** -+ * free_aa_namespace_kref - free aa_namespace by kref (see aa_put_namespace) -+ * @kr: kref callback for freeing of a namespace -+ */ -+void free_aa_namespace_kref(struct kref *kref) -+{ -+ struct aa_namespace *ns=container_of(kref, struct aa_namespace, count); -+ -+ free_aa_namespace(ns); -+} -+ -+/** -+ * alloc_aa_namespace - allocate, initialize and return a new namespace -+ * @name: a preallocated name -+ * Returns NULL on failure. -+ */ -+struct aa_namespace *alloc_aa_namespace(char *name) -+{ -+ struct aa_namespace *ns; -+ -+ ns = kzalloc(sizeof(*ns), GFP_KERNEL); -+ AA_DEBUG("%s(%p)\n", __FUNCTION__, ns); -+ if (ns) { -+ ns->name = name; -+ INIT_LIST_HEAD(&ns->list); -+ INIT_LIST_HEAD(&ns->profiles); -+ kref_init(&ns->count); -+ rwlock_init(&ns->lock); -+ -+ ns->null_complain_profile = alloc_aa_profile(); -+ if (!ns->null_complain_profile) { -+ if (!name) -+ kfree(ns->name); -+ kfree(ns); -+ return NULL; -+ } -+ ns->null_complain_profile->name = -+ kstrdup("null-complain-profile", GFP_KERNEL); -+ if (!ns->null_complain_profile->name) { -+ free_aa_profile(ns->null_complain_profile); -+ if (!name) -+ kfree(ns->name); -+ kfree(ns); -+ return NULL; -+ } -+ ns->null_complain_profile->flags.complain = 1; -+ /* null_complain_profile doesn't contribute to ns ref count */ -+ ns->null_complain_profile->ns = ns; -+ } -+ return ns; -+} -+ -+/** -+ * free_aa_namespace - free a profile namespace -+ * @namespace: the namespace to free -+ * -+ * Free a namespace. All references to the namespace must have been put. -+ * If the namespace was referenced by a profile confining a task, -+ * free_aa_namespace will be called indirectly (through free_aa_profile) -+ * from an rcu callback routine, so we must not sleep here. -+ */ -+void free_aa_namespace(struct aa_namespace *ns) -+{ -+ AA_DEBUG("%s(%p)\n", __FUNCTION__, ns); -+ -+ if (!ns) -+ return; -+ -+ /* namespace still contains profiles -- invalid */ -+ if (!list_empty(&ns->profiles)) { -+ AA_ERROR("%s: internal error, " -+ "namespace '%s' still contains profiles\n", -+ __FUNCTION__, -+ ns->name); -+ BUG(); -+ } -+ if (!list_empty(&ns->list)) { -+ AA_ERROR("%s: internal error, " -+ "namespace '%s' still on list\n", -+ __FUNCTION__, -+ ns->name); -+ BUG(); -+ } -+ /* null_complain_profile doesn't contribute to ns ref counting */ -+ ns->null_complain_profile->ns = NULL; -+ aa_put_profile(ns->null_complain_profile); -+ kfree(ns->name); -+ kfree(ns); - } - - /** -@@ -605,7 +785,7 @@ void free_aa_profile(struct aa_profile * - if (!profile) - return; - -- /* profile is still on global profile list -- invalid */ -+ /* profile is still on profile namespace list -- invalid */ - if (!list_empty(&profile->list)) { - AA_ERROR("%s: internal error, " - "profile '%s' still on global list\n", -@@ -613,6 +793,7 @@ void free_aa_profile(struct aa_profile * - profile->name); - BUG(); - } -+ aa_put_namespace(profile->ns); - - aa_match_free(profile->file_rules); - ---- a/security/apparmor/procattr.c -+++ b/security/apparmor/procattr.c -@@ -19,15 +19,22 @@ int aa_getprocattr(struct aa_profile *pr - if (profile) { - const char *mode_str = PROFILE_COMPLAIN(profile) ? - " (complain)" : " (enforce)"; -- int mode_len, name_len; -+ int mode_len, name_len, ns_len = 0; - - mode_len = strlen(mode_str); - name_len = strlen(profile->name); -- *len = mode_len + name_len + 1; -+ if (profile->ns != default_namespace) -+ ns_len = strlen(profile->ns->name) + 1; -+ *len = mode_len + ns_len + name_len + 1; - str = kmalloc(*len, GFP_ATOMIC); - if (!str) - return -ENOMEM; - -+ if (ns_len) { -+ memcpy(str, profile->ns->name, ns_len - 1); -+ str += ns_len - 1; -+ *str++ = ':'; -+ } - memcpy(str, profile->name, name_len); - str += name_len; - memcpy(str, mode_str, mode_len); -@@ -87,13 +94,26 @@ int aa_setprocattr_changehat(char *args) - - int aa_setprocattr_changeprofile(char *args) - { -- return aa_change_profile(args); -+ char *name = args, *ns_name = NULL; -+ -+ if (name[0] != '/') { -+ char *split = strchr(name, ':'); -+ if (split) { -+ *split = 0; -+ ns_name = name; -+ name = split + 1; -+ } -+ } -+ -+ return aa_change_profile(ns_name, name); - } - - int aa_setprocattr_setprofile(struct task_struct *task, char *args) - { - struct aa_profile *old_profile, *new_profile; -+ struct aa_namespace *ns; - struct aa_audit sa; -+ char *name, *ns_name = NULL; - - memset(&sa, 0, sizeof(sa)); - sa.operation = "profile_set"; -@@ -103,15 +123,38 @@ int aa_setprocattr_setprofile(struct tas - AA_DEBUG("%s: current %d\n", - __FUNCTION__, current->pid); - -+ name = args; -+ if (args[0] != '/') { -+ char *split = strchr(args, ':'); -+ if (split) { -+ *split = 0; -+ ns_name = args; -+ name = split + 1; -+ } -+ } -+ if (ns_name) -+ ns = aa_find_namespace(ns_name); -+ else -+ ns = aa_get_namespace(default_namespace); -+ if (!ns) { -+ sa.name = ns_name; -+ sa.info = "unknown namespace"; -+ aa_audit_reject(NULL, &sa); -+ aa_put_namespace(ns); -+ return -EINVAL; -+ } -+ - repeat: -- if (strcmp(args, "unconfined") == 0) -+ if (strcmp(name, "unconfined") == 0) - new_profile = NULL; - else { -- new_profile = aa_find_profile(args); -+ new_profile = aa_find_profile(ns, name); - if (!new_profile) { -- sa.name = args; -+ sa.name = ns_name; -+ sa.name2 = name; - sa.info = "unknown profile"; - aa_audit_reject(NULL, &sa); -+ aa_put_namespace(ns); - return -EINVAL; - } - } -@@ -124,12 +167,14 @@ repeat: - error = PTR_ERR(old_profile); - if (error == -ESTALE) - goto repeat; -+ aa_put_namespace(ns); - return error; - } - - if (new_profile) { -- sa.name = args; -- sa.name2 = old_profile ? old_profile->name : -+ sa.name = ns_name; -+ sa.name2 = name; -+ sa.name3 = old_profile ? old_profile->name : - "unconfined"; - aa_audit_status(NULL, &sa); - } else { -@@ -142,6 +187,7 @@ repeat: - aa_audit_status(NULL, &sa); - } - } -+ aa_put_namespace(ns); - aa_put_profile(old_profile); - aa_put_profile(new_profile); - return 0; diff --git a/kernel-patches/for-mainline/remove_suid.diff b/kernel-patches/for-mainline/remove_suid.diff deleted file mode 100644 index 6e594c907..000000000 --- a/kernel-patches/for-mainline/remove_suid.diff +++ /dev/null @@ -1,144 +0,0 @@ -From: Andreas Gruenbacher -Subject: Pass struct path down to remove_suid and children - -Required by a later patch that adds a struct vfsmount parameter to -notify_change(). - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - - fs/ntfs/file.c | 2 +- - fs/splice.c | 4 ++-- - fs/xfs/linux-2.6/xfs_lrw.c | 2 +- - include/linux/fs.h | 4 ++-- - mm/filemap.c | 16 ++++++++-------- - mm/filemap_xip.c | 2 +- - mm/shmem.c | 2 +- - 7 files changed, 16 insertions(+), 16 deletions(-) - ---- a/fs/ntfs/file.c -+++ b/fs/ntfs/file.c -@@ -2120,7 +2120,7 @@ static ssize_t ntfs_file_aio_write_noloc - goto out; - if (!count) - goto out; -- err = remove_suid(file->f_path.dentry); -+ err = remove_suid(&file->f_path); - if (err) - goto out; - file_update_time(file); ---- a/fs/splice.c -+++ b/fs/splice.c -@@ -775,7 +775,7 @@ generic_file_splice_write_nolock(struct - ssize_t ret; - int err; - -- err = remove_suid(out->f_path.dentry); -+ err = remove_suid(&out->f_path); - if (unlikely(err)) - return err; - -@@ -835,7 +835,7 @@ generic_file_splice_write(struct pipe_in - if (killpriv) - err = security_inode_killpriv(out->f_path.dentry); - if (!err && killsuid) -- err = __remove_suid(out->f_path.dentry, killsuid); -+ err = __remove_suid(&out->f_path, killsuid); - mutex_unlock(&inode->i_mutex); - if (err) - return err; ---- a/fs/xfs/linux-2.6/xfs_lrw.c -+++ b/fs/xfs/linux-2.6/xfs_lrw.c -@@ -727,7 +727,7 @@ start: - !capable(CAP_FSETID)) { - error = xfs_write_clear_setuid(xip); - if (likely(!error)) -- error = -remove_suid(file->f_path.dentry); -+ error = -remove_suid(&file->f_path); - if (unlikely(error)) { - goto out_unlock_internal; - } ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1766,9 +1766,9 @@ extern void __iget(struct inode * inode) - extern void clear_inode(struct inode *); - extern void destroy_inode(struct inode *); - extern struct inode *new_inode(struct super_block *); --extern int __remove_suid(struct dentry *, int); -+extern int __remove_suid(struct path *, int); - extern int should_remove_suid(struct dentry *); --extern int remove_suid(struct dentry *); -+extern int remove_suid(struct path *); - - extern void __insert_inode_hash(struct inode *, unsigned long hashval); - extern void remove_inode_hash(struct inode *); ---- a/mm/filemap.c -+++ b/mm/filemap.c -@@ -1610,26 +1610,26 @@ int should_remove_suid(struct dentry *de - } - EXPORT_SYMBOL(should_remove_suid); - --int __remove_suid(struct dentry *dentry, int kill) -+int __remove_suid(struct path *path, int kill) - { - struct iattr newattrs; - - newattrs.ia_valid = ATTR_FORCE | kill; -- return notify_change(dentry, &newattrs); -+ return notify_change(path->dentry, &newattrs); - } - --int remove_suid(struct dentry *dentry) -+int remove_suid(struct path *path) - { -- int killsuid = should_remove_suid(dentry); -- int killpriv = security_inode_need_killpriv(dentry); -+ int killsuid = should_remove_suid(path->dentry); -+ int killpriv = security_inode_need_killpriv(path->dentry); - int error = 0; - - if (killpriv < 0) - return killpriv; - if (killpriv) -- error = security_inode_killpriv(dentry); -+ error = security_inode_killpriv(path->dentry); - if (!error && killsuid) -- error = __remove_suid(dentry, killsuid); -+ error = __remove_suid(path, killsuid); - - return error; - } -@@ -2342,7 +2342,7 @@ __generic_file_aio_write_nolock(struct k - if (count == 0) - goto out; - -- err = remove_suid(file->f_path.dentry); -+ err = remove_suid(&file->f_path); - if (err) - goto out; - ---- a/mm/filemap_xip.c -+++ b/mm/filemap_xip.c -@@ -378,7 +378,7 @@ xip_file_write(struct file *filp, const - if (count == 0) - goto out_backing; - -- ret = remove_suid(filp->f_path.dentry); -+ ret = remove_suid(&filp->f_path); - if (ret) - goto out_backing; - ---- a/mm/shmem.c -+++ b/mm/shmem.c -@@ -1525,7 +1525,7 @@ shmem_file_write(struct file *file, cons - if (err || !count) - goto out; - -- err = remove_suid(file->f_path.dentry); -+ err = remove_suid(&file->f_path); - if (err) - goto out; - diff --git a/kernel-patches/for-mainline/security-create.diff b/kernel-patches/for-mainline/security-create.diff deleted file mode 100644 index 020e5f61e..000000000 --- a/kernel-patches/for-mainline/security-create.diff +++ /dev/null @@ -1,107 +0,0 @@ -From: Tony Jones -Subject: Pass struct vfsmount to the inode_create LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/namei.c | 2 +- - include/linux/security.h | 9 ++++++--- - security/dummy.c | 2 +- - security/security.c | 5 +++-- - security/selinux/hooks.c | 3 ++- - 5 files changed, 13 insertions(+), 8 deletions(-) - ---- a/fs/namei.c 2007-11-02 17:44:43.000000000 -0400 -+++ b/fs/namei.c 2007-11-02 17:49:23.000000000 -0400 -@@ -1583,7 +1583,7 @@ int vfs_create(struct inode *dir, struct - return -EACCES; /* shouldn't it be ENOSYS? */ - mode &= S_IALLUGO; - mode |= S_IFREG; -- error = security_inode_create(dir, dentry, mode); -+ error = security_inode_create(dir, dentry, nd ? nd->mnt : NULL, mode); - if (error) - return error; - DQUOT_INIT(dir); ---- a/include/linux/security.h 2007-11-02 17:44:43.000000000 -0400 -+++ b/include/linux/security.h 2007-11-02 17:49:39.000000000 -0400 -@@ -297,6 +297,7 @@ struct request_sock; - * Check permission to create a regular file. - * @dir contains inode structure of the parent of the new file. - * @dentry contains the dentry structure for the file to be created. -+ * @mnt is the vfsmount corresponding to @dentry (may be NULL). - * @mode contains the file mode of the file to be created. - * Return 0 if permission is granted. - * @inode_link: -@@ -1247,8 +1248,8 @@ struct security_operations { - void (*inode_free_security) (struct inode *inode); - int (*inode_init_security) (struct inode *inode, struct inode *dir, - char **name, void **value, size_t *len); -- int (*inode_create) (struct inode *dir, -- struct dentry *dentry, int mode); -+ int (*inode_create) (struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mode); - int (*inode_link) (struct dentry *old_dentry, - struct inode *dir, struct dentry *new_dentry); - int (*inode_unlink) (struct inode *dir, struct dentry *dentry); -@@ -1503,7 +1504,8 @@ int security_inode_alloc(struct inode *i - void security_inode_free(struct inode *inode); - int security_inode_init_security(struct inode *inode, struct inode *dir, - char **name, void **value, size_t *len); --int security_inode_create(struct inode *dir, struct dentry *dentry, int mode); -+int security_inode_create(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mode); - int security_inode_link(struct dentry *old_dentry, struct inode *dir, - struct dentry *new_dentry); - int security_inode_unlink(struct inode *dir, struct dentry *dentry); -@@ -1813,6 +1815,7 @@ static inline int security_inode_init_se - - static inline int security_inode_create (struct inode *dir, - struct dentry *dentry, -+ struct vfsmount *mnt, - int mode) - { - return 0; ---- a/security/dummy.c 2007-11-02 17:44:43.000000000 -0400 -+++ b/security/dummy.c 2007-11-02 17:49:23.000000000 -0400 -@@ -262,7 +262,7 @@ static int dummy_inode_init_security (st - } - - static int dummy_inode_create (struct inode *inode, struct dentry *dentry, -- int mask) -+ struct vfsmount *mnt, int mask) - { - return 0; - } ---- a/security/security.c 2007-11-02 17:46:44.000000000 -0400 -+++ b/security/security.c 2007-11-02 17:49:23.000000000 -0400 -@@ -329,11 +329,12 @@ int security_inode_init_security(struct - } - EXPORT_SYMBOL(security_inode_init_security); - --int security_inode_create(struct inode *dir, struct dentry *dentry, int mode) -+int security_inode_create(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mode) - { - if (unlikely(IS_PRIVATE(dir))) - return 0; -- return security_ops->inode_create(dir, dentry, mode); -+ return security_ops->inode_create(dir, dentry, mnt, mode); - } - - int security_inode_link(struct dentry *old_dentry, struct inode *dir, ---- a/security/selinux/hooks.c 2007-11-02 17:44:43.000000000 -0400 -+++ b/security/selinux/hooks.c 2007-11-02 17:49:23.000000000 -0400 -@@ -2184,7 +2184,8 @@ static int selinux_inode_init_security(s - return 0; - } - --static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask) -+static int selinux_inode_create(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mask) - { - return may_create(dir, dentry, SECCLASS_FILE); - } diff --git a/kernel-patches/for-mainline/security-getxattr.diff b/kernel-patches/for-mainline/security-getxattr.diff deleted file mode 100644 index c4bb632e0..000000000 --- a/kernel-patches/for-mainline/security-getxattr.diff +++ /dev/null @@ -1,110 +0,0 @@ -From: Tony Jones -Subject: Pass struct vfsmount to the inode_getxattr LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/xattr.c | 2 +- - include/linux/security.h | 11 +++++++---- - security/dummy.c | 3 ++- - security/security.c | 5 +++-- - security/selinux/hooks.c | 3 ++- - 5 files changed, 15 insertions(+), 9 deletions(-) - ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -115,7 +115,7 @@ vfs_getxattr(struct dentry *dentry, stru - if (error) - return error; - -- error = security_inode_getxattr(dentry, name); -+ error = security_inode_getxattr(dentry, mnt, name); - if (error) - return error; - ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -405,7 +405,7 @@ struct request_sock; - * @value identified by @name for @dentry and @mnt. - * @inode_getxattr: - * Check permission before obtaining the extended attributes -- * identified by @name for @dentry. -+ * identified by @name for @dentry and @mnt. - * Return 0 if permission is granted. - * @inode_listxattr: - * Check permission before obtaining the list of extended attribute -@@ -1291,7 +1291,8 @@ struct security_operations { - struct vfsmount *mnt, - char *name, void *value, - size_t size, int flags); -- int (*inode_getxattr) (struct dentry *dentry, char *name); -+ int (*inode_getxattr) (struct dentry *dentry, struct vfsmount *mnt, -+ char *name); - int (*inode_listxattr) (struct dentry *dentry); - int (*inode_removexattr) (struct dentry *dentry, char *name); - int (*inode_need_killpriv) (struct dentry *dentry); -@@ -1554,7 +1555,8 @@ int security_inode_setxattr(struct dentr - void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, - char *name, void *value, size_t size, - int flags); --int security_inode_getxattr(struct dentry *dentry, char *name); -+int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *name); - int security_inode_listxattr(struct dentry *dentry); - int security_inode_removexattr(struct dentry *dentry, char *name); - int security_inode_need_killpriv(struct dentry *dentry); -@@ -1954,7 +1956,8 @@ static inline void security_inode_post_s - int flags) - { } - --static inline int security_inode_getxattr (struct dentry *dentry, char *name) -+static inline int security_inode_getxattr (struct dentry *dentry, -+ struct vfsmount *mnt, char *name) - { - return 0; - } ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -365,7 +365,8 @@ static void dummy_inode_post_setxattr (s - { - } - --static int dummy_inode_getxattr (struct dentry *dentry, char *name) -+static int dummy_inode_getxattr (struct dentry *dentry, -+ struct vfsmount *mnt, char *name) - { - return 0; - } ---- a/security/security.c -+++ b/security/security.c -@@ -458,11 +458,12 @@ void security_inode_post_setxattr(struct - security_ops->inode_post_setxattr(dentry, mnt, name, value, size, flags); - } - --int security_inode_getxattr(struct dentry *dentry, char *name) -+int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *name) - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return 0; -- return security_ops->inode_getxattr(dentry, name); -+ return security_ops->inode_getxattr(dentry, mnt, name); - } - - int security_inode_listxattr(struct dentry *dentry) ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2409,7 +2409,8 @@ static void selinux_inode_post_setxattr( - return; - } - --static int selinux_inode_getxattr (struct dentry *dentry, char *name) -+static int selinux_inode_getxattr (struct dentry *dentry, struct vfsmount *mnt, -+ char *name) - { - return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); - } diff --git a/kernel-patches/for-mainline/security-link.diff b/kernel-patches/for-mainline/security-link.diff deleted file mode 100644 index eddd79a3a..000000000 --- a/kernel-patches/for-mainline/security-link.diff +++ /dev/null @@ -1,134 +0,0 @@ -From: Tony Jones -Subject: Pass the struct vfsmounts to the inode_link LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/namei.c | 3 ++- - include/linux/security.h | 16 +++++++++++----- - security/dummy.c | 6 ++++-- - security/security.c | 8 +++++--- - security/selinux/hooks.c | 9 +++++++-- - 5 files changed, 29 insertions(+), 13 deletions(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2356,7 +2356,8 @@ int vfs_link(struct dentry *old_dentry, - if (S_ISDIR(old_dentry->d_inode->i_mode)) - return -EPERM; - -- error = security_inode_link(old_dentry, dir, new_dentry); -+ error = security_inode_link(old_dentry, old_mnt, dir, new_dentry, -+ new_mnt); - if (error) - return error; - ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -303,8 +303,10 @@ struct request_sock; - * @inode_link: - * Check permission before creating a new hard link to a file. - * @old_dentry contains the dentry structure for an existing link to the file. -+ * @old_mnt is the vfsmount corresponding to @old_dentry (may be NULL). - * @dir contains the inode structure of the parent directory of the new link. - * @new_dentry contains the dentry structure for the new link. -+ * @new_mnt is the vfsmount corresponding to @new_dentry (may be NULL). - * Return 0 if permission is granted. - * @inode_unlink: - * Check the permission to remove a hard link to a file. -@@ -1255,8 +1257,9 @@ struct security_operations { - char **name, void **value, size_t *len); - int (*inode_create) (struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, int mode); -- int (*inode_link) (struct dentry *old_dentry, -- struct inode *dir, struct dentry *new_dentry); -+ int (*inode_link) (struct dentry *old_dentry, struct vfsmount *old_mnt, -+ struct inode *dir, struct dentry *new_dentry, -+ struct vfsmount *new_mnt); - int (*inode_unlink) (struct inode *dir, struct dentry *dentry); - int (*inode_symlink) (struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, const char *old_name); -@@ -1513,8 +1516,9 @@ int security_inode_init_security(struct - char **name, void **value, size_t *len); - int security_inode_create(struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, int mode); --int security_inode_link(struct dentry *old_dentry, struct inode *dir, -- struct dentry *new_dentry); -+int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt, -+ struct inode *dir, struct dentry *new_dentry, -+ struct vfsmount *new_mnt); - int security_inode_unlink(struct inode *dir, struct dentry *dentry); - int security_inode_symlink(struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, const char *old_name); -@@ -1832,8 +1836,10 @@ static inline int security_inode_create - } - - static inline int security_inode_link (struct dentry *old_dentry, -+ struct vfsmount *old_mnt, - struct inode *dir, -- struct dentry *new_dentry) -+ struct dentry *new_dentry, -+ struct vfsmount *new_mnt) - { - return 0; - } ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -267,8 +267,10 @@ static int dummy_inode_create (struct in - return 0; - } - --static int dummy_inode_link (struct dentry *old_dentry, struct inode *inode, -- struct dentry *new_dentry) -+static int dummy_inode_link (struct dentry *old_dentry, -+ struct vfsmount *old_mnt, struct inode *inode, -+ struct dentry *new_dentry, -+ struct vfsmount *new_mnt) - { - return 0; - } ---- a/security/security.c -+++ b/security/security.c -@@ -336,12 +336,14 @@ int security_inode_create(struct inode * - return security_ops->inode_create(dir, dentry, mnt, mode); - } - --int security_inode_link(struct dentry *old_dentry, struct inode *dir, -- struct dentry *new_dentry) -+int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt, -+ struct inode *dir, struct dentry *new_dentry, -+ struct vfsmount *new_mnt) - { - if (unlikely(IS_PRIVATE(old_dentry->d_inode))) - return 0; -- return security_ops->inode_link(old_dentry, dir, new_dentry); -+ return security_ops->inode_link(old_dentry, old_mnt, dir, -+ new_dentry, new_mnt); - } - - int security_inode_unlink(struct inode *dir, struct dentry *dentry) ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2190,11 +2190,16 @@ static int selinux_inode_create(struct i - return may_create(dir, dentry, SECCLASS_FILE); - } - --static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) -+static int selinux_inode_link(struct dentry *old_dentry, -+ struct vfsmount *old_mnt, -+ struct inode *dir, -+ struct dentry *new_dentry, -+ struct vfsmount *new_mnt) - { - int rc; - -- rc = secondary_ops->inode_link(old_dentry,dir,new_dentry); -+ rc = secondary_ops->inode_link(old_dentry, old_mnt, dir, new_dentry, -+ new_mnt); - if (rc) - return rc; - return may_link(dir, old_dentry, MAY_LINK); diff --git a/kernel-patches/for-mainline/security-listxattr.diff b/kernel-patches/for-mainline/security-listxattr.diff deleted file mode 100644 index c14389cdc..000000000 --- a/kernel-patches/for-mainline/security-listxattr.diff +++ /dev/null @@ -1,105 +0,0 @@ -From: Tony Jones -Subject: Pass struct vfsmount to the inode_listxattr LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/xattr.c | 2 +- - include/linux/security.h | 9 +++++---- - security/dummy.c | 2 +- - security/security.c | 4 ++-- - security/selinux/hooks.c | 2 +- - 5 files changed, 10 insertions(+), 9 deletions(-) - ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -148,7 +148,7 @@ vfs_listxattr(struct dentry *dentry, str - struct inode *inode = dentry->d_inode; - ssize_t error; - -- error = security_inode_listxattr(dentry); -+ error = security_inode_listxattr(dentry, mnt); - if (error) - return error; - error = -EOPNOTSUPP; ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -409,7 +409,7 @@ struct request_sock; - * Return 0 if permission is granted. - * @inode_listxattr: - * Check permission before obtaining the list of extended attribute -- * names for @dentry. -+ * names for @dentry and @mnt. - * Return 0 if permission is granted. - * @inode_removexattr: - * Check permission before removing the extended attribute -@@ -1293,7 +1293,7 @@ struct security_operations { - size_t size, int flags); - int (*inode_getxattr) (struct dentry *dentry, struct vfsmount *mnt, - char *name); -- int (*inode_listxattr) (struct dentry *dentry); -+ int (*inode_listxattr) (struct dentry *dentry, struct vfsmount *mnt); - int (*inode_removexattr) (struct dentry *dentry, char *name); - int (*inode_need_killpriv) (struct dentry *dentry); - int (*inode_killpriv) (struct dentry *dentry); -@@ -1557,7 +1557,7 @@ void security_inode_post_setxattr(struct - int flags); - int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, - char *name); --int security_inode_listxattr(struct dentry *dentry); -+int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt); - int security_inode_removexattr(struct dentry *dentry, char *name); - int security_inode_need_killpriv(struct dentry *dentry); - int security_inode_killpriv(struct dentry *dentry); -@@ -1962,7 +1962,8 @@ static inline int security_inode_getxatt - return 0; - } - --static inline int security_inode_listxattr (struct dentry *dentry) -+static inline int security_inode_listxattr (struct dentry *dentry, -+ struct vfsmount *mnt) - { - return 0; - } ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -371,7 +371,7 @@ static int dummy_inode_getxattr (struct - return 0; - } - --static int dummy_inode_listxattr (struct dentry *dentry) -+static int dummy_inode_listxattr (struct dentry *dentry, struct vfsmount *mnt) - { - return 0; - } ---- a/security/security.c -+++ b/security/security.c -@@ -466,11 +466,11 @@ int security_inode_getxattr(struct dentr - return security_ops->inode_getxattr(dentry, mnt, name); - } - --int security_inode_listxattr(struct dentry *dentry) -+int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt) - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return 0; -- return security_ops->inode_listxattr(dentry); -+ return security_ops->inode_listxattr(dentry, mnt); - } - - int security_inode_removexattr(struct dentry *dentry, char *name) ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2415,7 +2415,7 @@ static int selinux_inode_getxattr (struc - return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); - } - --static int selinux_inode_listxattr (struct dentry *dentry) -+static int selinux_inode_listxattr (struct dentry *dentry, struct vfsmount *mnt) - { - return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); - } diff --git a/kernel-patches/for-mainline/security-mkdir.diff b/kernel-patches/for-mainline/security-mkdir.diff deleted file mode 100644 index 171aecd82..000000000 --- a/kernel-patches/for-mainline/security-mkdir.diff +++ /dev/null @@ -1,106 +0,0 @@ -From: Tony Jones -Subject: Pass struct vfsmount to the inode_mkdir LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/namei.c | 2 +- - include/linux/security.h | 8 ++++++-- - security/dummy.c | 2 +- - security/security.c | 5 +++-- - security/selinux/hooks.c | 3 ++- - 5 files changed, 13 insertions(+), 7 deletions(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2009,7 +2009,7 @@ int vfs_mkdir(struct inode *dir, struct - return -EPERM; - - mode &= (S_IRWXUGO|S_ISVTX); -- error = security_inode_mkdir(dir, dentry, mode); -+ error = security_inode_mkdir(dir, dentry, mnt, mode); - if (error) - return error; - ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -322,6 +322,7 @@ struct request_sock; - * associated with inode strcture @dir. - * @dir containst the inode structure of parent of the directory to be created. - * @dentry contains the dentry structure of new directory. -+ * @mnt is the vfsmount corresponding to @dentry (may be NULL). - * @mode contains the mode of new directory. - * Return 0 if permission is granted. - * @inode_rmdir: -@@ -1256,7 +1257,8 @@ struct security_operations { - int (*inode_unlink) (struct inode *dir, struct dentry *dentry); - int (*inode_symlink) (struct inode *dir, - struct dentry *dentry, const char *old_name); -- int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, int mode); -+ int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mode); - int (*inode_rmdir) (struct inode *dir, struct dentry *dentry); - int (*inode_mknod) (struct inode *dir, struct dentry *dentry, - int mode, dev_t dev); -@@ -1513,7 +1515,8 @@ int security_inode_link(struct dentry *o - int security_inode_unlink(struct inode *dir, struct dentry *dentry); - int security_inode_symlink(struct inode *dir, struct dentry *dentry, - const char *old_name); --int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode); -+int security_inode_mkdir(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mode); - int security_inode_rmdir(struct inode *dir, struct dentry *dentry); - int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev); - int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, -@@ -1846,6 +1849,7 @@ static inline int security_inode_symlink - - static inline int security_inode_mkdir (struct inode *dir, - struct dentry *dentry, -+ struct vfsmount *mnt, - int mode) - { - return 0; ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -285,7 +285,7 @@ static int dummy_inode_symlink (struct i - } - - static int dummy_inode_mkdir (struct inode *inode, struct dentry *dentry, -- int mask) -+ struct vfsmount *mnt, int mask) - { - return 0; - } ---- a/security/security.c -+++ b/security/security.c -@@ -359,11 +359,12 @@ int security_inode_symlink(struct inode - return security_ops->inode_symlink(dir, dentry, old_name); - } - --int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode) -+int security_inode_mkdir(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mode) - { - if (unlikely(IS_PRIVATE(dir))) - return 0; -- return security_ops->inode_mkdir(dir, dentry, mode); -+ return security_ops->inode_mkdir(dir, dentry, mnt, mode); - } - - int security_inode_rmdir(struct inode *dir, struct dentry *dentry) ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2215,7 +2215,8 @@ static int selinux_inode_symlink(struct - return may_create(dir, dentry, SECCLASS_LNK_FILE); - } - --static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask) -+static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mask) - { - return may_create(dir, dentry, SECCLASS_DIR); - } diff --git a/kernel-patches/for-mainline/security-mknod.diff b/kernel-patches/for-mainline/security-mknod.diff deleted file mode 100644 index e4702e504..000000000 --- a/kernel-patches/for-mainline/security-mknod.diff +++ /dev/null @@ -1,110 +0,0 @@ -From: Tony Jones -Subject: Pass struct vfsmount to the inode_mknod LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/namei.c | 2 +- - include/linux/security.h | 7 +++++-- - security/dummy.c | 2 +- - security/security.c | 5 +++-- - security/selinux/hooks.c | 5 +++-- - 5 files changed, 13 insertions(+), 8 deletions(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -1932,7 +1932,7 @@ int vfs_mknod(struct inode *dir, struct - if (!dir->i_op || !dir->i_op->mknod) - return -EPERM; - -- error = security_inode_mknod(dir, dentry, mode, dev); -+ error = security_inode_mknod(dir, dentry, mnt, mode, dev); - if (error) - return error; - ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -337,6 +337,7 @@ struct request_sock; - * and not this hook. - * @dir contains the inode structure of parent of the new file. - * @dentry contains the dentry structure of the new file. -+ * @mnt is the vfsmount corresponding to @dentry (may be NULL). - * @mode contains the mode of the new file. - * @dev contains the device number. - * Return 0 if permission is granted. -@@ -1261,7 +1262,7 @@ struct security_operations { - struct vfsmount *mnt, int mode); - int (*inode_rmdir) (struct inode *dir, struct dentry *dentry); - int (*inode_mknod) (struct inode *dir, struct dentry *dentry, -- int mode, dev_t dev); -+ struct vfsmount *mnt, int mode, dev_t dev); - int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry); - int (*inode_readlink) (struct dentry *dentry); -@@ -1518,7 +1519,8 @@ int security_inode_symlink(struct inode - int security_inode_mkdir(struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, int mode); - int security_inode_rmdir(struct inode *dir, struct dentry *dentry); --int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev); -+int security_inode_mknod(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mode, dev_t dev); - int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry); - int security_inode_readlink(struct dentry *dentry); -@@ -1863,6 +1865,7 @@ static inline int security_inode_rmdir ( - - static inline int security_inode_mknod (struct inode *dir, - struct dentry *dentry, -+ struct vfsmount *mnt, - int mode, dev_t dev) - { - return 0; ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -296,7 +296,7 @@ static int dummy_inode_rmdir (struct ino - } - - static int dummy_inode_mknod (struct inode *inode, struct dentry *dentry, -- int mode, dev_t dev) -+ struct vfsmount *mnt, int mode, dev_t dev) - { - return 0; - } ---- a/security/security.c -+++ b/security/security.c -@@ -374,11 +374,12 @@ int security_inode_rmdir(struct inode *d - return security_ops->inode_rmdir(dir, dentry); - } - --int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) -+int security_inode_mknod(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mode, dev_t dev) - { - if (unlikely(IS_PRIVATE(dir))) - return 0; -- return security_ops->inode_mknod(dir, dentry, mode, dev); -+ return security_ops->inode_mknod(dir, dentry, mnt, mode, dev); - } - - int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2226,11 +2226,12 @@ static int selinux_inode_rmdir(struct in - return may_link(dir, dentry, MAY_RMDIR); - } - --static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) -+static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, int mode, dev_t dev) - { - int rc; - -- rc = secondary_ops->inode_mknod(dir, dentry, mode, dev); -+ rc = secondary_ops->inode_mknod(dir, dentry, mnt, mode, dev); - if (rc) - return rc; - diff --git a/kernel-patches/for-mainline/security-readlink.diff b/kernel-patches/for-mainline/security-readlink.diff deleted file mode 100644 index d40c85b8f..000000000 --- a/kernel-patches/for-mainline/security-readlink.diff +++ /dev/null @@ -1,104 +0,0 @@ -From: Tony Jones -Subject: Pass struct vfsmount to the inode_readlink LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/stat.c | 2 +- - include/linux/security.h | 8 +++++--- - security/dummy.c | 2 +- - security/security.c | 4 ++-- - security/selinux/hooks.c | 2 +- - 5 files changed, 10 insertions(+), 8 deletions(-) - ---- a/fs/stat.c -+++ b/fs/stat.c -@@ -306,7 +306,7 @@ asmlinkage long sys_readlinkat(int dfd, - - error = -EINVAL; - if (inode->i_op && inode->i_op->readlink) { -- error = security_inode_readlink(nd.dentry); -+ error = security_inode_readlink(nd.dentry, nd.mnt); - if (!error) { - touch_atime(nd.mnt, nd.dentry); - error = inode->i_op->readlink(nd.dentry, buf, bufsiz); ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -352,6 +352,7 @@ struct request_sock; - * @inode_readlink: - * Check the permission to read the symbolic link. - * @dentry contains the dentry structure for the file link. -+ * @mnt is the vfsmount corresponding to @dentry (may be NULL). - * Return 0 if permission is granted. - * @inode_follow_link: - * Check permission to follow a symbolic link when looking up a pathname. -@@ -1266,7 +1267,7 @@ struct security_operations { - struct vfsmount *mnt, int mode, dev_t dev); - int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry); -- int (*inode_readlink) (struct dentry *dentry); -+ int (*inode_readlink) (struct dentry *dentry, struct vfsmount *mnt); - int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); - int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd); - int (*inode_setattr) (struct dentry *dentry, struct vfsmount *mnt, -@@ -1524,7 +1525,7 @@ int security_inode_mknod(struct inode *d - struct vfsmount *mnt, int mode, dev_t dev); - int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry); --int security_inode_readlink(struct dentry *dentry); -+int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt); - int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd); - int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd); - int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, -@@ -1881,7 +1882,8 @@ static inline int security_inode_rename - return 0; - } - --static inline int security_inode_readlink (struct dentry *dentry) -+static inline int security_inode_readlink(struct dentry *dentry, -+ struct vfsmount *mnt) - { - return 0; - } ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -309,7 +309,7 @@ static int dummy_inode_rename (struct in - return 0; - } - --static int dummy_inode_readlink (struct dentry *dentry) -+static int dummy_inode_readlink (struct dentry *dentry, struct vfsmount *mnt) - { - return 0; - } ---- a/security/security.c -+++ b/security/security.c -@@ -392,11 +392,11 @@ int security_inode_rename(struct inode * - new_dir, new_dentry); - } - --int security_inode_readlink(struct dentry *dentry) -+int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt) - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return 0; -- return security_ops->inode_readlink(dentry); -+ return security_ops->inode_readlink(dentry, mnt); - } - - int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd) ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2245,7 +2245,7 @@ static int selinux_inode_rename(struct i - return may_rename(old_inode, old_dentry, new_inode, new_dentry); - } - --static int selinux_inode_readlink(struct dentry *dentry) -+static int selinux_inode_readlink(struct dentry *dentry, struct vfsmount *mnt) - { - return dentry_has_perm(current, NULL, dentry, FILE__READ); - } diff --git a/kernel-patches/for-mainline/security-removexattr.diff b/kernel-patches/for-mainline/security-removexattr.diff deleted file mode 100644 index 6fd147054..000000000 --- a/kernel-patches/for-mainline/security-removexattr.diff +++ /dev/null @@ -1,126 +0,0 @@ -From: Tony Jones -Subject: Pass struct vfsmount to the inode_removexattr LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/xattr.c | 2 +- - include/linux/security.h | 13 ++++++++----- - security/commoncap.c | 3 ++- - security/dummy.c | 3 ++- - security/security.c | 5 +++-- - security/selinux/hooks.c | 3 ++- - 6 files changed, 18 insertions(+), 11 deletions(-) - ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -176,7 +176,7 @@ vfs_removexattr(struct dentry *dentry, s - if (error) - return error; - -- error = security_inode_removexattr(dentry, name); -+ error = security_inode_removexattr(dentry, mnt, name); - if (error) - return error; - ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -57,7 +57,7 @@ extern int cap_bprm_set_security (struct - extern void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe); - extern int cap_bprm_secureexec(struct linux_binprm *bprm); - extern int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, void *value, size_t size, int flags); --extern int cap_inode_removexattr(struct dentry *dentry, char *name); -+extern int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name); - extern int cap_inode_need_killpriv(struct dentry *dentry); - extern int cap_inode_killpriv(struct dentry *dentry); - extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags); -@@ -1294,7 +1294,8 @@ struct security_operations { - int (*inode_getxattr) (struct dentry *dentry, struct vfsmount *mnt, - char *name); - int (*inode_listxattr) (struct dentry *dentry, struct vfsmount *mnt); -- int (*inode_removexattr) (struct dentry *dentry, char *name); -+ int (*inode_removexattr) (struct dentry *dentry, struct vfsmount *mnt, -+ char *name); - int (*inode_need_killpriv) (struct dentry *dentry); - int (*inode_killpriv) (struct dentry *dentry); - int (*inode_getsecurity)(const struct inode *inode, const char *name, void *buffer, size_t size, int err); -@@ -1558,7 +1559,8 @@ void security_inode_post_setxattr(struct - int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, - char *name); - int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt); --int security_inode_removexattr(struct dentry *dentry, char *name); -+int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *name); - int security_inode_need_killpriv(struct dentry *dentry); - int security_inode_killpriv(struct dentry *dentry); - int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err); -@@ -1968,9 +1970,10 @@ static inline int security_inode_listxat - return 0; - } - --static inline int security_inode_removexattr (struct dentry *dentry, char *name) -+static inline int security_inode_removexattr (struct dentry *dentry, -+ struct vfsmount *mnt, char *name) - { -- return cap_inode_removexattr(dentry, name); -+ return cap_inode_removexattr(dentry, mnt, name); - } - - static inline int security_inode_need_killpriv(struct dentry *dentry) ---- a/security/commoncap.c -+++ b/security/commoncap.c -@@ -382,7 +382,8 @@ int cap_inode_setxattr(struct dentry *de - return 0; - } - --int cap_inode_removexattr(struct dentry *dentry, char *name) -+int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *name) - { - if (!strcmp(name, XATTR_NAME_CAPS)) { - if (!capable(CAP_SETFCAP)) ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -376,7 +376,8 @@ static int dummy_inode_listxattr (struct - return 0; - } - --static int dummy_inode_removexattr (struct dentry *dentry, char *name) -+static int dummy_inode_removexattr (struct dentry *dentry, struct vfsmount *mnt, -+ char *name) - { - if (!strncmp(name, XATTR_SECURITY_PREFIX, - sizeof(XATTR_SECURITY_PREFIX) - 1) && ---- a/security/security.c -+++ b/security/security.c -@@ -473,11 +473,12 @@ int security_inode_listxattr(struct dent - return security_ops->inode_listxattr(dentry, mnt); - } - --int security_inode_removexattr(struct dentry *dentry, char *name) -+int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *name) - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return 0; -- return security_ops->inode_removexattr(dentry, name); -+ return security_ops->inode_removexattr(dentry, mnt, name); - } - - int security_inode_need_killpriv(struct dentry *dentry) ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2420,7 +2420,8 @@ static int selinux_inode_listxattr (stru - return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); - } - --static int selinux_inode_removexattr (struct dentry *dentry, char *name) -+static int selinux_inode_removexattr (struct dentry *dentry, -+ struct vfsmount *mnt, char *name) - { - if (strcmp(name, XATTR_NAME_SELINUX)) - return selinux_inode_setotherxattr(dentry, name); diff --git a/kernel-patches/for-mainline/security-rename.diff b/kernel-patches/for-mainline/security-rename.diff deleted file mode 100644 index b93f0507e..000000000 --- a/kernel-patches/for-mainline/security-rename.diff +++ /dev/null @@ -1,136 +0,0 @@ -From: Tony Jones -Subject: Pass struct vfsmount to the inode_rename LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/namei.c | 6 ++++-- - include/linux/security.h | 13 ++++++++++--- - security/dummy.c | 4 +++- - security/security.c | 7 ++++--- - security/selinux/hooks.c | 8 ++++++-- - 5 files changed, 27 insertions(+), 11 deletions(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2480,7 +2480,8 @@ static int vfs_rename_dir(struct inode * - return error; - } - -- error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry); -+ error = security_inode_rename(old_dir, old_dentry, old_mnt, -+ new_dir, new_dentry, new_mnt); - if (error) - return error; - -@@ -2514,7 +2515,8 @@ static int vfs_rename_other(struct inode - struct inode *target; - int error; - -- error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry); -+ error = security_inode_rename(old_dir, old_dentry, old_mnt, -+ new_dir, new_dentry, new_mnt); - if (error) - return error; - ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -350,8 +350,10 @@ struct request_sock; - * Check for permission to rename a file or directory. - * @old_dir contains the inode structure for parent of the old link. - * @old_dentry contains the dentry structure of the old link. -+ * @old_mnt is the vfsmount corresponding to @old_dentry (may be NULL). - * @new_dir contains the inode structure for parent of the new link. - * @new_dentry contains the dentry structure of the new link. -+ * @new_mnt is the vfsmount corresponding to @new_dentry (may be NULL). - * Return 0 if permission is granted. - * @inode_readlink: - * Check the permission to read the symbolic link. -@@ -1273,7 +1275,9 @@ struct security_operations { - int (*inode_mknod) (struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, int mode, dev_t dev); - int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry); -+ struct vfsmount *old_mnt, -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct vfsmount *new_mnt); - int (*inode_readlink) (struct dentry *dentry, struct vfsmount *mnt); - int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); - int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd); -@@ -1534,7 +1538,8 @@ int security_inode_rmdir(struct inode *d - int security_inode_mknod(struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, int mode, dev_t dev); - int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry); -+ struct vfsmount *old_mnt, struct inode *new_dir, -+ struct dentry *new_dentry, struct vfsmount *new_mnt); - int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt); - int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd); - int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd); -@@ -1890,8 +1895,10 @@ static inline int security_inode_mknod ( - - static inline int security_inode_rename (struct inode *old_dir, - struct dentry *old_dentry, -+ struct vfsmount *old_mnt, - struct inode *new_dir, -- struct dentry *new_dentry) -+ struct dentry *new_dentry, -+ struct vfsmount *new_mnt) - { - return 0; - } ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -307,8 +307,10 @@ static int dummy_inode_mknod (struct ino - - static int dummy_inode_rename (struct inode *old_inode, - struct dentry *old_dentry, -+ struct vfsmount *old_mnt, - struct inode *new_inode, -- struct dentry *new_dentry) -+ struct dentry *new_dentry, -+ struct vfsmount *new_mnt) - { - return 0; - } ---- a/security/security.c -+++ b/security/security.c -@@ -387,13 +387,14 @@ int security_inode_mknod(struct inode *d - } - - int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct vfsmount *old_mnt, struct inode *new_dir, -+ struct dentry *new_dentry, struct vfsmount *new_mnt) - { - if (unlikely(IS_PRIVATE(old_dentry->d_inode) || - (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) - return 0; -- return security_ops->inode_rename(old_dir, old_dentry, -- new_dir, new_dentry); -+ return security_ops->inode_rename(old_dir, old_dentry, old_mnt, -+ new_dir, new_dentry, new_mnt); - } - - int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt) ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2246,8 +2246,12 @@ static int selinux_inode_mknod(struct in - return may_create(dir, dentry, inode_mode_to_security_class(mode)); - } - --static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry, -- struct inode *new_inode, struct dentry *new_dentry) -+static int selinux_inode_rename(struct inode *old_inode, -+ struct dentry *old_dentry, -+ struct vfsmount *old_mnt, -+ struct inode *new_inode, -+ struct dentry *new_dentry, -+ struct vfsmount *new_mnt) - { - return may_rename(old_inode, old_dentry, new_inode, new_dentry); - } diff --git a/kernel-patches/for-mainline/security-rmdir.diff b/kernel-patches/for-mainline/security-rmdir.diff deleted file mode 100644 index 1a09b1a98..000000000 --- a/kernel-patches/for-mainline/security-rmdir.diff +++ /dev/null @@ -1,109 +0,0 @@ -From: Tony Jones -Subject: Pass struct vfsmount to the inode_rmdir LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/namei.c | 2 +- - include/linux/security.h | 10 +++++++--- - security/dummy.c | 3 ++- - security/security.c | 5 +++-- - security/selinux/hooks.c | 3 ++- - 5 files changed, 15 insertions(+), 8 deletions(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2104,7 +2104,7 @@ int vfs_rmdir(struct inode *dir, struct - if (d_mountpoint(dentry)) - error = -EBUSY; - else { -- error = security_inode_rmdir(dir, dentry); -+ error = security_inode_rmdir(dir, dentry, mnt); - if (!error) { - error = dir->i_op->rmdir(dir, dentry); - if (!error) ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -332,6 +332,7 @@ struct request_sock; - * Check the permission to remove a directory. - * @dir contains the inode structure of parent of the directory to be removed. - * @dentry contains the dentry structure of directory to be removed. -+ * @mnt is the vfsmount corresponding to @dentry (may be NULL). - * Return 0 if permission is granted. - * @inode_mknod: - * Check permissions when creating a special file (or a socket or a fifo -@@ -1265,7 +1266,8 @@ struct security_operations { - struct vfsmount *mnt, const char *old_name); - int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, int mode); -- int (*inode_rmdir) (struct inode *dir, struct dentry *dentry); -+ int (*inode_rmdir) (struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt); - int (*inode_mknod) (struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, int mode, dev_t dev); - int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry, -@@ -1524,7 +1526,8 @@ int security_inode_symlink(struct inode - struct vfsmount *mnt, const char *old_name); - int security_inode_mkdir(struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, int mode); --int security_inode_rmdir(struct inode *dir, struct dentry *dentry); -+int security_inode_rmdir(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt); - int security_inode_mknod(struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, int mode, dev_t dev); - int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, -@@ -1867,7 +1870,8 @@ static inline int security_inode_mkdir ( - } - - static inline int security_inode_rmdir (struct inode *dir, -- struct dentry *dentry) -+ struct dentry *dentry, -+ struct vfsmount *mnt) - { - return 0; - } ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -292,7 +292,8 @@ static int dummy_inode_mkdir (struct ino - return 0; - } - --static int dummy_inode_rmdir (struct inode *inode, struct dentry *dentry) -+static int dummy_inode_rmdir (struct inode *inode, struct dentry *dentry, -+ struct vfsmount *mnt) - { - return 0; - } ---- a/security/security.c -+++ b/security/security.c -@@ -369,11 +369,12 @@ int security_inode_mkdir(struct inode *d - return security_ops->inode_mkdir(dir, dentry, mnt, mode); - } - --int security_inode_rmdir(struct inode *dir, struct dentry *dentry) -+int security_inode_rmdir(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt) - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return 0; -- return security_ops->inode_rmdir(dir, dentry); -+ return security_ops->inode_rmdir(dir, dentry, mnt); - } - - int security_inode_mknod(struct inode *dir, struct dentry *dentry, ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2227,7 +2227,8 @@ static int selinux_inode_mkdir(struct in - return may_create(dir, dentry, SECCLASS_DIR); - } - --static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry) -+static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt) - { - return may_link(dir, dentry, MAY_RMDIR); - } diff --git a/kernel-patches/for-mainline/security-setattr.diff b/kernel-patches/for-mainline/security-setattr.diff deleted file mode 100644 index d7162a33c..000000000 --- a/kernel-patches/for-mainline/security-setattr.diff +++ /dev/null @@ -1,119 +0,0 @@ -From: Tony Jones -Subject: Pass struct vfsmount to the inode_setattr LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/attr.c | 4 ++-- - include/linux/security.h | 8 ++++++-- - security/dummy.c | 3 ++- - security/security.c | 5 +++-- - security/selinux/hooks.c | 5 +++-- - 5 files changed, 16 insertions(+), 9 deletions(-) - ---- a/fs/attr.c -+++ b/fs/attr.c -@@ -159,13 +159,13 @@ int notify_change(struct dentry *dentry, - down_write(&dentry->d_inode->i_alloc_sem); - - if (inode->i_op && inode->i_op->setattr) { -- error = security_inode_setattr(dentry, attr); -+ error = security_inode_setattr(dentry, mnt, attr); - if (!error) - error = inode->i_op->setattr(dentry, attr); - } else { - error = inode_change_ok(inode, attr); - if (!error) -- error = security_inode_setattr(dentry, attr); -+ error = security_inode_setattr(dentry, mnt, attr); - if (!error) { - if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || - (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -372,6 +372,7 @@ struct request_sock; - * file attributes change (such as when a file is truncated, chown/chmod - * operations, transferring disk quotas, etc). - * @dentry contains the dentry structure for the file. -+ * @mnt is the vfsmount corresponding to @dentry (may be NULL). - * @attr is the iattr structure containing the new file attributes. - * Return 0 if permission is granted. - * @inode_getattr: -@@ -1264,7 +1265,8 @@ struct security_operations { - int (*inode_readlink) (struct dentry *dentry); - int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); - int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd); -- int (*inode_setattr) (struct dentry *dentry, struct iattr *attr); -+ int (*inode_setattr) (struct dentry *dentry, struct vfsmount *mnt, -+ struct iattr *attr); - int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry); - void (*inode_delete) (struct inode *inode); - int (*inode_setxattr) (struct dentry *dentry, char *name, void *value, -@@ -1519,7 +1521,8 @@ int security_inode_rename(struct inode * - int security_inode_readlink(struct dentry *dentry); - int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd); - int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd); --int security_inode_setattr(struct dentry *dentry, struct iattr *attr); -+int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, -+ struct iattr *attr); - int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry); - void security_inode_delete(struct inode *inode); - int security_inode_setxattr(struct dentry *dentry, char *name, -@@ -1887,6 +1890,7 @@ static inline int security_inode_permiss - } - - static inline int security_inode_setattr (struct dentry *dentry, -+ struct vfsmount *mnt, - struct iattr *attr) - { - return 0; ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -325,7 +325,8 @@ static int dummy_inode_permission (struc - return 0; - } - --static int dummy_inode_setattr (struct dentry *dentry, struct iattr *iattr) -+static int dummy_inode_setattr (struct dentry *dentry, struct vfsmount *mnt, -+ struct iattr *iattr) - { - return 0; - } ---- a/security/security.c -+++ b/security/security.c -@@ -411,11 +411,12 @@ int security_inode_permission(struct ino - return security_ops->inode_permission(inode, mask, nd); - } - --int security_inode_setattr(struct dentry *dentry, struct iattr *attr) -+int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, -+ struct iattr *attr) - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return 0; -- return security_ops->inode_setattr(dentry, attr); -+ return security_ops->inode_setattr(dentry, mnt, attr); - } - - int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2275,11 +2275,12 @@ static int selinux_inode_permission(stru - file_mask_to_av(inode->i_mode, mask), NULL); - } - --static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) -+static int selinux_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, -+ struct iattr *iattr) - { - int rc; - -- rc = secondary_ops->inode_setattr(dentry, iattr); -+ rc = secondary_ops->inode_setattr(dentry, mnt, iattr); - if (rc) - return rc; - diff --git a/kernel-patches/for-mainline/security-setxattr.diff b/kernel-patches/for-mainline/security-setxattr.diff deleted file mode 100644 index cc728e0b6..000000000 --- a/kernel-patches/for-mainline/security-setxattr.diff +++ /dev/null @@ -1,210 +0,0 @@ -From: Tony Jones -Subject: Pass struct vfsmount to the inode_setxattr LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/xattr.c | 4 ++-- - include/linux/security.h | 35 +++++++++++++++++++++-------------- - security/commoncap.c | 4 ++-- - security/dummy.c | 9 ++++++--- - security/security.c | 14 ++++++++------ - security/selinux/hooks.c | 8 ++++++-- - 6 files changed, 45 insertions(+), 29 deletions(-) - ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -79,7 +79,7 @@ vfs_setxattr(struct dentry *dentry, stru - return error; - - mutex_lock(&inode->i_mutex); -- error = security_inode_setxattr(dentry, name, value, size, flags); -+ error = security_inode_setxattr(dentry, mnt, name, value, size, flags); - if (error) - goto out; - error = -EOPNOTSUPP; -@@ -87,7 +87,7 @@ vfs_setxattr(struct dentry *dentry, stru - error = inode->i_op->setxattr(dentry, name, value, size, flags); - if (!error) { - fsnotify_xattr(dentry); -- security_inode_post_setxattr(dentry, name, value, -+ security_inode_post_setxattr(dentry, mnt, name, value, - size, flags); - } - } else if (!strncmp(name, XATTR_SECURITY_PREFIX, ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -56,7 +56,7 @@ extern void cap_capset_set (struct task_ - extern int cap_bprm_set_security (struct linux_binprm *bprm); - extern void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe); - extern int cap_bprm_secureexec(struct linux_binprm *bprm); --extern int cap_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags); -+extern int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, void *value, size_t size, int flags); - extern int cap_inode_removexattr(struct dentry *dentry, char *name); - extern int cap_inode_need_killpriv(struct dentry *dentry); - extern int cap_inode_killpriv(struct dentry *dentry); -@@ -398,11 +398,11 @@ struct request_sock; - * inode. - * @inode_setxattr: - * Check permission before setting the extended attributes -- * @value identified by @name for @dentry. -+ * @value identified by @name for @dentry and @mnt. - * Return 0 if permission is granted. - * @inode_post_setxattr: - * Update inode security field after successful setxattr operation. -- * @value identified by @name for @dentry. -+ * @value identified by @name for @dentry and @mnt. - * @inode_getxattr: - * Check permission before obtaining the extended attributes - * identified by @name for @dentry. -@@ -1285,9 +1285,11 @@ struct security_operations { - struct iattr *attr); - int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry); - void (*inode_delete) (struct inode *inode); -- int (*inode_setxattr) (struct dentry *dentry, char *name, void *value, -- size_t size, int flags); -- void (*inode_post_setxattr) (struct dentry *dentry, char *name, void *value, -+ int (*inode_setxattr) (struct dentry *dentry, struct vfsmount *mnt, -+ char *name, void *value, size_t size, int flags); -+ void (*inode_post_setxattr) (struct dentry *dentry, -+ struct vfsmount *mnt, -+ char *name, void *value, - size_t size, int flags); - int (*inode_getxattr) (struct dentry *dentry, char *name); - int (*inode_listxattr) (struct dentry *dentry); -@@ -1547,10 +1549,11 @@ int security_inode_setattr(struct dentry - struct iattr *attr); - int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry); - void security_inode_delete(struct inode *inode); --int security_inode_setxattr(struct dentry *dentry, char *name, -- void *value, size_t size, int flags); --void security_inode_post_setxattr(struct dentry *dentry, char *name, -- void *value, size_t size, int flags); -+int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *name, void *value, size_t size, int flags); -+void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *name, void *value, size_t size, -+ int flags); - int security_inode_getxattr(struct dentry *dentry, char *name); - int security_inode_listxattr(struct dentry *dentry); - int security_inode_removexattr(struct dentry *dentry, char *name); -@@ -1937,14 +1940,18 @@ static inline int security_inode_getattr - static inline void security_inode_delete (struct inode *inode) - { } - --static inline int security_inode_setxattr (struct dentry *dentry, char *name, -+static inline int security_inode_setxattr (struct dentry *dentry, -+ struct vfsmount *mnt, char *name, - void *value, size_t size, int flags) - { -- return cap_inode_setxattr(dentry, name, value, size, flags); -+ return cap_inode_setxattr(dentry, mnt, name, value, size, flags); - } - --static inline void security_inode_post_setxattr (struct dentry *dentry, char *name, -- void *value, size_t size, int flags) -+static inline void security_inode_post_setxattr (struct dentry *dentry, -+ struct vfsmount *mnt, -+ char *name, -+ void *value, size_t size, -+ int flags) - { } - - static inline int security_inode_getxattr (struct dentry *dentry, char *name) ---- a/security/commoncap.c -+++ b/security/commoncap.c -@@ -368,8 +368,8 @@ int cap_bprm_secureexec (struct linux_bi - current->egid != current->gid); - } - --int cap_inode_setxattr(struct dentry *dentry, char *name, void *value, -- size_t size, int flags) -+int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, -+ void *value, size_t size, int flags) - { - if (!strcmp(name, XATTR_NAME_CAPS)) { - if (!capable(CAP_SETFCAP)) ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -347,8 +347,9 @@ static void dummy_inode_delete (struct i - return; - } - --static int dummy_inode_setxattr (struct dentry *dentry, char *name, void *value, -- size_t size, int flags) -+static int dummy_inode_setxattr (struct dentry *dentry, struct vfsmount *mnt, -+ char *name, void *value, size_t size, -+ int flags) - { - if (!strncmp(name, XATTR_SECURITY_PREFIX, - sizeof(XATTR_SECURITY_PREFIX) - 1) && -@@ -357,7 +358,9 @@ static int dummy_inode_setxattr (struct - return 0; - } - --static void dummy_inode_post_setxattr (struct dentry *dentry, char *name, void *value, -+static void dummy_inode_post_setxattr (struct dentry *dentry, -+ struct vfsmount *mnt, -+ char *name, void *value, - size_t size, int flags) - { - } ---- a/security/security.c -+++ b/security/security.c -@@ -440,20 +440,22 @@ void security_inode_delete(struct inode - security_ops->inode_delete(inode); - } - --int security_inode_setxattr(struct dentry *dentry, char *name, -- void *value, size_t size, int flags) -+int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *name, void *value, size_t size, int flags) - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return 0; -- return security_ops->inode_setxattr(dentry, name, value, size, flags); -+ return security_ops->inode_setxattr(dentry, mnt, name, value, size, -+ flags); - } - --void security_inode_post_setxattr(struct dentry *dentry, char *name, -- void *value, size_t size, int flags) -+void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *name, void *value, size_t size, -+ int flags) - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return; -- security_ops->inode_post_setxattr(dentry, name, value, size, flags); -+ security_ops->inode_post_setxattr(dentry, mnt, name, value, size, flags); - } - - int security_inode_getxattr(struct dentry *dentry, char *name) ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2332,7 +2332,9 @@ static int selinux_inode_setotherxattr(s - return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); - } - --static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags) -+static int selinux_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *name, void *value, size_t size, -+ int flags) - { - struct task_security_struct *tsec = current->security; - struct inode *inode = dentry->d_inode; -@@ -2381,7 +2383,9 @@ static int selinux_inode_setxattr(struct - &ad); - } - --static void selinux_inode_post_setxattr(struct dentry *dentry, char *name, -+static void selinux_inode_post_setxattr(struct dentry *dentry, -+ struct vfsmount *mnt, -+ char *name, - void *value, size_t size, int flags) - { - struct inode *inode = dentry->d_inode; diff --git a/kernel-patches/for-mainline/security-symlink.diff b/kernel-patches/for-mainline/security-symlink.diff deleted file mode 100644 index c170cccec..000000000 --- a/kernel-patches/for-mainline/security-symlink.diff +++ /dev/null @@ -1,105 +0,0 @@ -From: Tony Jones -Subject: Pass struct vfsmount to the inode_symlink LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/namei.c | 2 +- - include/linux/security.h | 8 +++++--- - security/dummy.c | 2 +- - security/security.c | 4 ++-- - security/selinux/hooks.c | 3 ++- - 5 files changed, 11 insertions(+), 8 deletions(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2277,7 +2277,7 @@ int vfs_symlink(struct inode *dir, struc - if (!dir->i_op || !dir->i_op->symlink) - return -EPERM; - -- error = security_inode_symlink(dir, dentry, oldname); -+ error = security_inode_symlink(dir, dentry, mnt, oldname); - if (error) - return error; - ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -315,6 +315,7 @@ struct request_sock; - * Check the permission to create a symbolic link to a file. - * @dir contains the inode structure of parent directory of the symbolic link. - * @dentry contains the dentry structure of the symbolic link. -+ * @mnt is the vfsmount corresponding to @dentry (may be NULL). - * @old_name contains the pathname of file. - * Return 0 if permission is granted. - * @inode_mkdir: -@@ -1256,8 +1257,8 @@ struct security_operations { - int (*inode_link) (struct dentry *old_dentry, - struct inode *dir, struct dentry *new_dentry); - int (*inode_unlink) (struct inode *dir, struct dentry *dentry); -- int (*inode_symlink) (struct inode *dir, -- struct dentry *dentry, const char *old_name); -+ int (*inode_symlink) (struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, const char *old_name); - int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, int mode); - int (*inode_rmdir) (struct inode *dir, struct dentry *dentry); -@@ -1515,7 +1516,7 @@ int security_inode_link(struct dentry *o - struct dentry *new_dentry); - int security_inode_unlink(struct inode *dir, struct dentry *dentry); - int security_inode_symlink(struct inode *dir, struct dentry *dentry, -- const char *old_name); -+ struct vfsmount *mnt, const char *old_name); - int security_inode_mkdir(struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, int mode); - int security_inode_rmdir(struct inode *dir, struct dentry *dentry); -@@ -1844,6 +1845,7 @@ static inline int security_inode_unlink - - static inline int security_inode_symlink (struct inode *dir, - struct dentry *dentry, -+ struct vfsmount *mnt, - const char *old_name) - { - return 0; ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -279,7 +279,7 @@ static int dummy_inode_unlink (struct in - } - - static int dummy_inode_symlink (struct inode *inode, struct dentry *dentry, -- const char *name) -+ struct vfsmount *mnt, const char *name) - { - return 0; - } ---- a/security/security.c -+++ b/security/security.c -@@ -352,11 +352,11 @@ int security_inode_unlink(struct inode * - } - - int security_inode_symlink(struct inode *dir, struct dentry *dentry, -- const char *old_name) -+ struct vfsmount *mnt, const char *old_name) - { - if (unlikely(IS_PRIVATE(dir))) - return 0; -- return security_ops->inode_symlink(dir, dentry, old_name); -+ return security_ops->inode_symlink(dir, dentry, mnt, old_name); - } - - int security_inode_mkdir(struct inode *dir, struct dentry *dentry, ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2210,7 +2210,8 @@ static int selinux_inode_unlink(struct i - return may_link(dir, dentry, MAY_UNLINK); - } - --static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name) -+static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt, const char *name) - { - return may_create(dir, dentry, SECCLASS_LNK_FILE); - } diff --git a/kernel-patches/for-mainline/security-unlink.diff b/kernel-patches/for-mainline/security-unlink.diff deleted file mode 100644 index b0a26e8d5..000000000 --- a/kernel-patches/for-mainline/security-unlink.diff +++ /dev/null @@ -1,114 +0,0 @@ -From: Tony Jones -Subject: Pass struct vfsmount to the inode_unlink LSM hook - -This is needed for computing pathnames in the AppArmor LSM. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/namei.c | 2 +- - include/linux/security.h | 10 +++++++--- - security/dummy.c | 3 ++- - security/security.c | 5 +++-- - security/selinux/hooks.c | 5 +++-- - 5 files changed, 16 insertions(+), 9 deletions(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2184,7 +2184,7 @@ int vfs_unlink(struct inode *dir, struct - if (d_mountpoint(dentry)) - error = -EBUSY; - else { -- error = security_inode_unlink(dir, dentry); -+ error = security_inode_unlink(dir, dentry, mnt); - if (!error) - error = dir->i_op->unlink(dir, dentry); - } ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -312,6 +312,7 @@ struct request_sock; - * Check the permission to remove a hard link to a file. - * @dir contains the inode structure of parent directory of the file. - * @dentry contains the dentry structure for file to be unlinked. -+ * @mnt is the vfsmount corresponding to @dentry (may be NULL). - * Return 0 if permission is granted. - * @inode_symlink: - * Check the permission to create a symbolic link to a file. -@@ -1261,7 +1262,8 @@ struct security_operations { - int (*inode_link) (struct dentry *old_dentry, struct vfsmount *old_mnt, - struct inode *dir, struct dentry *new_dentry, - struct vfsmount *new_mnt); -- int (*inode_unlink) (struct inode *dir, struct dentry *dentry); -+ int (*inode_unlink) (struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt); - int (*inode_symlink) (struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, const char *old_name); - int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, -@@ -1521,7 +1523,8 @@ int security_inode_create(struct inode * - int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt, - struct inode *dir, struct dentry *new_dentry, - struct vfsmount *new_mnt); --int security_inode_unlink(struct inode *dir, struct dentry *dentry); -+int security_inode_unlink(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt); - int security_inode_symlink(struct inode *dir, struct dentry *dentry, - struct vfsmount *mnt, const char *old_name); - int security_inode_mkdir(struct inode *dir, struct dentry *dentry, -@@ -1848,7 +1851,8 @@ static inline int security_inode_link (s - } - - static inline int security_inode_unlink (struct inode *dir, -- struct dentry *dentry) -+ struct dentry *dentry, -+ struct vfsmount *mnt) - { - return 0; - } ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -275,7 +275,8 @@ static int dummy_inode_link (struct dent - return 0; - } - --static int dummy_inode_unlink (struct inode *inode, struct dentry *dentry) -+static int dummy_inode_unlink (struct inode *inode, struct dentry *dentry, -+ struct vfsmount *mnt) - { - return 0; - } ---- a/security/security.c -+++ b/security/security.c -@@ -346,11 +346,12 @@ int security_inode_link(struct dentry *o - new_dentry, new_mnt); - } - --int security_inode_unlink(struct inode *dir, struct dentry *dentry) -+int security_inode_unlink(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt) - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return 0; -- return security_ops->inode_unlink(dir, dentry); -+ return security_ops->inode_unlink(dir, dentry, mnt); - } - - int security_inode_symlink(struct inode *dir, struct dentry *dentry, ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2205,11 +2205,12 @@ static int selinux_inode_link(struct den - return may_link(dir, old_dentry, MAY_LINK); - } - --static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry) -+static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry, -+ struct vfsmount *mnt) - { - int rc; - -- rc = secondary_ops->inode_unlink(dir, dentry); -+ rc = secondary_ops->inode_unlink(dir, dentry, mnt); - if (rc) - return rc; - return may_link(dir, dentry, MAY_UNLINK); diff --git a/kernel-patches/for-mainline/security-xattr-file.diff b/kernel-patches/for-mainline/security-xattr-file.diff deleted file mode 100644 index 8ef08a81e..000000000 --- a/kernel-patches/for-mainline/security-xattr-file.diff +++ /dev/null @@ -1,540 +0,0 @@ -From: Andreas Gruenbacher -Subject: Pass struct file down the inode_*xattr security LSM hooks - -This allows LSMs to also distinguish between file descriptor and path -access for the xattr operations. (The other relevant operations are -covered by the setattr hook.) - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/xattr.c | 58 ++++++++++++++++++++++++----------------------- - include/linux/security.h | 40 +++++++++++++++++++------------- - include/linux/xattr.h | 8 +++--- - security/commoncap.c | 4 +-- - security/dummy.c | 10 ++++---- - security/security.c | 21 +++++++++-------- - security/selinux/hooks.c | 10 ++++---- - 7 files changed, 84 insertions(+), 67 deletions(-) - ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -69,7 +69,7 @@ xattr_permission(struct inode *inode, co - - int - vfs_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, -- void *value, size_t size, int flags) -+ void *value, size_t size, int flags, struct file *file) - { - struct inode *inode = dentry->d_inode; - int error; -@@ -79,7 +79,7 @@ vfs_setxattr(struct dentry *dentry, stru - return error; - - mutex_lock(&inode->i_mutex); -- error = security_inode_setxattr(dentry, mnt, name, value, size, flags); -+ error = security_inode_setxattr(dentry, mnt, name, value, size, flags, file); - if (error) - goto out; - error = -EOPNOTSUPP; -@@ -106,7 +106,7 @@ EXPORT_SYMBOL_GPL(vfs_setxattr); - - ssize_t - vfs_getxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, -- void *value, size_t size) -+ void *value, size_t size, struct file *file) - { - struct inode *inode = dentry->d_inode; - int error; -@@ -115,7 +115,7 @@ vfs_getxattr(struct dentry *dentry, stru - if (error) - return error; - -- error = security_inode_getxattr(dentry, mnt, name); -+ error = security_inode_getxattr(dentry, mnt, name, file); - if (error) - return error; - -@@ -143,12 +143,12 @@ EXPORT_SYMBOL_GPL(vfs_getxattr); - - ssize_t - vfs_listxattr(struct dentry *dentry, struct vfsmount *mnt, char *list, -- size_t size) -+ size_t size, struct file *file) - { - struct inode *inode = dentry->d_inode; - ssize_t error; - -- error = security_inode_listxattr(dentry, mnt); -+ error = security_inode_listxattr(dentry, mnt, file); - if (error) - return error; - error = -EOPNOTSUPP; -@@ -164,7 +164,8 @@ vfs_listxattr(struct dentry *dentry, str - EXPORT_SYMBOL_GPL(vfs_listxattr); - - int --vfs_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name) -+vfs_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name, -+ struct file *file) - { - struct inode *inode = dentry->d_inode; - int error; -@@ -176,7 +177,7 @@ vfs_removexattr(struct dentry *dentry, s - if (error) - return error; - -- error = security_inode_removexattr(dentry, mnt, name); -+ error = security_inode_removexattr(dentry, mnt, name, file); - if (error) - return error; - -@@ -196,7 +197,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr); - */ - static long - setxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name, -- void __user *value, size_t size, int flags) -+ void __user *value, size_t size, int flags, struct file *file) - { - int error; - void *kvalue = NULL; -@@ -223,7 +224,7 @@ setxattr(struct dentry *dentry, struct v - } - } - -- error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags); -+ error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags, file); - kfree(kvalue); - return error; - } -@@ -238,7 +239,7 @@ sys_setxattr(char __user *path, char __u - error = user_path_walk(path, &nd); - if (error) - return error; -- error = setxattr(nd.dentry, nd.mnt, name, value, size, flags); -+ error = setxattr(nd.dentry, nd.mnt, name, value, size, flags, NULL); - path_release(&nd); - return error; - } -@@ -253,7 +254,7 @@ sys_lsetxattr(char __user *path, char __ - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = setxattr(nd.dentry, nd.mnt, name, value, size, flags); -+ error = setxattr(nd.dentry, nd.mnt, name, value, size, flags, NULL); - path_release(&nd); - return error; - } -@@ -271,7 +272,7 @@ sys_fsetxattr(int fd, char __user *name, - return error; - dentry = f->f_path.dentry; - audit_inode(NULL, dentry); -- error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags); -+ error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags, f); - fput(f); - return error; - } -@@ -281,7 +282,7 @@ sys_fsetxattr(int fd, char __user *name, - */ - static ssize_t - getxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name, -- void __user *value, size_t size) -+ void __user *value, size_t size, struct file *file) - { - ssize_t error; - void *kvalue = NULL; -@@ -301,7 +302,7 @@ getxattr(struct dentry *dentry, struct v - return -ENOMEM; - } - -- error = vfs_getxattr(dentry, mnt, kname, kvalue, size); -+ error = vfs_getxattr(dentry, mnt, kname, kvalue, size, file); - if (error > 0) { - if (size && copy_to_user(value, kvalue, error)) - error = -EFAULT; -@@ -324,7 +325,7 @@ sys_getxattr(char __user *path, char __u - error = user_path_walk(path, &nd); - if (error) - return error; -- error = getxattr(nd.dentry, nd.mnt, name, value, size); -+ error = getxattr(nd.dentry, nd.mnt, name, value, size, NULL); - path_release(&nd); - return error; - } -@@ -339,7 +340,7 @@ sys_lgetxattr(char __user *path, char __ - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = getxattr(nd.dentry, nd.mnt, name, value, size); -+ error = getxattr(nd.dentry, nd.mnt, name, value, size, NULL); - path_release(&nd); - return error; - } -@@ -354,7 +355,7 @@ sys_fgetxattr(int fd, char __user *name, - if (!f) - return error; - audit_inode(NULL, f->f_path.dentry); -- error = getxattr(f->f_path.dentry, f->f_path.mnt, name, value, size); -+ error = getxattr(f->f_path.dentry, f->f_path.mnt, name, value, size, f); - fput(f); - return error; - } -@@ -364,7 +365,7 @@ sys_fgetxattr(int fd, char __user *name, - */ - static ssize_t - listxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *list, -- size_t size) -+ size_t size, struct file *file) - { - ssize_t error; - char *klist = NULL; -@@ -377,7 +378,7 @@ listxattr(struct dentry *dentry, struct - return -ENOMEM; - } - -- error = vfs_listxattr(dentry, mnt, klist, size); -+ error = vfs_listxattr(dentry, mnt, klist, size, file); - if (error > 0) { - if (size && copy_to_user(list, klist, error)) - error = -EFAULT; -@@ -399,7 +400,7 @@ sys_listxattr(char __user *path, char __ - error = user_path_walk(path, &nd); - if (error) - return error; -- error = listxattr(nd.dentry, nd.mnt, list, size); -+ error = listxattr(nd.dentry, nd.mnt, list, size, NULL); - path_release(&nd); - return error; - } -@@ -413,7 +414,7 @@ sys_llistxattr(char __user *path, char _ - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = listxattr(nd.dentry, nd.mnt, list, size); -+ error = listxattr(nd.dentry, nd.mnt, list, size, NULL); - path_release(&nd); - return error; - } -@@ -428,7 +429,7 @@ sys_flistxattr(int fd, char __user *list - if (!f) - return error; - audit_inode(NULL, f->f_path.dentry); -- error = listxattr(f->f_path.dentry, f->f_path.mnt, list, size); -+ error = listxattr(f->f_path.dentry, f->f_path.mnt, list, size, f); - fput(f); - return error; - } -@@ -437,7 +438,8 @@ sys_flistxattr(int fd, char __user *list - * Extended attribute REMOVE operations - */ - static long --removexattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name) -+removexattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name, -+ struct file *file) - { - int error; - char kname[XATTR_NAME_MAX + 1]; -@@ -448,7 +450,7 @@ removexattr(struct dentry *dentry, struc - if (error < 0) - return error; - -- return vfs_removexattr(dentry, mnt, kname); -+ return vfs_removexattr(dentry, mnt, kname, file); - } - - asmlinkage long -@@ -460,7 +462,7 @@ sys_removexattr(char __user *path, char - error = user_path_walk(path, &nd); - if (error) - return error; -- error = removexattr(nd.dentry, nd.mnt, name); -+ error = removexattr(nd.dentry, nd.mnt, name, NULL); - path_release(&nd); - return error; - } -@@ -474,7 +476,7 @@ sys_lremovexattr(char __user *path, char - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = removexattr(nd.dentry, nd.mnt, name); -+ error = removexattr(nd.dentry, nd.mnt, name, NULL); - path_release(&nd); - return error; - } -@@ -491,7 +493,7 @@ sys_fremovexattr(int fd, char __user *na - return error; - dentry = f->f_path.dentry; - audit_inode(NULL, dentry); -- error = removexattr(dentry, f->f_path.mnt, name); -+ error = removexattr(dentry, f->f_path.mnt, name, f); - fput(f); - return error; - } ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -56,8 +56,8 @@ extern void cap_capset_set (struct task_ - extern int cap_bprm_set_security (struct linux_binprm *bprm); - extern void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe); - extern int cap_bprm_secureexec(struct linux_binprm *bprm); --extern int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, void *value, size_t size, int flags); --extern int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name); -+extern int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, void *value, size_t size, int flags, struct file *file); -+extern int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name, struct file *file); - extern int cap_inode_need_killpriv(struct dentry *dentry); - extern int cap_inode_killpriv(struct dentry *dentry); - extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags); -@@ -1286,16 +1286,18 @@ struct security_operations { - int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry); - void (*inode_delete) (struct inode *inode); - int (*inode_setxattr) (struct dentry *dentry, struct vfsmount *mnt, -- char *name, void *value, size_t size, int flags); -+ char *name, void *value, size_t size, int flags, -+ struct file *file); - void (*inode_post_setxattr) (struct dentry *dentry, - struct vfsmount *mnt, - char *name, void *value, - size_t size, int flags); - int (*inode_getxattr) (struct dentry *dentry, struct vfsmount *mnt, -- char *name); -- int (*inode_listxattr) (struct dentry *dentry, struct vfsmount *mnt); -+ char *name, struct file *file); -+ int (*inode_listxattr) (struct dentry *dentry, struct vfsmount *mnt, -+ struct file *file); - int (*inode_removexattr) (struct dentry *dentry, struct vfsmount *mnt, -- char *name); -+ char *name, struct file *file); - int (*inode_need_killpriv) (struct dentry *dentry); - int (*inode_killpriv) (struct dentry *dentry); - int (*inode_getsecurity)(const struct inode *inode, const char *name, void *buffer, size_t size, int err); -@@ -1552,15 +1554,17 @@ int security_inode_setattr(struct dentry - int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry); - void security_inode_delete(struct inode *inode); - int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, -- char *name, void *value, size_t size, int flags); -+ char *name, void *value, size_t size, int flags, -+ struct file *file); - void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, - char *name, void *value, size_t size, - int flags); - int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, -- char *name); --int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt); -+ char *name, struct file *file); -+int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, -+ struct file *file); - int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, -- char *name); -+ char *name, struct file *file); - int security_inode_need_killpriv(struct dentry *dentry); - int security_inode_killpriv(struct dentry *dentry); - int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err); -@@ -1946,9 +1950,10 @@ static inline void security_inode_delete - - static inline int security_inode_setxattr (struct dentry *dentry, - struct vfsmount *mnt, char *name, -- void *value, size_t size, int flags) -+ void *value, size_t size, int flags, -+ struct file *file) - { -- return cap_inode_setxattr(dentry, mnt, name, value, size, flags); -+ return cap_inode_setxattr(dentry, mnt, name, value, size, flags, file); - } - - static inline void security_inode_post_setxattr (struct dentry *dentry, -@@ -1959,21 +1964,24 @@ static inline void security_inode_post_s - { } - - static inline int security_inode_getxattr (struct dentry *dentry, -- struct vfsmount *mnt, char *name) -+ struct vfsmount *mnt, char *name, -+ struct file *file) - { - return 0; - } - - static inline int security_inode_listxattr (struct dentry *dentry, -- struct vfsmount *mnt) -+ struct vfsmount *mnt, -+ struct file *file) - { - return 0; - } - - static inline int security_inode_removexattr (struct dentry *dentry, -- struct vfsmount *mnt, char *name) -+ struct vfsmount *mnt, char *name, -+ struct file *file) - { -- return cap_inode_removexattr(dentry, mnt, name); -+ return cap_inode_removexattr(dentry, mnt, name, file); - } - - static inline int security_inode_need_killpriv(struct dentry *dentry) ---- a/include/linux/xattr.h -+++ b/include/linux/xattr.h -@@ -47,12 +47,12 @@ struct xattr_handler { - }; - - ssize_t vfs_getxattr(struct dentry *, struct vfsmount *, char *, void *, -- size_t); -+ size_t, struct file *); - ssize_t vfs_listxattr(struct dentry *d, struct vfsmount *, char *list, -- size_t size); -+ size_t size, struct file *); - int vfs_setxattr(struct dentry *, struct vfsmount *, char *, void *, size_t, -- int); --int vfs_removexattr(struct dentry *, struct vfsmount *, char *); -+ int, struct file *); -+int vfs_removexattr(struct dentry *, struct vfsmount *, char *, struct file *); - - ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size); - ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size); ---- a/security/commoncap.c -+++ b/security/commoncap.c -@@ -369,7 +369,7 @@ int cap_bprm_secureexec (struct linux_bi - } - - int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, -- void *value, size_t size, int flags) -+ void *value, size_t size, int flags, struct file *file) - { - if (!strcmp(name, XATTR_NAME_CAPS)) { - if (!capable(CAP_SETFCAP)) -@@ -383,7 +383,7 @@ int cap_inode_setxattr(struct dentry *de - } - - int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, -- char *name) -+ char *name, struct file *file) - { - if (!strcmp(name, XATTR_NAME_CAPS)) { - if (!capable(CAP_SETFCAP)) ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -349,7 +349,7 @@ static void dummy_inode_delete (struct i - - static int dummy_inode_setxattr (struct dentry *dentry, struct vfsmount *mnt, - char *name, void *value, size_t size, -- int flags) -+ int flags, struct file *file) - { - if (!strncmp(name, XATTR_SECURITY_PREFIX, - sizeof(XATTR_SECURITY_PREFIX) - 1) && -@@ -366,18 +366,20 @@ static void dummy_inode_post_setxattr (s - } - - static int dummy_inode_getxattr (struct dentry *dentry, -- struct vfsmount *mnt, char *name) -+ struct vfsmount *mnt, char *name, -+ struct file *file) - { - return 0; - } - --static int dummy_inode_listxattr (struct dentry *dentry, struct vfsmount *mnt) -+static int dummy_inode_listxattr (struct dentry *dentry, struct vfsmount *mnt, -+ struct file *file) - { - return 0; - } - - static int dummy_inode_removexattr (struct dentry *dentry, struct vfsmount *mnt, -- char *name) -+ char *name, struct file *file) - { - if (!strncmp(name, XATTR_SECURITY_PREFIX, - sizeof(XATTR_SECURITY_PREFIX) - 1) && ---- a/security/security.c -+++ b/security/security.c -@@ -441,12 +441,13 @@ void security_inode_delete(struct inode - } - - int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, -- char *name, void *value, size_t size, int flags) -+ char *name, void *value, size_t size, int flags, -+ struct file *file) - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return 0; - return security_ops->inode_setxattr(dentry, mnt, name, value, size, -- flags); -+ flags, file); - } - - void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, -@@ -455,30 +456,32 @@ void security_inode_post_setxattr(struct - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return; -- security_ops->inode_post_setxattr(dentry, mnt, name, value, size, flags); -+ security_ops->inode_post_setxattr(dentry, mnt, name, value, size, -+ flags); - } - - int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, -- char *name) -+ char *name, struct file *file) - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return 0; -- return security_ops->inode_getxattr(dentry, mnt, name); -+ return security_ops->inode_getxattr(dentry, mnt, name, file); - } - --int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt) -+int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, -+ struct file *file) - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return 0; -- return security_ops->inode_listxattr(dentry, mnt); -+ return security_ops->inode_listxattr(dentry, mnt, file); - } - - int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, -- char *name) -+ char *name, struct file *file) - { - if (unlikely(IS_PRIVATE(dentry->d_inode))) - return 0; -- return security_ops->inode_removexattr(dentry, mnt, name); -+ return security_ops->inode_removexattr(dentry, mnt, name, file); - } - - int security_inode_need_killpriv(struct dentry *dentry) ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2334,7 +2334,7 @@ static int selinux_inode_setotherxattr(s - - static int selinux_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, - char *name, void *value, size_t size, -- int flags) -+ int flags, struct file *file) - { - struct task_security_struct *tsec = current->security; - struct inode *inode = dentry->d_inode; -@@ -2410,18 +2410,20 @@ static void selinux_inode_post_setxattr( - } - - static int selinux_inode_getxattr (struct dentry *dentry, struct vfsmount *mnt, -- char *name) -+ char *name, struct file *file) - { - return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); - } - --static int selinux_inode_listxattr (struct dentry *dentry, struct vfsmount *mnt) -+static int selinux_inode_listxattr (struct dentry *dentry, struct vfsmount *mnt, -+ struct file *file) - { - return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); - } - - static int selinux_inode_removexattr (struct dentry *dentry, -- struct vfsmount *mnt, char *name) -+ struct vfsmount *mnt, char *name, -+ struct file *file) - { - if (strcmp(name, XATTR_NAME_SELINUX)) - return selinux_inode_setotherxattr(dentry, name); diff --git a/kernel-patches/for-mainline/security_chroot.diff b/kernel-patches/for-mainline/security_chroot.diff deleted file mode 100644 index 792d7c8cd..000000000 --- a/kernel-patches/for-mainline/security_chroot.diff +++ /dev/null @@ -1,85 +0,0 @@ -Index: linux-2.6/fs/open.c -=================================================================== ---- linux-2.6.orig/fs/open.c -+++ linux-2.6/fs/open.c -@@ -483,6 +483,10 @@ asmlinkage long sys_chroot(const char __ - if (!capable(CAP_SYS_CHROOT)) - goto dput_and_out; - -+ error = security_chroot(&nd); -+ if (error) -+ goto dput_and_out; -+ - set_fs_root(current->fs, nd.mnt, nd.dentry); - set_fs_altroot(); - error = 0; -Index: linux-2.6/include/linux/security.h -=================================================================== ---- linux-2.6.orig/include/linux/security.h -+++ linux-2.6/include/linux/security.h -@@ -247,6 +247,9 @@ struct request_sock; - * Update module state after a successful pivot. - * @old_nd contains the nameidata structure for the old root. - * @new_nd contains the nameidata structure for the new root. -+ * @sb_chroot: -+ * Check permission before chroot to chroot to point named by @nd -+ * @nd contains the nameidata object for the new root - * - * Security hooks for inode operations. - * -@@ -1211,6 +1214,7 @@ struct security_operations { - struct nameidata * new_nd); - void (*sb_post_pivotroot) (struct nameidata * old_nd, - struct nameidata * new_nd); -+ int (*sb_chroot) (struct nameidata * nd); - - int (*inode_alloc_security) (struct inode *inode); - void (*inode_free_security) (struct inode *inode); -@@ -1610,6 +1614,11 @@ static inline void security_sb_post_pivo - security_ops->sb_post_pivotroot (old_nd, new_nd); - } - -+static inline int security_chroot (struct nameidata *nd) -+{ -+ return security_ops->sb_chroot (nd); -+} -+ - static inline int security_inode_alloc (struct inode *inode) - { - inode->i_security = NULL; -@@ -2362,6 +2371,11 @@ static inline void security_sb_post_pivo - struct nameidata *new_nd) - { } - -+static inline int security_sb_chroot (struct nameidata *nd) -+{ -+ return 0; -+} -+ - static inline int security_inode_alloc (struct inode *inode) - { - return 0; -Index: linux-2.6/security/dummy.c -=================================================================== ---- linux-2.6.orig/security/dummy.c -+++ linux-2.6/security/dummy.c -@@ -248,6 +248,11 @@ static void dummy_sb_post_pivotroot (str - return; - } - -+static int dummy_sb_chroot (struct nameidata *nd) -+{ -+ return 0; -+} -+ - static int dummy_inode_alloc_security (struct inode *inode) - { - return 0; -@@ -1004,6 +1009,7 @@ void security_fixup_ops (struct security - set_to_dummy_if_null(ops, sb_post_addmount); - set_to_dummy_if_null(ops, sb_pivotroot); - set_to_dummy_if_null(ops, sb_post_pivotroot); -+ set_to_dummy_if_null(ops, sb_chroot); - set_to_dummy_if_null(ops, inode_alloc_security); - set_to_dummy_if_null(ops, inode_free_security); - set_to_dummy_if_null(ops, inode_init_security); diff --git a/kernel-patches/for-mainline/series b/kernel-patches/for-mainline/series deleted file mode 100644 index 65118cb6d..000000000 --- a/kernel-patches/for-mainline/series +++ /dev/null @@ -1,123 +0,0 @@ -#unionfs-2.2.2_for_2.6.24-rc7.diff -#unionfs-2.1.11_for_2.6.24-rc4.diff -security-create.diff -remove_suid.diff -vfs-notify_change.diff -#should_remove_suid.diff -security-setattr.diff -vfs-mkdir.diff -security-mkdir.diff -vfs-mknod.diff -security-mknod.diff -vfs-symlink.diff -security-symlink.diff -security-readlink.diff -vfs-link.diff -security-link.diff -vfs-rmdir.diff -security-rmdir.diff -fix-vfs_rmdir.diff -vfs-unlink.diff -security-unlink.diff -vfs-rename.diff -security-rename.diff -vfs-setxattr.diff -security-setxattr.diff -vfs-getxattr.diff -security-getxattr.diff -vfs-listxattr.diff -security-listxattr.diff -vfs-removexattr.diff -security-removexattr.diff -unambiguous-__d_path.diff -mount-consistent-__d_path.diff -d_namespace_path.diff -__d_path-keep-connected.diff -fsetattr.diff -#fix-fuse.diff -fsetattr-reintro-ATTR_FILE.diff -file-handle-ops.diff -security-xattr-file.diff -sysctl-pathname.diff -parent-permission.diff -do_path_lookup-nameidata.diff -sys_fchdir-nameidata.diff -file_permission-nameidata.diff -apparmor-audit.diff -apparmor-main.diff -apparmor-lsm.diff -apparmor-module_interface.diff -apparmor-misc.diff -apparmor-intree.diff - -#fix-rcu-deref.diff -#fix-name-errorpath.diff -#change-profile-kernel-v2.diff -#expand-dfa.diff -#slash-null-dfa.diff -#profile-namespaces.diff -#owner-perm-set.diff -#apparmor-link-pairs.diff -#apparmor-bootdisable.diff -#apparmor-builtin-only.diff -#apparmor-security-goal.diff -#apparmor-features.diff -#split_init.diff -#apparmor-fix-sysctl-refcount.diff -#apparmor-fix-lock-letter.diff -#fix-link-subset.diff -#hat_perm.diff -#extend-x-mods.diff -#no-safex-link-subset.diff -#apparmor-create-append.diff -#apparmor-failed-name-error.diff -#audit-uid.diff -#apparmor-secondary-accept.diff -#apparmor-audit-flags2.diff -#fix-profile-namespaces.diff -#fix-dfa.diff -#cap-set.diff - - -#foobar.diff -# # NOT YET -# ecryptfs-d_revalidate.diff -# nfs-nameidata-check.diff -# # statvfs.diff -# # statvfs-2.diff -# # fix-getcwd.diff -# # proc-mounts-cleanup.diff -# # proc-mounts-check-d_path-result.diff -# # fix-d_path.diff -##split-up-nameidata.diff -##vfs_create-nameidata.diff -##xattr_permission.diff -##nfsd_permission-nameidata.diff -# vfs_create-args.diff -# vfs_mknod-args.diff -# vfs_mkdir-args.diff -# vfs_symlink-args.diff -# vfs_link-args.diff -# vfs_rename-args.diff -# may_create-args.diff -# vfs_rmdir-args.diff -# vfs_unlink-args.diff -# may_delete-args.diff -#fix-change_profile-namespace.diff - -#audit_denied.diff -#apparmor-audit-flags.diff -#FS2.2.2_fix-unionfs-with-AppArmor.patch -#FS2.1.3_fix-unionfs-with-AppArmor.patch - -#named-transitions.diff -apparmor-network.diff -#fix-net.diff -apparmor-rlimits.diff -audit-log-type-in-syslog.diff -#fix-named-transitions.diff -#apparmor-xmods-accept-entry.diff -#apparmor-split-audit-deny.diff -#apparmor-cond-uid.diff -#apparmor-quiet-control.diff -#apparmor-direct-complain.diff diff --git a/kernel-patches/for-mainline/should_remove_suid.diff b/kernel-patches/for-mainline/should_remove_suid.diff deleted file mode 100644 index 61790f85d..000000000 --- a/kernel-patches/for-mainline/should_remove_suid.diff +++ /dev/null @@ -1,96 +0,0 @@ -From: Andreas Gruenbacher -Subject: Pass struct file down to should_remove_suid and children - -Pass struct path to should_remove_suid instead of only the dentry. -To make should_remove_suid consistent with changes made to -remove_suid. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/ocfs2/file.c | 2 +- - fs/open.c | 5 ++++- - fs/splice.c | 2 +- - include/linux/fs.h | 2 +- - mm/filemap.c | 6 +++--- - 5 files changed, 10 insertions(+), 7 deletions(-) - ---- a/fs/ocfs2/file.c -+++ b/fs/ocfs2/file.c -@@ -1191,7 +1191,7 @@ static int ocfs2_prepare_inode_for_write - * inode. There's also the dinode i_size state which - * can be lost via setattr during extending writes (we - * set inode->i_size at the end of a write. */ -- if (should_remove_suid(path->dentry)) { -+ if (should_remove_suid(path)) { - if (meta_level == 0) { - ocfs2_meta_unlock(inode, meta_level); - meta_level = 1; ---- a/fs/open.c -+++ b/fs/open.c -@@ -198,6 +198,7 @@ int do_truncate(struct dentry *dentry, s - { - int err; - struct iattr newattrs; -+ struct path path; - - /* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */ - if (length < 0) -@@ -211,7 +212,9 @@ int do_truncate(struct dentry *dentry, s - } - - /* Remove suid/sgid on truncate too */ -- newattrs.ia_valid |= should_remove_suid(dentry); -+ path.dentry = dentry; -+ path.mnt = mnt; -+ newattrs.ia_valid |= should_remove_suid(&path); - - mutex_lock(&dentry->d_inode->i_mutex); - err = notify_change(dentry, mnt, &newattrs); ---- a/fs/splice.c -+++ b/fs/splice.c -@@ -842,7 +842,7 @@ generic_file_splice_write(struct pipe_in - ssize_t ret; - int err; - -- err = should_remove_suid(out->f_path.dentry); -+ err = should_remove_suid(&out->f_path); - if (unlikely(err)) { - mutex_lock(&inode->i_mutex); - err = __remove_suid(&out->f_path, err); ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1698,7 +1698,7 @@ extern void clear_inode(struct inode *); - extern void destroy_inode(struct inode *); - extern struct inode *new_inode(struct super_block *); - extern int __remove_suid(struct path *, int); --extern int should_remove_suid(struct dentry *); -+extern int should_remove_suid(struct path *); - extern int remove_suid(struct path *); - - extern void __insert_inode_hash(struct inode *, unsigned long hashval); ---- a/mm/filemap.c -+++ b/mm/filemap.c -@@ -1882,9 +1882,9 @@ repeat: - * if suid or (sgid and xgrp) - * remove privs - */ --int should_remove_suid(struct dentry *dentry) -+int should_remove_suid(struct path *path) - { -- mode_t mode = dentry->d_inode->i_mode; -+ mode_t mode = path->dentry->d_inode->i_mode; - int kill = 0; - - /* suid always must be killed */ -@@ -1915,7 +1915,7 @@ int __remove_suid(struct path *path, int - - int remove_suid(struct path *path) - { -- int kill = should_remove_suid(path->dentry); -+ int kill = should_remove_suid(path); - - if (unlikely(kill)) - return __remove_suid(path, kill); diff --git a/kernel-patches/for-mainline/slash-null-dfa.diff b/kernel-patches/for-mainline/slash-null-dfa.diff deleted file mode 100644 index 50c31383c..000000000 --- a/kernel-patches/for-mainline/slash-null-dfa.diff +++ /dev/null @@ -1,40 +0,0 @@ -convert the null transition from using the 0 character to "//" until -the parser gets updated so that it can add a null character transition. - ---- - security/apparmor/match.c | 24 +----------------------- - 1 file changed, 1 insertion(+), 23 deletions(-) - ---- a/security/apparmor/match.c -+++ b/security/apparmor/match.c -@@ -262,29 +262,7 @@ unsigned int aa_dfa_next_state(struct aa - */ - unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start) - { -- u16 *def = DEFAULT_TABLE(dfa); -- u32 *base = BASE_TABLE(dfa); -- u16 *next = NEXT_TABLE(dfa); -- u16 *check = CHECK_TABLE(dfa); -- unsigned int state = start, pos; -- -- /* current state is , matching character *str */ -- if (dfa->tables[YYTD_ID_EC - 1]) { -- u8 *equiv = EQUIV_TABLE(dfa); -- pos = base[state] + equiv[0]; -- if (check[pos] == state) -- state = next[pos]; -- else -- state = def[state]; -- } else { -- pos = base[state] + 0; -- if (check[pos] == state) -- state = next[pos]; -- else -- state = def[state]; -- } -- -- return state; -+ return aa_dfa_next_state(dfa, start, "//"); - } - - /** diff --git a/kernel-patches/for-mainline/split-up-nameidata.diff b/kernel-patches/for-mainline/split-up-nameidata.diff deleted file mode 100644 index 4bf2ff26e..000000000 --- a/kernel-patches/for-mainline/split-up-nameidata.diff +++ /dev/null @@ -1,2604 +0,0 @@ -From: Andreas Gruenbacher -Subject: Pass no useless nameidata to the create, lookup, and permission IOPs - -The create, lookup, and permission inode operations are all passed a -full nameidata. This is unfortunate because in nfsd and the mqueue -filesystem, we must instantiate a struct nameidata but cannot provide -all of the same information that a regular lookup would provide. The -unused fields take up space on the stack, but more importantly, it is -not obvious which fields have meaningful values and which don't, and so -things might easily break. - -This patch introduces struct nameidata2 with only the fields that make -sense independent of an actual lookup, and uses that struct in those -places where a full nameidat is not needed. - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/9p/vfs_inode.c | 4 +-- - fs/adfs/dir.c | 2 - - fs/affs/affs.h | 4 +-- - fs/affs/namei.c | 4 +-- - fs/afs/dir.c | 12 +++++----- - fs/afs/internal.h | 4 --- - fs/afs/mntpt.c | 4 +-- - fs/afs/security.c | 2 - - fs/autofs/root.c | 6 ++--- - fs/autofs4/root.c | 8 +++---- - fs/bad_inode.c | 6 ++--- - fs/befs/linuxvfs.c | 4 +-- - fs/bfs/dir.c | 4 +-- - fs/cifs/cifsfs.c | 2 - - fs/cifs/cifsfs.h | 4 +-- - fs/cifs/dir.c | 6 ++--- - fs/coda/dir.c | 14 ++++++------ - fs/coda/pioctl.c | 4 +-- - fs/configfs/dir.c | 2 - - fs/cramfs/inode.c | 2 - - fs/ecryptfs/dentry.c | 2 - - fs/ecryptfs/inode.c | 10 ++++----- - fs/efs/namei.c | 2 - - fs/exec.c | 8 +++---- - fs/ext2/acl.c | 2 - - fs/ext2/acl.h | 2 - - fs/ext2/namei.c | 4 +-- - fs/ext3/acl.c | 2 - - fs/ext3/acl.h | 2 - - fs/ext3/namei.c | 4 +-- - fs/ext4/acl.c | 2 - - fs/ext4/acl.h | 2 - - fs/ext4/namei.c | 4 +-- - fs/freevxfs/vxfs_lookup.c | 4 +-- - fs/fuse/dir.c | 10 ++++----- - fs/gfs2/inode.c | 2 - - fs/gfs2/inode.h | 2 - - fs/gfs2/ops_dentry.c | 2 - - fs/gfs2/ops_inode.c | 6 ++--- - fs/hfs/dir.c | 4 +-- - fs/hfs/inode.c | 4 +-- - fs/hfs/sysdep.c | 2 - - fs/hfsplus/dir.c | 4 +-- - fs/hfsplus/inode.c | 4 +-- - fs/hpfs/dir.c | 2 - - fs/hpfs/hpfs_fn.h | 2 - - fs/hpfs/namei.c | 2 - - fs/hugetlbfs/inode.c | 2 - - fs/inotify_user.c | 2 - - fs/isofs/isofs.h | 2 - - fs/isofs/namei.c | 2 - - fs/jffs2/acl.c | 2 - - fs/jffs2/acl.h | 2 - - fs/jffs2/dir.c | 8 +++---- - fs/jfs/acl.c | 2 - - fs/jfs/jfs_acl.h | 2 - - fs/jfs/namei.c | 4 +-- - fs/libfs.c | 2 - - fs/minix/namei.c | 4 +-- - fs/msdos/namei.c | 4 +-- - fs/namei.c | 45 ++++++++++++++++++++--------------------- - fs/ncpfs/dir.c | 14 ++++++------ - fs/nfs/dir.c | 30 +++++++++++++-------------- - fs/nfs/nfs3proc.c | 2 - - fs/nfs/nfs4_fs.h | 4 +-- - fs/nfs/nfs4proc.c | 8 +++---- - fs/nfs/proc.c | 2 - - fs/ntfs/namei.c | 2 - - fs/ocfs2/dcache.c | 2 - - fs/ocfs2/dlm/dlmfs.c | 2 - - fs/ocfs2/file.c | 2 - - fs/ocfs2/file.h | 2 - - fs/ocfs2/namei.c | 4 +-- - fs/open.c | 15 +++++++------ - fs/proc/base.c | 22 ++++++++++---------- - fs/proc/generic.c | 2 - - fs/proc/proc_sysctl.c | 6 ++--- - fs/proc/root.c | 2 - - fs/qnx4/namei.c | 2 - - fs/ramfs/inode.c | 2 - - fs/reiserfs/namei.c | 4 +-- - fs/reiserfs/xattr.c | 2 - - fs/romfs/inode.c | 2 - - fs/smbfs/dir.c | 12 +++++----- - fs/smbfs/file.c | 2 - - fs/sysfs/dir.c | 2 - - fs/sysv/namei.c | 4 +-- - fs/udf/namei.c | 4 +-- - fs/ufs/namei.c | 4 +-- - fs/utimes.c | 2 - - fs/vfat/namei.c | 6 ++--- - fs/xfs/linux-2.6/xfs_iops.c | 6 ++--- - include/linux/coda_linux.h | 2 - - include/linux/dcache.h | 3 +- - include/linux/efs_fs.h | 2 - - include/linux/fs.h | 15 +++++++------ - include/linux/namei.h | 37 ++++++++++++++++++++++++--------- - include/linux/nfs_fs.h | 2 - - include/linux/nfs_xdr.h | 2 - - include/linux/proc_fs.h | 4 +-- - include/linux/qnx4_fs.h | 2 - - include/linux/reiserfs_xattr.h | 2 - - include/linux/security.h | 6 ++--- - include/linux/shmem_fs.h | 2 - - ipc/mqueue.c | 2 - - mm/shmem.c | 2 - - mm/shmem_acl.c | 2 - - net/unix/af_unix.c | 2 - - security/apparmor/lsm.c | 2 - - security/dummy.c | 2 - - security/selinux/hooks.c | 2 - - 111 files changed, 282 insertions(+), 263 deletions(-) - ---- a/fs/9p/vfs_inode.c -+++ b/fs/9p/vfs_inode.c -@@ -457,7 +457,7 @@ v9fs_open_created(struct inode *inode, s - - static int - v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int err; - u32 fid, perm, iounit; -@@ -615,7 +615,7 @@ error: - */ - - static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nameidata) -+ struct nameidata2 *nameidata) - { - struct super_block *sb; - struct v9fs_session_info *v9ses; ---- a/fs/adfs/dir.c -+++ b/fs/adfs/dir.c -@@ -268,7 +268,7 @@ struct dentry_operations adfs_dentry_ope - }; - - static struct dentry * --adfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+adfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct inode *inode = NULL; - struct object_info obj; ---- a/fs/affs/affs.h -+++ b/fs/affs/affs.h -@@ -153,9 +153,9 @@ extern void affs_free_bitmap(struct supe - /* namei.c */ - - extern int affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len); --extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *); -+extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *); - extern int affs_unlink(struct inode *dir, struct dentry *dentry); --extern int affs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *); -+extern int affs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata2 *); - extern int affs_mkdir(struct inode *dir, struct dentry *dentry, int mode); - extern int affs_rmdir(struct inode *dir, struct dentry *dentry); - extern int affs_link(struct dentry *olddentry, struct inode *dir, ---- a/fs/affs/namei.c -+++ b/fs/affs/namei.c -@@ -197,7 +197,7 @@ affs_find_entry(struct inode *dir, struc - } - - struct dentry * --affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct super_block *sb = dir->i_sb; - struct buffer_head *bh; -@@ -243,7 +243,7 @@ affs_unlink(struct inode *dir, struct de - } - - int --affs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) -+affs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata2 *nd) - { - struct super_block *sb = dir->i_sb; - struct inode *inode; ---- a/fs/afs/dir.c -+++ b/fs/afs/dir.c -@@ -20,16 +20,16 @@ - #include "internal.h" - - static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd); -+ struct nameidata2 *nd); - static int afs_dir_open(struct inode *inode, struct file *file); - static int afs_readdir(struct file *file, void *dirent, filldir_t filldir); --static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd); -+static int afs_d_revalidate(struct dentry *dentry, struct nameidata2 *nd); - static int afs_d_delete(struct dentry *dentry); - static void afs_d_release(struct dentry *dentry); - static int afs_lookup_filldir(void *_cookie, const char *name, int nlen, - loff_t fpos, u64 ino, unsigned dtype); - static int afs_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata *nd); -+ struct nameidata2 *nd); - static int afs_mkdir(struct inode *dir, struct dentry *dentry, int mode); - static int afs_rmdir(struct inode *dir, struct dentry *dentry); - static int afs_unlink(struct inode *dir, struct dentry *dentry); -@@ -483,7 +483,7 @@ static int afs_do_lookup(struct inode *d - * look up an entry in a directory - */ - static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct afs_vnode *vnode; - struct afs_fid fid; -@@ -559,7 +559,7 @@ static struct dentry *afs_lookup(struct - * - NOTE! the hit can be a negative hit too, so we can't assume we have an - * inode - */ --static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) -+static int afs_d_revalidate(struct dentry *dentry, struct nameidata2 *nd) - { - struct afs_vnode *vnode, *dir; - struct afs_fid fid; -@@ -905,7 +905,7 @@ error: - * create a regular file on an AFS filesystem - */ - static int afs_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct afs_file_status status; - struct afs_callback cb; ---- a/fs/afs/internal.h -+++ b/fs/afs/internal.h -@@ -461,8 +461,6 @@ extern bool afs_cm_incoming_call(struct - extern const struct inode_operations afs_dir_inode_operations; - extern const struct file_operations afs_dir_file_operations; - --extern int afs_permission(struct inode *, int, struct nameidata *); -- - /* - * file.c - */ -@@ -581,7 +579,7 @@ extern void afs_clear_permits(struct afs - extern void afs_cache_permit(struct afs_vnode *, struct key *, long); - extern void afs_zap_permits(struct rcu_head *); - extern struct key *afs_request_key(struct afs_cell *); --extern int afs_permission(struct inode *, int, struct nameidata *); -+extern int afs_permission(struct inode *, int, struct nameidata2 *); - - /* - * server.c ---- a/fs/afs/mntpt.c -+++ b/fs/afs/mntpt.c -@@ -23,7 +23,7 @@ - - static struct dentry *afs_mntpt_lookup(struct inode *dir, - struct dentry *dentry, -- struct nameidata *nd); -+ struct nameidata2 *nd); - static int afs_mntpt_open(struct inode *inode, struct file *file); - static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd); - static void afs_mntpt_expiry_timed_out(struct work_struct *work); -@@ -103,7 +103,7 @@ out: - */ - static struct dentry *afs_mntpt_lookup(struct inode *dir, - struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - _enter("%p,%p{%p{%s},%s}", - dir, ---- a/fs/afs/security.c -+++ b/fs/afs/security.c -@@ -284,7 +284,7 @@ static int afs_check_permit(struct afs_v - * - AFS ACLs are attached to directories only, and a file is controlled by its - * parent directory's ACL - */ --int afs_permission(struct inode *inode, int mask, struct nameidata *nd) -+int afs_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - struct afs_vnode *vnode = AFS_FS_I(inode); - afs_access_t access; ---- a/fs/autofs/root.c -+++ b/fs/autofs/root.c -@@ -19,7 +19,7 @@ - #include "autofs_i.h" - - static int autofs_root_readdir(struct file *,void *,filldir_t); --static struct dentry *autofs_root_lookup(struct inode *,struct dentry *, struct nameidata *); -+static struct dentry *autofs_root_lookup(struct inode *,struct dentry *, struct nameidata2 *); - static int autofs_root_symlink(struct inode *,struct dentry *,const char *); - static int autofs_root_unlink(struct inode *,struct dentry *); - static int autofs_root_rmdir(struct inode *,struct dentry *); -@@ -145,7 +145,7 @@ static int try_to_fill_dentry(struct den - * yet completely filled in, and revalidate has to delay such - * lookups.. - */ --static int autofs_revalidate(struct dentry * dentry, struct nameidata *nd) -+static int autofs_revalidate(struct dentry * dentry, struct nameidata2 *nd) - { - struct inode * dir; - struct autofs_sb_info *sbi; -@@ -196,7 +196,7 @@ static struct dentry_operations autofs_d - .d_revalidate = autofs_revalidate, - }; - --static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct autofs_sb_info *sbi; - int oz_mode; ---- a/fs/autofs4/root.c -+++ b/fs/autofs4/root.c -@@ -28,7 +28,7 @@ static int autofs4_dir_open(struct inode - static int autofs4_dir_close(struct inode *inode, struct file *file); - static int autofs4_dir_readdir(struct file * filp, void * dirent, filldir_t filldir); - static int autofs4_root_readdir(struct file * filp, void * dirent, filldir_t filldir); --static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); -+static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata2 *); - static void *autofs4_follow_link(struct dentry *, struct nameidata *); - - const struct file_operations autofs4_root_operations = { -@@ -122,7 +122,7 @@ static int autofs4_dir_open(struct inode - - status = -ENOENT; - if (!d_mountpoint(dentry) && dentry->d_op && dentry->d_op->d_revalidate) { -- struct nameidata nd; -+ struct nameidata2 nd; - int empty, ret; - - /* In case there are stale directory dentrys from a failed mount */ -@@ -392,7 +392,7 @@ out_error: - * yet completely filled in, and revalidate has to delay such - * lookups.. - */ --static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd) -+static int autofs4_revalidate(struct dentry *dentry, struct nameidata2 *nd) - { - struct inode *dir = dentry->d_parent->d_inode; - struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); -@@ -565,7 +565,7 @@ next: - } - - /* Lookups in the root directory */ --static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct autofs_sb_info *sbi; - struct dentry *unhashed; ---- a/fs/bad_inode.c -+++ b/fs/bad_inode.c -@@ -193,13 +193,13 @@ static const struct file_operations bad_ - }; - - static int bad_inode_create (struct inode *dir, struct dentry *dentry, -- int mode, struct nameidata *nd) -+ int mode, struct nameidata2 *nd) - { - return -EIO; - } - - static struct dentry *bad_inode_lookup(struct inode *dir, -- struct dentry *dentry, struct nameidata *nd) -+ struct dentry *dentry, struct nameidata2 *nd) - { - return ERR_PTR(-EIO); - } -@@ -251,7 +251,7 @@ static int bad_inode_readlink(struct den - } - - static int bad_inode_permission(struct inode *inode, int mask, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - return -EIO; - } ---- a/fs/befs/linuxvfs.c -+++ b/fs/befs/linuxvfs.c -@@ -34,7 +34,7 @@ static int befs_readdir(struct file *, v - static int befs_get_block(struct inode *, sector_t, struct buffer_head *, int); - static int befs_readpage(struct file *file, struct page *page); - static sector_t befs_bmap(struct address_space *mapping, sector_t block); --static struct dentry *befs_lookup(struct inode *, struct dentry *, struct nameidata *); -+static struct dentry *befs_lookup(struct inode *, struct dentry *, struct nameidata2 *); - static void befs_read_inode(struct inode *ino); - static struct inode *befs_alloc_inode(struct super_block *sb); - static void befs_destroy_inode(struct inode *inode); -@@ -159,7 +159,7 @@ befs_get_block(struct inode *inode, sect - } - - static struct dentry * --befs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+befs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct inode *inode = NULL; - struct super_block *sb = dir->i_sb; ---- a/fs/bfs/dir.c -+++ b/fs/bfs/dir.c -@@ -79,7 +79,7 @@ const struct file_operations bfs_dir_ope - extern void dump_imap(const char *, struct super_block *); - - static int bfs_create(struct inode * dir, struct dentry * dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int err; - struct inode * inode; -@@ -127,7 +127,7 @@ static int bfs_create(struct inode * dir - return 0; - } - --static struct dentry * bfs_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd) -+static struct dentry * bfs_lookup(struct inode * dir, struct dentry * dentry, struct nameidata2 *nd) - { - struct inode * inode = NULL; - struct buffer_head * bh; ---- a/fs/cifs/cifsfs.c -+++ b/fs/cifs/cifsfs.c -@@ -227,7 +227,7 @@ cifs_statfs(struct dentry *dentry, struc - longer available? */ - } - --static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd) -+static int cifs_permission(struct inode * inode, int mask, struct nameidata2 *nd) - { - struct cifs_sb_info *cifs_sb; - ---- a/fs/cifs/cifsfs.h -+++ b/fs/cifs/cifsfs.h -@@ -44,9 +44,9 @@ extern void cifs_read_inode(struct inode - /* Functions related to inodes */ - extern const struct inode_operations cifs_dir_inode_ops; - extern int cifs_create(struct inode *, struct dentry *, int, -- struct nameidata *); -+ struct nameidata2 *); - extern struct dentry * cifs_lookup(struct inode *, struct dentry *, -- struct nameidata *); -+ struct nameidata2 *); - extern int cifs_unlink(struct inode *, struct dentry *); - extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *); - extern int cifs_mknod(struct inode *, struct dentry *, int, dev_t); ---- a/fs/cifs/dir.c -+++ b/fs/cifs/dir.c -@@ -125,7 +125,7 @@ BB remove above eight lines BB */ - - int - cifs_create(struct inode *inode, struct dentry *direntry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int rc = -ENOENT; - int xid; -@@ -439,7 +439,7 @@ int cifs_mknod(struct inode *inode, stru - - struct dentry * - cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int xid; - int rc = 0; /* to get around spurious gcc warning, set to zero here */ -@@ -532,7 +532,7 @@ cifs_lookup(struct inode *parent_dir_ino - } - - static int --cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) -+cifs_d_revalidate(struct dentry *direntry, struct nameidata2 *nd) - { - int isValid = 1; - ---- a/fs/coda/dir.c -+++ b/fs/coda/dir.c -@@ -30,8 +30,8 @@ - #include "coda_int.h" - - /* dir inode-ops */ --static int coda_create(struct inode *dir, struct dentry *new, int mode, struct nameidata *nd); --static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, struct nameidata *nd); -+static int coda_create(struct inode *dir, struct dentry *new, int mode, struct nameidata2 *nd); -+static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, struct nameidata2 *nd); - static int coda_link(struct dentry *old_dentry, struct inode *dir_inode, - struct dentry *entry); - static int coda_unlink(struct inode *dir_inode, struct dentry *entry); -@@ -46,7 +46,7 @@ static int coda_rename(struct inode *old - static int coda_readdir(struct file *file, void *dirent, filldir_t filldir); - - /* dentry ops */ --static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd); -+static int coda_dentry_revalidate(struct dentry *de, struct nameidata2 *nd); - static int coda_dentry_delete(struct dentry *); - - /* support routines */ -@@ -95,7 +95,7 @@ const struct file_operations coda_dir_op - - /* inode operations for directories */ - /* access routines: lookup, readlink, permission */ --static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd) -+static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata2 *nd) - { - struct inode *res_inode = NULL; - struct CodaFid resfid = { { 0, } }; -@@ -152,7 +152,7 @@ exit: - } - - --int coda_permission(struct inode *inode, int mask, struct nameidata *nd) -+int coda_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - int error = 0; - -@@ -195,7 +195,7 @@ static inline void coda_dir_changed(stru - } - - /* creation routines: create, mknod, mkdir, link, symlink */ --static int coda_create(struct inode *dir, struct dentry *de, int mode, struct nameidata *nd) -+static int coda_create(struct inode *dir, struct dentry *de, int mode, struct nameidata2 *nd) - { - int error=0; - const char *name=de->d_name.name; -@@ -590,7 +590,7 @@ static int coda_venus_readdir(struct fil - } - - /* called when a cache lookup succeeds */ --static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd) -+static int coda_dentry_revalidate(struct dentry *de, struct nameidata2 *nd) - { - struct inode *inode = de->d_inode; - struct coda_inode_info *cii; ---- a/fs/coda/pioctl.c -+++ b/fs/coda/pioctl.c -@@ -25,7 +25,7 @@ - - /* pioctl ops */ - static int coda_ioctl_permission(struct inode *inode, int mask, -- struct nameidata *nd); -+ struct nameidata2 *nd); - static int coda_pioctl(struct inode * inode, struct file * filp, - unsigned int cmd, unsigned long user_data); - -@@ -43,7 +43,7 @@ const struct file_operations coda_ioctl_ - - /* the coda pioctl inode ops */ - static int coda_ioctl_permission(struct inode *inode, int mask, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - return 0; - } ---- a/fs/configfs/dir.c -+++ b/fs/configfs/dir.c -@@ -297,7 +297,7 @@ static int configfs_attach_attr(struct c - - static struct dentry * configfs_lookup(struct inode *dir, - struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct configfs_dirent * parent_sd = dentry->d_parent->d_fsdata; - struct configfs_dirent * sd; ---- a/fs/cramfs/inode.c -+++ b/fs/cramfs/inode.c -@@ -405,7 +405,7 @@ static int cramfs_readdir(struct file *f - /* - * Lookup and fill in the inode data.. - */ --static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - unsigned int offset = 0; - int sorted; ---- a/fs/ecryptfs/dentry.c -+++ b/fs/ecryptfs/dentry.c -@@ -41,7 +41,7 @@ - * Returns 1 if valid, 0 otherwise. - * - */ --static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) -+static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata2 *nd) - { - struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); - struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -69,7 +69,7 @@ static void unlock_dir(struct dentry *di - static int - ecryptfs_create_underlying_file(struct inode *lower_dir_inode, - struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); - struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); -@@ -103,7 +103,7 @@ ecryptfs_create_underlying_file(struct i - static int - ecryptfs_do_create(struct inode *directory_inode, - struct dentry *ecryptfs_dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int rc; - struct dentry *lower_dentry; -@@ -248,7 +248,7 @@ out: - */ - static int - ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, -- int mode, struct nameidata *nd) -+ int mode, struct nameidata2 *nd) - { - int rc; - -@@ -275,7 +275,7 @@ out: - * dentry cache and continue on to read it from the disk. - */ - static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int rc = 0; - struct dentry *lower_dir_dentry; -@@ -857,7 +857,7 @@ out: - } - - static int --ecryptfs_permission(struct inode *inode, int mask, struct nameidata *nd) -+ecryptfs_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - int rc; - ---- a/fs/efs/namei.c -+++ b/fs/efs/namei.c -@@ -57,7 +57,7 @@ static efs_ino_t efs_find_entry(struct i - return(0); - } - --struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { -+struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) { - efs_ino_t inodenum; - struct inode * inode = NULL; - ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -141,7 +141,7 @@ asmlinkage long sys_uselib(const char __ - if (!S_ISREG(nd.dentry->d_inode->i_mode)) - goto exit; - -- error = vfs_permission(&nd, MAY_READ | MAY_EXEC); -+ error = vfs_permission(ND2(&nd), MAY_READ | MAY_EXEC); - if (error) - goto exit; - -@@ -173,7 +173,7 @@ asmlinkage long sys_uselib(const char __ - out: - return error; - exit: -- release_open_intent(&nd); -+ release_open_intent(ND2(&nd)); - path_release(&nd); - goto out; - } -@@ -489,7 +489,7 @@ struct file *open_exec(const char *name) - file = ERR_PTR(-EACCES); - if (!(nd.mnt->mnt_flags & MNT_NOEXEC) && - S_ISREG(inode->i_mode)) { -- int err = vfs_permission(&nd, MAY_EXEC); -+ int err = vfs_permission(ND2(&nd), MAY_EXEC); - file = ERR_PTR(err); - if (!err) { - file = nameidata_to_filp(&nd, O_RDONLY); -@@ -504,7 +504,7 @@ out: - return file; - } - } -- release_open_intent(&nd); -+ release_open_intent(ND2(&nd)); - path_release(&nd); - } - goto out; ---- a/fs/ext2/acl.c -+++ b/fs/ext2/acl.c -@@ -294,7 +294,7 @@ ext2_check_acl(struct inode *inode, int - } - - int --ext2_permission(struct inode *inode, int mask, struct nameidata *nd) -+ext2_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - return generic_permission(inode, mask, ext2_check_acl); - } ---- a/fs/ext2/acl.h -+++ b/fs/ext2/acl.h -@@ -58,7 +58,7 @@ static inline int ext2_acl_count(size_t - #define EXT2_ACL_NOT_CACHED ((void *)-1) - - /* acl.c */ --extern int ext2_permission (struct inode *, int, struct nameidata *); -+extern int ext2_permission (struct inode *, int, struct nameidata2 *); - extern int ext2_acl_chmod (struct inode *); - extern int ext2_init_acl (struct inode *, struct inode *); - ---- a/fs/ext2/namei.c -+++ b/fs/ext2/namei.c -@@ -52,7 +52,7 @@ static inline int ext2_add_nondir(struct - * Methods themselves. - */ - --static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) -+static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct inode * inode; - ino_t ino; -@@ -103,7 +103,7 @@ struct dentry *ext2_get_parent(struct de - * If the create succeeds, we fill in the inode information - * with d_instantiate(). - */ --static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd) -+static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata2 *nd) - { - struct inode * inode = ext2_new_inode (dir, mode); - int err = PTR_ERR(inode); ---- a/fs/ext3/acl.c -+++ b/fs/ext3/acl.c -@@ -299,7 +299,7 @@ ext3_check_acl(struct inode *inode, int - } - - int --ext3_permission(struct inode *inode, int mask, struct nameidata *nd) -+ext3_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - return generic_permission(inode, mask, ext3_check_acl); - } ---- a/fs/ext3/acl.h -+++ b/fs/ext3/acl.h -@@ -58,7 +58,7 @@ static inline int ext3_acl_count(size_t - #define EXT3_ACL_NOT_CACHED ((void *)-1) - - /* acl.c */ --extern int ext3_permission (struct inode *, int, struct nameidata *); -+extern int ext3_permission (struct inode *, int, struct nameidata2 *); - extern int ext3_acl_chmod (struct inode *); - extern int ext3_init_acl (handle_t *, struct inode *, struct inode *); - ---- a/fs/ext3/namei.c -+++ b/fs/ext3/namei.c -@@ -996,7 +996,7 @@ errout: - } - #endif - --static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) -+static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct inode * inode; - struct ext3_dir_entry_2 * de; -@@ -1644,7 +1644,7 @@ static int ext3_add_nondir(handle_t *han - * with d_instantiate(). - */ - static int ext3_create (struct inode * dir, struct dentry * dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - handle_t *handle; - struct inode * inode; ---- a/fs/ext4/acl.c -+++ b/fs/ext4/acl.c -@@ -299,7 +299,7 @@ ext4_check_acl(struct inode *inode, int - } - - int --ext4_permission(struct inode *inode, int mask, struct nameidata *nd) -+ext4_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - return generic_permission(inode, mask, ext4_check_acl); - } ---- a/fs/ext4/acl.h -+++ b/fs/ext4/acl.h -@@ -58,7 +58,7 @@ static inline int ext4_acl_count(size_t - #define EXT4_ACL_NOT_CACHED ((void *)-1) - - /* acl.c */ --extern int ext4_permission (struct inode *, int, struct nameidata *); -+extern int ext4_permission (struct inode *, int, struct nameidata2 *); - extern int ext4_acl_chmod (struct inode *); - extern int ext4_init_acl (handle_t *, struct inode *, struct inode *); - ---- a/fs/ext4/namei.c -+++ b/fs/ext4/namei.c -@@ -994,7 +994,7 @@ errout: - } - #endif - --static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) -+static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct inode * inode; - struct ext4_dir_entry_2 * de; -@@ -1642,7 +1642,7 @@ static int ext4_add_nondir(handle_t *han - * with d_instantiate(). - */ - static int ext4_create (struct inode * dir, struct dentry * dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - handle_t *handle; - struct inode * inode; ---- a/fs/freevxfs/vxfs_lookup.c -+++ b/fs/freevxfs/vxfs_lookup.c -@@ -49,7 +49,7 @@ - #define VXFS_BLOCK_PER_PAGE(sbp) ((PAGE_CACHE_SIZE / (sbp)->s_blocksize)) - - --static struct dentry * vxfs_lookup(struct inode *, struct dentry *, struct nameidata *); -+static struct dentry * vxfs_lookup(struct inode *, struct dentry *, struct nameidata2 *); - static int vxfs_readdir(struct file *, void *, filldir_t); - - const struct inode_operations vxfs_dir_inode_ops = { -@@ -202,7 +202,7 @@ vxfs_inode_by_name(struct inode *dip, st - * in the return pointer. - */ - static struct dentry * --vxfs_lookup(struct inode *dip, struct dentry *dp, struct nameidata *nd) -+vxfs_lookup(struct inode *dip, struct dentry *dp, struct nameidata2 *nd) - { - struct inode *ip = NULL; - ino_t ino; ---- a/fs/fuse/dir.c -+++ b/fs/fuse/dir.c -@@ -127,7 +127,7 @@ static void fuse_lookup_init(struct fuse - * the lookup once more. If the lookup results in the same inode, - * then refresh the attributes, timeouts and mark the dentry valid. - */ --static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) -+static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata2 *nd) - { - struct inode *inode = entry->d_inode; - -@@ -220,7 +220,7 @@ static int fuse_d_add_directory(struct d - } - - static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int err; - struct fuse_entry_out outarg; -@@ -303,7 +303,7 @@ static void fuse_sync_release(struct fus - * 'mknod' + 'open' requests. - */ - static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int err; - struct inode *inode; -@@ -483,7 +483,7 @@ static int fuse_mknod(struct inode *dir, - } - - static int fuse_create(struct inode *dir, struct dentry *entry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - if (nd && (nd->flags & LOOKUP_OPEN)) { - int err = fuse_create_open(dir, entry, mode, nd); -@@ -792,7 +792,7 @@ static int fuse_access(struct inode *ino - * access request is sent. Execute permission is still checked - * locally based on file mode. - */ --static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) -+static int fuse_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - struct fuse_conn *fc = get_fuse_conn(inode); - ---- a/fs/gfs2/inode.c -+++ b/fs/gfs2/inode.c -@@ -361,7 +361,7 @@ struct inode *gfs2_lookup_simple(struct - */ - - struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, -- int is_root, struct nameidata *nd) -+ int is_root, struct nameidata2 *nd) - { - struct super_block *sb = dir->i_sb; - struct gfs2_inode *dip = GFS2_I(dir); ---- a/fs/gfs2/inode.h -+++ b/fs/gfs2/inode.h -@@ -41,7 +41,7 @@ int gfs2_inode_refresh(struct gfs2_inode - int gfs2_dinode_dealloc(struct gfs2_inode *inode); - int gfs2_change_nlink(struct gfs2_inode *ip, int diff); - struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, -- int is_root, struct nameidata *nd); -+ int is_root, struct nameidata2 *nd); - struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, - unsigned int mode, dev_t dev); - int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, ---- a/fs/gfs2/ops_dentry.c -+++ b/fs/gfs2/ops_dentry.c -@@ -33,7 +33,7 @@ - * Returns: 1 if the dentry is ok, 0 if it isn't - */ - --static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) -+static int gfs2_drevalidate(struct dentry *dentry, struct nameidata2 *nd) - { - struct dentry *parent = dget_parent(dentry); - struct gfs2_sbd *sdp = GFS2_SB(parent->d_inode); ---- a/fs/gfs2/ops_inode.c -+++ b/fs/gfs2/ops_inode.c -@@ -48,7 +48,7 @@ - */ - - static int gfs2_create(struct inode *dir, struct dentry *dentry, -- int mode, struct nameidata *nd) -+ int mode, struct nameidata2 *nd) - { - struct gfs2_inode *dip = GFS2_I(dir); - struct gfs2_sbd *sdp = GFS2_SB(dir); -@@ -103,7 +103,7 @@ static int gfs2_create(struct inode *dir - */ - - static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct inode *inode = NULL; - -@@ -872,7 +872,7 @@ static void *gfs2_follow_link(struct den - * Returns: errno - */ - --static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd) -+static int gfs2_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_holder i_gh; ---- a/fs/hfs/dir.c -+++ b/fs/hfs/dir.c -@@ -18,7 +18,7 @@ - * hfs_lookup() - */ - static struct dentry *hfs_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - hfs_cat_rec rec; - struct hfs_find_data fd; -@@ -178,7 +178,7 @@ static int hfs_dir_release(struct inode - * the directory and the name (and its length) of the new file. - */ - static int hfs_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct inode *inode; - int res; ---- a/fs/hfs/inode.c -+++ b/fs/hfs/inode.c -@@ -459,7 +459,7 @@ out: - } - - static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct inode *inode = NULL; - hfs_cat_rec rec; -@@ -508,7 +508,7 @@ void hfs_clear_inode(struct inode *inode - } - - static int hfs_permission(struct inode *inode, int mask, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - if (S_ISREG(inode->i_mode) && mask & MAY_EXEC) - return 0; ---- a/fs/hfs/sysdep.c -+++ b/fs/hfs/sysdep.c -@@ -12,7 +12,7 @@ - - /* dentry case-handling: just lowercase everything */ - --static int hfs_revalidate_dentry(struct dentry *dentry, struct nameidata *nd) -+static int hfs_revalidate_dentry(struct dentry *dentry, struct nameidata2 *nd) - { - struct inode *inode = dentry->d_inode; - int diff; ---- a/fs/hfsplus/dir.c -+++ b/fs/hfsplus/dir.c -@@ -25,7 +25,7 @@ static inline void hfsplus_instantiate(s - - /* Find the entry inside dir named dentry->d_name */ - static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct inode *inode = NULL; - struct hfs_find_data fd; -@@ -234,7 +234,7 @@ static int hfsplus_dir_release(struct in - } - - static int hfsplus_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct inode *inode; - int res; ---- a/fs/hfsplus/inode.c -+++ b/fs/hfsplus/inode.c -@@ -132,7 +132,7 @@ const struct address_space_operations hf - }; - - static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct hfs_find_data fd; - struct super_block *sb = dir->i_sb; -@@ -227,7 +227,7 @@ static void hfsplus_set_perms(struct ino - perms->dev = cpu_to_be32(HFSPLUS_I(inode).dev); - } - --static int hfsplus_permission(struct inode *inode, int mask, struct nameidata *nd) -+static int hfsplus_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - /* MAY_EXEC is also used for lookup, if no x bit is set allow lookup, - * open_exec has the same test, so it's still not executable, if a x bit ---- a/fs/hpfs/dir.c -+++ b/fs/hpfs/dir.c -@@ -184,7 +184,7 @@ out: - * to tell read_inode to read fnode or not. - */ - --struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - const char *name = dentry->d_name.name; - unsigned len = dentry->d_name.len; ---- a/fs/hpfs/hpfs_fn.h -+++ b/fs/hpfs/hpfs_fn.h -@@ -238,7 +238,7 @@ void hpfs_set_dentry_operations(struct d - - /* dir.c */ - --struct dentry *hpfs_lookup(struct inode *, struct dentry *, struct nameidata *); -+struct dentry *hpfs_lookup(struct inode *, struct dentry *, struct nameidata2 *); - extern const struct file_operations hpfs_dir_ops; - - /* dnode.c */ ---- a/fs/hpfs/namei.c -+++ b/fs/hpfs/namei.c -@@ -118,7 +118,7 @@ bail: - return err; - } - --static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) -+static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata2 *nd) - { - const char *name = dentry->d_name.name; - unsigned len = dentry->d_name.len; ---- a/fs/hugetlbfs/inode.c -+++ b/fs/hugetlbfs/inode.c -@@ -419,7 +419,7 @@ static int hugetlbfs_mkdir(struct inode - return retval; - } - --static int hugetlbfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) -+static int hugetlbfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata2 *nd) - { - return hugetlbfs_mknod(dir, dentry, mode | S_IFREG, 0); - } ---- a/fs/inotify_user.c -+++ b/fs/inotify_user.c -@@ -349,7 +349,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 = vfs_permission(nd, MAY_READ); -+ error = vfs_permission(ND2(nd), MAY_READ); - if (error) - path_release(nd); - return error; ---- a/fs/isofs/isofs.h -+++ b/fs/isofs/isofs.h -@@ -111,7 +111,7 @@ extern int isofs_name_translate(struct i - int get_joliet_filename(struct iso_directory_record *, unsigned char *, struct inode *); - int get_acorn_filename(struct iso_directory_record *, char *, struct inode *); - --extern struct dentry *isofs_lookup(struct inode *, struct dentry *, struct nameidata *); -+extern struct dentry *isofs_lookup(struct inode *, struct dentry *, struct nameidata2 *); - extern struct buffer_head *isofs_bread(struct inode *, sector_t); - extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long); - ---- a/fs/isofs/namei.c -+++ b/fs/isofs/namei.c -@@ -155,7 +155,7 @@ isofs_find_entry(struct inode *dir, stru - return 0; - } - --struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd) -+struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry, struct nameidata2 *nd) - { - int found; - unsigned long block, offset; ---- a/fs/jffs2/acl.c -+++ b/fs/jffs2/acl.c -@@ -302,7 +302,7 @@ static int jffs2_check_acl(struct inode - return -EAGAIN; - } - --int jffs2_permission(struct inode *inode, int mask, struct nameidata *nd) -+int jffs2_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - return generic_permission(inode, mask, jffs2_check_acl); - } ---- a/fs/jffs2/acl.h -+++ b/fs/jffs2/acl.h -@@ -28,7 +28,7 @@ struct jffs2_acl_header { - - #define JFFS2_ACL_NOT_CACHED ((void *)-1) - --extern int jffs2_permission(struct inode *, int, struct nameidata *); -+extern int jffs2_permission(struct inode *, int, struct nameidata2 *); - extern int jffs2_acl_chmod(struct inode *); - extern int jffs2_init_acl(struct inode *, struct inode *); - extern void jffs2_clear_acl(struct jffs2_inode_info *); ---- a/fs/jffs2/dir.c -+++ b/fs/jffs2/dir.c -@@ -22,9 +22,9 @@ - static int jffs2_readdir (struct file *, void *, filldir_t); - - static int jffs2_create (struct inode *,struct dentry *,int, -- struct nameidata *); -+ struct nameidata2 *); - static struct dentry *jffs2_lookup (struct inode *,struct dentry *, -- struct nameidata *); -+ struct nameidata2 *); - static int jffs2_link (struct dentry *,struct inode *,struct dentry *); - static int jffs2_unlink (struct inode *,struct dentry *); - static int jffs2_symlink (struct inode *,struct dentry *,const char *); -@@ -70,7 +70,7 @@ const struct inode_operations jffs2_dir_ - nice and simple - */ - static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct jffs2_inode_info *dir_f; - struct jffs2_sb_info *c; -@@ -176,7 +176,7 @@ static int jffs2_readdir(struct file *fi - - - static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct jffs2_raw_inode *ri; - struct jffs2_inode_info *f, *dir_f; ---- a/fs/jfs/acl.c -+++ b/fs/jfs/acl.c -@@ -140,7 +140,7 @@ static int jfs_check_acl(struct inode *i - return -EAGAIN; - } - --int jfs_permission(struct inode *inode, int mask, struct nameidata *nd) -+int jfs_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - return generic_permission(inode, mask, jfs_check_acl); - } ---- a/fs/jfs/jfs_acl.h -+++ b/fs/jfs/jfs_acl.h -@@ -20,7 +20,7 @@ - - #ifdef CONFIG_JFS_POSIX_ACL - --int jfs_permission(struct inode *, int, struct nameidata *); -+int jfs_permission(struct inode *, int, struct nameidata2 *); - int jfs_init_acl(tid_t, struct inode *, struct inode *); - int jfs_setattr(struct dentry *, struct iattr *); - ---- a/fs/jfs/namei.c -+++ b/fs/jfs/namei.c -@@ -71,7 +71,7 @@ static inline void free_ea_wmap(struct i - * - */ - static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int rc = 0; - tid_t tid; /* transaction id */ -@@ -1428,7 +1428,7 @@ static int jfs_mknod(struct inode *dir, - return rc; - } - --static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struct nameidata *nd) -+static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struct nameidata2 *nd) - { - struct btstack btstack; - ino_t inum; ---- a/fs/libfs.c -+++ b/fs/libfs.c -@@ -41,7 +41,7 @@ static int simple_delete_dentry(struct d - * Lookup the data. This is trivial - if the dentry didn't already - * exist, we know it is negative. Set d_op to delete negative dentries. - */ --struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - static struct dentry_operations simple_dentry_operations = { - .d_delete = simple_delete_dentry, ---- a/fs/minix/namei.c -+++ b/fs/minix/namei.c -@@ -42,7 +42,7 @@ struct dentry_operations minix_dentry_op - .d_hash = minix_hash, - }; - --static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) -+static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct inode * inode = NULL; - ino_t ino; -@@ -83,7 +83,7 @@ static int minix_mknod(struct inode * di - } - - static int minix_create(struct inode * dir, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - return minix_mknod(dir, dentry, mode, 0); - } ---- a/fs/msdos/namei.c -+++ b/fs/msdos/namei.c -@@ -205,7 +205,7 @@ static struct dentry_operations msdos_de - - /***** Get inode using directory and name */ - static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct super_block *sb = dir->i_sb; - struct fat_slot_info sinfo; -@@ -277,7 +277,7 @@ static int msdos_add_entry(struct inode - - /***** Create a file */ - static int msdos_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct super_block *sb = dir->i_sb; - struct inode *inode = NULL; ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -224,7 +224,7 @@ int generic_permission(struct inode *ino - return -EACCES; - } - --int permission(struct inode *inode, int mask, struct nameidata *nd) -+int permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - umode_t mode = inode->i_mode; - int retval, submask; -@@ -277,7 +277,7 @@ int permission(struct inode *inode, int - * for filesystem access without changing the "normal" uids which - * are used for other things. - */ --int vfs_permission(struct nameidata *nd, int mask) -+int vfs_permission(struct nameidata2 *nd, int mask) - { - return permission(nd->dentry->d_inode, mask, nd); - } -@@ -296,7 +296,7 @@ int vfs_permission(struct nameidata *nd, - */ - int file_permission(struct file *file, int mask) - { -- struct nameidata nd; -+ struct nameidata2 nd; - - nd.dentry = file->f_path.dentry; - nd.mnt = file->f_path.mnt; -@@ -371,7 +371,7 @@ void path_release_on_umount(struct namei - * release_open_intent - free up open intent resources - * @nd: pointer to nameidata - */ --void release_open_intent(struct nameidata *nd) -+void release_open_intent(struct nameidata2 *nd) - { - if (nd->intent.open.file->f_path.dentry == NULL) - put_filp(nd->intent.open.file); -@@ -382,7 +382,7 @@ void release_open_intent(struct nameidat - static inline struct dentry * - do_revalidate(struct dentry *dentry, struct nameidata *nd) - { -- int status = dentry->d_op->d_revalidate(dentry, nd); -+ int status = dentry->d_op->d_revalidate(dentry, ND2(nd)); - if (unlikely(status <= 0)) { - /* - * The dentry failed validation. -@@ -433,8 +433,7 @@ 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, -- struct nameidata *nd) -+static int exec_permission_lite(struct inode *inode, struct nameidata2 *nd) - { - umode_t mode = inode->i_mode; - -@@ -496,7 +495,7 @@ static struct dentry * real_lookup(struc - struct dentry * dentry = d_alloc(parent, name); - result = ERR_PTR(-ENOMEM); - if (dentry) { -- result = dir->i_op->lookup(dir, dentry, nd); -+ result = dir->i_op->lookup(dir, dentry, ND2(nd)); - if (result) - dput(dentry); - else -@@ -835,9 +834,9 @@ static fastcall int __link_path_walk(con - unsigned int c; - - nd->flags |= LOOKUP_CONTINUE; -- err = exec_permission_lite(inode, nd); -+ err = exec_permission_lite(inode, ND2(nd)); - if (err == -EAGAIN) -- err = vfs_permission(nd, MAY_EXEC); -+ err = vfs_permission(ND2(nd), MAY_EXEC); - if (err) - break; - -@@ -983,7 +982,8 @@ return_reval: - (nd->dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) { - err = -ESTALE; - /* Note: we do not d_invalidate() */ -- if (!nd->dentry->d_op->d_revalidate(nd->dentry, nd)) -+ if (!nd->dentry->d_op->d_revalidate(nd->dentry, -+ ND2(nd))) - break; - } - return_base: -@@ -1148,7 +1148,7 @@ static int fastcall do_path_lookup(int d - if (!S_ISDIR(nd->dentry->d_inode->i_mode)) - goto fput_fail; - -- retval = vfs_permission(nd, MAY_EXEC); -+ retval = vfs_permission(ND2(nd), MAY_EXEC); - if (retval) - goto fput_fail; - -@@ -1196,7 +1196,7 @@ static int __path_lookup_intent_open(int - path_release(nd); - } - } else if (err != 0) -- release_open_intent(nd); -+ release_open_intent(ND2(nd)); - return err; - } - -@@ -1270,7 +1270,7 @@ static inline struct dentry *__lookup_ha - dentry = ERR_PTR(-ENOMEM); - if (!new) - goto out; -- dentry = inode->i_op->lookup(inode, new, nd); -+ dentry = inode->i_op->lookup(inode, new, ND2(nd)); - if (!dentry) - dentry = new; - else -@@ -1293,7 +1293,7 @@ static inline struct dentry * __lookup_h - - inode = base->d_inode; - -- err = permission(inode, MAY_EXEC, nd); -+ err = permission(inode, MAY_EXEC, ND2(nd)); - dentry = ERR_PTR(err); - if (err) - goto out; -@@ -1449,7 +1449,7 @@ static int may_delete(struct inode *dir, - * 4. We can't do it if dir is immutable (done in permission()) - */ - static inline int may_create(struct inode *dir, struct dentry *child, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - if (child->d_inode) - return -EEXIST; -@@ -1521,7 +1521,7 @@ void unlock_rename(struct dentry *p1, st - } - - int vfs_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int error = may_create(dir, dentry, nd); - -@@ -1557,7 +1557,7 @@ int may_open(struct nameidata *nd, int a - if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE)) - return -EISDIR; - -- error = vfs_permission(nd, acc_mode); -+ error = vfs_permission(ND2(nd), acc_mode); - if (error) - return error; - -@@ -1630,7 +1630,7 @@ static int open_namei_create(struct name - - if (!IS_POSIXACL(dir->d_inode)) - mode &= ~current->fs->umask; -- error = vfs_create(dir->d_inode, path->dentry, mode, nd); -+ error = vfs_create(dir->d_inode, path->dentry, mode, ND2(nd)); - mutex_unlock(&dir->d_inode->i_mutex); - dput(nd->dentry); - nd->dentry = path->dentry; -@@ -1763,7 +1763,7 @@ exit_dput: - dput_path(&path, nd); - exit: - if (!IS_ERR(nd->intent.open.file)) -- release_open_intent(nd); -+ release_open_intent(ND2(nd)); - path_release(nd); - return error; - -@@ -1791,7 +1791,7 @@ do_link: - * me so stupid? Anathema to whoever designed this non-sense - * with "intent.open". - */ -- release_open_intent(nd); -+ release_open_intent(ND2(nd)); - return error; - } - nd->flags &= ~LOOKUP_PARENT; -@@ -1916,7 +1916,8 @@ asmlinkage long sys_mknodat(int dfd, con - if (!IS_ERR(dentry)) { - switch (mode & S_IFMT) { - case 0: case S_IFREG: -- error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); -+ error = vfs_create(nd.dentry->d_inode, dentry, mode, -+ ND2(&nd)); - break; - case S_IFCHR: case S_IFBLK: - error = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, ---- a/fs/ncpfs/dir.c -+++ b/fs/ncpfs/dir.c -@@ -33,8 +33,8 @@ static void ncp_do_readdir(struct file * - - static int ncp_readdir(struct file *, void *, filldir_t); - --static int ncp_create(struct inode *, struct dentry *, int, struct nameidata *); --static struct dentry *ncp_lookup(struct inode *, struct dentry *, struct nameidata *); -+static int ncp_create(struct inode *, struct dentry *, int, struct nameidata2 *); -+static struct dentry *ncp_lookup(struct inode *, struct dentry *, struct nameidata2 *); - static int ncp_unlink(struct inode *, struct dentry *); - static int ncp_mkdir(struct inode *, struct dentry *, int); - static int ncp_rmdir(struct inode *, struct dentry *); -@@ -74,7 +74,7 @@ const struct inode_operations ncp_dir_in - /* - * Dentry operations routines - */ --static int ncp_lookup_validate(struct dentry *, struct nameidata *); -+static int ncp_lookup_validate(struct dentry *, struct nameidata2 *); - static int ncp_hash_dentry(struct dentry *, struct qstr *); - static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *); - static int ncp_delete_dentry(struct dentry *); -@@ -266,7 +266,7 @@ leave_me:; - - - static int --__ncp_lookup_validate(struct dentry * dentry, struct nameidata *nd) -+__ncp_lookup_validate(struct dentry * dentry, struct nameidata2 *nd) - { - struct ncp_server *server; - struct dentry *parent; -@@ -336,7 +336,7 @@ finished: - } - - static int --ncp_lookup_validate(struct dentry * dentry, struct nameidata *nd) -+ncp_lookup_validate(struct dentry * dentry, struct nameidata2 *nd) - { - int res; - lock_kernel(); -@@ -791,7 +791,7 @@ out: - return result; - } - --static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct ncp_server *server = NCP_SERVER(dir); - struct inode *inode = NULL; -@@ -940,7 +940,7 @@ out: - } - - static int ncp_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - return ncp_create_new(dir, dentry, mode, 0, 0); - } ---- a/fs/nfs/dir.c -+++ b/fs/nfs/dir.c -@@ -43,8 +43,8 @@ - - static int nfs_opendir(struct inode *, struct file *); - static int nfs_readdir(struct file *, void *, filldir_t); --static struct dentry *nfs_lookup(struct inode *, struct dentry *, struct nameidata *); --static int nfs_create(struct inode *, struct dentry *, int, struct nameidata *); -+static struct dentry *nfs_lookup(struct inode *, struct dentry *, struct nameidata2 *); -+static int nfs_create(struct inode *, struct dentry *, int, struct nameidata2 *); - static int nfs_mkdir(struct inode *, struct dentry *, int); - static int nfs_rmdir(struct inode *, struct dentry *); - static int nfs_unlink(struct inode *, struct dentry *); -@@ -103,7 +103,7 @@ const struct inode_operations nfs3_dir_i - - #ifdef CONFIG_NFS_V4 - --static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *); -+static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata2 *); - const struct inode_operations nfs4_dir_inode_operations = { - .create = nfs_create, - .lookup = nfs_atomic_lookup, -@@ -687,7 +687,7 @@ static inline void nfs_renew_times(struc - * component of the path. - * We check for this using LOOKUP_CONTINUE and LOOKUP_PARENT. - */ --static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigned int mask) -+static inline unsigned int nfs_lookup_check_intent(struct nameidata2 *nd, unsigned int mask) - { - if (nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT)) - return 0; -@@ -703,7 +703,7 @@ static inline unsigned int nfs_lookup_ch - * - */ - static inline --int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd) -+int nfs_lookup_verify_inode(struct inode *inode, struct nameidata2 *nd) - { - struct nfs_server *server = NFS_SERVER(inode); - -@@ -732,7 +732,7 @@ out_force: - */ - static inline - int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - /* Don't revalidate a negative dentry if we're creating a new file */ - if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0) -@@ -751,7 +751,7 @@ int nfs_neg_need_reval(struct inode *dir - * If the parent directory is seen to have changed, we throw out the - * cached dentry and do a new lookup. - */ --static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) -+static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata2 *nd) - { - struct inode *dir; - struct inode *inode; -@@ -888,7 +888,7 @@ struct dentry_operations nfs_dentry_oper - * an O_EXCL create using this path component. - */ - static inline --int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) -+int nfs_is_exclusive_create(struct inode *dir, struct nameidata2 *nd) - { - if (NFS_PROTO(dir)->version == 2) - return 0; -@@ -908,7 +908,7 @@ static inline int nfs_reval_fsid(struct - return 0; - } - --static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) -+static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata2 *nd) - { - struct dentry *res; - struct inode *inode = NULL; -@@ -978,7 +978,7 @@ out: - } - - #ifdef CONFIG_NFS_V4 --static int nfs_open_revalidate(struct dentry *, struct nameidata *); -+static int nfs_open_revalidate(struct dentry *, struct nameidata2 *); - - struct dentry_operations nfs4_dentry_operations = { - .d_revalidate = nfs_open_revalidate, -@@ -990,7 +990,7 @@ struct dentry_operations nfs4_dentry_ope - * Use intent information to determine whether we need to substitute - * the NFSv4-style stateful OPEN for the LOOKUP call - */ --static int is_atomic_open(struct inode *dir, struct nameidata *nd) -+static int is_atomic_open(struct inode *dir, struct nameidata2 *nd) - { - if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0) - return 0; -@@ -1003,7 +1003,7 @@ static int is_atomic_open(struct inode * - return 1; - } - --static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct dentry *res = NULL; - int error; -@@ -1072,7 +1072,7 @@ no_open: - return nfs_lookup(dir, dentry, nd); - } - --static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) -+static int nfs_open_revalidate(struct dentry *dentry, struct nameidata2 *nd) - { - struct dentry *parent = NULL; - struct inode *inode = dentry->d_inode; -@@ -1232,7 +1232,7 @@ int nfs_instantiate(struct dentry *dentr - * reply path made it appear to have failed. - */ - static int nfs_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct iattr attr; - int error; -@@ -1955,7 +1955,7 @@ out: - return -EACCES; - } - --int nfs_permission(struct inode *inode, int mask, struct nameidata *nd) -+int nfs_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - struct rpc_cred *cred; - int res = 0; ---- a/fs/nfs/nfs3proc.c -+++ b/fs/nfs/nfs3proc.c -@@ -258,7 +258,7 @@ static int nfs3_proc_readlink(struct ino - */ - static int - nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, -- int flags, struct nameidata *nd) -+ int flags, struct nameidata2 *nd) - { - struct nfs_fh fhandle; - struct nfs_fattr fattr; ---- a/fs/nfs/nfs4_fs.h -+++ b/fs/nfs/nfs4_fs.h -@@ -166,8 +166,8 @@ extern int nfs4_proc_setclientid_confirm - extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *); - extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *); - extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state); --extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); --extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); -+extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata2 *); -+extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata2 *); - extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); - extern int nfs4_proc_fs_locations(struct inode *dir, struct qstr *name, - struct nfs4_fs_locations *fs_locations, struct page *page); ---- a/fs/nfs/nfs4proc.c -+++ b/fs/nfs/nfs4proc.c -@@ -1241,7 +1241,7 @@ out: - return status; - } - --static int nfs4_intent_set_file(struct nameidata *nd, struct dentry *dentry, struct nfs4_state *state) -+static int nfs4_intent_set_file(struct nameidata2 *nd, struct dentry *dentry, struct nfs4_state *state) - { - struct file *filp; - -@@ -1257,7 +1257,7 @@ static int nfs4_intent_set_file(struct n - } - - struct dentry * --nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct iattr attr; - struct rpc_cred *cred; -@@ -1292,7 +1292,7 @@ nfs4_atomic_open(struct inode *dir, stru - } - - int --nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd) -+nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata2 *nd) - { - struct rpc_cred *cred; - struct nfs4_state *state; -@@ -1750,7 +1750,7 @@ static int nfs4_proc_readlink(struct ino - - static int - nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, -- int flags, struct nameidata *nd) -+ int flags, struct nameidata2 *nd) - { - struct nfs4_state *state; - struct rpc_cred *cred; ---- a/fs/nfs/proc.c -+++ b/fs/nfs/proc.c -@@ -187,7 +187,7 @@ static int nfs_proc_readlink(struct inod - - static int - nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, -- int flags, struct nameidata *nd) -+ int flags, struct nameidata2 *nd) - { - struct nfs_fh fhandle; - struct nfs_fattr fattr; ---- a/fs/ntfs/namei.c -+++ b/fs/ntfs/namei.c -@@ -99,7 +99,7 @@ - * Locking: Caller must hold i_mutex on the directory. - */ - static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - ntfs_volume *vol = NTFS_SB(dir_ino->i_sb); - struct inode *dent_inode; ---- a/fs/ocfs2/dcache.c -+++ b/fs/ocfs2/dcache.c -@@ -41,7 +41,7 @@ - - - static int ocfs2_dentry_revalidate(struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct inode *inode = dentry->d_inode; - int ret = 0; /* if all else fails, just return false */ ---- a/fs/ocfs2/dlm/dlmfs.c -+++ b/fs/ocfs2/dlm/dlmfs.c -@@ -459,7 +459,7 @@ bail: - static int dlmfs_create(struct inode *dir, - struct dentry *dentry, - int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int status = 0; - struct inode *inode; ---- a/fs/ocfs2/file.c -+++ b/fs/ocfs2/file.c -@@ -1049,7 +1049,7 @@ bail: - return err; - } - --int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd) -+int ocfs2_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - int ret; - ---- a/fs/ocfs2/file.h -+++ b/fs/ocfs2/file.h -@@ -54,7 +54,7 @@ int ocfs2_setattr(struct dentry *dentry, - int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, - struct kstat *stat); - int ocfs2_permission(struct inode *inode, int mask, -- struct nameidata *nd); -+ struct nameidata2 *nd); - - int ocfs2_should_update_atime(struct inode *inode, - struct vfsmount *vfsmnt); ---- a/fs/ocfs2/namei.c -+++ b/fs/ocfs2/namei.c -@@ -138,7 +138,7 @@ static inline int ocfs2_add_entry(handle - #define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64))) - - static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int status; - u64 blkno; -@@ -626,7 +626,7 @@ static int ocfs2_mkdir(struct inode *dir - static int ocfs2_create(struct inode *dir, - struct dentry *dentry, - int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int ret; - ---- a/fs/open.c -+++ b/fs/open.c -@@ -243,7 +243,7 @@ static long do_sys_truncate(const char _ - if (!S_ISREG(inode->i_mode)) - goto dput_and_out; - -- error = vfs_permission(&nd, MAY_WRITE); -+ error = vfs_permission(ND2(&nd), MAY_WRITE); - if (error) - goto dput_and_out; - -@@ -392,7 +392,7 @@ asmlinkage long sys_faccessat(int dfd, c - if (res) - goto out; - -- res = vfs_permission(&nd, mode); -+ res = vfs_permission(ND2(&nd), mode); - /* SuS v2 requires we report a read only fs too */ - if(res || !(mode & S_IWOTH) || - special_file(nd.dentry->d_inode->i_mode)) -@@ -426,7 +426,7 @@ asmlinkage long sys_chdir(const char __u - if (error) - goto out; - -- error = vfs_permission(&nd, MAY_EXEC); -+ error = vfs_permission(ND2(&nd), MAY_EXEC); - if (error) - goto dput_and_out; - -@@ -440,7 +440,7 @@ out: - - asmlinkage long sys_fchdir(unsigned int fd) - { -- struct nameidata nd; -+ struct nameidata2 nd; - struct file *file; - int error; - -@@ -475,7 +475,7 @@ asmlinkage long sys_chroot(const char __ - if (error) - goto out; - -- error = vfs_permission(&nd, MAY_EXEC); -+ error = vfs_permission(ND2(&nd), MAY_EXEC); - if (error) - goto dput_and_out; - -@@ -796,8 +796,9 @@ EXPORT_SYMBOL(filp_open); - * If the open callback is set to NULL, then the standard f_op->open() - * filesystem callback is substituted. - */ --struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, -- int (*open)(struct inode *, struct file *)) -+struct file *lookup_instantiate_filp(struct nameidata2 *nd, -+ struct dentry *dentry, -+ int (*open)(struct inode *, struct file *)) - { - if (IS_ERR(nd->intent.open.file)) - goto out; ---- a/fs/proc/base.c -+++ b/fs/proc/base.c -@@ -1097,7 +1097,7 @@ static int pid_getattr(struct vfsmount * - * made this apply to all per process world readable and executable - * directories. - */ --static int pid_revalidate(struct dentry *dentry, struct nameidata *nd) -+static int pid_revalidate(struct dentry *dentry, struct nameidata2 *nd) - { - struct inode *inode = dentry->d_inode; - struct task_struct *task = get_proc_task(inode); -@@ -1263,7 +1263,7 @@ static int proc_fd_link(struct inode *in - return proc_fd_info(inode, dentry, mnt, NULL); - } - --static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) -+static int tid_fd_revalidate(struct dentry *dentry, struct nameidata2 *nd) - { - struct inode *inode = dentry->d_inode; - struct task_struct *task = get_proc_task(inode); -@@ -1441,7 +1441,7 @@ out_no_task: - } - - static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - return proc_lookupfd_common(dir, dentry, proc_fd_instantiate); - } -@@ -1476,7 +1476,7 @@ static const struct file_operations proc - * access /proc/self/fd after it has executed a setuid(). - */ - static int proc_fd_permission(struct inode *inode, int mask, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int rv; - -@@ -1524,7 +1524,7 @@ static struct dentry *proc_fdinfo_instan - - static struct dentry *proc_lookupfdinfo(struct inode *dir, - struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate); - } -@@ -1769,7 +1769,7 @@ static const struct file_operations proc - }; - - static struct dentry *proc_attr_dir_lookup(struct inode *dir, -- struct dentry *dentry, struct nameidata *nd) -+ struct dentry *dentry, struct nameidata2 *nd) - { - return proc_pident_lookup(dir, dentry, - attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff)); -@@ -1823,7 +1823,7 @@ static const struct pid_entry proc_base_ - * directory. In this case, however, we can do it - no aliasing problems - * due to the way we treat inodes. - */ --static int proc_base_revalidate(struct dentry *dentry, struct nameidata *nd) -+static int proc_base_revalidate(struct dentry *dentry, struct nameidata2 *nd) - { - struct inode *inode = dentry->d_inode; - struct task_struct *task = get_proc_task(inode); -@@ -2020,7 +2020,7 @@ static const struct file_operations proc - .readdir = proc_tgid_base_readdir, - }; - --static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ -+static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd){ - return proc_pident_lookup(dir, dentry, - tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff)); - } -@@ -2128,7 +2128,7 @@ out: - return error; - } - --struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) -+struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata2 *nd) - { - struct dentry *result = ERR_PTR(-ENOENT); - struct task_struct *task; -@@ -2295,7 +2295,7 @@ static int proc_tid_base_readdir(struct - tid_base_stuff,ARRAY_SIZE(tid_base_stuff)); - } - --static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ -+static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd){ - return proc_pident_lookup(dir, dentry, - tid_base_stuff, ARRAY_SIZE(tid_base_stuff)); - } -@@ -2339,7 +2339,7 @@ out: - return error; - } - --static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) -+static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata2 *nd) - { - struct dentry *result = ERR_PTR(-ENOENT); - struct task_struct *task; ---- a/fs/proc/generic.c -+++ b/fs/proc/generic.c -@@ -382,7 +382,7 @@ static struct dentry_operations proc_den - * Don't create negative dentries here, return -ENOENT by hand - * instead. - */ --struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) -+struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct inode *inode = NULL; - struct proc_dir_entry * de; ---- a/fs/proc/proc_sysctl.c -+++ b/fs/proc/proc_sysctl.c -@@ -139,7 +139,7 @@ static struct ctl_table *do_proc_sys_loo - } - - static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct ctl_table_header *head; - struct inode *inode; -@@ -369,7 +369,7 @@ out: - return ret; - } - --static int proc_sys_permission(struct inode *inode, int mask, struct nameidata *nd) -+static int proc_sys_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - /* - * sysctl entries that are not writeable, -@@ -450,7 +450,7 @@ static struct inode_operations proc_sys_ - .setattr = proc_sys_setattr, - }; - --static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd) -+static int proc_sys_revalidate(struct dentry *dentry, struct nameidata2 *nd) - { - struct ctl_table_header *head; - struct ctl_table *table; ---- a/fs/proc/root.c -+++ b/fs/proc/root.c -@@ -90,7 +90,7 @@ static int proc_root_getattr(struct vfsm - return 0; - } - --static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd) -+static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata2 *nd) - { - if (!proc_lookup(dir, dentry, nd)) { - return NULL; ---- a/fs/qnx4/namei.c -+++ b/fs/qnx4/namei.c -@@ -106,7 +106,7 @@ static struct buffer_head *qnx4_find_ent - return NULL; - } - --struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - int ino; - struct qnx4_inode_entry *de; ---- a/fs/ramfs/inode.c -+++ b/fs/ramfs/inode.c -@@ -116,7 +116,7 @@ static int ramfs_mkdir(struct inode * di - return retval; - } - --static int ramfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) -+static int ramfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata2 *nd) - { - return ramfs_mknod(dir, dentry, mode | S_IFREG, 0); - } ---- a/fs/reiserfs/namei.c -+++ b/fs/reiserfs/namei.c -@@ -324,7 +324,7 @@ static int reiserfs_find_entry(struct in - } - - static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int retval; - struct inode *inode = NULL; -@@ -600,7 +600,7 @@ static int new_inode_init(struct inode * - } - - static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int retval; - struct inode *inode; ---- a/fs/reiserfs/xattr.c -+++ b/fs/reiserfs/xattr.c -@@ -1294,7 +1294,7 @@ static int reiserfs_check_acl(struct ino - return error; - } - --int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd) -+int reiserfs_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - /* - * We don't do permission checks on the internal objects. ---- a/fs/romfs/inode.c -+++ b/fs/romfs/inode.c -@@ -332,7 +332,7 @@ out: - } - - static struct dentry * --romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - unsigned long offset, maxoff; - int fslen, res; ---- a/fs/smbfs/dir.c -+++ b/fs/smbfs/dir.c -@@ -25,8 +25,8 @@ - static int smb_readdir(struct file *, void *, filldir_t); - static int smb_dir_open(struct inode *, struct file *); - --static struct dentry *smb_lookup(struct inode *, struct dentry *, struct nameidata *); --static int smb_create(struct inode *, struct dentry *, int, struct nameidata *); -+static struct dentry *smb_lookup(struct inode *, struct dentry *, struct nameidata2 *); -+static int smb_create(struct inode *, struct dentry *, int, struct nameidata2 *); - static int smb_mkdir(struct inode *, struct dentry *, int); - static int smb_rmdir(struct inode *, struct dentry *); - static int smb_unlink(struct inode *, struct dentry *); -@@ -272,7 +272,7 @@ smb_dir_open(struct inode *dir, struct f - /* - * Dentry operations routines - */ --static int smb_lookup_validate(struct dentry *, struct nameidata *); -+static int smb_lookup_validate(struct dentry *, struct nameidata2 *); - static int smb_hash_dentry(struct dentry *, struct qstr *); - static int smb_compare_dentry(struct dentry *, struct qstr *, struct qstr *); - static int smb_delete_dentry(struct dentry *); -@@ -296,7 +296,7 @@ static struct dentry_operations smbfs_de - * This is the callback when the dcache has a lookup hit. - */ - static int --smb_lookup_validate(struct dentry * dentry, struct nameidata *nd) -+smb_lookup_validate(struct dentry * dentry, struct nameidata2 *nd) - { - struct smb_sb_info *server = server_from_dentry(dentry); - struct inode * inode = dentry->d_inode; -@@ -424,7 +424,7 @@ smb_renew_times(struct dentry * dentry) - } - - static struct dentry * --smb_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+smb_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct smb_fattr finfo; - struct inode *inode; -@@ -520,7 +520,7 @@ out_close: - /* N.B. How should the mode argument be used? */ - static int - smb_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct smb_sb_info *server = server_from_dentry(dentry); - __u16 fileid; ---- a/fs/smbfs/file.c -+++ b/fs/smbfs/file.c -@@ -390,7 +390,7 @@ smb_file_release(struct inode *inode, st - * privileges, so we need our own check for this. - */ - static int --smb_file_permission(struct inode *inode, int mask, struct nameidata *nd) -+smb_file_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - int mode = inode->i_mode; - int error = 0; ---- a/fs/sysfs/dir.c -+++ b/fs/sysfs/dir.c -@@ -299,7 +299,7 @@ static int sysfs_attach_link(struct sysf - } - - static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata; - struct sysfs_dirent * sd; ---- a/fs/sysv/namei.c -+++ b/fs/sysv/namei.c -@@ -42,7 +42,7 @@ struct dentry_operations sysv_dentry_ope - .d_hash = sysv_hash, - }; - --static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd) -+static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, struct nameidata2 *nd) - { - struct inode * inode = NULL; - ino_t ino; -@@ -80,7 +80,7 @@ static int sysv_mknod(struct inode * dir - return err; - } - --static int sysv_create(struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd) -+static int sysv_create(struct inode * dir, struct dentry * dentry, int mode, struct nameidata2 *nd) - { - return sysv_mknod(dir, dentry, mode, 0); - } ---- a/fs/udf/namei.c -+++ b/fs/udf/namei.c -@@ -294,7 +294,7 @@ udf_find_entry(struct inode *dir, struct - */ - - static struct dentry * --udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -+udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct inode *inode = NULL; - struct fileIdentDesc cfi; -@@ -615,7 +615,7 @@ static int udf_delete_entry(struct inode - return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL); - } - --static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) -+static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata2 *nd) - { - struct udf_fileident_bh fibh; - struct inode *inode; ---- a/fs/ufs/namei.c -+++ b/fs/ufs/namei.c -@@ -46,7 +46,7 @@ static inline int ufs_add_nondir(struct - return err; - } - --static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) -+static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, struct nameidata2 *nd) - { - struct inode * inode = NULL; - ino_t ino; -@@ -77,7 +77,7 @@ static struct dentry *ufs_lookup(struct - * with d_instantiate(). - */ - static int ufs_create (struct inode * dir, struct dentry * dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct inode *inode; - int err; ---- a/fs/utimes.c -+++ b/fs/utimes.c -@@ -108,7 +108,7 @@ long do_utimes(int dfd, char __user *fil - goto dput_and_out; - - if (current->fsuid != inode->i_uid && -- (error = vfs_permission(&nd, MAY_WRITE)) != 0) -+ (error = vfs_permission(ND2(&nd), MAY_WRITE)) != 0) - goto dput_and_out; - } - mutex_lock(&inode->i_mutex); ---- a/fs/vfat/namei.c -+++ b/fs/vfat/namei.c -@@ -25,7 +25,7 @@ - #include - #include - --static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd) -+static int vfat_revalidate(struct dentry *dentry, struct nameidata2 *nd) - { - int ret = 1; - -@@ -684,7 +684,7 @@ static int vfat_find(struct inode *dir, - } - - static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct super_block *sb = dir->i_sb; - struct fat_slot_info sinfo; -@@ -731,7 +731,7 @@ error: - } - - static int vfat_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - struct super_block *sb = dir->i_sb; - struct inode *inode; ---- a/fs/xfs/linux-2.6/xfs_iops.c -+++ b/fs/xfs/linux-2.6/xfs_iops.c -@@ -367,7 +367,7 @@ xfs_vn_create( - struct inode *dir, - struct dentry *dentry, - int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - return xfs_vn_mknod(dir, dentry, mode, 0); - } -@@ -385,7 +385,7 @@ STATIC struct dentry * - xfs_vn_lookup( - struct inode *dir, - struct dentry *dentry, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - bhv_vnode_t *vp = vn_from_inode(dir), *cvp; - int error; -@@ -605,7 +605,7 @@ STATIC int - xfs_vn_permission( - struct inode *inode, - int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - return -bhv_vop_access(vn_from_inode(inode), mode << 6, NULL); - } ---- a/include/linux/coda_linux.h -+++ b/include/linux/coda_linux.h -@@ -38,7 +38,7 @@ extern const struct file_operations coda - int coda_open(struct inode *i, struct file *f); - int coda_flush(struct file *f, fl_owner_t id); - int coda_release(struct inode *i, struct file *f); --int coda_permission(struct inode *inode, int mask, struct nameidata *nd); -+int coda_permission(struct inode *inode, int mask, struct nameidata2 *nd); - int coda_revalidate_inode(struct dentry *); - int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *); - int coda_setattr(struct dentry *, struct iattr *); ---- a/include/linux/dcache.h -+++ b/include/linux/dcache.h -@@ -10,6 +10,7 @@ - #include - - struct nameidata; -+struct nameidata2; - struct vfsmount; - - /* -@@ -127,7 +128,7 @@ enum dentry_d_lock_class - }; - - struct dentry_operations { -- int (*d_revalidate)(struct dentry *, struct nameidata *); -+ int (*d_revalidate)(struct dentry *, struct nameidata2 *); - int (*d_hash) (struct dentry *, struct qstr *); - int (*d_compare) (struct dentry *, struct qstr *, struct qstr *); - int (*d_delete)(struct dentry *); ---- a/include/linux/efs_fs.h -+++ b/include/linux/efs_fs.h -@@ -44,7 +44,7 @@ extern void efs_read_inode(struct inode - extern efs_block_t efs_map_block(struct inode *, efs_block_t); - extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int); - --extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *); -+extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata2 *); - extern struct dentry *efs_get_parent(struct dentry *); - extern int efs_bmap(struct inode *, int); - ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -291,6 +291,7 @@ extern int dir_notify_enable; - struct hd_geometry; - struct iovec; - struct nameidata; -+struct nameidata2; - struct kiocb; - struct pipe_inode_info; - struct poll_table_struct; -@@ -994,8 +995,8 @@ extern void unlock_super(struct super_bl - /* - * VFS helper functions.. - */ --extern int vfs_permission(struct nameidata *, int); --extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *); -+extern int vfs_permission(struct nameidata2 *, int); -+extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata2 *); - extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int); - extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t); - extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *, int); -@@ -1119,8 +1120,8 @@ struct file_operations { - }; - - struct inode_operations { -- int (*create) (struct inode *,struct dentry *,int, struct nameidata *); -- struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); -+ int (*create) (struct inode *,struct dentry *,int, struct nameidata2 *); -+ struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata2 *); - int (*link) (struct dentry *,struct inode *,struct dentry *); - int (*unlink) (struct inode *,struct dentry *); - int (*symlink) (struct inode *,struct dentry *,const char *); -@@ -1133,7 +1134,7 @@ struct inode_operations { - void * (*follow_link) (struct dentry *, struct nameidata *); - void (*put_link) (struct dentry *, struct nameidata *, void *); - void (*truncate) (struct inode *); -- int (*permission) (struct inode *, int, struct nameidata *); -+ int (*permission) (struct inode *, int, struct nameidata2 *); - int (*setattr) (struct dentry *, struct iattr *); - int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); - int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); -@@ -1656,7 +1657,7 @@ extern int do_remount_sb(struct super_bl - extern sector_t bmap(struct inode *, sector_t); - #endif - extern int notify_change(struct dentry *, struct vfsmount *, struct iattr *); --extern int permission(struct inode *, int, struct nameidata *); -+extern int permission(struct inode *, int, struct nameidata2 *); - extern int generic_permission(struct inode *, int, - int (*check_acl)(struct inode *, int)); - -@@ -1915,7 +1916,7 @@ extern int simple_prepare_write(struct f - extern int simple_commit_write(struct file *file, struct page *page, - unsigned offset, unsigned to); - --extern struct dentry *simple_lookup(struct inode *, struct dentry *, struct nameidata *); -+extern struct dentry *simple_lookup(struct inode *, struct dentry *, struct nameidata2 *); - extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *); - extern const struct file_operations simple_dir_operations; - extern const struct inode_operations simple_dir_inode_operations; ---- a/include/linux/namei.h -+++ b/include/linux/namei.h -@@ -14,21 +14,39 @@ struct open_intent { - - enum { MAX_NESTED_LINKS = 8 }; - -+/** -+ * Fields shared between nameidata and nameidata2 -- nameidata2 could -+ * simply be embedded in nameidata, but then the vfs code would become -+ * cluttered with dereferences. -+ */ -+#define __NAMEIDATA2 \ -+ struct dentry *dentry; \ -+ struct vfsmount *mnt; \ -+ unsigned int flags; \ -+ \ -+ union { \ -+ struct open_intent open; \ -+ } intent; -+ - struct nameidata { -- struct dentry *dentry; -- struct vfsmount *mnt; -+ struct { __NAMEIDATA2 }; - struct qstr last; -- unsigned int flags; - int last_type; - unsigned depth; - char *saved_names[MAX_NESTED_LINKS + 1]; -+}; - -- /* Intent data */ -- union { -- struct open_intent open; -- } intent; -+struct nameidata2 { -+ __NAMEIDATA2 - }; - -+#undef __NAMEIDATA2 -+ -+static inline struct nameidata2 *ND2(struct nameidata *nd) -+{ -+ return container_of(&nd->dentry, struct nameidata2, dentry); -+} -+ - struct path { - struct vfsmount *mnt; - struct dentry *dentry; -@@ -76,10 +94,9 @@ extern void path_release_on_umount(struc - - extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags); - extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags); --extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, -- int (*open)(struct inode *, struct file *)); -+extern struct file *lookup_instantiate_filp(struct nameidata2 *nd, struct dentry *dentry, int (*open)(struct inode *, struct file *)); - extern struct file *nameidata_to_filp(struct nameidata *nd, int flags); --extern void release_open_intent(struct nameidata *); -+extern void release_open_intent(struct nameidata2 *); - - extern struct dentry * lookup_one_len(const char *, struct dentry *, int); - extern struct dentry *lookup_one_len_kern(const char *, struct dentry *, int); ---- a/include/linux/nfs_fs.h -+++ b/include/linux/nfs_fs.h -@@ -290,7 +290,7 @@ extern struct inode *nfs_fhget(struct su - extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *); - extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr); - extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); --extern int nfs_permission(struct inode *, int, struct nameidata *); -+extern int nfs_permission(struct inode *, int, struct nameidata2 *); - extern int nfs_access_get_cached(struct inode *, struct rpc_cred *, struct nfs_access_entry *); - extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *); - extern void nfs_access_zap_cache(struct inode *inode); ---- a/include/linux/nfs_xdr.h -+++ b/include/linux/nfs_xdr.h -@@ -785,7 +785,7 @@ struct nfs_rpc_ops { - int (*readlink)(struct inode *, struct page *, unsigned int, - unsigned int); - int (*create) (struct inode *, struct dentry *, -- struct iattr *, int, struct nameidata *); -+ struct iattr *, int, struct nameidata2 *); - int (*remove) (struct inode *, struct qstr *); - int (*unlink_setup) (struct rpc_message *, - struct dentry *, struct qstr *); ---- a/include/linux/proc_fs.h -+++ b/include/linux/proc_fs.h -@@ -99,7 +99,7 @@ extern void proc_misc_init(void); - struct mm_struct; - - void proc_flush_task(struct task_struct *task); --struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *); -+struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata2 *); - int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir); - unsigned long task_vsize(struct mm_struct *); - int task_statm(struct mm_struct *, int *, int *, int *, int *); -@@ -125,7 +125,7 @@ extern struct inode *proc_get_inode(stru - * of the /proc/ subdirectories. - */ - extern int proc_readdir(struct file *, void *, filldir_t); --extern struct dentry *proc_lookup(struct inode *, struct dentry *, struct nameidata *); -+extern struct dentry *proc_lookup(struct inode *, struct dentry *, struct nameidata2 *); - - extern const struct file_operations proc_kcore_operations; - extern const struct file_operations proc_kmsg_operations; ---- a/include/linux/qnx4_fs.h -+++ b/include/linux/qnx4_fs.h -@@ -110,7 +110,7 @@ struct qnx4_inode_info { - struct inode vfs_inode; - }; - --extern struct dentry *qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd); -+extern struct dentry *qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata2 *nd); - extern unsigned long qnx4_count_free_blocks(struct super_block *sb); - extern unsigned long qnx4_block_map(struct inode *inode, long iblock); - ---- a/include/linux/reiserfs_xattr.h -+++ b/include/linux/reiserfs_xattr.h -@@ -55,7 +55,7 @@ int reiserfs_removexattr(struct dentry * - int reiserfs_delete_xattrs(struct inode *inode); - int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs); - int reiserfs_xattr_init(struct super_block *sb, int mount_flags); --int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd); -+int reiserfs_permission(struct inode *inode, int mask, struct nameidata2 *nd); - - int reiserfs_xattr_del(struct inode *, const char *); - int reiserfs_xattr_get(const struct inode *, const char *, void *, size_t); ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -1237,7 +1237,7 @@ struct security_operations { - struct vfsmount *new_mnt); - int (*inode_readlink) (struct dentry *dentry, struct vfsmount *mnt); - int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); -- int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd); -+ int (*inode_permission) (struct inode *inode, int mask, struct nameidata2 *nd); - int (*inode_setattr) (struct dentry *dentry, struct vfsmount *mnt, - struct iattr *attr); - int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry); -@@ -1735,7 +1735,7 @@ static inline int security_inode_follow_ - } - - static inline int security_inode_permission (struct inode *inode, int mask, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - if (unlikely (IS_PRIVATE (inode))) - return 0; -@@ -2464,7 +2464,7 @@ static inline int security_inode_follow_ - } - - static inline int security_inode_permission (struct inode *inode, int mask, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - return 0; - } ---- a/include/linux/shmem_fs.h -+++ b/include/linux/shmem_fs.h -@@ -41,7 +41,7 @@ static inline struct shmem_inode_info *S - } - - #ifdef CONFIG_TMPFS_POSIX_ACL --int shmem_permission(struct inode *, int, struct nameidata *); -+int shmem_permission(struct inode *, int, struct nameidata2 *); - int shmem_acl_init(struct inode *, struct inode *); - void shmem_acl_destroy_inode(struct inode *); - ---- a/ipc/mqueue.c -+++ b/ipc/mqueue.c -@@ -266,7 +266,7 @@ static void mqueue_delete_inode(struct i - } - - static int mqueue_create(struct inode *dir, struct dentry *dentry, -- int mode, struct nameidata *nd) -+ int mode, struct nameidata2 *nd) - { - struct inode *inode; - struct mq_attr *attr = dentry->d_fsdata; ---- a/mm/shmem.c -+++ b/mm/shmem.c -@@ -1798,7 +1798,7 @@ static int shmem_mkdir(struct inode *dir - } - - static int shmem_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - return shmem_mknod(dir, dentry, mode | S_IFREG, 0); - } ---- a/mm/shmem_acl.c -+++ b/mm/shmem_acl.c -@@ -191,7 +191,7 @@ shmem_check_acl(struct inode *inode, int - * shmem_permission - permission() inode operation - */ - int --shmem_permission(struct inode *inode, int mask, struct nameidata *nd) -+shmem_permission(struct inode *inode, int mask, struct nameidata2 *nd) - { - return generic_permission(inode, mask, shmem_check_acl); - } ---- a/net/unix/af_unix.c -+++ b/net/unix/af_unix.c -@@ -702,7 +702,7 @@ static struct sock *unix_find_other(stru - err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd); - if (err) - goto fail; -- err = vfs_permission(&nd, MAY_WRITE); -+ err = vfs_permission(ND2(&nd), MAY_WRITE); - if (err) - goto put_fail; - ---- a/security/apparmor/lsm.c -+++ b/security/apparmor/lsm.c -@@ -391,7 +391,7 @@ out: - } - - static int apparmor_inode_permission(struct inode *inode, int mask, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int check = 0; - ---- a/security/dummy.c -+++ b/security/dummy.c -@@ -329,7 +329,7 @@ static int dummy_inode_follow_link (stru - return 0; - } - --static int dummy_inode_permission (struct inode *inode, int mask, struct nameidata *nd) -+static int dummy_inode_permission (struct inode *inode, int mask, struct nameidata2 *nd) - { - return 0; - } ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -2239,7 +2239,7 @@ static int selinux_inode_follow_link(str - } - - static int selinux_inode_permission(struct inode *inode, int mask, -- struct nameidata *nd) -+ struct nameidata2 *nd) - { - int rc; - diff --git a/kernel-patches/for-mainline/split_init.diff b/kernel-patches/for-mainline/split_init.diff deleted file mode 100644 index 0e31f3f48..000000000 --- a/kernel-patches/for-mainline/split_init.diff +++ /dev/null @@ -1,215 +0,0 @@ ---- - security/apparmor/Kconfig | 15 ++++++ - security/apparmor/apparmor.h | 5 ++ - security/apparmor/apparmorfs.c | 8 +++ - security/apparmor/lsm.c | 95 ++++++++++++++++++++++++++++++++++------- - 4 files changed, 109 insertions(+), 14 deletions(-) - ---- a/security/apparmor/Kconfig -+++ b/security/apparmor/Kconfig -@@ -25,3 +25,18 @@ config SECURITY_APPARMOR_BOOTPARAM_VALUE - bootup. - - If you are unsure how to answer this question, answer 1. -+ -+config SECURITY_APPARMOR_DISABLE -+ bool "AppArmor runtime disable" -+ depends on SECURITY_APPARMOR -+ default n -+ help -+ This option enables writing to a apparmorfs node 'disable', which -+ allows AppArmor to be disabled at runtime prior to the policy load. -+ AppArmor will then remain disabled until the next boot. -+ This option is similar to the apparmor.enabled=0 boot parameter, -+ but is to support runtime disabling of AppArmor, e.g. from -+ /sbin/init, for portability across platforms where boot -+ parameters are difficult to employ. -+ -+ If you are unsure how to answer this question, answer N. ---- a/security/apparmor/apparmor.h -+++ b/security/apparmor/apparmor.h -@@ -284,6 +284,11 @@ extern int aa_net_perm(struct aa_profile - int family, int type, int protocol); - extern int aa_revalidate_sk(struct sock *sk, char *operation); - -+/* lsm.c */ -+extern int apparmor_initialized; -+extern void info_message(const char *str); -+extern void apparmor_disable(void); -+ - /* list.c */ - extern struct aa_namespace *__aa_find_namespace(const char *name, - struct list_head *list); ---- a/security/apparmor/apparmorfs.c -+++ b/security/apparmor/apparmorfs.c -@@ -231,6 +231,9 @@ int create_apparmorfs(void) - { - int error; - -+ if (!apparmor_initialized) -+ return 0; -+ - if (apparmor_dentry) { - AA_ERROR("%s: AppArmor securityfs already exists\n", - __FUNCTION__); -@@ -262,11 +265,16 @@ int create_apparmorfs(void) - if (error) - goto error; - -+ /* Report that AppArmor fs is enabled */ -+ info_message("AppArmor Filesystem Enabled"); - return 0; - - error: - destroy_apparmorfs(); - AA_ERROR("Error creating AppArmor securityfs\n"); -+ apparmor_disable(); - return error; - } - -+fs_initcall(create_apparmorfs); -+ ---- a/security/apparmor/lsm.c -+++ b/security/apparmor/lsm.c -@@ -23,16 +23,8 @@ - #include "apparmor.h" - #include "inline.h" - --/* Boot time disable flag */ --int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE; -- --static int __init apparmor_enabled_setup(char *str) --{ -- apparmor_enabled = simple_strtol(str, NULL, 0); -- return 1; --} --__setup("apparmor=", apparmor_enabled_setup); -- -+/* Flag indicating whether initialization completed */ -+int apparmor_initialized = 0; - - static int param_set_aabool(const char *val, struct kernel_param *kp); - static int param_get_aabool(char *buffer, struct kernel_param *kp); -@@ -75,6 +67,25 @@ unsigned int apparmor_path_max = 2 * PAT - module_param_named(path_max, apparmor_path_max, aauint, S_IRUSR | S_IWUSR); - MODULE_PARM_DESC(apparmor_path_max, "Maximum pathname length allowed"); - -+/* Boot time disable flag */ -+#ifdef CONFIG_SECURITY_APPARMOR_DISABLE -+#define AA_ENABLED_PERMS 0600 -+#else -+#define AA_ENABLED_PERMS 0400 -+#endif -+static int param_set_aa_enabled(const char *val, struct kernel_param *kp); -+unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE; -+module_param_call(enabled, param_set_aa_enabled, param_get_aauint, -+ &apparmor_enabled, AA_ENABLED_PERMS); -+MODULE_PARM_DESC(apparmor_enabled, "Enable/Disable Apparmor on boot"); -+ -+static int __init apparmor_enabled_setup(char *str) -+{ -+ apparmor_enabled = simple_strtol(str, NULL, 0); -+ return 1; -+} -+__setup("apparmor=", apparmor_enabled_setup); -+ - static int param_set_aabool(const char *val, struct kernel_param *kp) - { - if (aa_task_context(current)) -@@ -103,6 +114,35 @@ static int param_get_aauint(char *buffer - return param_get_uint(buffer, kp); - } - -+/* allow run time disabling of apparmor */ -+static int param_set_aa_enabled(const char *val, struct kernel_param *kp) -+{ -+ char *endp; -+ unsigned long l; -+ -+ if (!apparmor_initialized) { -+ apparmor_enabled = 0; -+ return 0; -+ } -+ -+ if (aa_task_context(current)) -+ return -EPERM; -+ -+ if (!apparmor_enabled) -+ return -EINVAL; -+ -+ if (!val) -+ return -EINVAL; -+ -+ l = simple_strtoul(val, &endp, 0); -+ if (endp == val || l != 0) -+ return -EINVAL; -+ -+ apparmor_enabled = 0; -+ apparmor_disable(); -+ return 0; -+} -+ - static int aa_reject_syscall(struct task_struct *task, gfp_t flags, - const char *name) - { -@@ -879,14 +919,15 @@ struct security_operations apparmor_ops - .socket_shutdown = apparmor_socket_shutdown, - }; - --static void info_message(const char *str) -+void info_message(const char *str) - { - struct aa_audit sa; - memset(&sa, 0, sizeof(sa)); - sa.gfp_mask = GFP_KERNEL; - sa.info = str; -- printk(KERN_INFO "AppArmor: %s", str); -- aa_audit_message(NULL, &sa, AUDIT_APPARMOR_STATUS); -+ printk(KERN_INFO "AppArmor: %s\n", str); -+ if (audit_enabled) -+ aa_audit_message(NULL, &sa, AUDIT_APPARMOR_STATUS); - } - - static int __init apparmor_init(void) -@@ -913,6 +954,8 @@ static int __init apparmor_init(void) - goto register_security_out; - } - -+ /* Report that AppArmor successfully initialized */ -+ apparmor_initialized = 1; - if (apparmor_complain) - info_message("AppArmor initialized: complainmode enabled"); - else -@@ -931,7 +974,31 @@ createfs_out: - - } - --module_init(apparmor_init); -+security_initcall(apparmor_init); -+ -+void apparmor_disable(void) -+{ -+ /* Remove and release all the profiles on the profile list. */ -+ mutex_lock(&aa_interface_lock); -+ aa_profile_ns_list_release(); -+ -+ /* FIXME: cleanup profiles references on files */ -+ free_default_namespace(); -+ -+ /* -+ * Delay for an rcu cycle to make sure that all active task -+ * context readers have finished, and all profiles have been -+ * freed by their rcu callbacks. -+ */ -+ synchronize_rcu(); -+ -+ destroy_apparmorfs(); -+ mutex_unlock(&aa_interface_lock); -+ -+ apparmor_initialized = 0; -+ -+ info_message("AppArmor protection removed"); -+} - - MODULE_DESCRIPTION("AppArmor process confinement"); - MODULE_AUTHOR("Novell/Immunix, http://bugs.opensuse.org"); diff --git a/kernel-patches/for-mainline/statvfs-2.diff b/kernel-patches/for-mainline/statvfs-2.diff deleted file mode 100644 index 57795ef3a..000000000 --- a/kernel-patches/for-mainline/statvfs-2.diff +++ /dev/null @@ -1,494 +0,0 @@ ---- - arch/alpha/kernel/osf_sys.c | 11 ++++---- - arch/mips/kernel/sysirix.c | 12 ++++----- - arch/parisc/hpux/sys_hpux.c | 11 ++++---- - arch/sparc64/solaris/fs.c | 16 ++++-------- - fs/compat.c | 13 +++++----- - fs/ecryptfs/super.c | 5 +++- - fs/nfsd/nfs4xdr.c | 2 - - fs/nfsd/vfs.c | 2 - - fs/open.c | 53 ++++++++++++++++++++++++++++++++++--------- - include/asm-arm/statfs.h | 6 +++- - include/asm-generic/statfs.h | 9 ++++--- - include/asm-ia64/compat.h | 3 +- - include/asm-ia64/statfs.h | 9 ++++--- - include/asm-parisc/compat.h | 3 +- - include/asm-parisc/statfs.h | 9 ++++--- - include/asm-powerpc/compat.h | 3 +- - include/asm-powerpc/statfs.h | 9 ++++--- - include/asm-s390/compat.h | 3 +- - include/asm-s390/statfs.h | 9 ++++--- - include/asm-sparc64/compat.h | 3 +- - include/asm-sparc64/statfs.h | 9 ++++--- - include/asm-x86_64/compat.h | 3 +- - include/asm-x86_64/statfs.h | 9 ++++--- - include/linux/fs.h | 2 - - include/linux/statfs.h | 13 +++++++++- - kernel/acct.c | 2 - - 26 files changed, 151 insertions(+), 78 deletions(-) - -Index: linux-2.6-apparmor/arch/alpha/kernel/osf_sys.c -=================================================================== ---- linux-2.6-apparmor.orig/arch/alpha/kernel/osf_sys.c -+++ linux-2.6-apparmor/arch/alpha/kernel/osf_sys.c -@@ -244,11 +244,11 @@ linux_to_osf_statfs(struct kstatfs *linu - } - - static int --do_osf_statfs(struct dentry * dentry, struct osf_statfs __user *buffer, -- unsigned long bufsiz) -+do_osf_statfs(struct dentry * dentry, struct vfsmount *mnt, -+ struct osf_statfs __user *buffer, unsigned long bufsiz) - { - struct kstatfs linux_stat; -- int error = vfs_statfs(dentry, &linux_stat); -+ int error = vfs_statfs(dentry, mnt, &linux_stat); - if (!error) - error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz); - return error; -@@ -262,7 +262,7 @@ osf_statfs(char __user *path, struct osf - - retval = user_path_walk(path, &nd); - if (!retval) { -- retval = do_osf_statfs(nd.dentry, buffer, bufsiz); -+ retval = do_osf_statfs(nd.dentry, nd.mnt, buffer, bufsiz); - path_release(&nd); - } - return retval; -@@ -277,7 +277,8 @@ osf_fstatfs(unsigned long fd, struct osf - retval = -EBADF; - file = fget(fd); - if (file) { -- retval = do_osf_statfs(file->f_path.dentry, buffer, bufsiz); -+ retval = do_osf_statfs(file->f_path.dentry, file->f_path.mnt, -+ buffer, bufsiz); - fput(file); - } - return retval; -Index: linux-2.6-apparmor/arch/mips/kernel/sysirix.c -=================================================================== ---- linux-2.6-apparmor.orig/arch/mips/kernel/sysirix.c -+++ linux-2.6-apparmor/arch/mips/kernel/sysirix.c -@@ -694,7 +694,7 @@ asmlinkage int irix_statfs(const char __ - if (error) - goto out; - -- error = vfs_statfs(nd.dentry, &kbuf); -+ error = vfs_statfs(nd.dentry, nd.mnt, &kbuf); - if (error) - goto dput_and_out; - -@@ -732,7 +732,7 @@ asmlinkage int irix_fstatfs(unsigned int - goto out; - } - -- error = vfs_statfs(file->f_path.dentry, &kbuf); -+ error = vfs_statfs(file->f_path.dentry, file->f_path.mnt, &kbuf); - if (error) - goto out_f; - -@@ -1360,7 +1360,7 @@ asmlinkage int irix_statvfs(char __user - error = user_path_walk(fname, &nd); - if (error) - goto out; -- error = vfs_statfs(nd.dentry, &kbuf); -+ error = vfs_statfs(nd.dentry, nd.mnt, &kbuf); - if (error) - goto dput_and_out; - -@@ -1406,7 +1406,7 @@ asmlinkage int irix_fstatvfs(int fd, str - error = -EBADF; - goto out; - } -- error = vfs_statfs(file->f_path.dentry, &kbuf); -+ error = vfs_statfs(file->f_path.dentry, file->f_path.mnt, &kbuf); - if (error) - goto out_f; - -@@ -1611,7 +1611,7 @@ asmlinkage int irix_statvfs64(char __use - error = user_path_walk(fname, &nd); - if (error) - goto out; -- error = vfs_statfs(nd.dentry, &kbuf); -+ error = vfs_statfs(nd.dentry, nd.mnt, &kbuf); - if (error) - goto dput_and_out; - -@@ -1658,7 +1658,7 @@ asmlinkage int irix_fstatvfs64(int fd, s - error = -EBADF; - goto out; - } -- error = vfs_statfs(file->f_path.dentry, &kbuf); -+ error = vfs_statfs(file->f_path.dentry, file->f_path.mnt, &kbuf); - if (error) - goto out_f; - -Index: linux-2.6-apparmor/arch/parisc/hpux/sys_hpux.c -=================================================================== ---- linux-2.6-apparmor.orig/arch/parisc/hpux/sys_hpux.c -+++ linux-2.6-apparmor/arch/parisc/hpux/sys_hpux.c -@@ -145,7 +145,7 @@ static int hpux_ustat(dev_t dev, struct - s = user_get_super(dev); - if (s == NULL) - goto out; -- err = vfs_statfs(s->s_root, &sbuf); -+ err = vfs_statfs(s->s_root, NULL, &sbuf); - drop_super(s); - if (err) - goto out; -@@ -186,12 +186,13 @@ struct hpux_statfs { - int16_t f_pad; - }; - --static int vfs_statfs_hpux(struct dentry *dentry, struct hpux_statfs *buf) -+static int vfs_statfs_hpux(struct dentry *dentry, struct vfsmount *mnt, -+ struct hpux_statfs *buf) - { - struct kstatfs st; - int retval; - -- retval = vfs_statfs(dentry, &st); -+ retval = vfs_statfs(dentry, mnt, &st); - if (retval) - return retval; - -@@ -219,7 +220,7 @@ asmlinkage long hpux_statfs(const char _ - error = user_path_walk(path, &nd); - if (!error) { - struct hpux_statfs tmp; -- error = vfs_statfs_hpux(nd.dentry, &tmp); -+ error = vfs_statfs_hpux(nd.dentry, nd.mnt, &tmp); - if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) - error = -EFAULT; - path_release(&nd); -@@ -237,7 +238,7 @@ asmlinkage long hpux_fstatfs(unsigned in - file = fget(fd); - if (!file) - goto out; -- error = vfs_statfs_hpux(file->f_path.dentry, &tmp); -+ error = vfs_statfs_hpux(file->f_path.dentry, file->f_path.mnt, &tmp); - if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) - error = -EFAULT; - fput(file); -Index: linux-2.6-apparmor/arch/sparc64/solaris/fs.c -=================================================================== ---- linux-2.6-apparmor.orig/arch/sparc64/solaris/fs.c -+++ linux-2.6-apparmor/arch/sparc64/solaris/fs.c -@@ -361,15 +361,12 @@ static int report_statvfs(struct vfsmoun - int error; - struct sol_statvfs __user *ss = A(buf); - -- error = vfs_statfs(mnt->mnt_root, &s); -+ error = vfs_statfs(mnt->mnt_root, mnt, &s); - if (!error) { - const char *p = mnt->mnt_sb->s_type->name; -- int i = 0; - int j = strlen (p); - - if (j > 15) j = 15; -- if (IS_RDONLY(inode)) i = 1; -- if (mnt->mnt_flags & MNT_NOSUID) i |= 2; - if (!sysv_valid_dev(inode->i_sb->s_dev)) - return -EOVERFLOW; - if (put_user (s.f_bsize, &ss->f_bsize) || -@@ -384,7 +381,8 @@ static int report_statvfs(struct vfsmoun - __copy_to_user (ss->f_basetype,p,j) || - __put_user (0, (char __user *)&ss->f_basetype[j]) || - __put_user (s.f_namelen, &ss->f_namemax) || -- __put_user (i, &ss->f_flag) || -+ __put_user (s.s_flag & (ST_RDONLY | ST_NOSUID), -+ &ss->f_flag) || - __clear_user (&ss->f_fstr, 32)) - return -EFAULT; - } -@@ -397,15 +395,12 @@ static int report_statvfs64(struct vfsmo - int error; - struct sol_statvfs64 __user *ss = A(buf); - -- error = vfs_statfs(mnt->mnt_root, &s); -+ error = vfs_statfs(mnt->mnt_root, mnt, &s); - if (!error) { - const char *p = mnt->mnt_sb->s_type->name; -- int i = 0; - int j = strlen (p); - - if (j > 15) j = 15; -- if (IS_RDONLY(inode)) i = 1; -- if (mnt->mnt_flags & MNT_NOSUID) i |= 2; - if (!sysv_valid_dev(inode->i_sb->s_dev)) - return -EOVERFLOW; - if (put_user (s.f_bsize, &ss->f_bsize) || -@@ -420,7 +415,8 @@ static int report_statvfs64(struct vfsmo - __copy_to_user (ss->f_basetype,p,j) || - __put_user (0, (char __user *)&ss->f_basetype[j]) || - __put_user (s.f_namelen, &ss->f_namemax) || -- __put_user (i, &ss->f_flag) || -+ __put_user (s.s_flag & (ST_RDONLY | ST_NOSUID), -+ &ss->f_flag) || - __clear_user (&ss->f_fstr, 32)) - return -EFAULT; - } -Index: linux-2.6-apparmor/include/asm-arm/statfs.h -=================================================================== ---- linux-2.6-apparmor.orig/include/asm-arm/statfs.h -+++ linux-2.6-apparmor/include/asm-arm/statfs.h -@@ -17,7 +17,8 @@ struct statfs { - __kernel_fsid_t f_fsid; - __u32 f_namelen; - __u32 f_frsize; -- __u32 f_spare[5]; -+ __u32 f_flag; -+ __u32 f_spare[4]; - }; - - /* -@@ -36,7 +37,8 @@ struct statfs64 { - __kernel_fsid_t f_fsid; - __u32 f_namelen; - __u32 f_frsize; -- __u32 f_spare[5]; -+ __u32 f_flag; -+ __u32 f_spare[4]; - } __attribute__ ((packed,aligned(4))); - - #endif -Index: linux-2.6-apparmor/include/asm-ia64/compat.h -=================================================================== ---- linux-2.6-apparmor.orig/include/asm-ia64/compat.h -+++ linux-2.6-apparmor/include/asm-ia64/compat.h -@@ -102,7 +102,8 @@ struct compat_statfs { - compat_fsid_t f_fsid; - int f_namelen; /* SunOS ignores this field. */ - int f_frsize; -- int f_spare[5]; -+ int f_flag; -+ int f_spare[4]; - }; - - #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff -Index: linux-2.6-apparmor/include/asm-ia64/statfs.h -=================================================================== ---- linux-2.6-apparmor.orig/include/asm-ia64/statfs.h -+++ linux-2.6-apparmor/include/asm-ia64/statfs.h -@@ -27,7 +27,8 @@ struct statfs { - __kernel_fsid_t f_fsid; - long f_namelen; - long f_frsize; -- long f_spare[5]; -+ long f_flag; -+ long f_spare[4]; - }; - - -@@ -42,7 +43,8 @@ struct statfs64 { - __kernel_fsid_t f_fsid; - long f_namelen; - long f_frsize; -- long f_spare[5]; -+ long f_flag; -+ long f_spare[4]; - }; - - struct compat_statfs64 { -@@ -56,7 +58,8 @@ struct compat_statfs64 { - __kernel_fsid_t f_fsid; - __u32 f_namelen; - __u32 f_frsize; -- __u32 f_spare[5]; -+ __u32 f_flag; -+ __u32 f_spare[4]; - } __attribute__((packed)); - - #endif /* _ASM_IA64_STATFS_H */ -Index: linux-2.6-apparmor/include/asm-parisc/compat.h -=================================================================== ---- linux-2.6-apparmor.orig/include/asm-parisc/compat.h -+++ linux-2.6-apparmor/include/asm-parisc/compat.h -@@ -102,7 +102,8 @@ struct compat_statfs { - __kernel_fsid_t f_fsid; - s32 f_namelen; - s32 f_frsize; -- s32 f_spare[5]; -+ s32 f_flag; -+ s32 f_spare[4]; - }; - - struct compat_sigcontext { -Index: linux-2.6-apparmor/include/asm-parisc/statfs.h -=================================================================== ---- linux-2.6-apparmor.orig/include/asm-parisc/statfs.h -+++ linux-2.6-apparmor/include/asm-parisc/statfs.h -@@ -24,7 +24,8 @@ struct statfs { - __kernel_fsid_t f_fsid; - long f_namelen; - long f_frsize; -- long f_spare[5]; -+ long f_flag; -+ long f_spare[4]; - }; - - struct statfs64 { -@@ -38,7 +39,8 @@ struct statfs64 { - __kernel_fsid_t f_fsid; - long f_namelen; - long f_frsize; -- long f_spare[5]; -+ long f_flag; -+ long f_spare[4]; - }; - - struct compat_statfs64 { -@@ -52,7 +54,8 @@ struct compat_statfs64 { - __kernel_fsid_t f_fsid; - __u32 f_namelen; - __u32 f_frsize; -- __u32 f_spare[5]; -+ __u32 f_flag; -+ __u32 f_spare[4]; - }; - - #endif -Index: linux-2.6-apparmor/include/asm-powerpc/compat.h -=================================================================== ---- linux-2.6-apparmor.orig/include/asm-powerpc/compat.h -+++ linux-2.6-apparmor/include/asm-powerpc/compat.h -@@ -97,7 +97,8 @@ struct compat_statfs { - compat_fsid_t f_fsid; - int f_namelen; /* SunOS ignores this field. */ - int f_frsize; -- int f_spare[5]; -+ int f_flag; -+ int f_spare[4]; - }; - - #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff -Index: linux-2.6-apparmor/include/asm-powerpc/statfs.h -=================================================================== ---- linux-2.6-apparmor.orig/include/asm-powerpc/statfs.h -+++ linux-2.6-apparmor/include/asm-powerpc/statfs.h -@@ -26,7 +26,8 @@ struct statfs { - __kernel_fsid_t f_fsid; - long f_namelen; - long f_frsize; -- long f_spare[5]; -+ long f_flag; -+ long f_spare[4]; - }; - - struct statfs64 { -@@ -40,7 +41,8 @@ struct statfs64 { - __kernel_fsid_t f_fsid; - long f_namelen; - long f_frsize; -- long f_spare[5]; -+ long f_flag; -+ long f_spare[4]; - }; - - struct compat_statfs64 { -@@ -54,7 +56,8 @@ struct compat_statfs64 { - __kernel_fsid_t f_fsid; - __u32 f_namelen; - __u32 f_frsize; -- __u32 f_spare[5]; -+ __u32 f_flag; -+ __u32 f_spare[4]; - }; - #endif /* ! __powerpc64__ */ - #endif -Index: linux-2.6-apparmor/include/asm-s390/compat.h -=================================================================== ---- linux-2.6-apparmor.orig/include/asm-s390/compat.h -+++ linux-2.6-apparmor/include/asm-s390/compat.h -@@ -127,7 +127,8 @@ struct compat_statfs { - compat_fsid_t f_fsid; - s32 f_namelen; - s32 f_frsize; -- s32 f_spare[6]; -+ s32 f_flag; -+ s32 f_spare[5]; - }; - - #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff -Index: linux-2.6-apparmor/include/asm-s390/statfs.h -=================================================================== ---- linux-2.6-apparmor.orig/include/asm-s390/statfs.h -+++ linux-2.6-apparmor/include/asm-s390/statfs.h -@@ -36,7 +36,8 @@ struct statfs { - __kernel_fsid_t f_fsid; - int f_namelen; - int f_frsize; -- int f_spare[5]; -+ int f_flag; -+ int f_spare[4]; - }; - - struct statfs64 { -@@ -50,7 +51,8 @@ struct statfs64 { - __kernel_fsid_t f_fsid; - int f_namelen; - int f_frsize; -- int f_spare[5]; -+ int f_flag; -+ int f_spare[4]; - }; - - struct compat_statfs64 { -@@ -64,7 +66,8 @@ struct compat_statfs64 { - __kernel_fsid_t f_fsid; - __u32 f_namelen; - __u32 f_frsize; -- __u32 f_spare[5]; -+ __u32 f_flag; -+ __u32 f_spare[4]; - }; - - #endif /* __s390x__ */ -Index: linux-2.6-apparmor/include/asm-sparc64/compat.h -=================================================================== ---- linux-2.6-apparmor.orig/include/asm-sparc64/compat.h -+++ linux-2.6-apparmor/include/asm-sparc64/compat.h -@@ -131,7 +131,8 @@ struct compat_statfs { - compat_fsid_t f_fsid; - int f_namelen; /* SunOS ignores this field. */ - int f_frsize; -- int f_spare[5]; -+ int f_flag; -+ int f_spare[4]; - }; - - #define COMPAT_RLIM_INFINITY 0x7fffffff -Index: linux-2.6-apparmor/include/asm-sparc64/statfs.h -=================================================================== ---- linux-2.6-apparmor.orig/include/asm-sparc64/statfs.h -+++ linux-2.6-apparmor/include/asm-sparc64/statfs.h -@@ -21,7 +21,8 @@ struct statfs { - __kernel_fsid_t f_fsid; - long f_namelen; - long f_frsize; -- long f_spare[5]; -+ long f_flag; -+ long f_spare[4]; - }; - - struct statfs64 { -@@ -35,7 +36,8 @@ struct statfs64 { - __kernel_fsid_t f_fsid; - long f_namelen; - long f_frsize; -- long f_spare[5]; -+ long f_flag; -+ long f_spare[4]; - }; - - struct compat_statfs64 { -@@ -49,7 +51,8 @@ struct compat_statfs64 { - __kernel_fsid_t f_fsid; - __u32 f_namelen; - __u32 f_frsize; -- __u32 f_spare[5]; -+ __u32 f_flag; -+ __u32 f_spare[4]; - }; - - #endif diff --git a/kernel-patches/for-mainline/statvfs.diff b/kernel-patches/for-mainline/statvfs.diff deleted file mode 100644 index 69bd1e501..000000000 --- a/kernel-patches/for-mainline/statvfs.diff +++ /dev/null @@ -1,370 +0,0 @@ ---- - fs/compat.c | 13 +++++----- - fs/ecryptfs/super.c | 5 +++- - fs/nfsd/nfs4xdr.c | 2 - - fs/nfsd/vfs.c | 2 - - fs/open.c | 53 ++++++++++++++++++++++++++++++++++--------- - fs/super.c | 2 - - include/asm-generic/statfs.h | 9 ++++--- - include/asm-x86_64/compat.h | 3 +- - include/asm-x86_64/statfs.h | 9 ++++--- - include/linux/fs.h | 2 - - include/linux/statfs.h | 13 +++++++++- - kernel/acct.c | 2 - - 12 files changed, 84 insertions(+), 31 deletions(-) - ---- a/fs/compat.c -+++ b/fs/compat.c -@@ -194,7 +194,7 @@ static int put_compat_statfs(struct comp - __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || - __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) || - __put_user(kbuf->f_frsize, &ubuf->f_frsize) || -- __put_user(0, &ubuf->f_spare[0]) || -+ __put_user(kbuf->f_flag, &ubuf->f_flag) || - __put_user(0, &ubuf->f_spare[1]) || - __put_user(0, &ubuf->f_spare[2]) || - __put_user(0, &ubuf->f_spare[3]) || -@@ -215,7 +215,7 @@ asmlinkage long compat_sys_statfs(const - error = user_path_walk(path, &nd); - if (!error) { - struct kstatfs tmp; -- error = vfs_statfs(nd.dentry, &tmp); -+ error = vfs_statfs(nd.dentry, nd.mnt, &tmp); - if (!error) - error = put_compat_statfs(buf, &tmp); - path_release(&nd); -@@ -233,7 +233,7 @@ asmlinkage long compat_sys_fstatfs(unsig - file = fget(fd); - if (!file) - goto out; -- error = vfs_statfs(file->f_path.dentry, &tmp); -+ error = vfs_statfs(file->f_path.dentry, file->f_path.mnt, &tmp); - if (!error) - error = put_compat_statfs(buf, &tmp); - fput(file); -@@ -267,7 +267,8 @@ static int put_compat_statfs64(struct co - __put_user(kbuf->f_namelen, &ubuf->f_namelen) || - __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || - __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) || -- __put_user(kbuf->f_frsize, &ubuf->f_frsize)) -+ __put_user(kbuf->f_frsize, &ubuf->f_frsize) || -+ __put_user(kbuf->f_flag, &ubuf->f_flag)) - return -EFAULT; - return 0; - } -@@ -283,7 +284,7 @@ asmlinkage long compat_sys_statfs64(cons - error = user_path_walk(path, &nd); - if (!error) { - struct kstatfs tmp; -- error = vfs_statfs(nd.dentry, &tmp); -+ error = vfs_statfs(nd.dentry, nd.mnt, &tmp); - if (!error) - error = put_compat_statfs64(buf, &tmp); - path_release(&nd); -@@ -304,7 +305,7 @@ asmlinkage long compat_sys_fstatfs64(uns - file = fget(fd); - if (!file) - goto out; -- error = vfs_statfs(file->f_path.dentry, &tmp); -+ error = vfs_statfs(file->f_path.dentry, file->f_path.mnt, &tmp); - if (!error) - error = put_compat_statfs64(buf, &tmp); - fput(file); ---- a/fs/ecryptfs/super.c -+++ b/fs/ecryptfs/super.c -@@ -119,7 +119,10 @@ static void ecryptfs_put_super(struct su - */ - static int ecryptfs_statfs(struct dentry *dentry, struct kstatfs *buf) - { -- return vfs_statfs(ecryptfs_dentry_to_lower(dentry), buf); -+ struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); -+ struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); -+ -+ return vfs_statfs(lower_dentry, lower_mnt, buf); - } - - /** ---- a/fs/nfsd/nfs4xdr.c -+++ b/fs/nfsd/nfs4xdr.c -@@ -1457,7 +1457,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s - if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) || - (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | - FATTR4_WORD1_SPACE_TOTAL))) { -- err = vfs_statfs(dentry, &statfs); -+ err = vfs_statfs(dentry, exp->ex_mnt, &statfs); - if (err) - goto out_nfserr; - } ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1767,7 +1767,7 @@ __be32 - nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat) - { - __be32 err = fh_verify(rqstp, fhp, 0, MAY_NOP); -- if (!err && vfs_statfs(fhp->fh_dentry,stat)) -+ if (!err && vfs_statfs(fhp->fh_dentry, fhp->fh_export->ex_mnt, stat)) - err = nfserr_io; - return err; - } ---- a/fs/open.c -+++ b/fs/open.c -@@ -28,7 +28,7 @@ - #include - #include - --int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) -+int vfs_statfs(struct dentry *dentry, struct vfsmount *mnt, struct kstatfs *buf) - { - int retval = -ENODEV; - -@@ -40,8 +40,35 @@ int vfs_statfs(struct dentry *dentry, st - if (retval) - return retval; - retval = dentry->d_sb->s_op->statfs(dentry, buf); -- if (retval == 0 && buf->f_frsize == 0) -- buf->f_frsize = buf->f_bsize; -+ if (retval == 0) { -+ unsigned long f_flag = ST_IN_USE; -+ unsigned long x; -+ -+ if (buf->f_frsize == 0) -+ buf->f_frsize = buf->f_bsize; -+ -+ x = dentry->d_inode->i_sb->s_flags; -+ if (x & MS_RDONLY) -+ f_flag |= ST_RDONLY; -+ if (x & MS_SYNCHRONOUS) -+ f_flag |= ST_SYNCHRONOUS; -+ if (x & MS_MANDLOCK) -+ f_flag |= ST_MANDLOCK; -+ -+ if (mnt) { -+ int x = mnt->mnt_flags; -+ -+ if (x & MNT_NOSUID) -+ f_flag |= ST_NOSUID; -+ if (x & MNT_NODEV) -+ f_flag |= ST_NODEV; -+ if (x & MNT_NOATIME) -+ f_flag |= ST_NOATIME; -+ if (x & MNT_NODIRATIME) -+ f_flag |= ST_NODIRATIME; -+ } -+ buf->f_flag = f_flag; -+ } - } - } - return retval; -@@ -49,12 +76,13 @@ int vfs_statfs(struct dentry *dentry, st - - EXPORT_SYMBOL(vfs_statfs); - --static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf) -+static int vfs_statfs_native(struct dentry *dentry, struct vfsmount *mnt, -+ struct statfs *buf) - { - struct kstatfs st; - int retval; - -- retval = vfs_statfs(dentry, &st); -+ retval = vfs_statfs(dentry, mnt, &st); - if (retval) - return retval; - -@@ -87,17 +115,19 @@ static int vfs_statfs_native(struct dent - buf->f_fsid = st.f_fsid; - buf->f_namelen = st.f_namelen; - buf->f_frsize = st.f_frsize; -+ buf->f_flag = st.f_flag; - memset(buf->f_spare, 0, sizeof(buf->f_spare)); - } - return 0; - } - --static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf) -+static int vfs_statfs64(struct dentry *dentry, struct vfsmount *mnt, -+ struct statfs64 *buf) - { - struct kstatfs st; - int retval; - -- retval = vfs_statfs(dentry, &st); -+ retval = vfs_statfs(dentry, mnt, &st); - if (retval) - return retval; - -@@ -114,6 +144,7 @@ static int vfs_statfs64(struct dentry *d - buf->f_fsid = st.f_fsid; - buf->f_namelen = st.f_namelen; - buf->f_frsize = st.f_frsize; -+ buf->f_flag = st.f_flag; - memset(buf->f_spare, 0, sizeof(buf->f_spare)); - } - return 0; -@@ -127,7 +158,7 @@ asmlinkage long sys_statfs(const char __ - error = user_path_walk(path, &nd); - if (!error) { - struct statfs tmp; -- error = vfs_statfs_native(nd.dentry, &tmp); -+ error = vfs_statfs_native(nd.dentry, nd.mnt, &tmp); - if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) - error = -EFAULT; - path_release(&nd); -@@ -146,7 +177,7 @@ asmlinkage long sys_statfs64(const char - error = user_path_walk(path, &nd); - if (!error) { - struct statfs64 tmp; -- error = vfs_statfs64(nd.dentry, &tmp); -+ error = vfs_statfs64(nd.dentry, nd.mnt, &tmp); - if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) - error = -EFAULT; - path_release(&nd); -@@ -165,7 +196,7 @@ asmlinkage long sys_fstatfs(unsigned int - file = fget(fd); - if (!file) - goto out; -- error = vfs_statfs_native(file->f_path.dentry, &tmp); -+ error = vfs_statfs_native(file->f_path.dentry, file->f_path.mnt, &tmp); - if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) - error = -EFAULT; - fput(file); -@@ -186,7 +217,7 @@ asmlinkage long sys_fstatfs64(unsigned i - file = fget(fd); - if (!file) - goto out; -- error = vfs_statfs64(file->f_path.dentry, &tmp); -+ error = vfs_statfs64(file->f_path.dentry, file->f_path.mnt, &tmp); - if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) - error = -EFAULT; - fput(file); ---- a/fs/super.c -+++ b/fs/super.c -@@ -542,7 +542,7 @@ asmlinkage long sys_ustat(unsigned dev, - s = user_get_super(new_decode_dev(dev)); - if (s == NULL) - goto out; -- err = vfs_statfs(s->s_root, &sbuf); -+ err = vfs_statfs(s->s_root, NULL, &sbuf); - drop_super(s); - if (err) - goto out; ---- a/include/asm-generic/statfs.h -+++ b/include/asm-generic/statfs.h -@@ -17,7 +17,8 @@ struct statfs { - __kernel_fsid_t f_fsid; - __u32 f_namelen; - __u32 f_frsize; -- __u32 f_spare[5]; -+ __u32 f_flag; -+ __u32 f_spare[4]; - }; - - struct statfs64 { -@@ -31,7 +32,8 @@ struct statfs64 { - __kernel_fsid_t f_fsid; - __u32 f_namelen; - __u32 f_frsize; -- __u32 f_spare[5]; -+ __u32 f_flag; -+ __u32 f_spare[4]; - }; - - struct compat_statfs64 { -@@ -45,7 +47,8 @@ struct compat_statfs64 { - __kernel_fsid_t f_fsid; - __u32 f_namelen; - __u32 f_frsize; -- __u32 f_spare[5]; -+ __u32 f_flag; -+ __u32 f_spare[4]; - }; - - #endif ---- a/include/asm-x86_64/compat.h -+++ b/include/asm-x86_64/compat.h -@@ -104,7 +104,8 @@ struct compat_statfs { - compat_fsid_t f_fsid; - int f_namelen; /* SunOS ignores this field. */ - int f_frsize; -- int f_spare[5]; -+ int f_flag; -+ int f_spare[4]; - }; - - #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff ---- a/include/asm-x86_64/statfs.h -+++ b/include/asm-x86_64/statfs.h -@@ -24,7 +24,8 @@ struct statfs { - __kernel_fsid_t f_fsid; - long f_namelen; - long f_frsize; -- long f_spare[5]; -+ long f_flag; -+ long f_spare[4]; - }; - - struct statfs64 { -@@ -38,7 +39,8 @@ struct statfs64 { - __kernel_fsid_t f_fsid; - long f_namelen; - long f_frsize; -- long f_spare[5]; -+ long f_flag; -+ long f_spare[4]; - }; - - struct compat_statfs64 { -@@ -52,7 +54,8 @@ struct compat_statfs64 { - __kernel_fsid_t f_fsid; - __u32 f_namelen; - __u32 f_frsize; -- __u32 f_spare[5]; -+ __u32 f_flag; -+ __u32 f_spare[4]; - } __attribute__((packed)); - - #endif ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1408,7 +1408,7 @@ extern struct vfsmount *copy_tree(struct - extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *, - struct vfsmount *); - --extern int vfs_statfs(struct dentry *, struct kstatfs *); -+extern int vfs_statfs(struct dentry *, struct vfsmount *, struct kstatfs *); - - /* /sys/fs */ - extern struct subsystem fs_subsys; ---- a/include/linux/statfs.h -+++ b/include/linux/statfs.h -@@ -16,7 +16,18 @@ struct kstatfs { - __kernel_fsid_t f_fsid; - long f_namelen; - long f_frsize; -- long f_spare[5]; -+ unsigned long f_flag; -+ long f_spare[4]; - }; - -+#define ST_RDONLY 1 -+#define ST_NOSUID 2 -+#define ST_NODEV 4 -+#define ST_NOEXEC 8 -+#define ST_SYNCHRONOUS 16 -+#define ST_MANDLOCK 64 -+#define ST_NOATIME 1024 -+#define ST_NODIRATIME 2048 -+#define ST_IN_USE (1 << 31) -+ - #endif ---- a/kernel/acct.c -+++ b/kernel/acct.c -@@ -118,7 +118,7 @@ static int check_free_space(struct file - spin_unlock(&acct_globals.lock); - - /* May block */ -- if (vfs_statfs(file->f_path.dentry, &sbuf)) -+ if (vfs_statfs(file->f_path.dentry, file->f_path.mnt, &sbuf)) - return res; - suspend = sbuf.f_blocks * SUSPEND; - resume = sbuf.f_blocks * RESUME; diff --git a/kernel-patches/for-mainline/struct_path/series b/kernel-patches/for-mainline/struct_path/series deleted file mode 100644 index e8304cf48..000000000 --- a/kernel-patches/for-mainline/struct_path/series +++ /dev/null @@ -1,5 +0,0 @@ -struct_path-nameidata.diff -struct_path-vfs_getattr.diff -struct_path-getattr-iop.diff -struct_path-security-getattr.diff -struct_path-nfsfh.diff diff --git a/kernel-patches/for-mainline/struct_path/struct_path-getattr-iop.diff b/kernel-patches/for-mainline/struct_path/struct_path-getattr-iop.diff deleted file mode 100644 index 9c93361af..000000000 --- a/kernel-patches/for-mainline/struct_path/struct_path-getattr-iop.diff +++ /dev/null @@ -1,504 +0,0 @@ -Index: linux-2.6/fs/9p/vfs_inode.c -=================================================================== ---- linux-2.6.orig/fs/9p/vfs_inode.c -+++ linux-2.6/fs/9p/vfs_inode.c -@@ -824,16 +824,15 @@ Release_lock: - - /** - * v9fs_vfs_getattr - retrieve file metadata -- * @mnt - mount information -- * @dentry - file to get attributes on -+ * @path - file to get attributes on - * @stat - metadata structure to populate - * - */ - - static int --v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, -- struct kstat *stat) -+v9fs_vfs_getattr(struct path *path, struct kstat *stat) - { -+ struct dentry *dentry = path->dentry; - struct v9fs_fcall *fcall = NULL; - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); - struct v9fs_fid *fid = v9fs_fid_clone(dentry); -Index: linux-2.6/fs/afs/inode.c -=================================================================== ---- linux-2.6.orig/fs/afs/inode.c -+++ linux-2.6/fs/afs/inode.c -@@ -218,15 +218,13 @@ inline int afs_iget(struct super_block * - /* - * read the attributes of an inode - */ --int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, -- struct kstat *stat) -+int afs_inode_getattr(struct path *path, struct kstat *stat) - { -+ struct dentry *dentry = path->dentry; -+ struct inode *inode = dentry->d_inode; - struct afs_vnode *vnode; -- struct inode *inode; - int ret; - -- inode = dentry->d_inode; -- - _enter("{ ino=%lu v=%lu }", inode->i_ino, inode->i_version); - - vnode = AFS_FS_I(inode); -Index: linux-2.6/fs/afs/internal.h -=================================================================== ---- linux-2.6.orig/fs/afs/internal.h -+++ linux-2.6/fs/afs/internal.h -@@ -82,8 +82,7 @@ extern int afs_cache_get_page_cookie(str - */ - extern int afs_iget(struct super_block *sb, struct afs_fid *fid, - struct inode **_inode); --extern int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, -- struct kstat *stat); -+extern int afs_inode_getattr(struct path *path, struct kstat *stat); - extern void afs_clear_inode(struct inode *inode); - - /* -Index: linux-2.6/fs/bad_inode.c -=================================================================== ---- linux-2.6.orig/fs/bad_inode.c -+++ linux-2.6/fs/bad_inode.c -@@ -257,8 +257,7 @@ static int bad_inode_permission(struct i - return -EIO; - } - --static int bad_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, -- struct kstat *stat) -+static int bad_inode_getattr(struct path *path, struct kstat *stat) - { - return -EIO; - } -Index: linux-2.6/fs/cifs/cifsfs.h -=================================================================== ---- linux-2.6.orig/fs/cifs/cifsfs.h -+++ linux-2.6/fs/cifs/cifsfs.h -@@ -55,7 +55,7 @@ extern int cifs_rmdir(struct inode *, st - extern int cifs_rename(struct inode *, struct dentry *, struct inode *, - struct dentry *); - extern int cifs_revalidate(struct dentry *); --extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *); -+extern int cifs_getattr(struct path *, struct kstat *); - extern int cifs_setattr(struct dentry *, struct iattr *); - - extern struct inode_operations cifs_file_inode_ops; -Index: linux-2.6/fs/cifs/inode.c -=================================================================== ---- linux-2.6.orig/fs/cifs/inode.c -+++ linux-2.6/fs/cifs/inode.c -@@ -1091,9 +1091,9 @@ int cifs_revalidate(struct dentry *diren - return rc; - } - --int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, -- struct kstat *stat) -+int cifs_getattr(struct path *path, struct kstat *stat) - { -+ struct dentry *dentry = path->dentry; - int err = cifs_revalidate(dentry); - if (!err) { - generic_fillattr(dentry->d_inode, stat); -Index: linux-2.6/fs/coda/inode.c -=================================================================== ---- linux-2.6.orig/fs/coda/inode.c -+++ linux-2.6/fs/coda/inode.c -@@ -236,8 +236,9 @@ static void coda_clear_inode(struct inod - coda_cache_clear_inode(inode); - } - --int coda_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -+int coda_getattr(struct path *path, struct kstat *stat) - { -+ struct dentry *dentry = path->dentry; - int err = coda_revalidate_inode(dentry); - if (!err) - generic_fillattr(dentry->d_inode, stat); -Index: linux-2.6/fs/fat/file.c -=================================================================== ---- linux-2.6.orig/fs/fat/file.c -+++ linux-2.6/fs/fat/file.c -@@ -303,8 +303,9 @@ void fat_truncate(struct inode *inode) - fat_flush_inodes(inode->i_sb, inode, NULL); - } - --int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -+int fat_getattr(struct path *path, struct kstat *stat) - { -+ struct dentry *dentry = path->dentry; - struct inode *inode = dentry->d_inode; - generic_fillattr(inode, stat); - stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size; -Index: linux-2.6/fs/fuse/dir.c -=================================================================== ---- linux-2.6.orig/fs/fuse/dir.c -+++ linux-2.6/fs/fuse/dir.c -@@ -1067,11 +1067,11 @@ static int fuse_setattr(struct dentry *e - return err; - } - --static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, -- struct kstat *stat) -+static int fuse_getattr(struct path *path, struct kstat *stat) - { -- struct inode *inode = entry->d_inode; -- int err = fuse_revalidate(entry); -+ struct dentry *dentry = path->dentry; -+ struct inode *inode = dentry->d_inode; -+ int err = fuse_revalidate(dentry); - if (!err) - generic_fillattr(inode, stat); - -Index: linux-2.6/fs/gfs2/ops_inode.c -=================================================================== ---- linux-2.6.orig/fs/gfs2/ops_inode.c -+++ linux-2.6/fs/gfs2/ops_inode.c -@@ -1001,9 +1001,9 @@ out: - * Returns: errno - */ - --static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, -- struct kstat *stat) -+static int gfs2_getattr(struct path *path, struct kstat *stat) - { -+ struct dentry *dentry = path->dentry; - struct inode *inode = dentry->d_inode; - struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_holder gh; -Index: linux-2.6/fs/hostfs/hostfs_kern.c -=================================================================== ---- linux-2.6.orig/fs/hostfs/hostfs_kern.c -+++ linux-2.6/fs/hostfs/hostfs_kern.c -@@ -873,10 +873,9 @@ int hostfs_setattr(struct dentry *dentry - return(inode_setattr(dentry->d_inode, attr)); - } - --int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry, -- struct kstat *stat) -+int hostfs_getattr(struct path *path, struct kstat *stat) - { -- generic_fillattr(dentry->d_inode, stat); -+ generic_fillattr(path->dentry->d_inode, stat); - return(0); - } - -Index: linux-2.6/fs/libfs.c -=================================================================== ---- linux-2.6.orig/fs/libfs.c -+++ linux-2.6/fs/libfs.c -@@ -11,10 +11,9 @@ - - #include - --int simple_getattr(struct vfsmount *mnt, struct dentry *dentry, -- struct kstat *stat) -+int simple_getattr(struct path *path, struct kstat *stat) - { -- struct inode *inode = dentry->d_inode; -+ struct inode *inode = path->dentry->d_inode; - generic_fillattr(inode, stat); - stat->blocks = inode->i_mapping->nrpages << (PAGE_CACHE_SHIFT - 9); - return 0; -Index: linux-2.6/fs/minix/inode.c -=================================================================== ---- linux-2.6.orig/fs/minix/inode.c -+++ linux-2.6/fs/minix/inode.c -@@ -535,8 +535,9 @@ int minix_sync_inode(struct inode * inod - return err; - } - --int minix_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -+int minix_getattr(struct path *path, struct kstat *stat) - { -+ struct dentry *dentry = path->dentry; - generic_fillattr(dentry->d_inode, stat); - if (INODE_VERSION(dentry->d_inode) == MINIX_V1) - stat->blocks = (BLOCK_SIZE / 512) * V1_minix_blocks(stat->size); -Index: linux-2.6/fs/minix/minix.h -=================================================================== ---- linux-2.6.orig/fs/minix/minix.h -+++ linux-2.6/fs/minix/minix.h -@@ -55,7 +55,7 @@ extern int minix_new_block(struct inode - extern void minix_free_block(struct inode * inode, int block); - extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi); - --extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *); -+extern int minix_getattr(struct path *, struct kstat *); - - extern void V2_minix_truncate(struct inode *); - extern void V1_minix_truncate(struct inode *); -Index: linux-2.6/fs/nfs/inode.c -=================================================================== ---- linux-2.6.orig/fs/nfs/inode.c -+++ linux-2.6/fs/nfs/inode.c -@@ -415,9 +415,9 @@ static void nfs_wake_up_inode(struct ino - wake_up_bit(&nfsi->flags, NFS_INO_REVALIDATING); - } - --int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -+int nfs_getattr(struct path *path, struct kstat *stat) - { -- struct inode *inode = dentry->d_inode; -+ struct inode *inode = path->dentry->d_inode; - int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; - int err; - -@@ -433,8 +433,8 @@ int nfs_getattr(struct vfsmount *mnt, st - * - NFS never sets MS_NOATIME or MS_NODIRATIME so there is - * no point in checking those. - */ -- if ((mnt->mnt_flags & MNT_NOATIME) || -- ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))) -+ if ((path->mnt->mnt_flags & MNT_NOATIME) || -+ ((path->mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))) - need_atime = 0; - - if (need_atime) -Index: linux-2.6/fs/ocfs2/file.c -=================================================================== ---- linux-2.6.orig/fs/ocfs2/file.c -+++ linux-2.6/fs/ocfs2/file.c -@@ -935,10 +935,9 @@ bail: - return status; - } - --int ocfs2_getattr(struct vfsmount *mnt, -- struct dentry *dentry, -- struct kstat *stat) -+int ocfs2_getattr(struct path *path, struct kstat *stat) - { -+ struct dentry *dentry = path->dentry; - struct inode *inode = dentry->d_inode; - struct super_block *sb = dentry->d_inode->i_sb; - struct ocfs2_super *osb = sb->s_fs_info; -Index: linux-2.6/fs/ocfs2/file.h -=================================================================== ---- linux-2.6.orig/fs/ocfs2/file.h -+++ linux-2.6/fs/ocfs2/file.h -@@ -46,8 +46,7 @@ int ocfs2_do_extend_allocation(struct oc - struct ocfs2_alloc_context *meta_ac, - enum ocfs2_alloc_restarted *reason); - int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); --int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, -- struct kstat *stat); -+int ocfs2_getattr(struct path *path, struct kstat *stat); - int ocfs2_permission(struct inode *inode, int mask, - struct nameidata *nd); - -Index: linux-2.6/fs/proc/base.c -=================================================================== ---- linux-2.6.orig/fs/proc/base.c -+++ linux-2.6/fs/proc/base.c -@@ -1045,9 +1045,9 @@ out_unlock: - return NULL; - } - --static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -+static int pid_getattr(struct path *path, struct kstat *stat) - { -- struct inode *inode = dentry->d_inode; -+ struct inode *inode = path->dentry->d_inode; - struct task_struct *task; - generic_fillattr(inode, stat); - -@@ -2379,9 +2379,9 @@ out_no_task: - return retval; - } - --static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -+static int proc_task_getattr(struct path *path, struct kstat *stat) - { -- struct inode *inode = dentry->d_inode; -+ struct inode *inode = path->dentry->d_inode; - struct task_struct *p = get_proc_task(inode); - generic_fillattr(inode, stat); - -Index: linux-2.6/fs/proc/generic.c -=================================================================== ---- linux-2.6.orig/fs/proc/generic.c -+++ linux-2.6/fs/proc/generic.c -@@ -253,10 +253,9 @@ out: - return error; - } - --static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry, -- struct kstat *stat) -+static int proc_getattr(struct path *path, struct kstat *stat) - { -- struct inode *inode = dentry->d_inode; -+ struct inode *inode = path->dentry->d_inode; - struct proc_dir_entry *de = PROC_I(inode)->pde; - if (de && de->nlink) - inode->i_nlink = de->nlink; -Index: linux-2.6/fs/proc/root.c -=================================================================== ---- linux-2.6.orig/fs/proc/root.c -+++ linux-2.6/fs/proc/root.c -@@ -92,10 +92,9 @@ void __init proc_root_init(void) - proc_bus = proc_mkdir("bus", NULL); - } - --static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat --) -+static int proc_root_getattr(struct path *path, struct kstat *stat) - { -- generic_fillattr(dentry->d_inode, stat); -+ generic_fillattr(path->dentry->d_inode, stat); - stat->nlink = proc_root.nlink + nr_processes(); - return 0; - } -Index: linux-2.6/fs/smbfs/inode.c -=================================================================== ---- linux-2.6.orig/fs/smbfs/inode.c -+++ linux-2.6/fs/smbfs/inode.c -@@ -653,8 +653,9 @@ smb_statfs(struct dentry *dentry, struct - return result; - } - --int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -+int smb_getattr(struct path *path, struct kstat *stat) - { -+ struct dentry *dentry = path->dentry; - int err = smb_revalidate_inode(dentry); - if (!err) - generic_fillattr(dentry->d_inode, stat); -Index: linux-2.6/fs/smbfs/proto.h -=================================================================== ---- linux-2.6.orig/fs/smbfs/proto.h -+++ linux-2.6/fs/smbfs/proto.h -@@ -60,7 +60,7 @@ extern void smb_get_inode_attr(struct in - extern void smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr); - extern void smb_invalidate_inodes(struct smb_sb_info *server); - extern int smb_revalidate_inode(struct dentry *dentry); --extern int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); -+extern int smb_getattr(struct path *path, struct kstat *stat); - extern int smb_notify_change(struct dentry *dentry, struct iattr *attr); - /* file.c */ - extern const struct address_space_operations smb_file_aops; -Index: linux-2.6/fs/stat.c -=================================================================== ---- linux-2.6.orig/fs/stat.c -+++ linux-2.6/fs/stat.c -@@ -48,7 +48,7 @@ int vfs_getattr(struct path *path, struc - return retval; - - if (inode->i_op->getattr) -- return inode->i_op->getattr(path->mnt, path->dentry, stat); -+ return inode->i_op->getattr(path, stat); - - generic_fillattr(inode, stat); - return 0; -Index: linux-2.6/fs/sysv/itree.c -=================================================================== ---- linux-2.6.orig/fs/sysv/itree.c -+++ linux-2.6/fs/sysv/itree.c -@@ -440,10 +440,10 @@ static unsigned sysv_nblocks(struct supe - return blocks; - } - --int sysv_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -+int sysv_getattr(struct path *path, struct kstat *stat) - { -- struct super_block *s = mnt->mnt_sb; -- generic_fillattr(dentry->d_inode, stat); -+ struct super_block *s = path->mnt->mnt_sb; -+ generic_fillattr(path->dentry->d_inode, stat); - stat->blocks = (s->s_blocksize / 512) * sysv_nblocks(s, stat->size); - stat->blksize = s->s_blocksize; - return 0; -Index: linux-2.6/fs/sysv/sysv.h -=================================================================== ---- linux-2.6.orig/fs/sysv/sysv.h -+++ linux-2.6/fs/sysv/sysv.h -@@ -142,7 +142,7 @@ extern int sysv_write_inode(struct inode - extern int sysv_sync_inode(struct inode *); - extern int sysv_sync_file(struct file *, struct dentry *, int); - extern void sysv_set_inode(struct inode *, dev_t); --extern int sysv_getattr(struct vfsmount *, struct dentry *, struct kstat *); -+extern int sysv_getattr(struct path *, struct kstat *); - extern int sysv_init_icache(void); - extern void sysv_destroy_icache(void); - -Index: linux-2.6/fs/xfs/linux-2.6/xfs_iops.c -=================================================================== ---- linux-2.6.orig/fs/xfs/linux-2.6/xfs_iops.c -+++ linux-2.6/fs/xfs/linux-2.6/xfs_iops.c -@@ -617,11 +617,10 @@ xfs_vn_permission( - - STATIC int - xfs_vn_getattr( -- struct vfsmount *mnt, -- struct dentry *dentry, -+ struct path *path, - struct kstat *stat) - { -- struct inode *inode = dentry->d_inode; -+ struct inode *inode = path->dentry->d_inode; - bhv_vnode_t *vp = vn_from_inode(inode); - bhv_vattr_t vattr = { .va_mask = XFS_AT_STAT }; - int error; -Index: linux-2.6/include/linux/coda_linux.h -=================================================================== ---- linux-2.6.orig/include/linux/coda_linux.h -+++ linux-2.6/include/linux/coda_linux.h -@@ -40,7 +40,7 @@ int coda_flush(struct file *f, fl_owner_ - int coda_release(struct inode *i, struct file *f); - int coda_permission(struct inode *inode, int mask, struct nameidata *nd); - int coda_revalidate_inode(struct dentry *); --int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *); -+int coda_getattr(struct path *, struct kstat *); - int coda_setattr(struct dentry *, struct iattr *); - - /* global variables */ -Index: linux-2.6/include/linux/fs.h -=================================================================== ---- linux-2.6.orig/include/linux/fs.h -+++ linux-2.6/include/linux/fs.h -@@ -1118,7 +1118,7 @@ struct inode_operations { - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int, struct nameidata *); - int (*setattr) (struct dentry *, struct iattr *); -- int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); -+ int (*getattr) (struct path *path, struct kstat *); - int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); - ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); - ssize_t (*listxattr) (struct dentry *, char *, size_t); -@@ -1850,7 +1850,7 @@ extern int dcache_dir_open(struct inode - extern int dcache_dir_close(struct inode *, struct file *); - extern loff_t dcache_dir_lseek(struct file *, loff_t, int); - extern int dcache_readdir(struct file *, void *, filldir_t); --extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *); -+extern int simple_getattr(struct path *, struct kstat *); - extern int simple_statfs(struct dentry *, struct kstatfs *); - extern int simple_link(struct dentry *, struct inode *, struct dentry *); - extern int simple_unlink(struct inode *, struct dentry *); -Index: linux-2.6/include/linux/msdos_fs.h -=================================================================== ---- linux-2.6.orig/include/linux/msdos_fs.h -+++ linux-2.6/include/linux/msdos_fs.h -@@ -402,8 +402,7 @@ extern const struct file_operations fat_ - extern struct inode_operations fat_file_inode_operations; - extern int fat_notify_change(struct dentry * dentry, struct iattr * attr); - extern void fat_truncate(struct inode *inode); --extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, -- struct kstat *stat); -+extern int fat_getattr(struct path *path, struct kstat *stat); - - /* fat/inode.c */ - extern void fat_attach(struct inode *inode, loff_t i_pos); -Index: linux-2.6/include/linux/nfs_fs.h -=================================================================== ---- linux-2.6.orig/include/linux/nfs_fs.h -+++ linux-2.6/include/linux/nfs_fs.h -@@ -297,7 +297,7 @@ extern struct inode *nfs_fhget(struct su - struct nfs_fattr *); - extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *); - extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr); --extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); -+extern int nfs_getattr(struct path *, struct kstat *); - extern int nfs_permission(struct inode *, int, struct nameidata *); - extern int nfs_access_get_cached(struct inode *, struct rpc_cred *, struct nfs_access_entry *); - extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *); diff --git a/kernel-patches/for-mainline/struct_path/struct_path-nameidata.diff b/kernel-patches/for-mainline/struct_path/struct_path-nameidata.diff deleted file mode 100644 index 6e0fcda79..000000000 --- a/kernel-patches/for-mainline/struct_path/struct_path-nameidata.diff +++ /dev/null @@ -1,2287 +0,0 @@ -Pack the vfsmount and dentry in nameidata into a struct path - -Signed-off-by: Andreas Gruenbacher - -Index: linux-2.6-hooks/include/linux/namei.h -=================================================================== ---- linux-2.6-hooks.orig/include/linux/namei.h -+++ linux-2.6-hooks/include/linux/namei.h -@@ -6,6 +6,11 @@ - - struct vfsmount; - -+struct path { -+ struct vfsmount *mnt; -+ struct dentry *dentry; -+}; -+ - struct open_intent { - int flags; - int create_mode; -@@ -15,8 +20,7 @@ struct open_intent { - enum { MAX_NESTED_LINKS = 8 }; - - struct nameidata { -- struct dentry *dentry; -- struct vfsmount *mnt; -+ struct path path; - struct qstr last; - unsigned int flags; - int last_type; -@@ -29,11 +33,6 @@ struct nameidata { - } intent; - }; - --struct path { -- struct vfsmount *mnt; -- struct dentry *dentry; --}; -- - /* - * Type of the last component on LOOKUP_PARENT - */ -Index: linux-2.6-hooks/drivers/md/dm-table.c -=================================================================== ---- linux-2.6-hooks.orig/drivers/md/dm-table.c -+++ linux-2.6-hooks/drivers/md/dm-table.c -@@ -356,7 +356,7 @@ static int lookup_device(const char *pat - if ((r = path_lookup(path, LOOKUP_FOLLOW, &nd))) - return r; - -- inode = nd.dentry->d_inode; -+ inode = nd.path.dentry->d_inode; - if (!inode) { - r = -ENOENT; - goto out; -Index: linux-2.6-hooks/fs/afs/mntpt.c -=================================================================== ---- linux-2.6-hooks.orig/fs/afs/mntpt.c -+++ linux-2.6-hooks/fs/afs/mntpt.c -@@ -235,9 +235,9 @@ static void *afs_mntpt_follow_link(struc - kenter("%p{%s},{%s:%p{%s}}", - dentry, - dentry->d_name.name, -- nd->mnt->mnt_devname, -+ nd->path.mnt->mnt_devname, - dentry, -- nd->dentry->d_name.name); -+ nd->path.dentry->d_name.name); - - newmnt = afs_mntpt_do_automount(dentry); - if (IS_ERR(newmnt)) { -@@ -245,18 +245,18 @@ static void *afs_mntpt_follow_link(struc - return (void *)newmnt; - } - -- old_dentry = nd->dentry; -- nd->dentry = dentry; -+ old_dentry = nd->path.dentry; -+ nd->path.dentry = dentry; - err = do_add_mount(newmnt, nd, 0, &afs_vfsmounts); -- nd->dentry = old_dentry; -+ nd->path.dentry = old_dentry; - - path_release(nd); - - if (!err) { - mntget(newmnt); -- nd->mnt = newmnt; -+ nd->path.mnt = newmnt; - dget(newmnt->mnt_root); -- nd->dentry = newmnt->mnt_root; -+ nd->path.dentry = newmnt->mnt_root; - } - - kleave(" = %d", err); -Index: linux-2.6-hooks/fs/autofs4/root.c -=================================================================== ---- linux-2.6-hooks.orig/fs/autofs4/root.c -+++ linux-2.6-hooks/fs/autofs4/root.c -@@ -369,7 +369,8 @@ static void *autofs4_follow_link(struct - * so we don't need to follow the mount. - */ - if (d_mountpoint(dentry)) { -- if (!autofs4_follow_mount(&nd->mnt, &nd->dentry)) { -+ if (!autofs4_follow_mount(&nd->path.mnt, -+ &nd->path.dentry)) { - status = -ENOENT; - goto out_error; - } -Index: linux-2.6-hooks/fs/block_dev.c -=================================================================== ---- linux-2.6-hooks.orig/fs/block_dev.c -+++ linux-2.6-hooks/fs/block_dev.c -@@ -1339,12 +1339,12 @@ struct block_device *lookup_bdev(const c - if (error) - return ERR_PTR(error); - -- inode = nd.dentry->d_inode; -+ inode = nd.path.dentry->d_inode; - error = -ENOTBLK; - if (!S_ISBLK(inode->i_mode)) - goto fail; - error = -EACCES; -- if (nd.mnt->mnt_flags & MNT_NODEV) -+ if (nd.path.mnt->mnt_flags & MNT_NODEV) - goto fail; - error = -ENOMEM; - bdev = bd_acquire(inode); -Index: linux-2.6-hooks/fs/coda/pioctl.c -=================================================================== ---- linux-2.6-hooks.orig/fs/coda/pioctl.c -+++ linux-2.6-hooks/fs/coda/pioctl.c -@@ -75,7 +75,7 @@ static int coda_pioctl(struct inode * in - if ( error ) { - return error; - } else { -- target_inode = nd.dentry->d_inode; -+ target_inode = nd.path.dentry->d_inode; - } - - /* return if it is not a Coda inode */ -Index: linux-2.6-hooks/fs/configfs/symlink.c -=================================================================== ---- linux-2.6-hooks.orig/fs/configfs/symlink.c -+++ linux-2.6-hooks/fs/configfs/symlink.c -@@ -99,8 +99,8 @@ static int get_target(const char *symnam - - ret = path_lookup(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, nd); - if (!ret) { -- if (nd->dentry->d_sb == configfs_sb) { -- *target = configfs_get_config_item(nd->dentry); -+ if (nd->path.dentry->d_sb == configfs_sb) { -+ *target = configfs_get_config_item(nd->path.dentry); - if (!*target) { - ret = -ENOENT; - path_release(nd); -Index: linux-2.6-hooks/fs/dquot.c -=================================================================== ---- linux-2.6-hooks.orig/fs/dquot.c -+++ linux-2.6-hooks/fs/dquot.c -@@ -1519,14 +1519,15 @@ int vfs_quota_on(struct super_block *sb, - error = path_lookup(path, LOOKUP_FOLLOW, &nd); - if (error < 0) - return error; -- error = security_quota_on(nd.dentry); -+ error = security_quota_on(nd.path.dentry); - if (error) - goto out_path; - /* Quota file not on the same filesystem? */ -- if (nd.mnt->mnt_sb != sb) -+ if (nd.path.mnt->mnt_sb != sb) - error = -EXDEV; - else -- error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id); -+ error = vfs_quota_on_inode(nd.path.dentry->d_inode, type, -+ format_id); - out_path: - path_release(&nd); - return error; -Index: linux-2.6-hooks/fs/ecryptfs/dentry.c -=================================================================== ---- linux-2.6-hooks.orig/fs/ecryptfs/dentry.c -+++ linux-2.6-hooks/fs/ecryptfs/dentry.c -@@ -51,13 +51,13 @@ static int ecryptfs_d_revalidate(struct - - if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate) - goto out; -- dentry_save = nd->dentry; -- vfsmount_save = nd->mnt; -- nd->dentry = lower_dentry; -- nd->mnt = lower_mnt; -+ dentry_save = nd->path.dentry; -+ vfsmount_save = nd->path.mnt; -+ nd->path.dentry = lower_dentry; -+ nd->path.mnt = lower_mnt; - rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd); -- nd->dentry = dentry_save; -- nd->mnt = vfsmount_save; -+ nd->path.dentry = dentry_save; -+ nd->path.mnt = vfsmount_save; - if (dentry->d_inode) { - struct inode *lower_inode = - ecryptfs_inode_to_lower(dentry->d_inode); -Index: linux-2.6-hooks/fs/ecryptfs/inode.c -=================================================================== ---- linux-2.6-hooks.orig/fs/ecryptfs/inode.c -+++ linux-2.6-hooks/fs/ecryptfs/inode.c -@@ -77,13 +77,13 @@ ecryptfs_create_underlying_file(struct i - struct vfsmount *vfsmount_save; - int rc; - -- dentry_save = nd->dentry; -- vfsmount_save = nd->mnt; -- nd->dentry = lower_dentry; -- nd->mnt = lower_mnt; -+ dentry_save = nd->path.dentry; -+ vfsmount_save = nd->path.mnt; -+ nd->path.dentry = lower_dentry; -+ nd->path.mnt = lower_mnt; - rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd); -- nd->dentry = dentry_save; -- nd->mnt = vfsmount_save; -+ nd->path.dentry = dentry_save; -+ nd->path.mnt = vfsmount_save; - return rc; - } - -@@ -371,7 +371,7 @@ static struct dentry *ecryptfs_lookup(st - goto out_dput; - } - memset(page_virt, 0, PAGE_CACHE_SIZE); -- rc = ecryptfs_read_header_region(page_virt, lower_dentry, nd->mnt); -+ rc = ecryptfs_read_header_region(page_virt, lower_dentry, nd->path.mnt); - crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; - if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) - ecryptfs_set_default_sizes(crypt_stat); -@@ -827,14 +827,14 @@ ecryptfs_permission(struct inode *inode, - int rc; - - if (nd) { -- struct vfsmount *vfsmnt_save = nd->mnt; -- struct dentry *dentry_save = nd->dentry; -+ struct vfsmount *vfsmnt_save = nd->path.mnt; -+ struct dentry *dentry_save = nd->path.dentry; - -- nd->mnt = ecryptfs_dentry_to_lower_mnt(nd->dentry); -- nd->dentry = ecryptfs_dentry_to_lower(nd->dentry); -+ nd->path.mnt = ecryptfs_dentry_to_lower_mnt(nd->path.dentry); -+ nd->path.dentry = ecryptfs_dentry_to_lower(nd->path.dentry); - rc = permission(ecryptfs_inode_to_lower(inode), mask, nd); -- nd->mnt = vfsmnt_save; -- nd->dentry = dentry_save; -+ nd->path.mnt = vfsmnt_save; -+ nd->path.dentry = dentry_save; - } else - rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL); - return rc; -Index: linux-2.6-hooks/fs/ecryptfs/main.c -=================================================================== ---- linux-2.6-hooks.orig/fs/ecryptfs/main.c -+++ linux-2.6-hooks/fs/ecryptfs/main.c -@@ -441,14 +441,14 @@ static int ecryptfs_read_super(struct su - ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n"); - goto out_free; - } -- lower_root = nd.dentry; -+ lower_root = nd.path.dentry; - if (!lower_root->d_inode) { - ecryptfs_printk(KERN_WARNING, - "No directory to interpose on\n"); - rc = -ENOENT; - goto out_free; - } -- lower_mnt = nd.mnt; -+ lower_mnt = nd.path.mnt; - ecryptfs_set_superblock_lower(sb, lower_root->d_sb); - sb->s_maxbytes = lower_root->d_sb->s_maxbytes; - ecryptfs_set_dentry_lower(sb->s_root, lower_root); -Index: linux-2.6-hooks/fs/exec.c -=================================================================== ---- linux-2.6-hooks.orig/fs/exec.c -+++ linux-2.6-hooks/fs/exec.c -@@ -133,7 +133,7 @@ asmlinkage long sys_uselib(const char __ - goto out; - - error = -EINVAL; -- if (!S_ISREG(nd.dentry->d_inode->i_mode)) -+ if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) - goto exit; - - error = vfs_permission(&nd, MAY_READ | MAY_EXEC); -@@ -482,9 +482,9 @@ struct file *open_exec(const char *name) - file = ERR_PTR(err); - - if (!err) { -- struct inode *inode = nd.dentry->d_inode; -+ struct inode *inode = nd.path.dentry->d_inode; - file = ERR_PTR(-EACCES); -- if (!(nd.mnt->mnt_flags & MNT_NOEXEC) && -+ if (!(nd.path.mnt->mnt_flags & MNT_NOEXEC) && - S_ISREG(inode->i_mode)) { - int err = vfs_permission(&nd, MAY_EXEC); - file = ERR_PTR(err); -Index: linux-2.6-hooks/fs/ext3/super.c -=================================================================== ---- linux-2.6-hooks.orig/fs/ext3/super.c -+++ linux-2.6-hooks/fs/ext3/super.c -@@ -2601,12 +2601,12 @@ static int ext3_quota_on(struct super_bl - if (err) - return err; - /* Quotafile not on the same filesystem? */ -- if (nd.mnt->mnt_sb != sb) { -+ if (nd.path.mnt->mnt_sb != sb) { - path_release(&nd); - return -EXDEV; - } - /* Quotafile not of fs root? */ -- if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode) -+ if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) - printk(KERN_WARNING - "EXT3-fs: Quota file not on filesystem root. " - "Journalled quota will not work.\n"); -Index: linux-2.6-hooks/fs/ext4/super.c -=================================================================== ---- linux-2.6-hooks.orig/fs/ext4/super.c -+++ linux-2.6-hooks/fs/ext4/super.c -@@ -2676,12 +2676,12 @@ static int ext4_quota_on(struct super_bl - if (err) - return err; - /* Quotafile not on the same filesystem? */ -- if (nd.mnt->mnt_sb != sb) { -+ if (nd.path.mnt->mnt_sb != sb) { - path_release(&nd); - return -EXDEV; - } - /* Quotafile not of fs root? */ -- if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode) -+ if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) - printk(KERN_WARNING - "EXT4-fs: Quota file not on filesystem root. " - "Journalled quota will not work.\n"); -Index: linux-2.6-hooks/fs/gfs2/ops_fstype.c -=================================================================== ---- linux-2.6-hooks.orig/fs/gfs2/ops_fstype.c -+++ linux-2.6-hooks/fs/gfs2/ops_fstype.c -@@ -827,13 +827,13 @@ static struct super_block* get_gfs2_sb(c - dev_name); - goto out; - } -- error = vfs_getattr(nd.mnt, nd.dentry, &stat); -+ error = vfs_getattr(nd.path.mnt, nd.path.dentry, &stat); - - fstype = get_fs_type("gfs2"); - list_for_each(l, &fstype->fs_supers) { - s = list_entry(l, struct super_block, s_instances); - if ((S_ISBLK(stat.mode) && s->s_dev == stat.rdev) || -- (S_ISDIR(stat.mode) && s == nd.dentry->d_inode->i_sb)) { -+ (S_ISDIR(stat.mode) && s == nd.path.dentry->d_inode->i_sb)) { - sb = s; - goto free_nd; - } -Index: linux-2.6-hooks/fs/inotify_user.c -=================================================================== ---- linux-2.6-hooks.orig/fs/inotify_user.c -+++ linux-2.6-hooks/fs/inotify_user.c -@@ -631,7 +631,7 @@ asmlinkage long sys_inotify_add_watch(in - goto fput_and_out; - - /* inode held in place by reference to nd; dev by fget on fd */ -- inode = nd.dentry->d_inode; -+ inode = nd.path.dentry->d_inode; - dev = filp->private_data; - - mutex_lock(&dev->up_mutex); -Index: linux-2.6-hooks/fs/jffs2/super.c -=================================================================== ---- linux-2.6-hooks.orig/fs/jffs2/super.c -+++ linux-2.6-hooks/fs/jffs2/super.c -@@ -248,29 +248,29 @@ static int jffs2_get_sb(struct file_syst - err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd); - - D1(printk(KERN_DEBUG "jffs2_get_sb(): path_lookup() returned %d, inode %p\n", -- err, nd.dentry->d_inode)); -+ err, nd.path.dentry->d_inode)); - - if (err) - return err; - - err = -EINVAL; - -- if (!S_ISBLK(nd.dentry->d_inode->i_mode)) -+ if (!S_ISBLK(nd.path.dentry->d_inode->i_mode)) - goto out; - -- if (nd.mnt->mnt_flags & MNT_NODEV) { -+ if (nd.path.mnt->mnt_flags & MNT_NODEV) { - err = -EACCES; - goto out; - } - -- if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR) { -+ if (imajor(nd.path.dentry->d_inode) != MTD_BLOCK_MAJOR) { - if (!(flags & MS_SILENT)) - printk(KERN_NOTICE "Attempt to mount non-MTD device \"%s\" as JFFS2\n", - dev_name); - goto out; - } - -- mtdnr = iminor(nd.dentry->d_inode); -+ mtdnr = iminor(nd.path.dentry->d_inode); - path_release(&nd); - - return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt); -Index: linux-2.6-hooks/fs/namei.c -=================================================================== ---- linux-2.6-hooks.orig/fs/namei.c -+++ linux-2.6-hooks/fs/namei.c -@@ -253,7 +253,8 @@ int permission(struct inode *inode, int - * the fs is mounted with the "noexec" flag. - */ - if ((mask & MAY_EXEC) && S_ISREG(mode) && (!(mode & S_IXUGO) || -- (nd && nd->mnt && (nd->mnt->mnt_flags & MNT_NOEXEC)))) -+ (nd && nd->path.mnt && -+ (nd->path.mnt->mnt_flags & MNT_NOEXEC)))) - return -EACCES; - - /* Ordinary permission routines do not understand MAY_APPEND. */ -@@ -280,7 +281,7 @@ int permission(struct inode *inode, int - */ - int vfs_permission(struct nameidata *nd, int mask) - { -- return permission(nd->dentry->d_inode, mask, nd); -+ return permission(nd->path.dentry->d_inode, mask, nd); - } - - /** -@@ -348,8 +349,8 @@ int deny_write_access(struct file * file - - void path_release(struct nameidata *nd) - { -- dput(nd->dentry); -- mntput(nd->mnt); -+ dput(nd->path.dentry); -+ mntput(nd->path.mnt); - } - - /* -@@ -358,8 +359,8 @@ void path_release(struct nameidata *nd) - */ - void path_release_on_umount(struct nameidata *nd) - { -- dput(nd->dentry); -- mntput_no_expire(nd->mnt); -+ dput(nd->path.dentry); -+ mntput_no_expire(nd->path.mnt); - } - - /** -@@ -524,15 +525,15 @@ walk_init_root(const char *name, struct - - read_lock(&fs->lock); - if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { -- nd->mnt = mntget(fs->altrootmnt); -- nd->dentry = dget(fs->altroot); -+ nd->path.mnt = mntget(fs->altrootmnt); -+ nd->path.dentry = dget(fs->altroot); - read_unlock(&fs->lock); - if (__emul_lookup_dentry(name,nd)) - return 0; - read_lock(&fs->lock); - } -- nd->mnt = mntget(fs->rootmnt); -- nd->dentry = dget(fs->root); -+ nd->path.mnt = mntget(fs->rootmnt); -+ nd->path.dentry = dget(fs->root); - read_unlock(&fs->lock); - return 1; - } -@@ -575,17 +576,16 @@ fail: - static inline void dput_path(struct path *path, struct nameidata *nd) - { - dput(path->dentry); -- if (path->mnt != nd->mnt) -+ if (path->mnt != nd->path.mnt) - mntput(path->mnt); - } - - static inline void path_to_nameidata(struct path *path, struct nameidata *nd) - { -- dput(nd->dentry); -- if (nd->mnt != path->mnt) -- mntput(nd->mnt); -- nd->mnt = path->mnt; -- nd->dentry = path->dentry; -+ dput(nd->path.dentry); -+ if (nd->path.mnt != path->mnt) -+ mntput(nd->path.mnt); -+ nd->path = *path; - } - - static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd) -@@ -597,7 +597,7 @@ static __always_inline int __do_follow_l - touch_atime(path->mnt, dentry); - nd_set_link(nd, NULL); - -- if (path->mnt != nd->mnt) { -+ if (path->mnt != nd->path.mnt) { - path_to_nameidata(path, nd); - dget(dentry); - } -@@ -727,37 +727,37 @@ static __always_inline void follow_dotdo - - while(1) { - struct vfsmount *parent; -- struct dentry *old = nd->dentry; -+ struct dentry *old = nd->path.dentry; - - read_lock(&fs->lock); -- if (nd->dentry == fs->root && -- nd->mnt == fs->rootmnt) { -+ if (nd->path.dentry == fs->root && -+ nd->path.mnt == fs->rootmnt) { - read_unlock(&fs->lock); - break; - } - read_unlock(&fs->lock); - spin_lock(&dcache_lock); -- if (nd->dentry != nd->mnt->mnt_root) { -- nd->dentry = dget(nd->dentry->d_parent); -+ if (nd->path.dentry != nd->path.mnt->mnt_root) { -+ nd->path.dentry = dget(nd->path.dentry->d_parent); - spin_unlock(&dcache_lock); - dput(old); - break; - } - spin_unlock(&dcache_lock); - spin_lock(&vfsmount_lock); -- parent = nd->mnt->mnt_parent; -- if (parent == nd->mnt) { -+ parent = nd->path.mnt->mnt_parent; -+ if (parent == nd->path.mnt) { - spin_unlock(&vfsmount_lock); - break; - } - mntget(parent); -- nd->dentry = dget(nd->mnt->mnt_mountpoint); -+ nd->path.dentry = dget(nd->path.mnt->mnt_mountpoint); - spin_unlock(&vfsmount_lock); - dput(old); -- mntput(nd->mnt); -- nd->mnt = parent; -+ mntput(nd->path.mnt); -+ nd->path.mnt = parent; - } -- follow_mount(&nd->mnt, &nd->dentry); -+ follow_mount(&nd->path.mnt, &nd->path.dentry); - } - - /* -@@ -768,8 +768,8 @@ static __always_inline void follow_dotdo - static int do_lookup(struct nameidata *nd, struct qstr *name, - struct path *path) - { -- struct vfsmount *mnt = nd->mnt; -- struct dentry *dentry = __d_lookup(nd->dentry, name); -+ struct vfsmount *mnt = nd->path.mnt; -+ struct dentry *dentry = __d_lookup(nd->path.dentry, name); - - if (!dentry) - goto need_lookup; -@@ -782,7 +782,7 @@ done: - return 0; - - need_lookup: -- dentry = real_lookup(nd->dentry, name, nd); -+ dentry = real_lookup(nd->path.dentry, name, nd); - if (IS_ERR(dentry)) - goto fail; - goto done; -@@ -819,7 +819,7 @@ static fastcall int __link_path_walk(con - if (!*name) - goto return_reval; - -- inode = nd->dentry->d_inode; -+ inode = nd->path.dentry->d_inode; - if (nd->depth) - lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE); - -@@ -867,7 +867,7 @@ static fastcall int __link_path_walk(con - if (this.name[1] != '.') - break; - follow_dotdot(nd); -- inode = nd->dentry->d_inode; -+ inode = nd->path.dentry->d_inode; - /* fallthrough */ - case 1: - continue; -@@ -876,8 +876,9 @@ static fastcall int __link_path_walk(con - * See if the low-level filesystem might want - * to use its own hash.. - */ -- if (nd->dentry->d_op && nd->dentry->d_op->d_hash) { -- err = nd->dentry->d_op->d_hash(nd->dentry, &this); -+ if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) { -+ err = nd->path.dentry->d_op->d_hash(nd->path.dentry, -+ &this); - if (err < 0) - break; - } -@@ -899,7 +900,7 @@ static fastcall int __link_path_walk(con - if (err) - goto return_err; - err = -ENOENT; -- inode = nd->dentry->d_inode; -+ inode = nd->path.dentry->d_inode; - if (!inode) - break; - err = -ENOTDIR; -@@ -927,13 +928,14 @@ last_component: - if (this.name[1] != '.') - break; - follow_dotdot(nd); -- inode = nd->dentry->d_inode; -+ inode = nd->path.dentry->d_inode; - /* fallthrough */ - case 1: - goto return_reval; - } -- if (nd->dentry->d_op && nd->dentry->d_op->d_hash) { -- err = nd->dentry->d_op->d_hash(nd->dentry, &this); -+ if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) { -+ err = nd->path.dentry->d_op->d_hash(nd->path.dentry, -+ &this); - if (err < 0) - break; - } -@@ -946,7 +948,7 @@ last_component: - err = do_follow_link(&next, nd); - if (err) - goto return_err; -- inode = nd->dentry->d_inode; -+ inode = nd->path.dentry->d_inode; - } else - path_to_nameidata(&next, nd); - err = -ENOENT; -@@ -974,11 +976,12 @@ return_reval: - * We bypassed the ordinary revalidation routines. - * We may need to check the cached dentry for staleness. - */ -- if (nd->dentry && nd->dentry->d_sb && -- (nd->dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) { -+ if (nd->path.dentry && nd->path.dentry->d_sb && -+ (nd->path.dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) { - err = -ESTALE; - /* Note: we do not d_invalidate() */ -- if (!nd->dentry->d_op->d_revalidate(nd->dentry, nd)) -+ if (!nd->path.dentry->d_op->d_revalidate( -+ nd->path.dentry, nd)) - break; - } - return_base: -@@ -1005,20 +1008,20 @@ int fastcall link_path_walk(const char * - int result; - - /* make sure the stuff we saved doesn't go away */ -- dget(save.dentry); -- mntget(save.mnt); -+ dget(save.path.dentry); -+ mntget(save.path.mnt); - - result = __link_path_walk(name, nd); - if (result == -ESTALE) { - *nd = save; -- dget(nd->dentry); -- mntget(nd->mnt); -+ dget(nd->path.dentry); -+ mntget(nd->path.mnt); - nd->flags |= LOOKUP_REVAL; - result = __link_path_walk(name, nd); - } - -- dput(save.dentry); -- mntput(save.mnt); -+ dput(save.path.dentry); -+ mntput(save.path.mnt); - - return result; - } -@@ -1038,9 +1041,10 @@ static int __emul_lookup_dentry(const ch - if (path_walk(name, nd)) - return 0; /* something went wrong... */ - -- if (!nd->dentry->d_inode || S_ISDIR(nd->dentry->d_inode->i_mode)) { -- struct dentry *old_dentry = nd->dentry; -- struct vfsmount *old_mnt = nd->mnt; -+ if (!nd->path.dentry->d_inode || -+ S_ISDIR(nd->path.dentry->d_inode->i_mode)) { -+ struct dentry *old_dentry = nd->path.dentry; -+ struct vfsmount *old_mnt = nd->path.mnt; - struct qstr last = nd->last; - int last_type = nd->last_type; - struct fs_struct *fs = current->fs; -@@ -1051,19 +1055,19 @@ static int __emul_lookup_dentry(const ch - */ - nd->last_type = LAST_ROOT; - read_lock(&fs->lock); -- nd->mnt = mntget(fs->rootmnt); -- nd->dentry = dget(fs->root); -+ nd->path.mnt = mntget(fs->rootmnt); -+ nd->path.dentry = dget(fs->root); - read_unlock(&fs->lock); - if (path_walk(name, nd) == 0) { -- if (nd->dentry->d_inode) { -+ if (nd->path.dentry->d_inode) { - dput(old_dentry); - mntput(old_mnt); - return 1; - } - path_release(nd); - } -- nd->dentry = old_dentry; -- nd->mnt = old_mnt; -+ nd->path.dentry = old_dentry; -+ nd->path.mnt = old_mnt; - nd->last = last; - nd->last_type = last_type; - } -@@ -1083,8 +1087,8 @@ void set_fs_altroot(void) - goto set_it; - err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd); - if (!err) { -- mnt = nd.mnt; -- dentry = nd.dentry; -+ mnt = nd.path.mnt; -+ dentry = nd.path.dentry; - } - set_it: - write_lock(&fs->lock); -@@ -1115,20 +1119,20 @@ static int fastcall do_path_lookup(int d - if (*name=='/') { - read_lock(&fs->lock); - if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { -- nd->mnt = mntget(fs->altrootmnt); -- nd->dentry = dget(fs->altroot); -+ nd->path.mnt = mntget(fs->altrootmnt); -+ nd->path.dentry = dget(fs->altroot); - read_unlock(&fs->lock); - if (__emul_lookup_dentry(name,nd)) - goto out; /* found in altroot */ - read_lock(&fs->lock); - } -- nd->mnt = mntget(fs->rootmnt); -- nd->dentry = dget(fs->root); -+ nd->path.mnt = mntget(fs->rootmnt); -+ nd->path.dentry = dget(fs->root); - read_unlock(&fs->lock); - } else if (dfd == AT_FDCWD) { - read_lock(&fs->lock); -- nd->mnt = mntget(fs->pwdmnt); -- nd->dentry = dget(fs->pwd); -+ nd->path.mnt = mntget(fs->pwdmnt); -+ nd->path.dentry = dget(fs->pwd); - read_unlock(&fs->lock); - } else { - struct dentry *dentry; -@@ -1148,8 +1152,8 @@ static int fastcall do_path_lookup(int d - if (retval) - goto fput_fail; - -- nd->mnt = mntget(file->f_path.mnt); -- nd->dentry = dget(dentry); -+ nd->path.mnt = mntget(file->f_path.mnt); -+ nd->path.dentry = dget(dentry); - - fput_light(file, fput_needed); - } -@@ -1157,9 +1161,10 @@ static int fastcall do_path_lookup(int d - retval = link_path_walk(name, nd); - out: - if (likely(retval == 0)) { -- if (unlikely(!audit_dummy_context() && nd && nd->dentry && -- nd->dentry->d_inode)) -- audit_inode(name, nd->dentry->d_inode); -+ if (unlikely(!audit_dummy_context() && nd && -+ nd->path.dentry && -+ nd->path.dentry->d_inode)) -+ audit_inode(name, nd->path.dentry->d_inode); - } - out_fail: - return retval; -@@ -1289,7 +1294,7 @@ out: - - static struct dentry *lookup_hash(struct nameidata *nd) - { -- return __lookup_hash(&nd->last, nd->dentry, nd); -+ return __lookup_hash(&nd->last, nd->path.dentry, nd); - } - - /* SMP-safe */ -@@ -1515,7 +1520,7 @@ int vfs_create(struct inode *dir, struct - - int may_open(struct nameidata *nd, int acc_mode, int flag) - { -- struct dentry *dentry = nd->dentry; -+ struct dentry *dentry = nd->path.dentry; - struct inode *inode = dentry->d_inode; - int error; - -@@ -1540,7 +1545,7 @@ int may_open(struct nameidata *nd, int a - if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { - flag &= ~O_TRUNC; - } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { -- if (nd->mnt->mnt_flags & MNT_NODEV) -+ if (nd->path.mnt->mnt_flags & MNT_NODEV) - return -EACCES; - - flag &= ~O_TRUNC; -@@ -1596,14 +1601,14 @@ static int open_namei_create(struct name - int flag, int mode) - { - int error; -- struct dentry *dir = nd->dentry; -+ struct dentry *dir = nd->path.dentry; - - if (!IS_POSIXACL(dir->d_inode)) - mode &= ~current->fs->umask; - error = vfs_create(dir->d_inode, path->dentry, mode, nd); - mutex_unlock(&dir->d_inode->i_mutex); -- dput(nd->dentry); -- nd->dentry = path->dentry; -+ dput(nd->path.dentry); -+ nd->path.dentry = path->dentry; - if (error) - return error; - /* Don't check for write permission, don't truncate */ -@@ -1670,11 +1675,11 @@ int open_namei(int dfd, const char *path - if (nd->last_type != LAST_NORM || nd->last.name[nd->last.len]) - goto exit; - -- dir = nd->dentry; -+ dir = nd->path.dentry; - nd->flags &= ~LOOKUP_PARENT; - mutex_lock(&dir->d_inode->i_mutex); - path.dentry = lookup_hash(nd); -- path.mnt = nd->mnt; -+ path.mnt = nd->path.mnt; - - do_last: - error = PTR_ERR(path.dentry); -@@ -1779,10 +1784,10 @@ do_link: - __putname(nd->last.name); - goto exit; - } -- dir = nd->dentry; -+ dir = nd->path.dentry; - mutex_lock(&dir->d_inode->i_mutex); - path.dentry = lookup_hash(nd); -- path.mnt = nd->mnt; -+ path.mnt = nd->path.mnt; - __putname(nd->last.name); - goto do_last; - } -@@ -1795,13 +1800,13 @@ do_link: - * Simple function to lookup and return a dentry and create it - * if it doesn't exist. Is SMP-safe. - * -- * Returns with nd->dentry->d_inode->i_mutex locked. -+ * Returns with nd->path.dentry->d_inode->i_mutex locked. - */ - struct dentry *lookup_create(struct nameidata *nd, int is_dir) - { - struct dentry *dentry = ERR_PTR(-EEXIST); - -- mutex_lock_nested(&nd->dentry->d_inode->i_mutex, I_MUTEX_PARENT); -+ mutex_lock_nested(&nd->path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); - /* - * Yucky last component or no last component at all? - * (foo/., foo/.., /////) -@@ -1880,19 +1885,21 @@ asmlinkage long sys_mknodat(int dfd, con - dentry = lookup_create(&nd, 0); - error = PTR_ERR(dentry); - -- if (!IS_POSIXACL(nd.dentry->d_inode)) -+ if (!IS_POSIXACL(nd.path.dentry->d_inode)) - mode &= ~current->fs->umask; - if (!IS_ERR(dentry)) { - switch (mode & S_IFMT) { - case 0: case S_IFREG: -- error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); -+ error = vfs_create(nd.path.dentry->d_inode, dentry, -+ mode, &nd); - break; - case S_IFCHR: case S_IFBLK: -- error = vfs_mknod(nd.dentry->d_inode,dentry,mode, -- new_decode_dev(dev)); -+ error = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, -+ new_decode_dev(dev)); - break; - case S_IFIFO: case S_IFSOCK: -- error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0); -+ error = vfs_mknod(nd.path.dentry->d_inode, dentry, -+ mode, 0); - break; - case S_IFDIR: - error = -EPERM; -@@ -1902,7 +1909,7 @@ asmlinkage long sys_mknodat(int dfd, con - } - dput(dentry); - } -- mutex_unlock(&nd.dentry->d_inode->i_mutex); -+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - path_release(&nd); - out: - putname(tmp); -@@ -1957,12 +1964,12 @@ asmlinkage long sys_mkdirat(int dfd, con - if (IS_ERR(dentry)) - goto out_unlock; - -- if (!IS_POSIXACL(nd.dentry->d_inode)) -+ if (!IS_POSIXACL(nd.path.dentry->d_inode)) - mode &= ~current->fs->umask; -- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); -+ error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); - dput(dentry); - out_unlock: -- mutex_unlock(&nd.dentry->d_inode->i_mutex); -+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - path_release(&nd); - out: - putname(tmp); -@@ -2061,15 +2068,15 @@ static long do_rmdir(int dfd, const char - error = -EBUSY; - goto exit1; - } -- mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT); -+ mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); - dentry = lookup_hash(&nd); - error = PTR_ERR(dentry); - if (IS_ERR(dentry)) - goto exit2; -- error = vfs_rmdir(nd.dentry->d_inode, dentry); -+ error = vfs_rmdir(nd.path.dentry->d_inode, dentry); - dput(dentry); - exit2: -- mutex_unlock(&nd.dentry->d_inode->i_mutex); -+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - exit1: - path_release(&nd); - exit: -@@ -2136,7 +2143,7 @@ static long do_unlinkat(int dfd, const c - error = -EISDIR; - if (nd.last_type != LAST_NORM) - goto exit1; -- mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT); -+ mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); - dentry = lookup_hash(&nd); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { -@@ -2146,11 +2153,11 @@ static long do_unlinkat(int dfd, const c - inode = dentry->d_inode; - if (inode) - atomic_inc(&inode->i_count); -- error = vfs_unlink(nd.dentry->d_inode, dentry); -+ error = vfs_unlink(nd.path.dentry->d_inode, dentry); - exit2: - dput(dentry); - } -- mutex_unlock(&nd.dentry->d_inode->i_mutex); -+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - if (inode) - iput(inode); /* truncate the inode here */ - exit1: -@@ -2227,10 +2234,10 @@ asmlinkage long sys_symlinkat(const char - if (IS_ERR(dentry)) - goto out_unlock; - -- error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); -+ error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); - dput(dentry); - out_unlock: -- mutex_unlock(&nd.dentry->d_inode->i_mutex); -+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - path_release(&nd); - out: - putname(to); -@@ -2316,16 +2323,17 @@ asmlinkage long sys_linkat(int olddfd, c - if (error) - goto out; - error = -EXDEV; -- if (old_nd.mnt != nd.mnt) -+ if (old_nd.path.mnt != nd.path.mnt) - goto out_release; - new_dentry = lookup_create(&nd, 0); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto out_unlock; -- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); -+ error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, -+ new_dentry); - dput(new_dentry); - out_unlock: -- mutex_unlock(&nd.dentry->d_inode->i_mutex); -+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - out_release: - path_release(&nd); - out: -@@ -2505,15 +2513,15 @@ static int do_rename(int olddfd, const c - goto exit1; - - error = -EXDEV; -- if (oldnd.mnt != newnd.mnt) -+ if (oldnd.path.mnt != newnd.path.mnt) - goto exit2; - -- old_dir = oldnd.dentry; -+ old_dir = oldnd.path.dentry; - error = -EBUSY; - if (oldnd.last_type != LAST_NORM) - goto exit2; - -- new_dir = newnd.dentry; -+ new_dir = newnd.path.dentry; - if (newnd.last_type != LAST_NORM) - goto exit2; - -Index: linux-2.6-hooks/fs/namespace.c -=================================================================== ---- linux-2.6-hooks.orig/fs/namespace.c -+++ linux-2.6-hooks/fs/namespace.c -@@ -154,13 +154,13 @@ static void __touch_mnt_namespace(struct - - static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd) - { -- old_nd->dentry = mnt->mnt_mountpoint; -- old_nd->mnt = mnt->mnt_parent; -+ old_nd->path.dentry = mnt->mnt_mountpoint; -+ old_nd->path.mnt = mnt->mnt_parent; - mnt->mnt_parent = mnt; - mnt->mnt_mountpoint = mnt->mnt_root; - list_del_init(&mnt->mnt_child); - list_del_init(&mnt->mnt_hash); -- old_nd->dentry->d_mounted--; -+ old_nd->path.dentry->d_mounted--; - } - - void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, -@@ -173,10 +173,10 @@ void mnt_set_mountpoint(struct vfsmount - - static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd) - { -- mnt_set_mountpoint(nd->mnt, nd->dentry, mnt); -+ mnt_set_mountpoint(nd->path.mnt, nd->path.dentry, mnt); - list_add_tail(&mnt->mnt_hash, mount_hashtable + -- hash(nd->mnt, nd->dentry)); -- list_add_tail(&mnt->mnt_child, &nd->mnt->mnt_mounts); -+ hash(nd->path.mnt, nd->path.dentry)); -+ list_add_tail(&mnt->mnt_child, &nd->path.mnt->mnt_mounts); - } - - /* -@@ -639,16 +639,16 @@ asmlinkage long sys_umount(char __user * - if (retval) - goto out; - retval = -EINVAL; -- if (nd.dentry != nd.mnt->mnt_root) -+ if (nd.path.dentry != nd.path.mnt->mnt_root) - goto dput_and_out; -- if (!check_mnt(nd.mnt)) -+ if (!check_mnt(nd.path.mnt)) - goto dput_and_out; - - retval = -EPERM; - if (!capable(CAP_SYS_ADMIN)) - goto dput_and_out; - -- retval = do_umount(nd.mnt, flags); -+ retval = do_umount(nd.path.mnt, flags); - dput_and_out: - path_release_on_umount(&nd); - out: -@@ -673,10 +673,10 @@ static int mount_is_safe(struct nameidat - return 0; - return -EPERM; - #ifdef notyet -- if (S_ISLNK(nd->dentry->d_inode->i_mode)) -+ if (S_ISLNK(nd->path.dentry->d_inode->i_mode)) - return -EPERM; -- if (nd->dentry->d_inode->i_mode & S_ISVTX) { -- if (current->uid != nd->dentry->d_inode->i_uid) -+ if (nd->path.dentry->d_inode->i_mode & S_ISVTX) { -+ if (current->uid != nd->path.dentry->d_inode->i_uid) - return -EPERM; - } - if (vfs_permission(nd, MAY_WRITE)) -@@ -725,8 +725,8 @@ struct vfsmount *copy_tree(struct vfsmou - q = q->mnt_parent; - } - p = s; -- nd.mnt = q; -- nd.dentry = p->mnt_mountpoint; -+ nd.path.mnt = q; -+ nd.path.dentry = p->mnt_mountpoint; - q = clone_mnt(p, p->mnt_root, flag); - if (!q) - goto Enomem; -@@ -815,8 +815,8 @@ static int attach_recursive_mnt(struct v - struct nameidata *nd, struct nameidata *parent_nd) - { - LIST_HEAD(tree_list); -- struct vfsmount *dest_mnt = nd->mnt; -- struct dentry *dest_dentry = nd->dentry; -+ struct vfsmount *dest_mnt = nd->path.mnt; -+ struct dentry *dest_dentry = nd->path.dentry; - struct vfsmount *child, *p; - - if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list)) -@@ -851,13 +851,13 @@ static int graft_tree(struct vfsmount *m - if (mnt->mnt_sb->s_flags & MS_NOUSER) - return -EINVAL; - -- if (S_ISDIR(nd->dentry->d_inode->i_mode) != -+ if (S_ISDIR(nd->path.dentry->d_inode->i_mode) != - S_ISDIR(mnt->mnt_root->d_inode->i_mode)) - return -ENOTDIR; - - err = -ENOENT; -- mutex_lock(&nd->dentry->d_inode->i_mutex); -- if (IS_DEADDIR(nd->dentry->d_inode)) -+ mutex_lock(&nd->path.dentry->d_inode->i_mutex); -+ if (IS_DEADDIR(nd->path.dentry->d_inode)) - goto out_unlock; - - err = security_sb_check_sb(mnt, nd); -@@ -865,10 +865,10 @@ static int graft_tree(struct vfsmount *m - goto out_unlock; - - err = -ENOENT; -- if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry)) -+ if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry)) - err = attach_recursive_mnt(mnt, nd, NULL); - out_unlock: -- mutex_unlock(&nd->dentry->d_inode->i_mutex); -+ mutex_unlock(&nd->path.dentry->d_inode->i_mutex); - if (!err) - security_sb_post_addmount(mnt, nd); - return err; -@@ -879,11 +879,11 @@ out_unlock: - */ - static int do_change_type(struct nameidata *nd, int flag) - { -- struct vfsmount *m, *mnt = nd->mnt; -+ struct vfsmount *m, *mnt = nd->path.mnt; - int recurse = flag & MS_REC; - int type = flag & ~MS_REC; - -- if (nd->dentry != nd->mnt->mnt_root) -+ if (nd->path.dentry != nd->path.mnt->mnt_root) - return -EINVAL; - - down_write(&namespace_sem); -@@ -913,17 +913,17 @@ static int do_loopback(struct nameidata - - down_write(&namespace_sem); - err = -EINVAL; -- if (IS_MNT_UNBINDABLE(old_nd.mnt)) -+ if (IS_MNT_UNBINDABLE(old_nd.path.mnt)) - goto out; - -- if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt)) -+ if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt)) - goto out; - - err = -ENOMEM; - if (recurse) -- mnt = copy_tree(old_nd.mnt, old_nd.dentry, 0); -+ mnt = copy_tree(old_nd.path.mnt, old_nd.path.dentry, 0); - else -- mnt = clone_mnt(old_nd.mnt, old_nd.dentry, 0); -+ mnt = clone_mnt(old_nd.path.mnt, old_nd.path.dentry, 0); - - if (!mnt) - goto out; -@@ -952,24 +952,24 @@ static int do_remount(struct nameidata * - void *data) - { - int err; -- struct super_block *sb = nd->mnt->mnt_sb; -+ struct super_block *sb = nd->path.mnt->mnt_sb; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - -- if (!check_mnt(nd->mnt)) -+ if (!check_mnt(nd->path.mnt)) - return -EINVAL; - -- if (nd->dentry != nd->mnt->mnt_root) -+ if (nd->path.dentry != nd->path.mnt->mnt_root) - return -EINVAL; - - down_write(&sb->s_umount); - err = do_remount_sb(sb, flags, data, 0); - if (!err) -- nd->mnt->mnt_flags = mnt_flags; -+ nd->path.mnt->mnt_flags = mnt_flags; - up_write(&sb->s_umount); - if (!err) -- security_sb_post_remount(nd->mnt, flags, data); -+ security_sb_post_remount(nd->path.mnt, flags, data); - return err; - } - -@@ -997,56 +997,59 @@ static int do_move_mount(struct nameidat - return err; - - down_write(&namespace_sem); -- while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) -+ while (d_mountpoint(nd->path.dentry) && -+ follow_down(&nd->path.mnt, &nd->path.dentry)) - ; - err = -EINVAL; -- if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt)) -+ if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt)) - goto out; - - err = -ENOENT; -- mutex_lock(&nd->dentry->d_inode->i_mutex); -- if (IS_DEADDIR(nd->dentry->d_inode)) -+ mutex_lock(&nd->path.dentry->d_inode->i_mutex); -+ if (IS_DEADDIR(nd->path.dentry->d_inode)) - goto out1; - -- if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry)) -+ if (!IS_ROOT(nd->path.dentry) && d_unhashed(nd->path.dentry)) - goto out1; - - err = -EINVAL; -- if (old_nd.dentry != old_nd.mnt->mnt_root) -+ if (old_nd.path.dentry != old_nd.path.mnt->mnt_root) - goto out1; - -- if (old_nd.mnt == old_nd.mnt->mnt_parent) -+ if (old_nd.path.mnt == old_nd.path.mnt->mnt_parent) - goto out1; - -- if (S_ISDIR(nd->dentry->d_inode->i_mode) != -- S_ISDIR(old_nd.dentry->d_inode->i_mode)) -+ if (S_ISDIR(nd->path.dentry->d_inode->i_mode) != -+ S_ISDIR(old_nd.path.dentry->d_inode->i_mode)) - goto out1; - /* - * Don't move a mount residing in a shared parent. - */ -- if (old_nd.mnt->mnt_parent && IS_MNT_SHARED(old_nd.mnt->mnt_parent)) -+ if (old_nd.path.mnt->mnt_parent && -+ IS_MNT_SHARED(old_nd.path.mnt->mnt_parent)) - goto out1; - /* - * Don't move a mount tree containing unbindable mounts to a destination - * mount which is shared. - */ -- if (IS_MNT_SHARED(nd->mnt) && tree_contains_unbindable(old_nd.mnt)) -+ if (IS_MNT_SHARED(nd->path.mnt) && -+ tree_contains_unbindable(old_nd.path.mnt)) - goto out1; - err = -ELOOP; -- for (p = nd->mnt; p->mnt_parent != p; p = p->mnt_parent) -- if (p == old_nd.mnt) -+ for (p = nd->path.mnt; p->mnt_parent != p; p = p->mnt_parent) -+ if (p == old_nd.path.mnt) - goto out1; - -- if ((err = attach_recursive_mnt(old_nd.mnt, nd, &parent_nd))) -+ if ((err = attach_recursive_mnt(old_nd.path.mnt, nd, &parent_nd))) - goto out1; - - spin_lock(&vfsmount_lock); - /* if the mount is moved, it should no longer be expire - * automatically */ -- list_del_init(&old_nd.mnt->mnt_expire); -+ list_del_init(&old_nd.path.mnt->mnt_expire); - spin_unlock(&vfsmount_lock); - out1: -- mutex_unlock(&nd->dentry->d_inode->i_mutex); -+ mutex_unlock(&nd->path.dentry->d_inode->i_mutex); - out: - up_write(&namespace_sem); - if (!err) -@@ -1089,16 +1092,17 @@ int do_add_mount(struct vfsmount *newmnt - - down_write(&namespace_sem); - /* Something was mounted here while we slept */ -- while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) -+ while (d_mountpoint(nd->path.dentry) && -+ follow_down(&nd->path.mnt, &nd->path.dentry)) - ; - err = -EINVAL; -- if (!check_mnt(nd->mnt)) -+ if (!check_mnt(nd->path.mnt)) - goto unlock; - - /* Refuse the same filesystem on the same mount point */ - err = -EBUSY; -- if (nd->mnt->mnt_sb == newmnt->mnt_sb && -- nd->mnt->mnt_root == nd->dentry) -+ if (nd->path.mnt->mnt_sb == newmnt->mnt_sb && -+ nd->path.mnt->mnt_root == nd->path.dentry) - goto unlock; - - err = -EINVAL; -@@ -1640,12 +1644,14 @@ static void chroot_fs_refs(struct nameid - if (fs) { - atomic_inc(&fs->count); - task_unlock(p); -- if (fs->root == old_nd->dentry -- && fs->rootmnt == old_nd->mnt) -- set_fs_root(fs, new_nd->mnt, new_nd->dentry); -- if (fs->pwd == old_nd->dentry -- && fs->pwdmnt == old_nd->mnt) -- set_fs_pwd(fs, new_nd->mnt, new_nd->dentry); -+ if (fs->root == old_nd->path.dentry -+ && fs->rootmnt == old_nd->path.mnt) -+ set_fs_root(fs, new_nd->path.mnt, -+ new_nd->path.dentry); -+ if (fs->pwd == old_nd->path.dentry -+ && fs->pwdmnt == old_nd->path.mnt) -+ set_fs_pwd(fs, new_nd->path.mnt, -+ new_nd->path.dentry); - put_fs_struct(fs); - } else - task_unlock(p); -@@ -1695,7 +1701,7 @@ asmlinkage long sys_pivot_root(const cha - if (error) - goto out0; - error = -EINVAL; -- if (!check_mnt(new_nd.mnt)) -+ if (!check_mnt(new_nd.path.mnt)) - goto out1; - - error = __user_walk(put_old, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old_nd); -@@ -1709,55 +1715,56 @@ asmlinkage long sys_pivot_root(const cha - } - - read_lock(¤t->fs->lock); -- user_nd.mnt = mntget(current->fs->rootmnt); -- user_nd.dentry = dget(current->fs->root); -+ user_nd.path.mnt = mntget(current->fs->rootmnt); -+ user_nd.path.dentry = dget(current->fs->root); - read_unlock(¤t->fs->lock); - down_write(&namespace_sem); -- mutex_lock(&old_nd.dentry->d_inode->i_mutex); -+ mutex_lock(&old_nd.path.dentry->d_inode->i_mutex); - error = -EINVAL; -- if (IS_MNT_SHARED(old_nd.mnt) || -- IS_MNT_SHARED(new_nd.mnt->mnt_parent) || -- IS_MNT_SHARED(user_nd.mnt->mnt_parent)) -+ if (IS_MNT_SHARED(old_nd.path.mnt) || -+ IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) || -+ IS_MNT_SHARED(user_nd.path.mnt->mnt_parent)) - goto out2; -- if (!check_mnt(user_nd.mnt)) -+ if (!check_mnt(user_nd.path.mnt)) - goto out2; - error = -ENOENT; -- if (IS_DEADDIR(new_nd.dentry->d_inode)) -+ if (IS_DEADDIR(new_nd.path.dentry->d_inode)) - goto out2; -- if (d_unhashed(new_nd.dentry) && !IS_ROOT(new_nd.dentry)) -+ if (d_unhashed(new_nd.path.dentry) && !IS_ROOT(new_nd.path.dentry)) - goto out2; -- if (d_unhashed(old_nd.dentry) && !IS_ROOT(old_nd.dentry)) -+ if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry)) - goto out2; - error = -EBUSY; -- if (new_nd.mnt == user_nd.mnt || old_nd.mnt == user_nd.mnt) -+ if (new_nd.path.mnt == user_nd.path.mnt || -+ old_nd.path.mnt == user_nd.path.mnt) - goto out2; /* loop, on the same file system */ - error = -EINVAL; -- if (user_nd.mnt->mnt_root != user_nd.dentry) -+ if (user_nd.path.mnt->mnt_root != user_nd.path.dentry) - goto out2; /* not a mountpoint */ -- if (user_nd.mnt->mnt_parent == user_nd.mnt) -+ if (user_nd.path.mnt->mnt_parent == user_nd.path.mnt) - goto out2; /* not attached */ -- if (new_nd.mnt->mnt_root != new_nd.dentry) -+ if (new_nd.path.mnt->mnt_root != new_nd.path.dentry) - goto out2; /* not a mountpoint */ -- if (new_nd.mnt->mnt_parent == new_nd.mnt) -+ if (new_nd.path.mnt->mnt_parent == new_nd.path.mnt) - goto out2; /* not attached */ -- tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */ -+ tmp = old_nd.path.mnt; /* make sure we can reach put_old from new_root */ - spin_lock(&vfsmount_lock); -- if (tmp != new_nd.mnt) { -+ if (tmp != new_nd.path.mnt) { - for (;;) { - if (tmp->mnt_parent == tmp) - goto out3; /* already mounted on put_old */ -- if (tmp->mnt_parent == new_nd.mnt) -+ if (tmp->mnt_parent == new_nd.path.mnt) - break; - tmp = tmp->mnt_parent; - } -- if (!is_subdir(tmp->mnt_mountpoint, new_nd.dentry)) -+ if (!is_subdir(tmp->mnt_mountpoint, new_nd.path.dentry)) - goto out3; -- } else if (!is_subdir(old_nd.dentry, new_nd.dentry)) -+ } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry)) - goto out3; -- detach_mnt(new_nd.mnt, &parent_nd); -- detach_mnt(user_nd.mnt, &root_parent); -- attach_mnt(user_nd.mnt, &old_nd); /* mount old root on put_old */ -- attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */ -+ detach_mnt(new_nd.path.mnt, &parent_nd); -+ detach_mnt(user_nd.path.mnt, &root_parent); -+ attach_mnt(user_nd.path.mnt, &old_nd); /* mount old root on put_old */ -+ attach_mnt(new_nd.path.mnt, &root_parent); /* mount new_root on / */ - touch_mnt_namespace(current->nsproxy->mnt_ns); - spin_unlock(&vfsmount_lock); - chroot_fs_refs(&user_nd, &new_nd); -@@ -1766,7 +1773,7 @@ asmlinkage long sys_pivot_root(const cha - path_release(&root_parent); - path_release(&parent_nd); - out2: -- mutex_unlock(&old_nd.dentry->d_inode->i_mutex); -+ mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex); - up_write(&namespace_sem); - path_release(&user_nd); - path_release(&old_nd); -Index: linux-2.6-hooks/fs/nfs/dir.c -=================================================================== ---- linux-2.6-hooks.orig/fs/nfs/dir.c -+++ linux-2.6-hooks/fs/nfs/dir.c -@@ -923,7 +923,7 @@ static struct dentry *nfs_lookup(struct - res = ERR_PTR(error); - goto out_unlock; - } -- error = nfs_reval_fsid(nd->mnt, dir, &fhandle, &fattr); -+ error = nfs_reval_fsid(nd->path.mnt, dir, &fhandle, &fattr); - if (error < 0) { - res = ERR_PTR(error); - goto out_unlock; -Index: linux-2.6-hooks/fs/nfs/namespace.c -=================================================================== ---- linux-2.6-hooks.orig/fs/nfs/namespace.c -+++ linux-2.6-hooks/fs/nfs/namespace.c -@@ -107,38 +107,40 @@ static void * nfs_follow_mountpoint(stru - - BUG_ON(IS_ROOT(dentry)); - dprintk("%s: enter\n", __FUNCTION__); -- dput(nd->dentry); -- nd->dentry = dget(dentry); -+ dput(nd->path.dentry); -+ nd->path.dentry = dget(dentry); - - /* Look it up again */ -- parent = dget_parent(nd->dentry); -+ parent = dget_parent(nd->path.dentry); - err = server->nfs_client->rpc_ops->lookup(parent->d_inode, -- &nd->dentry->d_name, -+ &nd->path.dentry->d_name, - &fh, &fattr); - dput(parent); - if (err != 0) - goto out_err; - - if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) -- mnt = nfs_do_refmount(nd->mnt, nd->dentry); -+ mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry); - else -- mnt = nfs_do_submount(nd->mnt, nd->dentry, &fh, &fattr); -+ mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, &fh, -+ &fattr); - err = PTR_ERR(mnt); - if (IS_ERR(mnt)) - goto out_err; - - mntget(mnt); -- err = do_add_mount(mnt, nd, nd->mnt->mnt_flags|MNT_SHRINKABLE, &nfs_automount_list); -+ err = do_add_mount(mnt, nd, nd->path.mnt->mnt_flags|MNT_SHRINKABLE, -+ &nfs_automount_list); - if (err < 0) { - mntput(mnt); - if (err == -EBUSY) - goto out_follow; - goto out_err; - } -- mntput(nd->mnt); -- dput(nd->dentry); -- nd->mnt = mnt; -- nd->dentry = dget(mnt->mnt_root); -+ mntput(nd->path.mnt); -+ dput(nd->path.dentry); -+ nd->path.mnt = mnt; -+ nd->path.dentry = dget(mnt->mnt_root); - schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); - out: - dprintk("%s: done, returned %d\n", __FUNCTION__, err); -@@ -149,7 +151,8 @@ out_err: - path_release(nd); - goto out; - out_follow: -- while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) -+ while(d_mountpoint(nd->path.dentry) && -+ follow_down(&nd->path.mnt, &nd->path.dentry)) - ; - err = 0; - goto out; -Index: linux-2.6-hooks/fs/nfsctl.c -=================================================================== ---- linux-2.6-hooks.orig/fs/nfsctl.c -+++ linux-2.6-hooks/fs/nfsctl.c -@@ -25,12 +25,12 @@ static struct file *do_open(char *name, - struct nameidata nd; - int error; - -- nd.mnt = do_kern_mount("nfsd", 0, "nfsd", NULL); -+ nd.path.mnt = do_kern_mount("nfsd", 0, "nfsd", NULL); - -- if (IS_ERR(nd.mnt)) -- return (struct file *)nd.mnt; -+ if (IS_ERR(nd.path.mnt)) -+ return (struct file *)nd.path.mnt; - -- nd.dentry = dget(nd.mnt->mnt_root); -+ nd.path.dentry = dget(nd.path.mnt->mnt_root); - nd.last_type = LAST_ROOT; - nd.flags = 0; - nd.depth = 0; -@@ -45,7 +45,7 @@ static struct file *do_open(char *name, - error = may_open(&nd, MAY_WRITE, FMODE_WRITE); - - if (!error) -- return dentry_open(nd.dentry, nd.mnt, flags); -+ return dentry_open(nd.path.dentry, nd.path.mnt, flags); - - path_release(&nd); - return ERR_PTR(error); -Index: linux-2.6-hooks/fs/nfsd/export.c -=================================================================== ---- linux-2.6-hooks.orig/fs/nfsd/export.c -+++ linux-2.6-hooks/fs/nfsd/export.c -@@ -167,8 +167,8 @@ static int expkey_parse(struct cache_det - goto out; - - dprintk("Found the path %s\n", buf); -- key.ek_mnt = nd.mnt; -- key.ek_dentry = nd.dentry; -+ key.ek_mnt = nd.path.mnt; -+ key.ek_dentry = nd.path.dentry; - - ek = svc_expkey_update(&key, ek); - if (ek) -@@ -472,7 +472,7 @@ static int svc_export_parse(struct cache - struct svc_export exp, *expp; - int an_int; - -- nd.dentry = NULL; -+ nd.path.dentry = NULL; - exp.ex_path = NULL; - - if (mesg[mlen-1] != '\n') -@@ -502,8 +502,8 @@ static int svc_export_parse(struct cache - - exp.h.flags = 0; - exp.ex_client = dom; -- exp.ex_mnt = nd.mnt; -- exp.ex_dentry = nd.dentry; -+ exp.ex_mnt = nd.path.mnt; -+ exp.ex_dentry = nd.path.dentry; - exp.ex_path = kstrdup(buf, GFP_KERNEL); - err = -ENOMEM; - if (!exp.ex_path) -@@ -543,7 +543,7 @@ static int svc_export_parse(struct cache - if (err) goto out; - exp.ex_fsid = an_int; - -- err = check_export(nd.dentry->d_inode, exp.ex_flags); -+ err = check_export(nd.path.dentry->d_inode, exp.ex_flags); - if (err) goto out; - - err = fsloc_parse(&mesg, buf, &exp.ex_fslocs); -@@ -563,7 +563,7 @@ static int svc_export_parse(struct cache - exp_put(expp); - out: - kfree(exp.ex_path); -- if (nd.dentry) -+ if (nd.path.dentry) - path_release(&nd); - out_no_path: - if (dom) -@@ -952,7 +952,7 @@ exp_export(struct nfsctl_export *nxp) - goto out_unlock; - err = -EINVAL; - -- exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL); -+ exp = exp_get_by_name(clp, nd.path.mnt, nd.path.dentry, NULL); - - memset(&new, 0, sizeof(new)); - -@@ -961,7 +961,8 @@ exp_export(struct nfsctl_export *nxp) - (fsid_key = exp_get_fsid_key(clp, nxp->ex_dev)) && - !IS_ERR(fsid_key) && - fsid_key->ek_mnt && -- (fsid_key->ek_mnt != nd.mnt || fsid_key->ek_dentry != nd.dentry) ) -+ (fsid_key->ek_mnt != nd.path.mnt || -+ fsid_key->ek_dentry != nd.path.dentry) ) - goto finish; - - if (exp) { -@@ -977,7 +978,7 @@ exp_export(struct nfsctl_export *nxp) - goto finish; - } - -- err = check_export(nd.dentry->d_inode, nxp->ex_flags); -+ err = check_export(nd.path.dentry->d_inode, nxp->ex_flags); - if (err) goto finish; - - err = -ENOMEM; -@@ -990,8 +991,8 @@ exp_export(struct nfsctl_export *nxp) - if (!new.ex_path) - goto finish; - new.ex_client = clp; -- new.ex_mnt = nd.mnt; -- new.ex_dentry = nd.dentry; -+ new.ex_mnt = nd.path.mnt; -+ new.ex_dentry = nd.path.dentry; - new.ex_flags = nxp->ex_flags; - new.ex_anon_uid = nxp->ex_anon_uid; - new.ex_anon_gid = nxp->ex_anon_gid; -@@ -1071,7 +1072,7 @@ exp_unexport(struct nfsctl_export *nxp) - goto out_domain; - - err = -EINVAL; -- exp = exp_get_by_name(dom, nd.mnt, nd.dentry, NULL); -+ exp = exp_get_by_name(dom, nd.path.mnt, nd.path.dentry, NULL); - path_release(&nd); - if (!exp) - goto out_domain; -@@ -1108,12 +1109,12 @@ exp_rootfh(svc_client *clp, char *path, - printk("nfsd: exp_rootfh path not found %s", path); - return err; - } -- inode = nd.dentry->d_inode; -+ inode = nd.path.dentry->d_inode; - - dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n", -- path, nd.dentry, clp->name, -+ path, nd.path.dentry, clp->name, - inode->i_sb->s_id, inode->i_ino); -- exp = exp_parent(clp, nd.mnt, nd.dentry, NULL); -+ exp = exp_parent(clp, nd.path.mnt, nd.path.dentry, NULL); - if (IS_ERR(exp)) { - err = PTR_ERR(exp); - goto out; -@@ -1127,7 +1128,7 @@ exp_rootfh(svc_client *clp, char *path, - * fh must be initialized before calling fh_compose - */ - fh_init(&fh, maxsize); -- if (fh_compose(&fh, exp, nd.dentry, NULL)) -+ if (fh_compose(&fh, exp, nd.path.dentry, NULL)) - err = -EINVAL; - else - err = 0; -Index: linux-2.6-hooks/fs/nfsd/nfs4recover.c -=================================================================== ---- linux-2.6-hooks.orig/fs/nfsd/nfs4recover.c -+++ linux-2.6-hooks/fs/nfsd/nfs4recover.c -@@ -122,9 +122,9 @@ out_no_tfm: - static void - nfsd4_sync_rec_dir(void) - { -- mutex_lock(&rec_dir.dentry->d_inode->i_mutex); -- nfsd_sync_dir(rec_dir.dentry); -- mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); -+ mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex); -+ nfsd_sync_dir(rec_dir.path.dentry); -+ mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex); - } - - int -@@ -144,9 +144,9 @@ nfsd4_create_clid_dir(struct nfs4_client - nfs4_save_user(&uid, &gid); - - /* lock the parent */ -- mutex_lock(&rec_dir.dentry->d_inode->i_mutex); -+ mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex); - -- dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1); -+ dentry = lookup_one_len(dname, rec_dir.path.dentry, HEXDIR_LEN-1); - if (IS_ERR(dentry)) { - status = PTR_ERR(dentry); - goto out_unlock; -@@ -156,11 +156,11 @@ nfsd4_create_clid_dir(struct nfs4_client - dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); - goto out_put; - } -- status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU); -+ status = vfs_mkdir(rec_dir.path.dentry->d_inode, dentry, S_IRWXU); - out_put: - dput(dentry); - out_unlock: -- mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); -+ mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex); - if (status == 0) { - clp->cl_firststate = 1; - nfsd4_sync_rec_dir(); -@@ -223,7 +223,7 @@ nfsd4_list_rec_dir(struct dentry *dir, r - - nfs4_save_user(&uid, &gid); - -- filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY); -+ filp = dentry_open(dget(dir), mntget(rec_dir.path.mnt), O_RDONLY); - status = PTR_ERR(filp); - if (IS_ERR(filp)) - goto out; -@@ -288,9 +288,9 @@ nfsd4_unlink_clid_dir(char *name, int na - - dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name); - -- mutex_lock(&rec_dir.dentry->d_inode->i_mutex); -- dentry = lookup_one_len(name, rec_dir.dentry, namlen); -- mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); -+ mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex); -+ dentry = lookup_one_len(name, rec_dir.path.dentry, namlen); -+ mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex); - if (IS_ERR(dentry)) { - status = PTR_ERR(dentry); - return status; -@@ -299,7 +299,7 @@ nfsd4_unlink_clid_dir(char *name, int na - if (!dentry->d_inode) - goto out; - -- status = nfsd4_clear_clid_dir(rec_dir.dentry, dentry); -+ status = nfsd4_clear_clid_dir(rec_dir.path.dentry, dentry); - out: - dput(dentry); - return status; -@@ -349,12 +349,12 @@ nfsd4_recdir_purge_old(void) { - - if (!rec_dir_init) - return; -- status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old); -+ status = nfsd4_list_rec_dir(rec_dir.path.dentry, purge_old); - if (status == 0) - nfsd4_sync_rec_dir(); - if (status) - printk("nfsd4: failed to purge old clients from recovery" -- " directory %s\n", rec_dir.dentry->d_name.name); -+ " directory %s\n", rec_dir.path.dentry->d_name.name); - return; - } - -@@ -375,10 +375,10 @@ int - nfsd4_recdir_load(void) { - int status; - -- status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir); -+ status = nfsd4_list_rec_dir(rec_dir.path.dentry, load_recdir); - if (status) - printk("nfsd4: failed loading clients from recovery" -- " directory %s\n", rec_dir.dentry->d_name.name); -+ " directory %s\n", rec_dir.path.dentry->d_name.name); - return status; - } - -Index: linux-2.6-hooks/fs/nfsd/nfs4state.c -=================================================================== ---- linux-2.6-hooks.orig/fs/nfsd/nfs4state.c -+++ linux-2.6-hooks/fs/nfsd/nfs4state.c -@@ -3299,7 +3299,7 @@ nfs4_reset_recoverydir(char *recdir) - if (status) - return status; - status = -ENOTDIR; -- if (S_ISDIR(nd.dentry->d_inode->i_mode)) { -+ if (S_ISDIR(nd.path.dentry->d_inode->i_mode)) { - nfs4_set_recdir(recdir); - status = 0; - } -Index: linux-2.6-hooks/fs/open.c -=================================================================== ---- linux-2.6-hooks.orig/fs/open.c -+++ linux-2.6-hooks/fs/open.c -@@ -127,7 +127,7 @@ asmlinkage long sys_statfs(const char __ - error = user_path_walk(path, &nd); - if (!error) { - struct statfs tmp; -- error = vfs_statfs_native(nd.dentry, &tmp); -+ error = vfs_statfs_native(nd.path.dentry, &tmp); - if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) - error = -EFAULT; - path_release(&nd); -@@ -146,7 +146,7 @@ asmlinkage long sys_statfs64(const char - error = user_path_walk(path, &nd); - if (!error) { - struct statfs64 tmp; -- error = vfs_statfs64(nd.dentry, &tmp); -+ error = vfs_statfs64(nd.path.dentry, &tmp); - if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) - error = -EFAULT; - path_release(&nd); -@@ -230,7 +230,7 @@ static long do_sys_truncate(const char _ - error = user_path_walk(path, &nd); - if (error) - goto out; -- inode = nd.dentry->d_inode; -+ inode = nd.path.dentry->d_inode; - - /* For directories it's -EISDIR, for other non-regulars - -EINVAL */ - error = -EISDIR; -@@ -267,7 +267,7 @@ static long do_sys_truncate(const char _ - error = locks_verify_truncate(inode, NULL, length); - if (!error) { - DQUOT_INIT(inode); -- error = do_truncate(nd.dentry, length, 0, NULL); -+ error = do_truncate(nd.path.dentry, length, 0, NULL); - } - put_write_access(inode); - -@@ -392,10 +392,10 @@ asmlinkage long sys_faccessat(int dfd, c - res = vfs_permission(&nd, mode); - /* SuS v2 requires we report a read only fs too */ - if(res || !(mode & S_IWOTH) || -- special_file(nd.dentry->d_inode->i_mode)) -+ special_file(nd.path.dentry->d_inode->i_mode)) - goto out_path_release; - -- if(IS_RDONLY(nd.dentry->d_inode)) -+ if(IS_RDONLY(nd.path.dentry->d_inode)) - res = -EROFS; - - out_path_release: -@@ -427,7 +427,7 @@ asmlinkage long sys_chdir(const char __u - if (error) - goto dput_and_out; - -- set_fs_pwd(current->fs, nd.mnt, nd.dentry); -+ set_fs_pwd(current->fs, nd.path.mnt, nd.path.dentry); - - dput_and_out: - path_release(&nd); -@@ -482,7 +482,7 @@ asmlinkage long sys_chroot(const char __ - if (!capable(CAP_SYS_CHROOT)) - goto dput_and_out; - -- set_fs_root(current->fs, nd.mnt, nd.dentry); -+ set_fs_root(current->fs, nd.path.mnt, nd.path.dentry); - set_fs_altroot(); - error = 0; - dput_and_out: -@@ -539,7 +539,7 @@ asmlinkage long sys_fchmodat(int dfd, co - error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd); - if (error) - goto out; -- inode = nd.dentry->d_inode; -+ inode = nd.path.dentry->d_inode; - - error = -EROFS; - if (IS_RDONLY(inode)) -@@ -554,7 +554,7 @@ asmlinkage long sys_fchmodat(int dfd, co - mode = inode->i_mode; - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -- error = notify_change(nd.dentry, &newattrs); -+ error = notify_change(nd.path.dentry, &newattrs); - mutex_unlock(&inode->i_mutex); - - dput_and_out: -@@ -611,7 +611,7 @@ asmlinkage long sys_chown(const char __u - error = user_path_walk(filename, &nd); - if (error) - goto out; -- error = chown_common(nd.dentry, user, group); -+ error = chown_common(nd.path.dentry, user, group); - path_release(&nd); - out: - return error; -@@ -631,7 +631,7 @@ asmlinkage long sys_fchownat(int dfd, co - error = __user_walk_fd(dfd, filename, follow, &nd); - if (error) - goto out; -- error = chown_common(nd.dentry, user, group); -+ error = chown_common(nd.path.dentry, user, group); - path_release(&nd); - out: - return error; -@@ -645,7 +645,7 @@ asmlinkage long sys_lchown(const char __ - error = user_path_walk_link(filename, &nd); - if (error) - goto out; -- error = chown_common(nd.dentry, user, group); -+ error = chown_common(nd.path.dentry, user, group); - path_release(&nd); - out: - return error; -@@ -795,7 +795,7 @@ struct file *lookup_instantiate_filp(str - goto out; - if (IS_ERR(dentry)) - goto out_err; -- nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->mnt), -+ nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), - nd->intent.open.flags - 1, - nd->intent.open.file, - open); -@@ -823,7 +823,8 @@ struct file *nameidata_to_filp(struct na - filp = nd->intent.open.file; - /* Has the filesystem initialised the file for us? */ - if (filp->f_path.dentry == NULL) -- filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL); -+ filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp, -+ NULL); - else - path_release(nd); - return filp; -Index: linux-2.6-hooks/fs/proc/base.c -=================================================================== ---- linux-2.6-hooks.orig/fs/proc/base.c -+++ linux-2.6-hooks/fs/proc/base.c -@@ -926,7 +926,8 @@ static void *proc_pid_follow_link(struct - if (!proc_fd_access_allowed(inode)) - goto out; - -- error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt); -+ error = PROC_I(inode)->op.proc_get_link(inode, &nd->path.dentry, -+ &nd->path.mnt); - nd->last_type = LAST_BIND; - out: - return ERR_PTR(error); -Index: linux-2.6-hooks/fs/reiserfs/super.c -=================================================================== ---- linux-2.6-hooks.orig/fs/reiserfs/super.c -+++ linux-2.6-hooks/fs/reiserfs/super.c -@@ -1983,12 +1983,12 @@ static int reiserfs_quota_on(struct supe - if (err) - return err; - /* Quotafile not on the same filesystem? */ -- if (nd.mnt->mnt_sb != sb) { -+ if (nd.path.mnt->mnt_sb != sb) { - path_release(&nd); - return -EXDEV; - } - /* We must not pack tails for quota files on reiserfs for quota IO to work */ -- if (!REISERFS_I(nd.dentry->d_inode)->i_flags & i_nopack_mask) { -+ if (!REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask) { - reiserfs_warning(sb, - "reiserfs: Quota file must have tail packing disabled."); - path_release(&nd); -@@ -2001,7 +2001,7 @@ static int reiserfs_quota_on(struct supe - return vfs_quota_on(sb, type, format_id, path); - } - /* Quotafile not of fs root? */ -- if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode) -+ if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) - reiserfs_warning(sb, - "reiserfs: Quota file not on filesystem root. " - "Journalled quota will not work."); -Index: linux-2.6-hooks/fs/stat.c -=================================================================== ---- linux-2.6-hooks.orig/fs/stat.c -+++ linux-2.6-hooks/fs/stat.c -@@ -63,7 +63,7 @@ int vfs_stat_fd(int dfd, char __user *na - - error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd); - if (!error) { -- error = vfs_getattr(nd.mnt, nd.dentry, stat); -+ error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); - path_release(&nd); - } - return error; -@@ -83,7 +83,7 @@ int vfs_lstat_fd(int dfd, char __user *n - - error = __user_walk_fd(dfd, name, 0, &nd); - if (!error) { -- error = vfs_getattr(nd.mnt, nd.dentry, stat); -+ error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); - path_release(&nd); - } - return error; -@@ -303,14 +303,15 @@ asmlinkage long sys_readlinkat(int dfd, - - error = __user_walk_fd(dfd, path, 0, &nd); - if (!error) { -- struct inode * inode = nd.dentry->d_inode; -+ struct inode * inode = nd.path.dentry->d_inode; - - error = -EINVAL; - if (inode->i_op && inode->i_op->readlink) { -- error = security_inode_readlink(nd.dentry); -+ error = security_inode_readlink(nd.path.dentry); - if (!error) { -- touch_atime(nd.mnt, nd.dentry); -- error = inode->i_op->readlink(nd.dentry, buf, bufsiz); -+ touch_atime(nd.path.mnt, nd.path.dentry); -+ error = inode->i_op->readlink(nd.path.dentry, -+ buf, bufsiz); - } - } - path_release(&nd); -Index: linux-2.6-hooks/fs/utimes.c -=================================================================== ---- linux-2.6-hooks.orig/fs/utimes.c -+++ linux-2.6-hooks/fs/utimes.c -@@ -30,7 +30,7 @@ asmlinkage long sys_utime(char __user * - error = user_path_walk(filename, &nd); - if (error) - goto out; -- inode = nd.dentry->d_inode; -+ inode = nd.path.dentry->d_inode; - - error = -EROFS; - if (IS_RDONLY(inode)) -@@ -62,7 +62,7 @@ asmlinkage long sys_utime(char __user * - goto dput_and_out; - } - mutex_lock(&inode->i_mutex); -- error = notify_change(nd.dentry, &newattrs); -+ error = notify_change(nd.path.dentry, &newattrs); - mutex_unlock(&inode->i_mutex); - dput_and_out: - path_release(&nd); -@@ -87,7 +87,7 @@ long do_utimes(int dfd, char __user *fil - - if (error) - goto out; -- inode = nd.dentry->d_inode; -+ inode = nd.path.dentry->d_inode; - - error = -EROFS; - if (IS_RDONLY(inode)) -@@ -115,7 +115,7 @@ long do_utimes(int dfd, char __user *fil - goto dput_and_out; - } - mutex_lock(&inode->i_mutex); -- error = notify_change(nd.dentry, &newattrs); -+ error = notify_change(nd.path.dentry, &newattrs); - mutex_unlock(&inode->i_mutex); - dput_and_out: - path_release(&nd); -Index: linux-2.6-hooks/fs/xattr.c -=================================================================== ---- linux-2.6-hooks.orig/fs/xattr.c -+++ linux-2.6-hooks/fs/xattr.c -@@ -237,7 +237,7 @@ sys_setxattr(char __user *path, char __u - error = user_path_walk(path, &nd); - if (error) - return error; -- error = setxattr(nd.dentry, name, value, size, flags); -+ error = setxattr(nd.path.dentry, name, value, size, flags); - path_release(&nd); - return error; - } -@@ -252,7 +252,7 @@ sys_lsetxattr(char __user *path, char __ - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = setxattr(nd.dentry, name, value, size, flags); -+ error = setxattr(nd.path.dentry, name, value, size, flags); - path_release(&nd); - return error; - } -@@ -322,7 +322,7 @@ sys_getxattr(char __user *path, char __u - error = user_path_walk(path, &nd); - if (error) - return error; -- error = getxattr(nd.dentry, name, value, size); -+ error = getxattr(nd.path.dentry, name, value, size); - path_release(&nd); - return error; - } -@@ -337,7 +337,7 @@ sys_lgetxattr(char __user *path, char __ - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = getxattr(nd.dentry, name, value, size); -+ error = getxattr(nd.path.dentry, name, value, size); - path_release(&nd); - return error; - } -@@ -395,7 +395,7 @@ sys_listxattr(char __user *path, char __ - error = user_path_walk(path, &nd); - if (error) - return error; -- error = listxattr(nd.dentry, list, size); -+ error = listxattr(nd.path.dentry, list, size); - path_release(&nd); - return error; - } -@@ -409,7 +409,7 @@ sys_llistxattr(char __user *path, char _ - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = listxattr(nd.dentry, list, size); -+ error = listxattr(nd.path.dentry, list, size); - path_release(&nd); - return error; - } -@@ -455,7 +455,7 @@ sys_removexattr(char __user *path, char - error = user_path_walk(path, &nd); - if (error) - return error; -- error = removexattr(nd.dentry, name); -+ error = removexattr(nd.path.dentry, name); - path_release(&nd); - return error; - } -@@ -469,7 +469,7 @@ sys_lremovexattr(char __user *path, char - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = removexattr(nd.dentry, name); -+ error = removexattr(nd.path.dentry, name); - path_release(&nd); - return error; - } -Index: linux-2.6-hooks/fs/xfs/linux-2.6/xfs_ioctl.c -=================================================================== ---- linux-2.6-hooks.orig/fs/xfs/linux-2.6/xfs_ioctl.c -+++ linux-2.6-hooks/fs/xfs/linux-2.6/xfs_ioctl.c -@@ -93,9 +93,9 @@ xfs_find_handle( - if (error) - return error; - -- ASSERT(nd.dentry); -- ASSERT(nd.dentry->d_inode); -- inode = igrab(nd.dentry->d_inode); -+ ASSERT(nd.path.dentry); -+ ASSERT(nd.path.dentry->d_inode); -+ inode = igrab(nd.path.dentry->d_inode); - path_release(&nd); - break; - } -Index: linux-2.6-hooks/kernel/auditfilter.c -=================================================================== ---- linux-2.6-hooks.orig/kernel/auditfilter.c -+++ linux-2.6-hooks/kernel/auditfilter.c -@@ -167,8 +167,8 @@ static struct audit_parent *audit_init_p - inotify_init_watch(&parent->wdata); - /* grab a ref so inotify watch hangs around until we take audit_filter_mutex */ - get_inotify_watch(&parent->wdata); -- wd = inotify_add_watch(audit_ih, &parent->wdata, ndp->dentry->d_inode, -- AUDIT_IN_WATCH); -+ wd = inotify_add_watch(audit_ih, &parent->wdata, -+ ndp->path.dentry->d_inode, AUDIT_IN_WATCH); - if (wd < 0) { - audit_free_parent(&parent->wdata); - return ERR_PTR(wd); -@@ -1126,8 +1126,8 @@ static int audit_add_watch(struct audit_ - - /* update watch filter fields */ - if (ndw) { -- watch->dev = ndw->dentry->d_inode->i_sb->s_dev; -- watch->ino = ndw->dentry->d_inode->i_ino; -+ watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev; -+ watch->ino = ndw->path.dentry->d_inode->i_ino; - } - - /* The audit_filter_mutex must not be held during inotify calls because -@@ -1137,7 +1137,8 @@ static int audit_add_watch(struct audit_ - */ - mutex_unlock(&audit_filter_mutex); - -- if (inotify_find_watch(audit_ih, ndp->dentry->d_inode, &i_watch) < 0) { -+ if (inotify_find_watch(audit_ih, ndp->path.dentry->d_inode, -+ &i_watch) < 0) { - parent = audit_init_parent(ndp); - if (IS_ERR(parent)) { - /* caller expects mutex locked */ -Index: linux-2.6-hooks/net/sunrpc/rpc_pipe.c -=================================================================== ---- linux-2.6-hooks.orig/net/sunrpc/rpc_pipe.c -+++ linux-2.6-hooks/net/sunrpc/rpc_pipe.c -@@ -453,14 +453,14 @@ rpc_lookup_parent(char *path, struct nam - { - if (path[0] == '\0') - return -ENOENT; -- nd->mnt = rpc_get_mount(); -- if (IS_ERR(nd->mnt)) { -+ nd->path.mnt = rpc_get_mount(); -+ if (IS_ERR(nd->path.mnt)) { - printk(KERN_WARNING "%s: %s failed to mount " - "pseudofilesystem \n", __FILE__, __FUNCTION__); -- return PTR_ERR(nd->mnt); -+ return PTR_ERR(nd->path.mnt); - } -- mntget(nd->mnt); -- nd->dentry = dget(rpc_mount->mnt_root); -+ mntget(nd->path.mnt); -+ nd->path.dentry = dget(rpc_mount->mnt_root); - nd->last_type = LAST_ROOT; - nd->flags = LOOKUP_PARENT; - nd->depth = 0; -@@ -649,7 +649,8 @@ rpc_lookup_negative(char *path, struct n - - if ((error = rpc_lookup_parent(path, nd)) != 0) - return ERR_PTR(error); -- dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len); -+ dentry = rpc_lookup_create(nd->path.dentry, nd->last.name, -+ nd->last.len); - if (IS_ERR(dentry)) - rpc_release_path(nd); - return dentry; -@@ -667,7 +668,7 @@ rpc_mkdir(char *path, struct rpc_clnt *r - dentry = rpc_lookup_negative(path, &nd); - if (IS_ERR(dentry)) - return dentry; -- dir = nd.dentry->d_inode; -+ dir = nd.path.dentry->d_inode; - if ((error = __rpc_mkdir(dir, dentry)) != 0) - goto err_dput; - RPC_I(dentry->d_inode)->private = rpc_client; -Index: linux-2.6-hooks/net/unix/af_unix.c -=================================================================== ---- linux-2.6-hooks.orig/net/unix/af_unix.c -+++ linux-2.6-hooks/net/unix/af_unix.c -@@ -708,14 +708,14 @@ static struct sock *unix_find_other(stru - goto put_fail; - - err = -ECONNREFUSED; -- if (!S_ISSOCK(nd.dentry->d_inode->i_mode)) -+ if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode)) - goto put_fail; -- u=unix_find_socket_byinode(nd.dentry->d_inode); -+ u=unix_find_socket_byinode(nd.path.dentry->d_inode); - if (!u) - goto put_fail; - - if (u->sk_type == type) -- touch_atime(nd.mnt, nd.dentry); -+ touch_atime(nd.path.mnt, nd.path.dentry); - - path_release(&nd); - -@@ -808,12 +808,12 @@ static int unix_bind(struct socket *sock - */ - mode = S_IFSOCK | - (SOCK_INODE(sock)->i_mode & ~current->fs->umask); -- err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); -+ err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0); - if (err) - goto out_mknod_dput; -- mutex_unlock(&nd.dentry->d_inode->i_mutex); -- dput(nd.dentry); -- nd.dentry = dentry; -+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex); -+ dput(nd.path.dentry); -+ nd.path.dentry = dentry; - - addr->hash = UNIX_HASH_SIZE; - } -@@ -831,8 +831,8 @@ static int unix_bind(struct socket *sock - list = &unix_socket_table[addr->hash]; - } else { - list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; -- u->dentry = nd.dentry; -- u->mnt = nd.mnt; -+ u->dentry = nd.path.dentry; -+ u->mnt = nd.path.mnt; - } - - err = 0; -@@ -850,7 +850,7 @@ out: - out_mknod_dput: - dput(dentry); - out_mknod_unlock: -- mutex_unlock(&nd.dentry->d_inode->i_mutex); -+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - path_release(&nd); - out_mknod_parent: - if (err==-EEXIST) -Index: linux-2.6-hooks/security/selinux/hooks.c -=================================================================== ---- linux-2.6-hooks.orig/security/selinux/hooks.c -+++ linux-2.6-hooks/security/selinux/hooks.c -@@ -2042,10 +2042,10 @@ static int selinux_mount(char * dev_name - return rc; - - if (flags & MS_REMOUNT) -- return superblock_has_perm(current, nd->mnt->mnt_sb, -+ return superblock_has_perm(current, nd->path.mnt->mnt_sb, - FILESYSTEM__REMOUNT, NULL); - else -- return dentry_has_perm(current, nd->mnt, nd->dentry, -+ return dentry_has_perm(current, nd->path.mnt, nd->path.dentry, - FILE__MOUNTON); - } - diff --git a/kernel-patches/for-mainline/struct_path/struct_path-nfsfh.diff b/kernel-patches/for-mainline/struct_path/struct_path-nfsfh.diff deleted file mode 100644 index edf974994..000000000 --- a/kernel-patches/for-mainline/struct_path/struct_path-nfsfh.diff +++ /dev/null @@ -1,920 +0,0 @@ -Index: linux-2.6/fs/nfsd/nfs2acl.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfs2acl.c -+++ linux-2.6/fs/nfsd/nfs2acl.c -@@ -62,7 +62,7 @@ static __be32 nfsacld_proc_getacl(struct - if (acl == NULL) { - /* Solaris returns the inode's minimum ACL. */ - -- struct inode *inode = fh->fh_dentry->d_inode; -+ struct inode *inode = fh->fh_path.dentry->d_inode; - acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); - } - resp->acl_access = acl; -@@ -220,7 +220,7 @@ static int nfsaclsvc_decode_accessargs(s - static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_getaclres *resp) - { -- struct dentry *dentry = resp->fh.fh_dentry; -+ struct dentry *dentry = resp->fh.fh_path.dentry; - struct inode *inode = dentry->d_inode; - struct kvec *head = rqstp->rq_res.head; - unsigned int base; -Index: linux-2.6/fs/nfsd/nfs3acl.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfs3acl.c -+++ linux-2.6/fs/nfsd/nfs3acl.c -@@ -58,7 +58,7 @@ static __be32 nfsd3_proc_getacl(struct s - if (acl == NULL) { - /* Solaris returns the inode's minimum ACL. */ - -- struct inode *inode = fh->fh_dentry->d_inode; -+ struct inode *inode = fh->fh_path.dentry->d_inode; - acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); - } - resp->acl_access = acl; -@@ -166,7 +166,7 @@ static int nfs3svc_decode_setaclargs(str - static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_getaclres *resp) - { -- struct dentry *dentry = resp->fh.fh_dentry; -+ struct dentry *dentry = resp->fh.fh_path.dentry; - - p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh); - if (resp->status == 0 && dentry && dentry->d_inode) { -Index: linux-2.6/fs/nfsd/nfs3proc.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfs3proc.c -+++ linux-2.6/fs/nfsd/nfs3proc.c -@@ -58,7 +58,6 @@ nfsd3_proc_getattr(struct svc_rqst *rqst - { - int err; - __be32 nfserr; -- struct path path; - - dprintk("nfsd: GETATTR(3) %s\n", - SVCFH_fmt(&argp->fh)); -@@ -68,9 +67,7 @@ nfsd3_proc_getattr(struct svc_rqst *rqst - if (nfserr) - RETURN_STATUS(nfserr); - -- path.mnt = resp->fh.fh_export->ex_mnt; -- path.dentry = resp->fh.fh_dentry; -- err = vfs_getattr(&path, &resp->stat); -+ err = vfs_getattr(&resp->fh.fh_path, &resp->stat); - nfserr = nfserrno(err); - - RETURN_STATUS(nfserr); -@@ -187,7 +184,7 @@ nfsd3_proc_read(struct svc_rqst *rqstp, - rqstp->rq_vec, argp->vlen, - &resp->count); - if (nfserr == 0) { -- struct inode *inode = resp->fh.fh_dentry->d_inode; -+ struct inode *inode = resp->fh.fh_path.dentry->d_inode; - - resp->eof = (argp->offset + resp->count) >= inode->i_size; - } -@@ -566,7 +563,7 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqst - * different read/write sizes for file systems known to have - * problems with large blocks */ - if (nfserr == 0) { -- struct super_block *sb = argp->fh.fh_dentry->d_inode->i_sb; -+ struct super_block *sb = argp->fh.fh_path.dentry->d_inode->i_sb; - - /* Note that we don't care for remote fs's here */ - if (sb->s_magic == 0x4d44 /* MSDOS_SUPER_MAGIC */) { -@@ -602,7 +599,7 @@ nfsd3_proc_pathconf(struct svc_rqst * rq - nfserr = fh_verify(rqstp, &argp->fh, 0, MAY_NOP); - - if (nfserr == 0) { -- struct super_block *sb = argp->fh.fh_dentry->d_inode->i_sb; -+ struct super_block *sb = argp->fh.fh_path.dentry->d_inode->i_sb; - - /* Note that we don't care for remote fs's here */ - switch (sb->s_magic) { -Index: linux-2.6/fs/nfsd/nfs3xdr.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfs3xdr.c -+++ linux-2.6/fs/nfsd/nfs3xdr.c -@@ -153,7 +153,7 @@ static __be32 * - encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, - struct kstat *stat) - { -- struct dentry *dentry = fhp->fh_dentry; -+ struct dentry *dentry = fhp->fh_path.dentry; - struct timespec time; - - *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); -@@ -185,7 +185,7 @@ encode_fattr3(struct svc_rqst *rqstp, __ - static __be32 * - encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) - { -- struct inode *inode = fhp->fh_dentry->d_inode; -+ struct inode *inode = fhp->fh_path.dentry->d_inode; - - /* Attributes to follow */ - *p++ = xdr_one; -@@ -223,15 +223,13 @@ encode_saved_post_attr(struct svc_rqst * - static __be32 * - encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) - { -- struct path path; -+ struct dentry *dentry = fhp->fh_path.dentry; - -- path.dentry = fhp->fh_dentry; -- if (path.dentry && path.dentry->d_inode != NULL) { -+ if (dentry && dentry->d_inode != NULL) { - int err; - struct kstat stat; - -- path.mnt = fhp->fh_export->ex_mnt; -- err = vfs_getattr(&path, &stat); -+ err = vfs_getattr(&fhp->fh_path, &stat); - if (!err) { - *p++ = xdr_one; /* attributes follow */ - return encode_fattr3(rqstp, p, fhp, &stat); -@@ -254,7 +252,7 @@ nfs3svc_encode_post_op_attr(struct svc_r - static __be32 * - encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) - { -- struct dentry *dentry = fhp->fh_dentry; -+ struct dentry *dentry = fhp->fh_path.dentry; - - if (dentry && dentry->d_inode && fhp->fh_post_saved) { - if (fhp->fh_pre_saved) { -@@ -808,7 +806,7 @@ compose_entry_fh(struct nfsd3_readdirres - struct dentry *dparent, *dchild; - int rv = 0; - -- dparent = cd->fh.fh_dentry; -+ dparent = cd->fh.fh_path.dentry; - exp = cd->fh.fh_export; - - fh_init(fhp, NFS3_FHSIZE); -Index: linux-2.6/fs/nfsd/nfs4proc.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfs4proc.c -+++ linux-2.6/fs/nfsd/nfs4proc.c -@@ -54,7 +54,7 @@ static inline void - fh_dup2(struct svc_fh *dst, struct svc_fh *src) - { - fh_put(dst); -- dget(src->fh_dentry); -+ dget(src->fh_path.dentry); - if (src->fh_export) - cache_get(&src->fh_export->h); - *dst = *src; -@@ -261,7 +261,7 @@ static __be32 - nfsd4_getfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct svc_fh **getfh) - { -- if (!cstate->current_fh.fh_dentry) -+ if (!cstate->current_fh.fh_path.dentry) - return nfserr_nofilehandle; - - *getfh = &cstate->current_fh; -@@ -295,7 +295,7 @@ static __be32 - nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - void *arg) - { -- if (!cstate->save_fh.fh_dentry) -+ if (!cstate->save_fh.fh_path.dentry) - return nfserr_restorefh; - - fh_dup2(&cstate->current_fh, &cstate->save_fh); -@@ -306,7 +306,7 @@ static __be32 - nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - void *arg) - { -- if (!cstate->current_fh.fh_dentry) -+ if (!cstate->current_fh.fh_path.dentry) - return nfserr_nofilehandle; - - fh_dup2(&cstate->save_fh, &cstate->current_fh); -@@ -457,7 +457,7 @@ nfsd4_link(struct svc_rqst *rqstp, struc - { - __be32 status = nfserr_nofilehandle; - -- if (!cstate->save_fh.fh_dentry) -+ if (!cstate->save_fh.fh_path.dentry) - return status; - status = nfsd_link(rqstp, &cstate->current_fh, - link->li_name, link->li_namelen, &cstate->save_fh); -@@ -477,7 +477,7 @@ nfsd4_lookupp(struct svc_rqst *rqstp, st - if((ret = exp_pseudoroot(rqstp->rq_client, &tmp_fh, - &rqstp->rq_chandle)) != 0) - return ret; -- if (tmp_fh.fh_dentry == cstate->current_fh.fh_dentry) { -+ if (tmp_fh.fh_path.dentry == cstate->current_fh.fh_path.dentry) { - fh_put(&tmp_fh); - return nfserr_noent; - } -@@ -583,7 +583,7 @@ nfsd4_rename(struct svc_rqst *rqstp, str - { - __be32 status = nfserr_nofilehandle; - -- if (!cstate->save_fh.fh_dentry) -+ if (!cstate->save_fh.fh_path.dentry) - return status; - if (nfs4_in_grace() && !(cstate->save_fh.fh_export->ex_flags - & NFSEXP_NOSUBTREECHECK)) -@@ -597,8 +597,8 @@ nfsd4_rename(struct svc_rqst *rqstp, str - if (status == nfserr_isdir) - status = nfserr_exist; - else if ((status == nfserr_notdir) && -- (S_ISDIR(cstate->save_fh.fh_dentry->d_inode->i_mode) && -- S_ISDIR(cstate->current_fh.fh_dentry->d_inode->i_mode))) -+ (S_ISDIR(cstate->save_fh.fh_path.dentry->d_inode->i_mode) && -+ S_ISDIR(cstate->current_fh.fh_path.dentry->d_inode->i_mode))) - status = nfserr_exist; - else if (status == nfserr_symlink) - status = nfserr_notdir; -@@ -716,7 +716,7 @@ _nfsd4_verify(struct svc_rqst *rqstp, st - - status = nfsd4_encode_fattr(&cstate->current_fh, - cstate->current_fh.fh_export, -- cstate->current_fh.fh_dentry, buf, -+ &cstate->current_fh.fh_path, buf, - &count, verify->ve_bmval, - rqstp); - -@@ -876,7 +876,7 @@ nfsd4_proc_compound(struct svc_rqst *rqs - - opdesc = &nfsd4_ops[op->opnum]; - -- if (!cstate->current_fh.fh_dentry) { -+ if (!cstate->current_fh.fh_path.dentry) { - if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { - op->status = nfserr_nofilehandle; - goto encode_op; -Index: linux-2.6/fs/nfsd/nfs4state.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfs4state.c -+++ linux-2.6/fs/nfsd/nfs4state.c -@@ -1286,7 +1286,7 @@ test_share(struct nfs4_stateid *stp, str - static __be32 - nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type) - { -- struct inode *ino = current_fh->fh_dentry->d_inode; -+ struct inode *ino = current_fh->fh_path.dentry->d_inode; - struct nfs4_file *fp; - struct nfs4_stateid *stp; - __be32 ret; -@@ -1745,7 +1745,7 @@ __be32 - nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) - { - struct nfs4_file *fp = NULL; -- struct inode *ino = current_fh->fh_dentry->d_inode; -+ struct inode *ino = current_fh->fh_path.dentry->d_inode; - struct nfs4_stateid *stp = NULL; - struct nfs4_delegation *dp = NULL; - __be32 status; -@@ -1969,7 +1969,7 @@ search_close_lru(u32 st_id, int flags) - static inline int - nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp) - { -- return fhp->fh_dentry->d_inode != stp->st_vfs_file->f_path.dentry->d_inode; -+ return fhp->fh_path.dentry->d_inode != stp->st_vfs_file->f_path.dentry->d_inode; - } - - static int -@@ -2052,7 +2052,7 @@ nfs4_preprocess_stateid_op(struct svc_fh - struct nfs4_stateid *stp = NULL; - struct nfs4_delegation *dp = NULL; - stateid_t *stidp; -- struct inode *ino = current_fh->fh_dentry->d_inode; -+ struct inode *ino = current_fh->fh_path.dentry->d_inode; - __be32 status; - - dprintk("NFSD: preprocess_stateid_op: stateid = (%08x/%08x/%08x/%08x)\n", -@@ -2253,8 +2253,8 @@ nfsd4_open_confirm(struct svc_rqst *rqst - struct nfs4_stateid *stp; - - dprintk("NFSD: nfsd4_open_confirm on file %.*s\n", -- (int)cstate->current_fh.fh_dentry->d_name.len, -- cstate->current_fh.fh_dentry->d_name.name); -+ (int)cstate->current_fh.fh_path.dentry->d_name.len, -+ cstate->current_fh.fh_path.dentry->d_name.name); - - status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0); - if (status) -@@ -2324,8 +2324,8 @@ nfsd4_open_downgrade(struct svc_rqst *rq - unsigned int share_access; - - dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", -- (int)cstate->current_fh.fh_dentry->d_name.len, -- cstate->current_fh.fh_dentry->d_name.name); -+ (int)cstate->current_fh.fh_path.dentry->d_name.len, -+ cstate->current_fh.fh_path.dentry->d_name.name); - - if (!access_valid(od->od_share_access) - || !deny_valid(od->od_share_deny)) -@@ -2380,8 +2380,8 @@ nfsd4_close(struct svc_rqst *rqstp, stru - struct nfs4_stateid *stp; - - dprintk("NFSD: nfsd4_close on file %.*s\n", -- (int)cstate->current_fh.fh_dentry->d_name.len, -- cstate->current_fh.fh_dentry->d_name.name); -+ (int)cstate->current_fh.fh_path.dentry->d_name.len, -+ cstate->current_fh.fh_path.dentry->d_name.name); - - nfs4_lock_state(); - /* check close_lru for replay */ -@@ -2837,7 +2837,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, stru - goto out; - } - -- inode = cstate->current_fh.fh_dentry->d_inode; -+ inode = cstate->current_fh.fh_path.dentry->d_inode; - locks_init_lock(&file_lock); - switch (lockt->lt_type) { - case NFS4_READ_LT: -@@ -2876,7 +2876,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, stru - * only the dentry:inode set. - */ - memset(&file, 0, sizeof (struct file)); -- file.f_path.dentry = cstate->current_fh.fh_dentry; -+ file.f_path.dentry = cstate->current_fh.fh_path.dentry; - - status = nfs_ok; - if (posix_test_lock(&file, &file_lock, &conflock)) { -Index: linux-2.6/fs/nfsd/nfs4xdr.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfs4xdr.c -+++ linux-2.6/fs/nfsd/nfs4xdr.c -@@ -1424,7 +1424,7 @@ static __be32 fattr_handle_absent_fs(u32 - */ - __be32 - nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, -- struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval, -+ struct path *path, __be32 *buffer, int *countp, u32 *bmval, - struct svc_rqst *rqstp) - { - u32 bmval0 = bmval[0]; -@@ -1442,7 +1442,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s - int err; - int aclsupport = 0; - struct nfs4_acl *acl = NULL; -- struct path path; -+ struct dentry *dentry = path->dentry; - - BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1); - BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0); -@@ -1454,9 +1454,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s - goto out; - } - -- path.mnt = exp->ex_mnt; -- path.dentry = dentry; -- err = vfs_getattr(&path, &stat); -+ err = vfs_getattr(path, &stat); - if (err) - goto out_nfserr; - if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) || -@@ -1839,28 +1837,29 @@ nfsd4_encode_dirent_fattr(struct nfsd4_r - const char *name, int namlen, __be32 *p, int *buflen) - { - struct svc_export *exp = cd->rd_fhp->fh_export; -- struct dentry *dentry; -+ struct path path; - __be32 nfserr; - -- dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); -- if (IS_ERR(dentry)) -- return nfserrno(PTR_ERR(dentry)); -+ path.dentry = lookup_one_len(name, cd->rd_fhp->fh_path.dentry, namlen); -+ if (IS_ERR(path.dentry)) -+ return nfserrno(PTR_ERR(path.dentry)); - - exp_get(exp); -- if (d_mountpoint(dentry)) { -+ if (d_mountpoint(path.dentry)) { - int err; - -- err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp); -+ err = nfsd_cross_mnt(cd->rd_rqstp, &path.dentry, &exp); - if (err) { - nfserr = nfserrno(err); - goto out_put; - } - - } -- nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval, -+ path.mnt = exp->ex_mnt; -+ nfserr = nfsd4_encode_fattr(NULL, exp, &path, p, buflen, cd->rd_bmval, - cd->rd_rqstp); - out_put: -- dput(dentry); -+ dput(path.dentry); - exp_put(exp); - return nfserr; - } -@@ -2010,7 +2009,7 @@ nfsd4_encode_getattr(struct nfsd4_compou - return nfserr; - - buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2); -- nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry, -+ nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, &fhp->fh_path, - resp->p, &buflen, getattr->ga_bmval, - resp->rqstp); - if (!nfserr) -@@ -2248,7 +2247,7 @@ nfsd4_encode_read(struct nfsd4_compoundr - if (nfserr) - return nfserr; - eof = (read->rd_offset + maxcount >= -- read->rd_fhp->fh_dentry->d_inode->i_size); -+ read->rd_fhp->fh_path.dentry->d_inode->i_size); - - WRITE32(eof); - WRITE32(maxcount); -Index: linux-2.6/fs/nfsd/nfsfh.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfsfh.c -+++ linux-2.6/fs/nfsd/nfsfh.c -@@ -123,7 +123,7 @@ fh_verify(struct svc_rqst *rqstp, struct - /* keep this filehandle for possible reference when encoding attributes */ - rqstp->rq_reffh = fh; - -- if (!fhp->fh_dentry) { -+ if (!fhp->fh_path.dentry) { - __u32 *datap=NULL; - __u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */ - int fileid_type; -@@ -238,7 +238,7 @@ fh_verify(struct svc_rqst *rqstp, struct - } - #endif - -- fhp->fh_dentry = dentry; -+ fhp->fh_path.dentry = dentry; - fhp->fh_export = exp; - nfsd_nr_verified++; - } else { -@@ -246,7 +246,7 @@ fh_verify(struct svc_rqst *rqstp, struct - * (e.g. nfsproc_create calls fh_verify, then nfsd_create does as well) - */ - dprintk("nfsd: fh_verify - just checking\n"); -- dentry = fhp->fh_dentry; -+ dentry = fhp->fh_path.dentry; - exp = fhp->fh_export; - /* Set user creds for this exportpoint; necessary even - * in the "just checking" case because this may be a -@@ -372,7 +372,7 @@ fh_compose(struct svc_fh *fhp, struct sv - if (ref_fh == fhp) - fh_put(ref_fh); - -- if (fhp->fh_locked || fhp->fh_dentry) { -+ if (fhp->fh_locked || fhp->fh_path.dentry) { - printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n", - parent->d_name.name, dentry->d_name.name); - } -@@ -380,7 +380,8 @@ fh_compose(struct svc_fh *fhp, struct sv - printk(KERN_ERR "fh_compose: called with maxsize %d! %s/%s\n", - fhp->fh_maxsize, parent->d_name.name, dentry->d_name.name); - -- fhp->fh_dentry = dget(dentry); /* our internal copy */ -+ fhp->fh_path.mnt = exp->ex_mnt; /* FIXME: can this get released while we still keep the copy here? Probably not... */ -+ fhp->fh_path.dentry = dget(dentry); /* our internal copy */ - fhp->fh_export = exp; - cache_get(&exp->h); - -@@ -459,10 +460,10 @@ fh_update(struct svc_fh *fhp) - struct dentry *dentry; - __u32 *datap; - -- if (!fhp->fh_dentry) -+ if (!fhp->fh_path.dentry) - goto out_bad; - -- dentry = fhp->fh_dentry; -+ dentry = fhp->fh_path.dentry; - if (!dentry->d_inode) - goto out_negative; - if (fhp->fh_handle.fh_version != 1) { -@@ -498,11 +499,11 @@ out_negative: - void - fh_put(struct svc_fh *fhp) - { -- struct dentry * dentry = fhp->fh_dentry; -+ struct dentry * dentry = fhp->fh_path.dentry; - struct svc_export * exp = fhp->fh_export; - if (dentry) { - fh_unlock(fhp); -- fhp->fh_dentry = NULL; -+ fhp->fh_path.dentry = NULL; - dput(dentry); - #ifdef CONFIG_NFSD_V3 - fhp->fh_pre_saved = 0; -Index: linux-2.6/fs/nfsd/nfsproc.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfsproc.c -+++ linux-2.6/fs/nfsd/nfsproc.c -@@ -39,25 +39,17 @@ nfsd_proc_null(struct svc_rqst *rqstp, v - static __be32 - nfsd_return_attrs(__be32 err, struct nfsd_attrstat *resp) - { -- struct path path; -- - if (err) - return err; -- path.mnt = resp->fh.fh_export->ex_mnt; -- path.dentry = resp->fh.fh_dentry; -- return nfserrno(vfs_getattr(&path, &resp->stat)); -+ return nfserrno(vfs_getattr(&resp->fh.fh_path, &resp->stat)); - } - - static __be32 - nfsd_return_dirop(__be32 err, struct nfsd_diropres *resp) - { -- struct path path; -- - if (err) - return err; -- path.mnt = resp->fh.fh_export->ex_mnt; -- path.dentry = resp->fh.fh_dentry; -- return nfserrno(vfs_getattr(&path, &resp->stat)); -+ return nfserrno(vfs_getattr(&resp->fh.fh_path, &resp->stat)); - } - /* - * Get a file's attributes -@@ -143,7 +135,6 @@ static __be32 - nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp, - struct nfsd_readres *resp) - { -- struct path path; - __be32 nfserr; - - dprintk("nfsd: READ %s %d bytes at %d\n", -@@ -172,9 +163,7 @@ nfsd_proc_read(struct svc_rqst *rqstp, s - - if (nfserr) - return nfserr; -- path.mnt = resp->fh.fh_export->ex_mnt; -- path.dentry = resp->fh.fh_dentry; -- return nfserrno(vfs_getattr(&path, &resp->stat)); -+ return nfserrno(vfs_getattr(&resp->fh.fh_path, &resp->stat)); - } - - /* -@@ -236,7 +225,7 @@ nfsd_proc_create(struct svc_rqst *rqstp, - if (isdotent(argp->name, argp->len)) - goto done; - fh_lock_nested(dirfhp, I_MUTEX_PARENT); -- dchild = lookup_one_len(argp->name, dirfhp->fh_dentry, argp->len); -+ dchild = lookup_one_len(argp->name, dirfhp->fh_path.dentry, argp->len); - if (IS_ERR(dchild)) { - nfserr = nfserrno(PTR_ERR(dchild)); - goto out_unlock; -@@ -254,14 +243,14 @@ nfsd_proc_create(struct svc_rqst *rqstp, - * whether the file exists or not. Time to bail ... - */ - nfserr = nfserr_acces; -- if (!newfhp->fh_dentry) { -+ if (!newfhp->fh_path.dentry) { - printk(KERN_WARNING - "nfsd_proc_create: file handle not verified\n"); - goto out_unlock; - } - } - -- inode = newfhp->fh_dentry->d_inode; -+ inode = newfhp->fh_path.dentry->d_inode; - - /* Unfudge the mode bits */ - if (attr->ia_valid & ATTR_MODE) { -@@ -286,9 +275,10 @@ nfsd_proc_create(struct svc_rqst *rqstp, - * echo thing > device-special-file-or-pipe - * by doing a CREATE with type==0 - */ -- nfserr = nfsd_permission(newfhp->fh_export, -- newfhp->fh_dentry, -- MAY_WRITE|MAY_LOCAL_ACCESS); -+ nfserr = nfsd_permission( -+ newfhp->fh_export, -+ newfhp->fh_path.dentry, -+ MAY_WRITE|MAY_LOCAL_ACCESS); - if (nfserr && nfserr != nfserr_rofs) - goto out_unlock; - } -@@ -448,7 +438,7 @@ nfsd_proc_mkdir(struct svc_rqst *rqstp, - - dprintk("nfsd: MKDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name); - -- if (resp->fh.fh_dentry) { -+ if (resp->fh.fh_path.dentry) { - printk(KERN_WARNING - "nfsd_proc_mkdir: response already verified??\n"); - } -Index: linux-2.6/fs/nfsd/nfsxdr.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfsxdr.c -+++ linux-2.6/fs/nfsd/nfsxdr.c -@@ -150,7 +150,7 @@ static __be32 * - encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, - struct kstat *stat) - { -- struct dentry *dentry = fhp->fh_dentry; -+ struct dentry *dentry = fhp->fh_path.dentry; - int type; - struct timespec time; - -@@ -193,11 +193,8 @@ encode_fattr(struct svc_rqst *rqstp, __b - __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) - { - struct kstat stat; -- struct path path; - -- path.mnt = fhp->fh_export->ex_mnt; -- path.dentry = fhp->fh_dentry; -- vfs_getattr(&path, &stat); -+ vfs_getattr(&fhp->fh_path, &stat); - return encode_fattr(rqstp, p, fhp, &stat); - } - -Index: linux-2.6/fs/nfsd/vfs.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/vfs.c -+++ linux-2.6/fs/nfsd/vfs.c -@@ -165,7 +165,7 @@ nfsd_lookup(struct svc_rqst *rqstp, stru - if (err) - return err; - -- dparent = fhp->fh_dentry; -+ dparent = fhp->fh_path.dentry; - exp = fhp->fh_export; - exp_get(exp); - -@@ -268,7 +268,7 @@ nfsd_setattr(struct svc_rqst *rqstp, str - if (err) - goto out; - -- dentry = fhp->fh_dentry; -+ dentry = fhp->fh_path.dentry; - inode = dentry->d_inode; - - /* Ignore any mode updates on symlinks */ -@@ -438,7 +438,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst - if (error) - goto out; - -- dentry = fhp->fh_dentry; -+ dentry = fhp->fh_path.dentry; - inode = dentry->d_inode; - if (S_ISDIR(inode->i_mode)) - flags = NFS4_ACL_DIR; -@@ -588,7 +588,7 @@ nfsd_access(struct svc_rqst *rqstp, stru - goto out; - - export = fhp->fh_export; -- dentry = fhp->fh_dentry; -+ dentry = fhp->fh_path.dentry; - - if (S_ISREG(dentry->d_inode->i_mode)) - map = nfs3_regaccess; -@@ -659,7 +659,7 @@ nfsd_open(struct svc_rqst *rqstp, struct - if (err) - goto out; - -- dentry = fhp->fh_dentry; -+ dentry = fhp->fh_path.dentry; - inode = dentry->d_inode; - - /* Disallow write access to files with the append-only bit set -@@ -1016,7 +1016,7 @@ nfsd_read(struct svc_rqst *rqstp, struct - __be32 err; - - if (file) { -- err = nfsd_permission(fhp->fh_export, fhp->fh_dentry, -+ err = nfsd_permission(fhp->fh_export, fhp->fh_path.dentry, - MAY_READ|MAY_OWNER_OVERRIDE); - if (err) - goto out; -@@ -1045,7 +1045,7 @@ nfsd_write(struct svc_rqst *rqstp, struc - __be32 err = 0; - - if (file) { -- err = nfsd_permission(fhp->fh_export, fhp->fh_dentry, -+ err = nfsd_permission(fhp->fh_export, fhp->fh_path.dentry, - MAY_WRITE|MAY_OWNER_OVERRIDE); - if (err) - goto out; -@@ -1128,7 +1128,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - if (err) - goto out; - -- dentry = fhp->fh_dentry; -+ dentry = fhp->fh_path.dentry; - dirp = dentry->d_inode; - - err = nfserr_notdir; -@@ -1138,7 +1138,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - * Check whether the response file handle has been verified yet. - * If it has, the parent directory should already be locked. - */ -- if (!resfhp->fh_dentry) { -+ if (!resfhp->fh_path.dentry) { - /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */ - fh_lock_nested(fhp, I_MUTEX_PARENT); - dchild = lookup_one_len(fname, dentry, flen); -@@ -1150,7 +1150,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - goto out; - } else { - /* called from nfsd_proc_create */ -- dchild = dget(resfhp->fh_dentry); -+ dchild = dget(resfhp->fh_path.dentry); - if (!fhp->fh_locked) { - /* not actually possible */ - printk(KERN_ERR -@@ -1258,7 +1258,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, s - if (err) - goto out; - -- dentry = fhp->fh_dentry; -+ dentry = fhp->fh_path.dentry; - dirp = dentry->d_inode; - - /* Get all the sanity checks out of the way before -@@ -1391,7 +1391,7 @@ nfsd_readlink(struct svc_rqst *rqstp, st - if (err) - goto out; - -- dentry = fhp->fh_dentry; -+ dentry = fhp->fh_path.dentry; - inode = dentry->d_inode; - - err = nfserr_inval; -@@ -1446,7 +1446,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str - if (err) - goto out; - fh_lock(fhp); -- dentry = fhp->fh_dentry; -+ dentry = fhp->fh_path.dentry; - dnew = lookup_one_len(fname, dentry, flen); - host_err = PTR_ERR(dnew); - if (IS_ERR(dnew)) -@@ -1516,7 +1516,7 @@ nfsd_link(struct svc_rqst *rqstp, struct - goto out; - - fh_lock_nested(ffhp, I_MUTEX_PARENT); -- ddir = ffhp->fh_dentry; -+ ddir = ffhp->fh_path.dentry; - dirp = ddir->d_inode; - - dnew = lookup_one_len(name, ddir, len); -@@ -1524,7 +1524,7 @@ nfsd_link(struct svc_rqst *rqstp, struct - if (IS_ERR(dnew)) - goto out_nfserr; - -- dold = tfhp->fh_dentry; -+ dold = tfhp->fh_path.dentry; - dest = dold->d_inode; - - host_err = vfs_link(dold, dirp, dnew); -@@ -1572,10 +1572,10 @@ nfsd_rename(struct svc_rqst *rqstp, stru - if (err) - goto out; - -- fdentry = ffhp->fh_dentry; -+ fdentry = ffhp->fh_path.dentry; - fdir = fdentry->d_inode; - -- tdentry = tfhp->fh_dentry; -+ tdentry = tfhp->fh_path.dentry; - tdir = tdentry->d_inode; - - err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev; -@@ -1668,7 +1668,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru - goto out; - - fh_lock_nested(fhp, I_MUTEX_PARENT); -- dentry = fhp->fh_dentry; -+ dentry = fhp->fh_path.dentry; - dirp = dentry->d_inode; - - rdentry = lookup_one_len(fname, dentry, flen); -@@ -1765,7 +1765,7 @@ __be32 - nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat) - { - __be32 err = fh_verify(rqstp, fhp, 0, MAY_NOP); -- if (!err && vfs_statfs(fhp->fh_dentry,stat)) -+ if (!err && vfs_statfs(fhp->fh_path.dentry,stat)) - err = nfserr_io; - return err; - } -@@ -1904,7 +1904,7 @@ nfsd_racache_init(int cache_size) - struct posix_acl * - nfsd_get_posix_acl(struct svc_fh *fhp, int type) - { -- struct inode *inode = fhp->fh_dentry->d_inode; -+ struct inode *inode = fhp->fh_path.dentry->d_inode; - char *name; - void *value = NULL; - ssize_t size; -@@ -1924,7 +1924,7 @@ nfsd_get_posix_acl(struct svc_fh *fhp, i - return ERR_PTR(-EOPNOTSUPP); - } - -- size = nfsd_getxattr(fhp->fh_dentry, name, &value); -+ size = nfsd_getxattr(fhp->fh_path.dentry, name, &value); - if (size < 0) - return ERR_PTR(size); - -@@ -1936,7 +1936,7 @@ nfsd_get_posix_acl(struct svc_fh *fhp, i - int - nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl) - { -- struct inode *inode = fhp->fh_dentry->d_inode; -+ struct inode *inode = fhp->fh_path.dentry->d_inode; - char *name; - void *value = NULL; - size_t size; -@@ -1969,12 +1969,12 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i - size = 0; - - if (size) -- error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0); -+ error = vfs_setxattr(fhp->fh_path.dentry, name, value, size, 0); - else { - if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT) - error = 0; - else { -- error = vfs_removexattr(fhp->fh_dentry, name); -+ error = vfs_removexattr(fhp->fh_path.dentry, name); - if (error == -ENODATA) - error = 0; - } -Index: linux-2.6/include/linux/nfsd/nfsfh.h -=================================================================== ---- linux-2.6.orig/include/linux/nfsd/nfsfh.h -+++ linux-2.6/include/linux/nfsd/nfsfh.h -@@ -134,7 +134,7 @@ static inline ino_t u32_to_ino_t(__u32 u - */ - typedef struct svc_fh { - struct knfsd_fh fh_handle; /* FH data */ -- struct dentry * fh_dentry; /* validated dentry */ -+ struct path fh_path; /* validated path */ - struct svc_export * fh_export; /* export pointer */ - int fh_maxsize; /* max size for fh_handle */ - -@@ -217,7 +217,7 @@ void fh_put(struct svc_fh *); - static __inline__ struct svc_fh * - fh_copy(struct svc_fh *dst, struct svc_fh *src) - { -- WARN_ON(src->fh_dentry || src->fh_locked); -+ WARN_ON(src->fh_path.dentry || src->fh_locked); - - *dst = *src; - return dst; -@@ -240,7 +240,7 @@ fill_pre_wcc(struct svc_fh *fhp) - { - struct inode *inode; - -- inode = fhp->fh_dentry->d_inode; -+ inode = fhp->fh_path.dentry->d_inode; - if (!fhp->fh_pre_saved) { - fhp->fh_pre_mtime = inode->i_mtime; - fhp->fh_pre_ctime = inode->i_ctime; -@@ -255,7 +255,7 @@ fill_pre_wcc(struct svc_fh *fhp) - static inline void - fill_post_wcc(struct svc_fh *fhp) - { -- struct inode *inode = fhp->fh_dentry->d_inode; -+ struct inode *inode = fhp->fh_path.dentry->d_inode; - - if (fhp->fh_post_saved) - printk("nfsd: inode locked twice during operation.\n"); -@@ -290,7 +290,7 @@ fill_post_wcc(struct svc_fh *fhp) - static inline void - fh_lock_nested(struct svc_fh *fhp, unsigned int subclass) - { -- struct dentry *dentry = fhp->fh_dentry; -+ struct dentry *dentry = fhp->fh_path.dentry; - struct inode *inode; - - dfprintk(FILEOP, "nfsd: fh_lock(%s) locked = %d\n", -@@ -322,11 +322,11 @@ fh_lock(struct svc_fh *fhp) - static inline void - fh_unlock(struct svc_fh *fhp) - { -- BUG_ON(!fhp->fh_dentry); -+ BUG_ON(!fhp->fh_path.dentry); - - if (fhp->fh_locked) { - fill_post_wcc(fhp); -- mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex); -+ mutex_unlock(&fhp->fh_path.dentry->d_inode->i_mutex); - fhp->fh_locked = 0; - } - } -Index: linux-2.6/include/linux/nfsd/xdr4.h -=================================================================== ---- linux-2.6.orig/include/linux/nfsd/xdr4.h -+++ linux-2.6/include/linux/nfsd/xdr4.h -@@ -433,7 +433,7 @@ int nfs4svc_encode_compoundres(struct sv - void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); - void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op); - __be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, -- struct dentry *dentry, __be32 *buffer, int *countp, -+ struct path *path, __be32 *buffer, int *countp, - u32 *bmval, struct svc_rqst *); - extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, diff --git a/kernel-patches/for-mainline/struct_path/struct_path-security-getattr.diff b/kernel-patches/for-mainline/struct_path/struct_path-security-getattr.diff deleted file mode 100644 index ae5263c8a..000000000 --- a/kernel-patches/for-mainline/struct_path/struct_path-security-getattr.diff +++ /dev/null @@ -1,91 +0,0 @@ -Index: linux-2.6/include/linux/security.h -=================================================================== ---- linux-2.6.orig/include/linux/security.h -+++ linux-2.6/include/linux/security.h -@@ -361,8 +361,7 @@ struct request_sock; - * Return 0 if permission is granted. - * @inode_getattr: - * Check permission before obtaining file attributes. -- * @mnt is the vfsmount where the dentry was looked up -- * @dentry contains the dentry structure for the file. -+ * @path contains the vfsmount and dentry of the file. - * Return 0 if permission is granted. - * @inode_delete: - * @inode contains the inode structure for deleted inode. -@@ -1221,7 +1220,7 @@ struct security_operations { - int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); - int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd); - int (*inode_setattr) (struct dentry *dentry, struct iattr *attr); -- int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry); -+ int (*inode_getattr) (struct path *path); - void (*inode_delete) (struct inode *inode); - int (*inode_setxattr) (struct dentry *dentry, char *name, void *value, - size_t size, int flags); -@@ -1713,12 +1712,11 @@ static inline int security_inode_setattr - return security_ops->inode_setattr (dentry, attr); - } - --static inline int security_inode_getattr (struct vfsmount *mnt, -- struct dentry *dentry) -+static inline int security_inode_getattr (struct path *path) - { -- if (unlikely (IS_PRIVATE (dentry->d_inode))) -+ if (unlikely (IS_PRIVATE (path->dentry->d_inode))) - return 0; -- return security_ops->inode_getattr (mnt, dentry); -+ return security_ops->inode_getattr (path); - } - - static inline void security_inode_delete (struct inode *inode) -@@ -2414,8 +2412,7 @@ static inline int security_inode_setattr - return 0; - } - --static inline int security_inode_getattr (struct vfsmount *mnt, -- struct dentry *dentry) -+static inline int security_inode_getattr (struct path *path) - { - return 0; - } -Index: linux-2.6/security/dummy.c -=================================================================== ---- linux-2.6.orig/security/dummy.c -+++ linux-2.6/security/dummy.c -@@ -333,7 +333,7 @@ static int dummy_inode_setattr (struct d - return 0; - } - --static int dummy_inode_getattr (struct vfsmount *mnt, struct dentry *dentry) -+static int dummy_inode_getattr (struct path *path) - { - return 0; - } -Index: linux-2.6/security/selinux/hooks.c -=================================================================== ---- linux-2.6.orig/security/selinux/hooks.c -+++ linux-2.6/security/selinux/hooks.c -@@ -2243,9 +2243,9 @@ static int selinux_inode_setattr(struct - return dentry_has_perm(current, NULL, dentry, FILE__WRITE); - } - --static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) -+static int selinux_inode_getattr(struct path *path) - { -- return dentry_has_perm(current, mnt, dentry, FILE__GETATTR); -+ return dentry_has_perm(current, path->mnt, path->dentry, FILE__GETATTR); - } - - static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags) -Index: linux-2.6/fs/stat.c -=================================================================== ---- linux-2.6.orig/fs/stat.c -+++ linux-2.6/fs/stat.c -@@ -43,7 +43,7 @@ int vfs_getattr(struct path *path, struc - struct inode *inode = path->dentry->d_inode; - int retval; - -- retval = security_inode_getattr(path->mnt, path->dentry); -+ retval = security_inode_getattr(path); - if (retval) - return retval; - diff --git a/kernel-patches/for-mainline/struct_path/struct_path-vfs_getattr.diff b/kernel-patches/for-mainline/struct_path/struct_path-vfs_getattr.diff deleted file mode 100644 index c36bbdbff..000000000 --- a/kernel-patches/for-mainline/struct_path/struct_path-vfs_getattr.diff +++ /dev/null @@ -1,241 +0,0 @@ -Index: linux-2.6/drivers/block/loop.c -=================================================================== ---- linux-2.6.orig/drivers/block/loop.c -+++ linux-2.6/drivers/block/loop.c -@@ -1000,7 +1000,7 @@ loop_get_status(struct loop_device *lo, - - if (lo->lo_state != Lo_bound) - return -ENXIO; -- error = vfs_getattr(file->f_path.mnt, file->f_path.dentry, &stat); -+ error = vfs_getattr(&file->f_path, &stat); - if (error) - return error; - memset(info, 0, sizeof(*info)); -Index: linux-2.6/fs/gfs2/ops_fstype.c -=================================================================== ---- linux-2.6.orig/fs/gfs2/ops_fstype.c -+++ linux-2.6/fs/gfs2/ops_fstype.c -@@ -827,7 +827,7 @@ static struct super_block* get_gfs2_sb(c - dev_name); - goto out; - } -- error = vfs_getattr(nd.path.mnt, nd.path.dentry, &stat); -+ error = vfs_getattr(&nd.path, &stat); - - fstype = get_fs_type("gfs2"); - list_for_each(l, &fstype->fs_supers) { -Index: linux-2.6/fs/nfsd/nfs3proc.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfs3proc.c -+++ linux-2.6/fs/nfsd/nfs3proc.c -@@ -58,6 +58,7 @@ nfsd3_proc_getattr(struct svc_rqst *rqst - { - int err; - __be32 nfserr; -+ struct path path; - - dprintk("nfsd: GETATTR(3) %s\n", - SVCFH_fmt(&argp->fh)); -@@ -67,8 +68,9 @@ nfsd3_proc_getattr(struct svc_rqst *rqst - if (nfserr) - RETURN_STATUS(nfserr); - -- err = vfs_getattr(resp->fh.fh_export->ex_mnt, -- resp->fh.fh_dentry, &resp->stat); -+ path.mnt = resp->fh.fh_export->ex_mnt; -+ path.dentry = resp->fh.fh_dentry; -+ err = vfs_getattr(&path, &resp->stat); - nfserr = nfserrno(err); - - RETURN_STATUS(nfserr); -Index: linux-2.6/fs/nfsd/nfs3xdr.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfs3xdr.c -+++ linux-2.6/fs/nfsd/nfs3xdr.c -@@ -223,12 +223,15 @@ encode_saved_post_attr(struct svc_rqst * - static __be32 * - encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) - { -- struct dentry *dentry = fhp->fh_dentry; -- if (dentry && dentry->d_inode != NULL) { -+ struct path path; -+ -+ path.dentry = fhp->fh_dentry; -+ if (path.dentry && path.dentry->d_inode != NULL) { - int err; - struct kstat stat; - -- err = vfs_getattr(fhp->fh_export->ex_mnt, dentry, &stat); -+ path.mnt = fhp->fh_export->ex_mnt; -+ err = vfs_getattr(&path, &stat); - if (!err) { - *p++ = xdr_one; /* attributes follow */ - return encode_fattr3(rqstp, p, fhp, &stat); -Index: linux-2.6/fs/nfsd/nfs4xdr.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfs4xdr.c -+++ linux-2.6/fs/nfsd/nfs4xdr.c -@@ -1442,6 +1442,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s - int err; - int aclsupport = 0; - struct nfs4_acl *acl = NULL; -+ struct path path; - - BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1); - BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0); -@@ -1453,7 +1454,9 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s - goto out; - } - -- err = vfs_getattr(exp->ex_mnt, dentry, &stat); -+ path.mnt = exp->ex_mnt; -+ path.dentry = dentry; -+ err = vfs_getattr(&path, &stat); - if (err) - goto out_nfserr; - if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) || -Index: linux-2.6/fs/nfsd/nfsproc.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfsproc.c -+++ linux-2.6/fs/nfsd/nfsproc.c -@@ -39,18 +39,25 @@ nfsd_proc_null(struct svc_rqst *rqstp, v - static __be32 - nfsd_return_attrs(__be32 err, struct nfsd_attrstat *resp) - { -- if (err) return err; -- return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt, -- resp->fh.fh_dentry, -- &resp->stat)); -+ struct path path; -+ -+ if (err) -+ return err; -+ path.mnt = resp->fh.fh_export->ex_mnt; -+ path.dentry = resp->fh.fh_dentry; -+ return nfserrno(vfs_getattr(&path, &resp->stat)); - } -+ - static __be32 - nfsd_return_dirop(__be32 err, struct nfsd_diropres *resp) - { -- if (err) return err; -- return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt, -- resp->fh.fh_dentry, -- &resp->stat)); -+ struct path path; -+ -+ if (err) -+ return err; -+ path.mnt = resp->fh.fh_export->ex_mnt; -+ path.dentry = resp->fh.fh_dentry; -+ return nfserrno(vfs_getattr(&path, &resp->stat)); - } - /* - * Get a file's attributes -@@ -136,6 +143,7 @@ static __be32 - nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp, - struct nfsd_readres *resp) - { -+ struct path path; - __be32 nfserr; - - dprintk("nfsd: READ %s %d bytes at %d\n", -@@ -162,10 +170,11 @@ nfsd_proc_read(struct svc_rqst *rqstp, s - rqstp->rq_vec, argp->vlen, - &resp->count); - -- if (nfserr) return nfserr; -- return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt, -- resp->fh.fh_dentry, -- &resp->stat)); -+ if (nfserr) -+ return nfserr; -+ path.mnt = resp->fh.fh_export->ex_mnt; -+ path.dentry = resp->fh.fh_dentry; -+ return nfserrno(vfs_getattr(&path, &resp->stat)); - } - - /* -Index: linux-2.6/fs/nfsd/nfsxdr.c -=================================================================== ---- linux-2.6.orig/fs/nfsd/nfsxdr.c -+++ linux-2.6/fs/nfsd/nfsxdr.c -@@ -193,7 +193,11 @@ encode_fattr(struct svc_rqst *rqstp, __b - __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) - { - struct kstat stat; -- vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry, &stat); -+ struct path path; -+ -+ path.mnt = fhp->fh_export->ex_mnt; -+ path.dentry = fhp->fh_dentry; -+ vfs_getattr(&path, &stat); - return encode_fattr(rqstp, p, fhp, &stat); - } - -Index: linux-2.6/fs/stat.c -=================================================================== ---- linux-2.6.orig/fs/stat.c -+++ linux-2.6/fs/stat.c -@@ -38,17 +38,17 @@ void generic_fillattr(struct inode *inod - - EXPORT_SYMBOL(generic_fillattr); - --int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -+int vfs_getattr(struct path *path, struct kstat *stat) - { -- struct inode *inode = dentry->d_inode; -+ struct inode *inode = path->dentry->d_inode; - int retval; - -- retval = security_inode_getattr(mnt, dentry); -+ retval = security_inode_getattr(path->mnt, path->dentry); - if (retval) - return retval; - - if (inode->i_op->getattr) -- return inode->i_op->getattr(mnt, dentry, stat); -+ return inode->i_op->getattr(path->mnt, path->dentry, stat); - - generic_fillattr(inode, stat); - return 0; -@@ -63,7 +63,7 @@ int vfs_stat_fd(int dfd, char __user *na - - error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd); - if (!error) { -- error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); -+ error = vfs_getattr(&nd.path, stat); - path_release(&nd); - } - return error; -@@ -83,7 +83,7 @@ int vfs_lstat_fd(int dfd, char __user *n - - error = __user_walk_fd(dfd, name, 0, &nd); - if (!error) { -- error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); -+ error = vfs_getattr(&nd.path, stat); - path_release(&nd); - } - return error; -@@ -102,7 +102,7 @@ int vfs_fstat(unsigned int fd, struct ks - int error = -EBADF; - - if (f) { -- error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat); -+ error = vfs_getattr(&f->f_path, stat); - fput(f); - } - return error; -Index: linux-2.6/include/linux/fs.h -=================================================================== ---- linux-2.6.orig/include/linux/fs.h -+++ linux-2.6/include/linux/fs.h -@@ -1825,7 +1825,7 @@ extern int page_symlink(struct inode *in - extern struct inode_operations page_symlink_inode_operations; - extern int generic_readlink(struct dentry *, char __user *, int); - extern void generic_fillattr(struct inode *, struct kstat *); --extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); -+extern int vfs_getattr(struct path *, struct kstat *); - void inode_add_bytes(struct inode *inode, loff_t bytes); - void inode_sub_bytes(struct inode *inode, loff_t bytes); - loff_t inode_get_bytes(struct inode *inode); diff --git a/kernel-patches/for-mainline/sys_fchdir-nameidata.diff b/kernel-patches/for-mainline/sys_fchdir-nameidata.diff deleted file mode 100644 index 360cab1f0..000000000 --- a/kernel-patches/for-mainline/sys_fchdir-nameidata.diff +++ /dev/null @@ -1,51 +0,0 @@ -From: Andreas Gruenbacher -Subject: Switch to vfs_permission() in sys_fchdir() - -Switch from file_permission() to vfs_permission() in sys_fchdir(): this -avoids calling permission() with a NULL nameidata here. - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/open.c | 16 +++++++--------- - 1 file changed, 7 insertions(+), 9 deletions(-) - ---- a/fs/open.c -+++ b/fs/open.c -@@ -501,10 +501,8 @@ out: - - asmlinkage long sys_fchdir(unsigned int fd) - { -+ struct nameidata nd; - struct file *file; -- struct dentry *dentry; -- struct inode *inode; -- struct vfsmount *mnt; - int error; - - error = -EBADF; -@@ -512,17 +510,17 @@ asmlinkage long sys_fchdir(unsigned int - if (!file) - goto out; - -- dentry = file->f_path.dentry; -- mnt = file->f_path.mnt; -- inode = dentry->d_inode; -+ nd.dentry = file->f_path.dentry; -+ nd.mnt = file->f_path.mnt; -+ nd.flags = 0; - - error = -ENOTDIR; -- if (!S_ISDIR(inode->i_mode)) -+ if (!S_ISDIR(nd.dentry->d_inode->i_mode)) - goto out_putf; - -- error = file_permission(file, MAY_EXEC); -+ error = vfs_permission(&nd, MAY_EXEC); - if (!error) -- set_fs_pwd(current->fs, mnt, dentry); -+ set_fs_pwd(current->fs, nd.mnt, nd.dentry); - out_putf: - fput(file); - out: diff --git a/kernel-patches/for-mainline/sysctl-pathname.diff b/kernel-patches/for-mainline/sysctl-pathname.diff deleted file mode 100644 index c0e479200..000000000 --- a/kernel-patches/for-mainline/sysctl-pathname.diff +++ /dev/null @@ -1,111 +0,0 @@ -From: Andreas Gruenbacher -Subject: Factor out sysctl pathname code - -Convert the selinux sysctl pathname computation code into a standalone -function. - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen -Reviewed-by: James Morris - ---- - include/linux/sysctl.h | 2 ++ - kernel/sysctl.c | 27 +++++++++++++++++++++++++++ - security/selinux/hooks.c | 35 +++++------------------------------ - 3 files changed, 34 insertions(+), 30 deletions(-) - ---- a/include/linux/sysctl.h -+++ b/include/linux/sysctl.h -@@ -983,6 +983,8 @@ extern int proc_doulongvec_minmax(struct - extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int, - struct file *, void __user *, size_t *, loff_t *); - -+extern char *sysctl_pathname(ctl_table *, char *, int); -+ - extern int do_sysctl (int __user *name, int nlen, - void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen); ---- a/kernel/sysctl.c -+++ b/kernel/sysctl.c -@@ -1327,6 +1327,33 @@ struct ctl_table_header *sysctl_head_nex - return NULL; - } - -+char *sysctl_pathname(ctl_table *table, char *buffer, int buflen) -+{ -+ if (buflen < 1) -+ return NULL; -+ buffer += --buflen; -+ *buffer = '\0'; -+ -+ while (table) { -+ int namelen = strlen(table->procname); -+ -+ if (buflen < namelen + 1) -+ return NULL; -+ buflen -= namelen + 1; -+ buffer -= namelen; -+ memcpy(buffer, table->procname, namelen); -+ *--buffer = '/'; -+ table = table->parent; -+ } -+ if (buflen < 4) -+ return NULL; -+ buffer -= 4; -+ memcpy(buffer, "/sys", 4); -+ -+ return buffer; -+} -+EXPORT_SYMBOL(sysctl_pathname); -+ - #ifdef CONFIG_SYSCTL_SYSCALL - int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen) ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -1431,40 +1431,15 @@ static int selinux_capable(struct task_s - - static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) - { -- int buflen, rc; -- char *buffer, *path, *end; -+ char *buffer, *path; -+ int rc = -ENOMEM; - -- rc = -ENOMEM; - buffer = (char*)__get_free_page(GFP_KERNEL); - if (!buffer) - goto out; -- -- buflen = PAGE_SIZE; -- end = buffer+buflen; -- *--end = '\0'; -- buflen--; -- path = end-1; -- *path = '/'; -- while (table) { -- const char *name = table->procname; -- size_t namelen = strlen(name); -- buflen -= namelen + 1; -- if (buflen < 0) -- goto out_free; -- end -= namelen; -- memcpy(end, name, namelen); -- *--end = '/'; -- path = end; -- table = table->parent; -- } -- buflen -= 4; -- if (buflen < 0) -- goto out_free; -- end -= 4; -- memcpy(end, "/sys", 4); -- path = end; -- rc = security_genfs_sid("proc", path, tclass, sid); --out_free: -+ path = sysctl_pathname(table, buffer, PAGE_SIZE); -+ if (path) -+ rc = security_genfs_sid("proc", path, tclass, sid); - free_page((unsigned long)buffer); - out: - return rc; diff --git a/kernel-patches/for-mainline/unambiguous-__d_path.diff b/kernel-patches/for-mainline/unambiguous-__d_path.diff deleted file mode 100644 index e3196b231..000000000 --- a/kernel-patches/for-mainline/unambiguous-__d_path.diff +++ /dev/null @@ -1,268 +0,0 @@ -From: Andreas Gruenbacher -Subject: Fix __d_path() for lazy unmounts and make it unambiguous - -First, when __d_path() hits a lazily unmounted mount point, it tries to prepend -the name of the lazily unmounted dentry to the path name. It gets this wrong, -and also overwrites the slash that separates the name from the following -pathname component. This patch fixes that; if a process was in directory -/foo/bar and /foo got lazily unmounted, the old result was ``foobar'' (note the -missing slash), while the new result with this patch is ``foo/bar''. - -Second, it isn't always possible to tell from the __d_path() result whether the -specified root and rootmnt (i.e., the chroot) was reached. We need an -unambiguous result for AppArmor at least though, so we make sure that paths -will only start with a slash if the path leads all the way up to the root. - -We also add a @fail_deleted argument, which allows to get rid of some of the -mess in sys_getcwd(). - -This patch leaves getcwd() and d_path() as they were before for everything -except for bind-mounted directories; for them, it reports ``/foo/bar'' instead -of ``foobar'' in the example described above. - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen -Acked-by: Alan Cox - ---- - fs/dcache.c | 169 ++++++++++++++++++++++++++++++++++-------------------------- - 1 file changed, 98 insertions(+), 71 deletions(-) - ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -1764,52 +1764,51 @@ shouldnt_be_hashed: - } - - /** -- * d_path - return the path of a dentry -+ * __d_path - return the path of a dentry - * @dentry: dentry to report - * @vfsmnt: vfsmnt to which the dentry belongs - * @root: root dentry - * @rootmnt: vfsmnt to which the root dentry belongs - * @buffer: buffer to return value in - * @buflen: buffer length -+ * @fail_deleted: what to return for deleted files - * -- * Convert a dentry into an ASCII path name. If the entry has been deleted -+ * Convert a dentry into an ASCII path name. If the entry has been deleted, -+ * then if @fail_deleted is true, ERR_PTR(-ENOENT) is returned. Otherwise, - * the string " (deleted)" is appended. Note that this is ambiguous. - * -- * Returns the buffer or an error code if the path was too long. -+ * If @dentry is not connected to @root, the path returned will be relative -+ * (i.e., it will not start with a slash). - * -- * "buflen" should be positive. Caller holds the dcache_lock. -+ * Returns the buffer or an error code. - */ --static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt, -- struct dentry *root, struct vfsmount *rootmnt, -- char *buffer, int buflen) --{ -- char * end = buffer+buflen; -- char * retval; -- int namelen; -+static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt, -+ struct dentry *root, struct vfsmount *rootmnt, -+ char *buffer, int buflen, int fail_deleted) -+{ -+ int namelen, is_slash; -+ -+ if (buflen < 2) -+ return ERR_PTR(-ENAMETOOLONG); -+ buffer += --buflen; -+ *buffer = '\0'; - -- *--end = '\0'; -- buflen--; -+ spin_lock(&dcache_lock); - if (!IS_ROOT(dentry) && d_unhashed(dentry)) { -- buflen -= 10; -- end -= 10; -- if (buflen < 0) -+ if (fail_deleted) { -+ buffer = ERR_PTR(-ENOENT); -+ goto out; -+ } -+ if (buflen < 10) - goto Elong; -- memcpy(end, " (deleted)", 10); -+ buflen -= 10; -+ buffer -= 10; -+ memcpy(buffer, " (deleted)", 10); - } -- -- if (buflen < 1) -- goto Elong; -- /* Get '/' right */ -- retval = end-1; -- *retval = '/'; -- -- for (;;) { -+ while (dentry != root || vfsmnt != rootmnt) { - struct dentry * parent; - -- if (dentry == root && vfsmnt == rootmnt) -- break; - if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { -- /* Global root? */ - spin_lock(&vfsmount_lock); - if (vfsmnt->mnt_parent == vfsmnt) { - spin_unlock(&vfsmount_lock); -@@ -1823,33 +1822,72 @@ static char * __d_path( struct dentry *d - parent = dentry->d_parent; - prefetch(parent); - namelen = dentry->d_name.len; -- buflen -= namelen + 1; -- if (buflen < 0) -+ if (buflen < namelen + 1) - goto Elong; -- end -= namelen; -- memcpy(end, dentry->d_name.name, namelen); -- *--end = '/'; -- retval = end; -+ buflen -= namelen + 1; -+ buffer -= namelen; -+ memcpy(buffer, dentry->d_name.name, namelen); -+ *--buffer = '/'; - dentry = parent; - } -+ /* Get '/' right. */ -+ if (*buffer != '/') -+ *--buffer = '/'; - -- return retval; -+out: -+ spin_unlock(&dcache_lock); -+ return buffer; - - global_root: -+ /* -+ * We went past the (vfsmount, dentry) we were looking for and have -+ * either hit a root dentry, a lazily unmounted dentry, an -+ * unconnected dentry, or the file is on a pseudo filesystem. -+ */ - namelen = dentry->d_name.len; -- buflen -= namelen; -- if (buflen < 0) -+ is_slash = (namelen == 1 && *dentry->d_name.name == '/'); -+ if (is_slash || (dentry->d_sb->s_flags & MS_NOUSER)) { -+ /* -+ * Make sure we won't return a pathname starting with '/'. -+ * -+ * Historically, we also glue together the root dentry and -+ * remaining name for pseudo filesystems like pipefs, which -+ * have the MS_NOUSER flag set. This results in pathnames -+ * like "pipe:[439336]". -+ */ -+ if (*buffer == '/') { -+ buffer++; -+ buflen++; -+ } -+ if (is_slash) -+ goto out; -+ } -+ if (buflen < namelen) - goto Elong; -- retval -= namelen-1; /* hit the slash */ -- memcpy(retval, dentry->d_name.name, namelen); -- return retval; -+ buffer -= namelen; -+ memcpy(buffer, dentry->d_name.name, namelen); -+ goto out; -+ - Elong: -- return ERR_PTR(-ENAMETOOLONG); -+ buffer = ERR_PTR(-ENAMETOOLONG); -+ goto out; -+} -+ -+static char *__connect_d_path(char *path, char *buffer) -+{ -+ if (!IS_ERR(path) && *path != '/') { -+ /* Pretend that disconnected paths are hanging off the root. */ -+ if (path == buffer) -+ path = ERR_PTR(-ENAMETOOLONG); -+ else -+ *--path = '/'; -+ } -+ return path; - } - - /* write full pathname into buffer and return start of pathname */ --char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, -- char *buf, int buflen) -+char *d_path(struct dentry *dentry, struct vfsmount *vfsmnt, char *buf, -+ int buflen) - { - char *res; - struct vfsmount *rootmnt; -@@ -1869,9 +1907,8 @@ char * d_path(struct dentry *dentry, str - rootmnt = mntget(current->fs->rootmnt); - root = dget(current->fs->root); - read_unlock(¤t->fs->lock); -- spin_lock(&dcache_lock); -- res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen); -- spin_unlock(&dcache_lock); -+ res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, 0); -+ res = __connect_d_path(res, buf); - dput(root); - mntput(rootmnt); - return res; -@@ -1918,10 +1955,10 @@ char *dynamic_dname(struct dentry *dentr - */ - asmlinkage long sys_getcwd(char __user *buf, unsigned long size) - { -- int error; -+ int error, len; - struct vfsmount *pwdmnt, *rootmnt; - struct dentry *pwd, *root; -- char *page = (char *) __get_free_page(GFP_USER); -+ char *page = (char *) __get_free_page(GFP_USER), *cwd; - - if (!page) - return -ENOMEM; -@@ -1933,29 +1970,19 @@ asmlinkage long sys_getcwd(char __user * - root = dget(current->fs->root); - read_unlock(¤t->fs->lock); - -- error = -ENOENT; -- /* Has the current directory has been unlinked? */ -- spin_lock(&dcache_lock); -- if (pwd->d_parent == pwd || !d_unhashed(pwd)) { -- unsigned long len; -- char * cwd; -- -- cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE); -- spin_unlock(&dcache_lock); -- -- error = PTR_ERR(cwd); -- if (IS_ERR(cwd)) -- goto out; -- -- error = -ERANGE; -- len = PAGE_SIZE + page - cwd; -- if (len <= size) { -- error = len; -- if (copy_to_user(buf, cwd, len)) -- error = -EFAULT; -- } -- } else -- spin_unlock(&dcache_lock); -+ cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1); -+ cwd = __connect_d_path(cwd, page); -+ error = PTR_ERR(cwd); -+ if (IS_ERR(cwd)) -+ goto out; -+ -+ error = -ERANGE; -+ len = PAGE_SIZE + page - cwd; -+ if (len <= size) { -+ error = len; -+ if (copy_to_user(buf, cwd, len)) -+ error = -EFAULT; -+ } - - out: - dput(pwd); diff --git a/kernel-patches/for-mainline/vfs-getxattr.diff b/kernel-patches/for-mainline/vfs-getxattr.diff deleted file mode 100644 index a22f52b87..000000000 --- a/kernel-patches/for-mainline/vfs-getxattr.diff +++ /dev/null @@ -1,190 +0,0 @@ -From: Tony Jones -Subject: Add a struct vfsmount parameter to vfs_getxattr() - -The vfsmount will be passed down to the LSM hook so that LSMs can compute -pathnames. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/nfsd/nfs4xdr.c | 2 +- - fs/nfsd/vfs.c | 21 ++++++++++++--------- - fs/xattr.c | 14 ++++++++------ - include/linux/nfsd/nfsd.h | 3 ++- - include/linux/xattr.h | 3 ++- - 5 files changed, 25 insertions(+), 18 deletions(-) - ---- a/fs/nfsd/nfs4xdr.c -+++ b/fs/nfsd/nfs4xdr.c -@@ -1496,7 +1496,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s - } - if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT - | FATTR4_WORD0_SUPPORTED_ATTRS)) { -- err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); -+ err = nfsd4_get_nfs4_acl(rqstp, dentry, exp->ex_mnt, &acl); - aclsupport = (err == 0); - if (bmval0 & FATTR4_WORD0_ACL) { - if (err == -EOPNOTSUPP) ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -408,11 +408,12 @@ out_nfserr: - #if defined(CONFIG_NFSD_V2_ACL) || \ - defined(CONFIG_NFSD_V3_ACL) || \ - defined(CONFIG_NFSD_V4) --static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf) -+static ssize_t nfsd_getxattr(struct dentry *dentry, struct vfsmount *mnt, -+ char *key, void **buf) - { - ssize_t buflen; - -- buflen = vfs_getxattr(dentry, key, NULL, 0); -+ buflen = vfs_getxattr(dentry, mnt, key, NULL, 0); - if (buflen <= 0) - return buflen; - -@@ -420,7 +421,7 @@ static ssize_t nfsd_getxattr(struct dent - if (!*buf) - return -ENOMEM; - -- return vfs_getxattr(dentry, key, *buf, buflen); -+ return vfs_getxattr(dentry, mnt, key, *buf, buflen); - } - #endif - -@@ -501,13 +502,13 @@ out_nfserr: - } - - static struct posix_acl * --_get_posix_acl(struct dentry *dentry, char *key) -+_get_posix_acl(struct dentry *dentry, struct vfsmount *mnt, char *key) - { - void *buf = NULL; - struct posix_acl *pacl = NULL; - int buflen; - -- buflen = nfsd_getxattr(dentry, key, &buf); -+ buflen = nfsd_getxattr(dentry, mnt, key, &buf); - if (!buflen) - buflen = -ENODATA; - if (buflen <= 0) -@@ -519,14 +520,15 @@ _get_posix_acl(struct dentry *dentry, ch - } - - int --nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_acl **acl) -+nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, -+ struct vfsmount *mnt, struct nfs4_acl **acl) - { - struct inode *inode = dentry->d_inode; - int error = 0; - struct posix_acl *pacl = NULL, *dpacl = NULL; - unsigned int flags = 0; - -- pacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_ACCESS); -+ pacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_ACCESS); - if (IS_ERR(pacl) && PTR_ERR(pacl) == -ENODATA) - pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); - if (IS_ERR(pacl)) { -@@ -536,7 +538,7 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqst - } - - if (S_ISDIR(inode->i_mode)) { -- dpacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_DEFAULT); -+ dpacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_DEFAULT); - if (IS_ERR(dpacl) && PTR_ERR(dpacl) == -ENODATA) - dpacl = NULL; - else if (IS_ERR(dpacl)) { -@@ -2001,7 +2003,8 @@ nfsd_get_posix_acl(struct svc_fh *fhp, i - return ERR_PTR(-EOPNOTSUPP); - } - -- size = nfsd_getxattr(fhp->fh_dentry, name, &value); -+ size = nfsd_getxattr(fhp->fh_dentry, fhp->fh_export->ex_mnt, name, -+ &value); - if (size < 0) - return ERR_PTR(size); - ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -105,7 +105,8 @@ out: - EXPORT_SYMBOL_GPL(vfs_setxattr); - - ssize_t --vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size) -+vfs_getxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, -+ void *value, size_t size) - { - struct inode *inode = dentry->d_inode; - int error; -@@ -277,7 +278,8 @@ sys_fsetxattr(int fd, char __user *name, - * Extended attribute GET operations - */ - static ssize_t --getxattr(struct dentry *d, char __user *name, void __user *value, size_t size) -+getxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name, -+ void __user *value, size_t size) - { - ssize_t error; - void *kvalue = NULL; -@@ -297,7 +299,7 @@ getxattr(struct dentry *d, char __user * - return -ENOMEM; - } - -- error = vfs_getxattr(d, kname, kvalue, size); -+ error = vfs_getxattr(dentry, mnt, kname, kvalue, size); - if (error > 0) { - if (size && copy_to_user(value, kvalue, error)) - error = -EFAULT; -@@ -320,7 +322,7 @@ sys_getxattr(char __user *path, char __u - error = user_path_walk(path, &nd); - if (error) - return error; -- error = getxattr(nd.dentry, name, value, size); -+ error = getxattr(nd.dentry, nd.mnt, name, value, size); - path_release(&nd); - return error; - } -@@ -335,7 +337,7 @@ sys_lgetxattr(char __user *path, char __ - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = getxattr(nd.dentry, name, value, size); -+ error = getxattr(nd.dentry, nd.mnt, name, value, size); - path_release(&nd); - return error; - } -@@ -350,7 +352,7 @@ sys_fgetxattr(int fd, char __user *name, - if (!f) - return error; - audit_inode(NULL, f->f_path.dentry); -- error = getxattr(f->f_path.dentry, name, value, size); -+ error = getxattr(f->f_path.dentry, f->f_path.mnt, name, value, size); - fput(f); - return error; - } ---- a/include/linux/nfsd/nfsd.h -+++ b/include/linux/nfsd/nfsd.h -@@ -79,7 +79,8 @@ __be32 nfsd_setattr(struct svc_rqst *, - #ifdef CONFIG_NFSD_V4 - __be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *, - struct nfs4_acl *); --int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **); -+int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, -+ struct vfsmount *mnt, struct nfs4_acl **); - #endif /* CONFIG_NFSD_V4 */ - __be32 nfsd_create(struct svc_rqst *, struct svc_fh *, - char *name, int len, struct iattr *attrs, ---- a/include/linux/xattr.h -+++ b/include/linux/xattr.h -@@ -46,7 +46,8 @@ struct xattr_handler { - size_t size, int flags); - }; - --ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t); -+ssize_t vfs_getxattr(struct dentry *, struct vfsmount *, char *, void *, -+ size_t); - ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); - int vfs_setxattr(struct dentry *, struct vfsmount *, char *, void *, size_t, - int); diff --git a/kernel-patches/for-mainline/vfs-link.diff b/kernel-patches/for-mainline/vfs-link.diff deleted file mode 100644 index 8a4f24d26..000000000 --- a/kernel-patches/for-mainline/vfs-link.diff +++ /dev/null @@ -1,90 +0,0 @@ -From: Tony Jones -Subject: Add struct vfsmount parameters to vfs_link() - -The vfsmount will be passed down to the LSM hook so that LSMs can compute -pathnames. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/ecryptfs/inode.c | 9 +++++++-- - fs/namei.c | 5 +++-- - fs/nfsd/vfs.c | 3 ++- - include/linux/fs.h | 2 +- - 4 files changed, 13 insertions(+), 6 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -402,19 +402,24 @@ static int ecryptfs_link(struct dentry * - struct dentry *new_dentry) - { - struct dentry *lower_old_dentry; -+ struct vfsmount *lower_old_mnt; - struct dentry *lower_new_dentry; -+ struct vfsmount *lower_new_mnt; - struct dentry *lower_dir_dentry; - u64 file_size_save; - int rc; - - file_size_save = i_size_read(old_dentry->d_inode); - lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); -+ lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry); - lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); -+ lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry); - dget(lower_old_dentry); - dget(lower_new_dentry); - lower_dir_dentry = lock_parent(lower_new_dentry); -- rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode, -- lower_new_dentry); -+ rc = vfs_link(lower_old_dentry, lower_old_mnt, -+ lower_dir_dentry->d_inode, lower_new_dentry, -+ lower_new_mnt); - if (rc || !lower_new_dentry->d_inode) - goto out_lock; - rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2331,7 +2331,7 @@ asmlinkage long sys_symlink(const char _ - return sys_symlinkat(oldname, AT_FDCWD, newname); - } - --int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) -+int vfs_link(struct dentry *old_dentry, struct vfsmount *old_mnt, struct inode *dir, struct dentry *new_dentry, struct vfsmount *new_mnt) - { - struct inode *inode = old_dentry->d_inode; - int error; -@@ -2409,7 +2409,8 @@ asmlinkage long sys_linkat(int olddfd, c - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto out_unlock; -- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); -+ error = vfs_link(old_nd.dentry, old_nd.mnt, nd.dentry->d_inode, -+ new_dentry, nd.mnt); - dput(new_dentry); - out_unlock: - mutex_unlock(&nd.dentry->d_inode->i_mutex); ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1589,7 +1589,8 @@ nfsd_link(struct svc_rqst *rqstp, struct - dold = tfhp->fh_dentry; - dest = dold->d_inode; - -- host_err = vfs_link(dold, dirp, dnew); -+ host_err = vfs_link(dold, tfhp->fh_export->ex_mnt, dirp, -+ dnew, ffhp->fh_export->ex_mnt); - if (!host_err) { - if (EX_ISSYNC(ffhp->fh_export)) { - err = nfserrno(nfsd_sync_dir(ddir)); ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1071,7 +1071,7 @@ extern int vfs_create(struct inode *, st - extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int); - extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t); - extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *, int); --extern int vfs_link(struct dentry *, struct inode *, struct dentry *); -+extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); - extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); diff --git a/kernel-patches/for-mainline/vfs-listxattr.diff b/kernel-patches/for-mainline/vfs-listxattr.diff deleted file mode 100644 index d0cb8e0d8..000000000 --- a/kernel-patches/for-mainline/vfs-listxattr.diff +++ /dev/null @@ -1,102 +0,0 @@ -From: Tony Jones -Subject: Add a struct vfsmount parameter to vfs_listxattr() - -The vfsmount will be passed down to the LSM hook so that LSMs can compute -pathnames. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/xattr.c | 25 ++++++++++++++----------- - include/linux/xattr.h | 3 ++- - 2 files changed, 16 insertions(+), 12 deletions(-) - ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -142,18 +142,20 @@ vfs_getxattr(struct dentry *dentry, stru - EXPORT_SYMBOL_GPL(vfs_getxattr); - - ssize_t --vfs_listxattr(struct dentry *d, char *list, size_t size) -+vfs_listxattr(struct dentry *dentry, struct vfsmount *mnt, char *list, -+ size_t size) - { -+ struct inode *inode = dentry->d_inode; - ssize_t error; - -- error = security_inode_listxattr(d); -+ error = security_inode_listxattr(dentry); - if (error) - return error; - error = -EOPNOTSUPP; -- if (d->d_inode->i_op && d->d_inode->i_op->listxattr) { -- error = d->d_inode->i_op->listxattr(d, list, size); -- } else { -- error = security_inode_listsecurity(d->d_inode, list, size); -+ if (inode->i_op && inode->i_op->listxattr) -+ error = inode->i_op->listxattr(dentry, list, size); -+ else { -+ error = security_inode_listsecurity(inode, list, size); - if (size && error > size) - error = -ERANGE; - } -@@ -361,7 +363,8 @@ sys_fgetxattr(int fd, char __user *name, - * Extended attribute LIST operations - */ - static ssize_t --listxattr(struct dentry *d, char __user *list, size_t size) -+listxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *list, -+ size_t size) - { - ssize_t error; - char *klist = NULL; -@@ -374,7 +377,7 @@ listxattr(struct dentry *d, char __user - return -ENOMEM; - } - -- error = vfs_listxattr(d, klist, size); -+ error = vfs_listxattr(dentry, mnt, klist, size); - if (error > 0) { - if (size && copy_to_user(list, klist, error)) - error = -EFAULT; -@@ -396,7 +399,7 @@ sys_listxattr(char __user *path, char __ - error = user_path_walk(path, &nd); - if (error) - return error; -- error = listxattr(nd.dentry, list, size); -+ error = listxattr(nd.dentry, nd.mnt, list, size); - path_release(&nd); - return error; - } -@@ -410,7 +413,7 @@ sys_llistxattr(char __user *path, char _ - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = listxattr(nd.dentry, list, size); -+ error = listxattr(nd.dentry, nd.mnt, list, size); - path_release(&nd); - return error; - } -@@ -425,7 +428,7 @@ sys_flistxattr(int fd, char __user *list - if (!f) - return error; - audit_inode(NULL, f->f_path.dentry); -- error = listxattr(f->f_path.dentry, list, size); -+ error = listxattr(f->f_path.dentry, f->f_path.mnt, list, size); - fput(f); - return error; - } ---- a/include/linux/xattr.h -+++ b/include/linux/xattr.h -@@ -48,7 +48,8 @@ struct xattr_handler { - - ssize_t vfs_getxattr(struct dentry *, struct vfsmount *, char *, void *, - size_t); --ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); -+ssize_t vfs_listxattr(struct dentry *d, struct vfsmount *, char *list, -+ size_t size); - int vfs_setxattr(struct dentry *, struct vfsmount *, char *, void *, size_t, - int); - int vfs_removexattr(struct dentry *, char *); diff --git a/kernel-patches/for-mainline/vfs-mkdir.diff b/kernel-patches/for-mainline/vfs-mkdir.diff deleted file mode 100644 index 2ceec7691..000000000 --- a/kernel-patches/for-mainline/vfs-mkdir.diff +++ /dev/null @@ -1,137 +0,0 @@ -From: Tony Jones -Subject: Add struct vfsmount parameter to vfs_mkdir() - -The vfsmount will be passed down to the LSM hook so that LSMs can compute -pathnames. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/ecryptfs/inode.c | 5 ++++- - fs/namei.c | 5 +++-- - fs/nfsd/nfs4recover.c | 3 ++- - fs/nfsd/vfs.c | 8 +++++--- - include/linux/fs.h | 2 +- - kernel/cgroup.c | 2 +- - 6 files changed, 16 insertions(+), 9 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -488,11 +488,14 @@ static int ecryptfs_mkdir(struct inode * - { - int rc; - struct dentry *lower_dentry; -+ struct vfsmount *lower_mnt; - struct dentry *lower_dir_dentry; - - lower_dentry = ecryptfs_dentry_to_lower(dentry); -+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); - lower_dir_dentry = lock_parent(lower_dentry); -- rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode); -+ rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, -+ mode); - if (rc || !lower_dentry->d_inode) - goto out; - rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -1998,7 +1998,8 @@ asmlinkage long sys_mknod(const char __u - return sys_mknodat(AT_FDCWD, filename, mode, dev); - } - --int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) -+int vfs_mkdir(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, -+ int mode) - { - int error = may_create(dir, dentry, NULL); - -@@ -2042,7 +2043,7 @@ asmlinkage long sys_mkdirat(int dfd, con - - if (!IS_POSIXACL(nd.dentry->d_inode)) - mode &= ~current->fs->umask; -- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); -+ error = vfs_mkdir(nd.dentry->d_inode, dentry, nd.mnt, mode); - dput(dentry); - out_unlock: - mutex_unlock(&nd.dentry->d_inode->i_mutex); ---- a/fs/nfsd/nfs4recover.c -+++ b/fs/nfsd/nfs4recover.c -@@ -154,7 +154,8 @@ nfsd4_create_clid_dir(struct nfs4_client - dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); - goto out_put; - } -- status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU); -+ status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, rec_dir.mnt, -+ S_IRWXU); - out_put: - dput(dentry); - out_unlock: ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1165,6 +1165,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - int type, dev_t rdev, struct svc_fh *resfhp) - { - struct dentry *dentry, *dchild = NULL; -+ struct svc_export *exp; - struct inode *dirp; - __be32 err; - int host_err; -@@ -1181,6 +1182,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - goto out; - - dentry = fhp->fh_dentry; -+ exp = fhp->fh_export; - dirp = dentry->d_inode; - - err = nfserr_notdir; -@@ -1197,7 +1199,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - host_err = PTR_ERR(dchild); - if (IS_ERR(dchild)) - goto out_nfserr; -- err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); -+ err = fh_compose(resfhp, exp, dchild, fhp); - if (err) - goto out; - } else { -@@ -1236,7 +1238,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); - break; - case S_IFDIR: -- host_err = vfs_mkdir(dirp, dchild, iap->ia_mode); -+ host_err = vfs_mkdir(dirp, dchild, exp->ex_mnt, iap->ia_mode); - break; - case S_IFCHR: - case S_IFBLK: -@@ -1251,7 +1253,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - if (host_err < 0) - goto out_nfserr; - -- if (EX_ISSYNC(fhp->fh_export)) { -+ if (EX_ISSYNC(exp)) { - err = nfserrno(nfsd_sync_dir(dentry)); - write_inode_now(dchild->d_inode, 1); - } ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1068,7 +1068,7 @@ extern void unlock_super(struct super_bl - */ - extern int vfs_permission(struct nameidata *, int); - extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *); --extern int vfs_mkdir(struct inode *, struct dentry *, int); -+extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int); - extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t); - extern int vfs_symlink(struct inode *, struct dentry *, const char *, int); - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); ---- a/kernel/cgroup.c -+++ b/kernel/cgroup.c -@@ -2611,7 +2611,7 @@ int cgroup_clone(struct task_struct *tsk - } - - /* Create the cgroup directory, which also creates the cgroup */ -- ret = vfs_mkdir(inode, dentry, S_IFDIR | 0755); -+ ret = vfs_mkdir(inode, dentry, NULL, S_IFDIR | 0755); - child = __d_cgrp(dentry); - dput(dentry); - if (ret) { diff --git a/kernel-patches/for-mainline/vfs-mknod.diff b/kernel-patches/for-mainline/vfs-mknod.diff deleted file mode 100644 index fd6c20c58..000000000 --- a/kernel-patches/for-mainline/vfs-mknod.diff +++ /dev/null @@ -1,98 +0,0 @@ -From: Tony Jones -Subject: Add a struct vfsmount parameter to vfs_mknod() - -The vfsmount will be passed down to the LSM hook so that LSMs can compute -pathnames. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/ecryptfs/inode.c | 5 ++++- - fs/namei.c | 10 ++++++---- - fs/nfsd/vfs.c | 3 ++- - include/linux/fs.h | 2 +- - net/unix/af_unix.c | 2 +- - 5 files changed, 14 insertions(+), 8 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -551,11 +551,14 @@ ecryptfs_mknod(struct inode *dir, struct - { - int rc; - struct dentry *lower_dentry; -+ struct vfsmount *lower_mnt; - struct dentry *lower_dir_dentry; - - lower_dentry = ecryptfs_dentry_to_lower(dentry); -+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); - lower_dir_dentry = lock_parent(lower_dentry); -- rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev); -+ rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, mode, -+ dev); - if (rc || !lower_dentry->d_inode) - goto out; - rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -1918,7 +1918,8 @@ fail: - } - EXPORT_SYMBOL_GPL(lookup_create); - --int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) -+int vfs_mknod(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, -+ int mode, dev_t dev) - { - int error = may_create(dir, dentry, NULL); - -@@ -1970,11 +1971,12 @@ asmlinkage long sys_mknodat(int dfd, con - error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); - break; - case S_IFCHR: case S_IFBLK: -- error = vfs_mknod(nd.dentry->d_inode,dentry,mode, -- new_decode_dev(dev)); -+ error = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, -+ mode, new_decode_dev(dev)); - break; - case S_IFIFO: case S_IFSOCK: -- error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0); -+ error = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, -+ mode, 0); - break; - case S_IFDIR: - error = -EPERM; ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1244,7 +1244,8 @@ nfsd_create(struct svc_rqst *rqstp, stru - case S_IFBLK: - case S_IFIFO: - case S_IFSOCK: -- host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); -+ host_err = vfs_mknod(dirp, dchild, exp->ex_mnt, iap->ia_mode, -+ rdev); - break; - default: - printk("nfsd: bad file type %o in nfsd_create\n", type); ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1069,7 +1069,7 @@ extern void unlock_super(struct super_bl - extern int vfs_permission(struct nameidata *, int); - extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *); - extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int); --extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t); -+extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t); - extern int vfs_symlink(struct inode *, struct dentry *, const char *, int); - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); ---- a/net/unix/af_unix.c -+++ b/net/unix/af_unix.c -@@ -839,7 +839,7 @@ static int unix_bind(struct socket *sock - */ - mode = S_IFSOCK | - (SOCK_INODE(sock)->i_mode & ~current->fs->umask); -- err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); -+ err = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, mode, 0); - if (err) - goto out_mknod_dput; - mutex_unlock(&nd.dentry->d_inode->i_mutex); diff --git a/kernel-patches/for-mainline/vfs-notify_change.diff b/kernel-patches/for-mainline/vfs-notify_change.diff deleted file mode 100644 index 1d7513938..000000000 --- a/kernel-patches/for-mainline/vfs-notify_change.diff +++ /dev/null @@ -1,387 +0,0 @@ -From: Tony Jones -Subject: Add a vfsmount parameter to notify_change() - -The vfsmount parameter must be set appropriately for files visibile -outside the kernel. Files that are only used in a filesystem (e.g., -reiserfs xattr files) will have a NULL vfsmount. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/attr.c | 3 ++- - fs/ecryptfs/inode.c | 4 +++- - fs/exec.c | 3 ++- - fs/fat/file.c | 2 +- - fs/hpfs/namei.c | 2 +- - fs/namei.c | 2 +- - fs/nfsd/vfs.c | 8 ++++---- - fs/open.c | 28 +++++++++++++++------------- - fs/reiserfs/xattr.c | 6 +++--- - fs/sysfs/file.c | 2 +- - fs/utimes.c | 11 ++++++----- - include/linux/fs.h | 6 +++--- - mm/filemap.c | 2 +- - mm/tiny-shmem.c | 2 +- - 14 files changed, 44 insertions(+), 37 deletions(-) - ---- a/fs/attr.c -+++ b/fs/attr.c -@@ -100,7 +100,8 @@ int inode_setattr(struct inode * inode, - } - EXPORT_SYMBOL(inode_setattr); - --int notify_change(struct dentry * dentry, struct iattr * attr) -+int notify_change(struct dentry *dentry, struct vfsmount *mnt, -+ struct iattr *attr) - { - struct inode *inode = dentry->d_inode; - mode_t mode = inode->i_mode; ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -862,6 +862,7 @@ static int ecryptfs_setattr(struct dentr - { - int rc = 0; - struct dentry *lower_dentry; -+ struct vfsmount *lower_mnt; - struct inode *inode; - struct inode *lower_inode; - struct ecryptfs_crypt_stat *crypt_stat; -@@ -872,6 +873,7 @@ static int ecryptfs_setattr(struct dentr - inode = dentry->d_inode; - lower_inode = ecryptfs_inode_to_lower(inode); - lower_dentry = ecryptfs_dentry_to_lower(dentry); -+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); - mutex_lock(&crypt_stat->cs_mutex); - if (S_ISDIR(dentry->d_inode->i_mode)) - crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); -@@ -922,7 +924,7 @@ static int ecryptfs_setattr(struct dentr - if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) - ia->ia_valid &= ~ATTR_MODE; - -- rc = notify_change(lower_dentry, ia); -+ rc = notify_change(lower_dentry, lower_mnt, ia); - out: - fsstack_copy_attr_all(inode, lower_inode, NULL); - return rc; ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -1784,7 +1784,8 @@ int do_coredump(long signr, int exit_cod - goto close_fail; - if (!file->f_op->write) - goto close_fail; -- if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0) -+ if (!ispipe && -+ do_truncate(file->f_path.dentry, file->f_path.mnt, 0, 0, file) != 0) - goto close_fail; - - retval = binfmt->core_dump(signr, regs, file, core_limit); ---- a/fs/fat/file.c -+++ b/fs/fat/file.c -@@ -92,7 +92,7 @@ int fat_generic_ioctl(struct inode *inod - } - - /* This MUST be done before doing anything irreversible... */ -- err = notify_change(filp->f_path.dentry, &ia); -+ err = notify_change(filp->f_path.dentry, filp->f_path.mnt, &ia); - if (err) - goto up; - ---- a/fs/hpfs/namei.c -+++ b/fs/hpfs/namei.c -@@ -426,7 +426,7 @@ again: - /*printk("HPFS: truncating file before delete.\n");*/ - newattrs.ia_size = 0; - newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; -- err = notify_change(dentry, &newattrs); -+ err = notify_change(dentry, NULL, &newattrs); - put_write_access(inode); - if (!err) - goto again; ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -1660,7 +1660,7 @@ int may_open(struct nameidata *nd, int a - if (!error) { - DQUOT_INIT(inode); - -- error = do_truncate(dentry, 0, -+ error = do_truncate(dentry, nd->mnt, 0, - ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, - NULL); - } ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -388,7 +388,7 @@ nfsd_setattr(struct svc_rqst *rqstp, str - err = nfserr_notsync; - if (!check_guard || guardtime == inode->i_ctime.tv_sec) { - fh_lock(fhp); -- host_err = notify_change(dentry, iap); -+ host_err = notify_change(dentry, fhp->fh_export->ex_mnt, iap); - err = nfserrno(host_err); - fh_unlock(fhp); - } -@@ -943,13 +943,13 @@ out: - return err; - } - --static void kill_suid(struct dentry *dentry) -+static void kill_suid(struct dentry *dentry, struct vfsmount *mnt) - { - struct iattr ia; - ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; - - mutex_lock(&dentry->d_inode->i_mutex); -- notify_change(dentry, &ia); -+ notify_change(dentry, mnt, &ia); - mutex_unlock(&dentry->d_inode->i_mutex); - } - -@@ -1008,7 +1008,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s - - /* clear setuid/setgid flag after write */ - if (host_err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) -- kill_suid(dentry); -+ kill_suid(dentry, exp->ex_mnt); - - if (host_err >= 0 && stable) { - static ino_t last_ino; ---- a/fs/open.c -+++ b/fs/open.c -@@ -194,8 +194,8 @@ out: - return error; - } - --int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, -- struct file *filp) -+int do_truncate(struct dentry *dentry, struct vfsmount *mnt, loff_t length, -+ unsigned int time_attrs, struct file *filp) - { - int err; - struct iattr newattrs; -@@ -215,7 +215,7 @@ int do_truncate(struct dentry *dentry, l - newattrs.ia_valid |= should_remove_suid(dentry); - - mutex_lock(&dentry->d_inode->i_mutex); -- err = notify_change(dentry, &newattrs); -+ err = notify_change(dentry, mnt, &newattrs); - mutex_unlock(&dentry->d_inode->i_mutex); - return err; - } -@@ -271,7 +271,7 @@ static long do_sys_truncate(const char _ - error = locks_verify_truncate(inode, NULL, length); - if (!error) { - DQUOT_INIT(inode); -- error = do_truncate(nd.dentry, length, 0, NULL); -+ error = do_truncate(nd.dentry, nd.mnt, length, 0, NULL); - } - - put_write_and_out: -@@ -324,7 +324,8 @@ static long do_sys_ftruncate(unsigned in - - error = locks_verify_truncate(inode, file, length); - if (!error) -- error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); -+ error = do_truncate(dentry, file->f_path.mnt, length, -+ ATTR_MTIME|ATTR_CTIME, file); - out_putf: - fput(file); - out: -@@ -582,7 +583,7 @@ asmlinkage long sys_fchmod(unsigned int - mode = inode->i_mode; - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -- err = notify_change(dentry, &newattrs); -+ err = notify_change(dentry, file->f_path.mnt, &newattrs); - mutex_unlock(&inode->i_mutex); - - out_putf: -@@ -617,7 +618,7 @@ asmlinkage long sys_fchmodat(int dfd, co - mode = inode->i_mode; - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -- error = notify_change(nd.dentry, &newattrs); -+ error = notify_change(nd.dentry, nd.mnt, &newattrs); - mutex_unlock(&inode->i_mutex); - - dput_and_out: -@@ -631,7 +632,8 @@ asmlinkage long sys_chmod(const char __u - return sys_fchmodat(AT_FDCWD, filename, mode); - } - --static int chown_common(struct dentry * dentry, uid_t user, gid_t group) -+static int chown_common(struct dentry * dentry, struct vfsmount *mnt, -+ uid_t user, gid_t group) - { - struct inode * inode; - int error; -@@ -661,7 +663,7 @@ static int chown_common(struct dentry * - newattrs.ia_valid |= - ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; - mutex_lock(&inode->i_mutex); -- error = notify_change(dentry, &newattrs); -+ error = notify_change(dentry, mnt, &newattrs); - mutex_unlock(&inode->i_mutex); - out: - return error; -@@ -675,7 +677,7 @@ asmlinkage long sys_chown(const char __u - error = user_path_walk(filename, &nd); - if (error) - goto out; -- error = chown_common(nd.dentry, user, group); -+ error = chown_common(nd.dentry, nd.mnt, user, group); - path_release(&nd); - out: - return error; -@@ -695,7 +697,7 @@ asmlinkage long sys_fchownat(int dfd, co - error = __user_walk_fd(dfd, filename, follow, &nd); - if (error) - goto out; -- error = chown_common(nd.dentry, user, group); -+ error = chown_common(nd.dentry, nd.mnt, user, group); - path_release(&nd); - out: - return error; -@@ -709,7 +711,7 @@ asmlinkage long sys_lchown(const char __ - error = user_path_walk_link(filename, &nd); - if (error) - goto out; -- error = chown_common(nd.dentry, user, group); -+ error = chown_common(nd.dentry, nd.mnt, user, group); - path_release(&nd); - out: - return error; -@@ -728,7 +730,7 @@ asmlinkage long sys_fchown(unsigned int - - dentry = file->f_path.dentry; - audit_inode(NULL, dentry); -- error = chown_common(dentry, user, group); -+ error = chown_common(dentry, file->f_path.mnt, user, group); - fput(file); - out: - return error; ---- a/fs/reiserfs/xattr.c -+++ b/fs/reiserfs/xattr.c -@@ -485,7 +485,7 @@ reiserfs_xattr_set(struct inode *inode, - newattrs.ia_size = buffer_size; - newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; - mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR); -- err = notify_change(fp->f_path.dentry, &newattrs); -+ err = notify_change(fp->f_path.dentry, NULL, &newattrs); - if (err) - goto out_filp; - -@@ -825,7 +825,7 @@ reiserfs_chown_xattrs_filler(void *buf, - } - - if (!S_ISDIR(xafile->d_inode->i_mode)) -- err = notify_change(xafile, attrs); -+ err = notify_change(xafile, NULL, attrs); - dput(xafile); - - return err; -@@ -877,7 +877,7 @@ int reiserfs_chown_xattrs(struct inode * - goto out_dir; - } - -- err = notify_change(dir, attrs); -+ err = notify_change(dir, NULL, attrs); - unlock_kernel(); - - out_dir: ---- a/fs/sysfs/file.c -+++ b/fs/sysfs/file.c -@@ -610,7 +610,7 @@ int sysfs_chmod_file(struct kobject *kob - - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -- rc = notify_change(victim, &newattrs); -+ rc = notify_change(victim, NULL, &newattrs); - - if (rc == 0) { - mutex_lock(&sysfs_mutex); ---- a/fs/utimes.c -+++ b/fs/utimes.c -@@ -54,7 +54,7 @@ long do_utimes(int dfd, char __user *fil - { - int error; - struct nameidata nd; -- struct dentry *dentry; -+ struct path path; - struct inode *inode; - struct iattr newattrs; - struct file *f = NULL; -@@ -77,16 +77,17 @@ long do_utimes(int dfd, char __user *fil - f = fget(dfd); - if (!f) - goto out; -- dentry = f->f_path.dentry; -+ path = f->f_path; - } else { - error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd); - if (error) - goto out; - -- dentry = nd.dentry; -+ path.dentry = nd.dentry; -+ path.mnt = nd.mnt; - } - -- inode = dentry->d_inode; -+ inode = path.dentry->d_inode; - - error = -EROFS; - if (IS_RDONLY(inode)) -@@ -131,7 +132,7 @@ long do_utimes(int dfd, char __user *fil - } - } - mutex_lock(&inode->i_mutex); -- error = notify_change(dentry, &newattrs); -+ error = notify_change(path.dentry, path.mnt, &newattrs); - mutex_unlock(&inode->i_mutex); - dput_and_out: - if (f) ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1536,8 +1536,8 @@ static inline int break_lease(struct ino - - /* fs/open.c */ - --extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, -- struct file *filp); -+extern int do_truncate(struct dentry *, struct vfsmount *, loff_t start, -+ unsigned int time_attrs, struct file *filp); - extern long do_sys_open(int dfd, const char __user *filename, int flags, - int mode); - extern struct file *filp_open(const char *, int, int); -@@ -1693,7 +1693,7 @@ extern int do_remount_sb(struct super_bl - #ifdef CONFIG_BLOCK - extern sector_t bmap(struct inode *, sector_t); - #endif --extern int notify_change(struct dentry *, struct iattr *); -+extern int notify_change(struct dentry *, struct vfsmount *, struct iattr *); - extern int permission(struct inode *, int, struct nameidata *); - extern int generic_permission(struct inode *, int, - int (*check_acl)(struct inode *, int)); ---- a/mm/filemap.c -+++ b/mm/filemap.c -@@ -1615,7 +1615,7 @@ int __remove_suid(struct path *path, int - struct iattr newattrs; - - newattrs.ia_valid = ATTR_FORCE | kill; -- return notify_change(path->dentry, &newattrs); -+ return notify_change(path->dentry, path->mnt, &newattrs); - } - - int remove_suid(struct path *path) ---- a/mm/tiny-shmem.c -+++ b/mm/tiny-shmem.c -@@ -81,7 +81,7 @@ struct file *shmem_file_setup(char *name - inode->i_nlink = 0; /* It is unlinked */ - - /* notify everyone as to the change of file size */ -- error = do_truncate(dentry, size, 0, file); -+ error = do_truncate(dentry, file->f_path.mnt, size, 0, file); - if (error < 0) - goto close_file; - diff --git a/kernel-patches/for-mainline/vfs-removexattr.diff b/kernel-patches/for-mainline/vfs-removexattr.diff deleted file mode 100644 index daafb871d..000000000 --- a/kernel-patches/for-mainline/vfs-removexattr.diff +++ /dev/null @@ -1,111 +0,0 @@ -From: Tony Jones -Subject: Add a struct vfsmount parameter to vfs_removexattr() - -The vfsmount will be passed down to the LSM hook so that LSMs can compute -pathnames. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/nfsd/vfs.c | 7 ++++--- - fs/xattr.c | 12 ++++++------ - include/linux/xattr.h | 2 +- - 3 files changed, 11 insertions(+), 10 deletions(-) - ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -2016,6 +2016,7 @@ nfsd_get_posix_acl(struct svc_fh *fhp, i - int - nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl) - { -+ struct vfsmount *mnt; - struct inode *inode = fhp->fh_dentry->d_inode; - char *name; - void *value = NULL; -@@ -2048,14 +2049,14 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i - } else - size = 0; - -+ mnt = fhp->fh_export->ex_mnt; - if (size) -- error = vfs_setxattr(fhp->fh_dentry, fhp->fh_export->ex_mnt, -- name, value, size,0); -+ error = vfs_setxattr(fhp->fh_dentry, mnt, name, value, size,0); - else { - if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT) - error = 0; - else { -- error = vfs_removexattr(fhp->fh_dentry, name); -+ error = vfs_removexattr(fhp->fh_dentry, mnt, name); - if (error == -ENODATA) - error = 0; - } ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -164,7 +164,7 @@ vfs_listxattr(struct dentry *dentry, str - EXPORT_SYMBOL_GPL(vfs_listxattr); - - int --vfs_removexattr(struct dentry *dentry, char *name) -+vfs_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name) - { - struct inode *inode = dentry->d_inode; - int error; -@@ -437,7 +437,7 @@ sys_flistxattr(int fd, char __user *list - * Extended attribute REMOVE operations - */ - static long --removexattr(struct dentry *d, char __user *name) -+removexattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name) - { - int error; - char kname[XATTR_NAME_MAX + 1]; -@@ -448,7 +448,7 @@ removexattr(struct dentry *d, char __use - if (error < 0) - return error; - -- return vfs_removexattr(d, kname); -+ return vfs_removexattr(dentry, mnt, kname); - } - - asmlinkage long -@@ -460,7 +460,7 @@ sys_removexattr(char __user *path, char - error = user_path_walk(path, &nd); - if (error) - return error; -- error = removexattr(nd.dentry, name); -+ error = removexattr(nd.dentry, nd.mnt, name); - path_release(&nd); - return error; - } -@@ -474,7 +474,7 @@ sys_lremovexattr(char __user *path, char - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = removexattr(nd.dentry, name); -+ error = removexattr(nd.dentry, nd.mnt, name); - path_release(&nd); - return error; - } -@@ -491,7 +491,7 @@ sys_fremovexattr(int fd, char __user *na - return error; - dentry = f->f_path.dentry; - audit_inode(NULL, dentry); -- error = removexattr(dentry, name); -+ error = removexattr(dentry, f->f_path.mnt, name); - fput(f); - return error; - } ---- a/include/linux/xattr.h -+++ b/include/linux/xattr.h -@@ -52,7 +52,7 @@ ssize_t vfs_listxattr(struct dentry *d, - size_t size); - int vfs_setxattr(struct dentry *, struct vfsmount *, char *, void *, size_t, - int); --int vfs_removexattr(struct dentry *, char *); -+int vfs_removexattr(struct dentry *, struct vfsmount *, char *); - - ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size); - ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size); diff --git a/kernel-patches/for-mainline/vfs-rename.diff b/kernel-patches/for-mainline/vfs-rename.diff deleted file mode 100644 index d2b18d463..000000000 --- a/kernel-patches/for-mainline/vfs-rename.diff +++ /dev/null @@ -1,125 +0,0 @@ -From: Tony Jones -Subject: Add struct vfsmount parameters to vfs_rename() - -The vfsmount will be passed down to the LSM hook so that LSMs can compute -pathnames. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/ecryptfs/inode.c | 7 ++++++- - fs/namei.c | 19 ++++++++++++------- - fs/nfsd/vfs.c | 3 ++- - include/linux/fs.h | 2 +- - 4 files changed, 21 insertions(+), 10 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -589,19 +589,24 @@ ecryptfs_rename(struct inode *old_dir, s - { - int rc; - struct dentry *lower_old_dentry; -+ struct vfsmount *lower_old_mnt; - struct dentry *lower_new_dentry; -+ struct vfsmount *lower_new_mnt; - struct dentry *lower_old_dir_dentry; - struct dentry *lower_new_dir_dentry; - - lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); -+ lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry); - lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); -+ lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry); - dget(lower_old_dentry); - dget(lower_new_dentry); - lower_old_dir_dentry = dget_parent(lower_old_dentry); - lower_new_dir_dentry = dget_parent(lower_new_dentry); - lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); - rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry, -- lower_new_dir_dentry->d_inode, lower_new_dentry); -+ lower_old_mnt, lower_new_dir_dentry->d_inode, -+ lower_new_dentry, lower_new_mnt); - if (rc) - goto out_lock; - fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL); ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2464,7 +2464,8 @@ asmlinkage long sys_link(const char __us - * locking]. - */ - static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct vfsmount *old_mnt, struct inode *new_dir, -+ struct dentry *new_dentry, struct vfsmount *new_mnt) - { - int error = 0; - struct inode *target; -@@ -2507,7 +2508,8 @@ static int vfs_rename_dir(struct inode * - } - - static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct vfsmount *old_mnt, struct inode *new_dir, -+ struct dentry *new_dentry, struct vfsmount *new_mnt) - { - struct inode *target; - int error; -@@ -2535,7 +2537,8 @@ static int vfs_rename_other(struct inode - } - - int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct vfsmount *old_mnt, struct inode *new_dir, -+ struct dentry *new_dentry, struct vfsmount *new_mnt) - { - int error; - int is_dir = S_ISDIR(old_dentry->d_inode->i_mode); -@@ -2564,9 +2567,11 @@ int vfs_rename(struct inode *old_dir, st - old_name = fsnotify_oldname_init(old_dentry->d_name.name); - - if (is_dir) -- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_dir(old_dir, old_dentry, old_mnt, -+ new_dir, new_dentry, new_mnt); - else -- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); -+ error = vfs_rename_other(old_dir, old_dentry, old_mnt, -+ new_dir, new_dentry, new_mnt); - if (!error) { - const char *new_name = old_dentry->d_name.name; - fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir, -@@ -2638,8 +2643,8 @@ static int do_rename(int olddfd, const c - if (new_dentry == trap) - goto exit5; - -- error = vfs_rename(old_dir->d_inode, old_dentry, -- new_dir->d_inode, new_dentry); -+ error = vfs_rename(old_dir->d_inode, old_dentry, oldnd.mnt, -+ new_dir->d_inode, new_dentry, newnd.mnt); - exit5: - dput(new_dentry); - exit4: ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1683,7 +1683,8 @@ nfsd_rename(struct svc_rqst *rqstp, stru - host_err = -EPERM; - } else - #endif -- host_err = vfs_rename(fdir, odentry, tdir, ndentry); -+ host_err = vfs_rename(fdir, odentry, ffhp->fh_export->ex_mnt, -+ tdir, ndentry, tfhp->fh_export->ex_mnt); - if (!host_err && EX_ISSYNC(tfhp->fh_export)) { - host_err = nfsd_sync_dir(tdentry); - if (!host_err) ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1074,7 +1074,7 @@ extern int vfs_symlink(struct inode *, s - extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); - extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *); - extern int vfs_unlink(struct inode *, struct dentry *, struct vfsmount *); --extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -+extern int vfs_rename(struct inode *, struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); - - /* - * VFS dentry helper functions. diff --git a/kernel-patches/for-mainline/vfs-rmdir.diff b/kernel-patches/for-mainline/vfs-rmdir.diff deleted file mode 100644 index 3b47ff8d0..000000000 --- a/kernel-patches/for-mainline/vfs-rmdir.diff +++ /dev/null @@ -1,135 +0,0 @@ -From: Tony Jones -Subject: Add a struct vfsmount parameter to vfs_rmdir() - -The vfsmount will be passed down to the LSM hook so that LSMs can compute -pathnames. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/ecryptfs/inode.c | 4 +++- - fs/namei.c | 4 ++-- - fs/nfsd/nfs4recover.c | 2 +- - fs/nfsd/vfs.c | 8 +++++--- - fs/reiserfs/xattr.c | 2 +- - include/linux/fs.h | 2 +- - 6 files changed, 13 insertions(+), 9 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -533,14 +533,16 @@ out: - static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) - { - struct dentry *lower_dentry; -+ struct vfsmount *lower_mnt; - struct dentry *lower_dir_dentry; - int rc; - - lower_dentry = ecryptfs_dentry_to_lower(dentry); -+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); - dget(dentry); - lower_dir_dentry = lock_parent(lower_dentry); - dget(lower_dentry); -- rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); -+ rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt); - dput(lower_dentry); - if (!rc) - d_delete(lower_dentry); ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2087,7 +2087,7 @@ void dentry_unhash(struct dentry *dentry - spin_unlock(&dcache_lock); - } - --int vfs_rmdir(struct inode *dir, struct dentry *dentry) -+int vfs_rmdir(struct inode *dir, struct dentry *dentry,struct vfsmount *mnt) - { - int error = may_delete(dir, dentry, 1); - -@@ -2151,7 +2151,7 @@ static long do_rmdir(int dfd, const char - error = PTR_ERR(dentry); - if (IS_ERR(dentry)) - goto exit2; -- error = vfs_rmdir(nd.dentry->d_inode, dentry); -+ error = vfs_rmdir(nd.dentry->d_inode, dentry, nd.mnt); - dput(dentry); - exit2: - mutex_unlock(&nd.dentry->d_inode->i_mutex); ---- a/fs/nfsd/nfs4recover.c -+++ b/fs/nfsd/nfs4recover.c -@@ -274,7 +274,7 @@ nfsd4_clear_clid_dir(struct dentry *dir, - * a kernel from the future.... */ - nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); - mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); -- status = vfs_rmdir(dir->d_inode, dentry); -+ status = vfs_rmdir(dir->d_inode, dentry, rec_dir.mnt); - mutex_unlock(&dir->d_inode->i_mutex); - return status; - } ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1719,6 +1719,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru - char *fname, int flen) - { - struct dentry *dentry, *rdentry; -+ struct svc_export *exp; - struct inode *dirp; - __be32 err; - int host_err; -@@ -1733,6 +1734,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru - fh_lock_nested(fhp, I_MUTEX_PARENT); - dentry = fhp->fh_dentry; - dirp = dentry->d_inode; -+ exp = fhp->fh_export; - - rdentry = lookup_one_len(fname, dentry, flen); - host_err = PTR_ERR(rdentry); -@@ -1750,21 +1752,21 @@ nfsd_unlink(struct svc_rqst *rqstp, stru - - if (type != S_IFDIR) { /* It's UNLINK */ - #ifdef MSNFS -- if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && -+ if ((exp->ex_flags & NFSEXP_MSNFS) && - (atomic_read(&rdentry->d_count) > 1)) { - host_err = -EPERM; - } else - #endif - host_err = vfs_unlink(dirp, rdentry); - } else { /* It's RMDIR */ -- host_err = vfs_rmdir(dirp, rdentry); -+ host_err = vfs_rmdir(dirp, rdentry, exp->ex_mnt); - } - - dput(rdentry); - - if (host_err) - goto out_nfserr; -- if (EX_ISSYNC(fhp->fh_export)) -+ if (EX_ISSYNC(exp)) - host_err = nfsd_sync_dir(dentry); - - out_nfserr: ---- a/fs/reiserfs/xattr.c -+++ b/fs/reiserfs/xattr.c -@@ -781,7 +781,7 @@ int reiserfs_delete_xattrs(struct inode - if (dir->d_inode->i_nlink <= 2) { - root = get_xa_root(inode->i_sb, XATTR_REPLACE); - reiserfs_write_lock_xattrs(inode->i_sb); -- err = vfs_rmdir(root->d_inode, dir); -+ err = vfs_rmdir(root->d_inode, dir, NULL); - reiserfs_write_unlock_xattrs(inode->i_sb); - dput(root); - } else { ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1072,7 +1072,7 @@ extern int vfs_mkdir(struct inode *, str - extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t); - extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *, int); - extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); --extern int vfs_rmdir(struct inode *, struct dentry *); -+extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *); - extern int vfs_unlink(struct inode *, struct dentry *); - extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); - diff --git a/kernel-patches/for-mainline/vfs-setxattr.diff b/kernel-patches/for-mainline/vfs-setxattr.diff deleted file mode 100644 index be604011f..000000000 --- a/kernel-patches/for-mainline/vfs-setxattr.diff +++ /dev/null @@ -1,152 +0,0 @@ -From: Tony Jones -Subject: Add a struct vfsmount parameter to vfs_setxattr() - -The vfsmount will be passed down to the LSM hook so that LSMs can compute -pathnames. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/nfsd/vfs.c | 16 +++++++++++----- - fs/xattr.c | 16 ++++++++-------- - include/linux/xattr.h | 3 ++- - 3 files changed, 21 insertions(+), 14 deletions(-) - ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -426,7 +426,8 @@ static ssize_t nfsd_getxattr(struct dent - - #if defined(CONFIG_NFSD_V4) - static int --set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key) -+set_nfsv4_acl_one(struct dentry *dentry, struct vfsmount *mnt, -+ struct posix_acl *pacl, char *key) - { - int len; - size_t buflen; -@@ -445,7 +446,7 @@ set_nfsv4_acl_one(struct dentry *dentry, - goto out; - } - -- error = vfs_setxattr(dentry, key, buf, len, 0); -+ error = vfs_setxattr(dentry, mnt, key, buf, len, 0); - out: - kfree(buf); - return error; -@@ -458,6 +459,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst - __be32 error; - int host_error; - struct dentry *dentry; -+ struct vfsmount *mnt; - struct inode *inode; - struct posix_acl *pacl = NULL, *dpacl = NULL; - unsigned int flags = 0; -@@ -468,6 +470,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst - return error; - - dentry = fhp->fh_dentry; -+ mnt = fhp->fh_export->ex_mnt; - inode = dentry->d_inode; - if (S_ISDIR(inode->i_mode)) - flags = NFS4_ACL_DIR; -@@ -478,12 +481,14 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst - } else if (host_error < 0) - goto out_nfserr; - -- host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS); -+ host_error = set_nfsv4_acl_one(dentry, mnt, pacl, -+ POSIX_ACL_XATTR_ACCESS); - if (host_error < 0) - goto out_release; - - if (S_ISDIR(inode->i_mode)) -- host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT); -+ host_error = set_nfsv4_acl_one(dentry, mnt, dpacl, -+ POSIX_ACL_XATTR_DEFAULT); - - out_release: - posix_acl_release(pacl); -@@ -2041,7 +2046,8 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i - size = 0; - - if (size) -- error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0); -+ error = vfs_setxattr(fhp->fh_dentry, fhp->fh_export->ex_mnt, -+ name, value, size,0); - else { - if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT) - error = 0; ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -68,8 +68,8 @@ xattr_permission(struct inode *inode, co - } - - int --vfs_setxattr(struct dentry *dentry, char *name, void *value, -- size_t size, int flags) -+vfs_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, -+ void *value, size_t size, int flags) - { - struct inode *inode = dentry->d_inode; - int error; -@@ -192,8 +192,8 @@ EXPORT_SYMBOL_GPL(vfs_removexattr); - * Extended attribute SET operations - */ - static long --setxattr(struct dentry *d, char __user *name, void __user *value, -- size_t size, int flags) -+setxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name, -+ void __user *value, size_t size, int flags) - { - int error; - void *kvalue = NULL; -@@ -220,7 +220,7 @@ setxattr(struct dentry *d, char __user * - } - } - -- error = vfs_setxattr(d, kname, kvalue, size, flags); -+ error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags); - kfree(kvalue); - return error; - } -@@ -235,7 +235,7 @@ sys_setxattr(char __user *path, char __u - error = user_path_walk(path, &nd); - if (error) - return error; -- error = setxattr(nd.dentry, name, value, size, flags); -+ error = setxattr(nd.dentry, nd.mnt, name, value, size, flags); - path_release(&nd); - return error; - } -@@ -250,7 +250,7 @@ sys_lsetxattr(char __user *path, char __ - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = setxattr(nd.dentry, name, value, size, flags); -+ error = setxattr(nd.dentry, nd.mnt, name, value, size, flags); - path_release(&nd); - return error; - } -@@ -268,7 +268,7 @@ sys_fsetxattr(int fd, char __user *name, - return error; - dentry = f->f_path.dentry; - audit_inode(NULL, dentry); -- error = setxattr(dentry, name, value, size, flags); -+ error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags); - fput(f); - return error; - } ---- a/include/linux/xattr.h -+++ b/include/linux/xattr.h -@@ -48,7 +48,8 @@ struct xattr_handler { - - ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t); - ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); --int vfs_setxattr(struct dentry *, char *, void *, size_t, int); -+int vfs_setxattr(struct dentry *, struct vfsmount *, char *, void *, size_t, -+ int); - int vfs_removexattr(struct dentry *, char *); - - ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size); diff --git a/kernel-patches/for-mainline/vfs-symlink.diff b/kernel-patches/for-mainline/vfs-symlink.diff deleted file mode 100644 index 1788aad57..000000000 --- a/kernel-patches/for-mainline/vfs-symlink.diff +++ /dev/null @@ -1,122 +0,0 @@ -From: Tony Jones -Subject: Add a struct vfsmount parameter to vfs_symlink() - -The vfsmount will be passed down to the LSM hook so that LSMs can compute -pathnames. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/ecryptfs/inode.c | 4 +++- - fs/namei.c | 6 ++++-- - fs/nfsd/vfs.c | 12 ++++++++---- - include/linux/fs.h | 2 +- - 4 files changed, 16 insertions(+), 8 deletions(-) - ---- a/fs/ecryptfs/inode.c 2007-11-01 16:43:54.000000000 -0400 -+++ b/fs/ecryptfs/inode.c 2007-11-01 16:47:29.000000000 -0400 -@@ -461,6 +461,7 @@ static int ecryptfs_symlink(struct inode - { - int rc; - struct dentry *lower_dentry; -+ struct vfsmount *lower_mnt; - struct dentry *lower_dir_dentry; - umode_t mode; - char *encoded_symname; -@@ -469,6 +470,7 @@ static int ecryptfs_symlink(struct inode - - lower_dentry = ecryptfs_dentry_to_lower(dentry); - dget(lower_dentry); -+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); - lower_dir_dentry = lock_parent(lower_dentry); - mode = S_IALLUGO; - encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname, -@@ -478,7 +480,7 @@ static int ecryptfs_symlink(struct inode - rc = encoded_symlen; - goto out_lock; - } -- rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, -+ rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, - encoded_symname, mode); - kfree(encoded_symname); - if (rc || !lower_dentry->d_inode) ---- a/fs/namei.c 2007-11-01 16:47:26.000000000 -0400 -+++ b/fs/namei.c 2007-11-01 16:47:29.000000000 -0400 -@@ -2266,7 +2266,8 @@ asmlinkage long sys_unlink(const char __ - return do_unlinkat(AT_FDCWD, pathname); - } - --int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode) -+int vfs_symlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, -+ const char *oldname, int mode) - { - int error = may_create(dir, dentry, NULL); - -@@ -2312,7 +2313,8 @@ asmlinkage long sys_symlinkat(const char - if (IS_ERR(dentry)) - goto out_unlock; - -- error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); -+ error = vfs_symlink(nd.dentry->d_inode, dentry, nd.mnt, from, -+ S_IALLUGO); - dput(dentry); - out_unlock: - mutex_unlock(&nd.dentry->d_inode->i_mutex); ---- a/fs/nfsd/vfs.c 2007-11-01 16:43:54.000000000 -0400 -+++ b/fs/nfsd/vfs.c 2007-11-01 16:47:29.000000000 -0400 -@@ -1489,6 +1489,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str - struct iattr *iap) - { - struct dentry *dentry, *dnew; -+ struct svc_export *exp; - __be32 err, cerr; - int host_err; - umode_t mode; -@@ -1515,6 +1516,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str - if (iap && (iap->ia_valid & ATTR_MODE)) - mode = iap->ia_mode & S_IALLUGO; - -+ exp = fhp->fh_export; - if (unlikely(path[plen] != 0)) { - char *path_alloced = kmalloc(plen+1, GFP_KERNEL); - if (path_alloced == NULL) -@@ -1522,20 +1524,22 @@ nfsd_symlink(struct svc_rqst *rqstp, str - else { - strncpy(path_alloced, path, plen); - path_alloced[plen] = 0; -- host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode); -+ host_err = vfs_symlink(dentry->d_inode, dnew, -+ exp->ex_mnt, path_alloced, mode); - kfree(path_alloced); - } - } else -- host_err = vfs_symlink(dentry->d_inode, dnew, path, mode); -+ host_err = vfs_symlink(dentry->d_inode, dnew, exp->ex_mnt, path, -+ mode); - - if (!host_err) { -- if (EX_ISSYNC(fhp->fh_export)) -+ if (EX_ISSYNC(exp)) - host_err = nfsd_sync_dir(dentry); - } - err = nfserrno(host_err); - fh_unlock(fhp); - -- cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp); -+ cerr = fh_compose(resfhp, exp, dnew, fhp); - dput(dnew); - if (err==0) err = cerr; - out: ---- a/include/linux/fs.h 2007-11-01 16:43:54.000000000 -0400 -+++ b/include/linux/fs.h 2007-11-01 16:47:29.000000000 -0400 -@@ -1070,7 +1070,7 @@ extern int vfs_permission(struct nameida - extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *); - extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int); - extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t); --extern int vfs_symlink(struct inode *, struct dentry *, const char *, int); -+extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *, int); - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); diff --git a/kernel-patches/for-mainline/vfs-unlink.diff b/kernel-patches/for-mainline/vfs-unlink.diff deleted file mode 100644 index 88af2e274..000000000 --- a/kernel-patches/for-mainline/vfs-unlink.diff +++ /dev/null @@ -1,98 +0,0 @@ -From: Tony Jones -Subject: Add a struct vfsmount parameter to vfs_unlink() - -The vfsmount will be passed down to the LSM hook so that LSMs can compute -pathnames. - -Signed-off-by: Tony Jones -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/ecryptfs/inode.c | 3 ++- - fs/namei.c | 4 ++-- - fs/nfsd/nfs4recover.c | 2 +- - fs/nfsd/vfs.c | 2 +- - include/linux/fs.h | 2 +- - ipc/mqueue.c | 2 +- - 6 files changed, 8 insertions(+), 7 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -444,10 +444,11 @@ static int ecryptfs_unlink(struct inode - { - int rc = 0; - struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); -+ struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); - struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); - - lock_parent(lower_dentry); -- rc = vfs_unlink(lower_dir_inode, lower_dentry); -+ rc = vfs_unlink(lower_dir_inode, lower_dentry, lower_mnt); - if (rc) { - printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); - goto out_unlock; ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2168,7 +2168,7 @@ asmlinkage long sys_rmdir(const char __u - return do_rmdir(AT_FDCWD, pathname); - } - --int vfs_unlink(struct inode *dir, struct dentry *dentry) -+int vfs_unlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt) - { - int error = may_delete(dir, dentry, 0); - -@@ -2232,7 +2232,7 @@ static long do_unlinkat(int dfd, const c - inode = dentry->d_inode; - if (inode) - atomic_inc(&inode->i_count); -- error = vfs_unlink(nd.dentry->d_inode, dentry); -+ error = vfs_unlink(nd.dentry->d_inode, dentry, nd.mnt); - exit2: - dput(dentry); - } ---- a/fs/nfsd/nfs4recover.c -+++ b/fs/nfsd/nfs4recover.c -@@ -259,7 +259,7 @@ nfsd4_remove_clid_file(struct dentry *di - return -EINVAL; - } - mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); -- status = vfs_unlink(dir->d_inode, dentry); -+ status = vfs_unlink(dir->d_inode, dentry, rec_dir.mnt); - mutex_unlock(&dir->d_inode->i_mutex); - return status; - } ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1757,7 +1757,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru - host_err = -EPERM; - } else - #endif -- host_err = vfs_unlink(dirp, rdentry); -+ host_err = vfs_unlink(dirp, rdentry, exp->ex_mnt); - } else { /* It's RMDIR */ - host_err = vfs_rmdir(dirp, rdentry, exp->ex_mnt); - } ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1073,7 +1073,7 @@ extern int vfs_mknod(struct inode *, str - extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *, int); - extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); - extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *); --extern int vfs_unlink(struct inode *, struct dentry *); -+extern int vfs_unlink(struct inode *, struct dentry *, struct vfsmount *); - extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); - - /* ---- a/ipc/mqueue.c -+++ b/ipc/mqueue.c -@@ -744,7 +744,7 @@ asmlinkage long sys_mq_unlink(const char - if (inode) - atomic_inc(&inode->i_count); - -- err = vfs_unlink(dentry->d_parent->d_inode, dentry); -+ err = vfs_unlink(dentry->d_parent->d_inode, dentry, mqueue_mnt); - out_err: - dput(dentry); - diff --git a/kernel-patches/for-mainline/vfs_create-args.diff b/kernel-patches/for-mainline/vfs_create-args.diff deleted file mode 100644 index d2069c56c..000000000 --- a/kernel-patches/for-mainline/vfs_create-args.diff +++ /dev/null @@ -1,150 +0,0 @@ -From: Andreas Gruenbacher -Subject: Remove redundant vfs_create() argument - -vfs_create() is passed a redundant inode now; dir is always the same -as nd->dentry->d_inode. - -Signed-off-by: Andreas Gruenbacher - ---- - fs/ecryptfs/inode.c | 10 +++++----- - fs/namei.c | 9 ++++----- - fs/nfsd/vfs.c | 4 ++-- - include/linux/fs.h | 2 +- - ipc/mqueue.c | 11 +++++------ - 5 files changed, 17 insertions(+), 19 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -67,7 +67,7 @@ static void unlock_dir(struct dentry *di - * Returns zero on success; non-zero on error condition - */ - static int --ecryptfs_create_underlying_file(struct inode *lower_dir_inode, -+ecryptfs_create_underlying_file(struct dentry *lower_dir_dentry, - struct dentry *dentry, int mode, - struct nameidata2 *nd) - { -@@ -79,9 +79,9 @@ ecryptfs_create_underlying_file(struct i - - dentry_save = nd->dentry; - vfsmount_save = nd->mnt; -- nd->dentry = lower_dentry; -+ nd->dentry = lower_dir_dentry; - nd->mnt = lower_mnt; -- rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd); -+ rc = vfs_create(nd, lower_dentry, mode); - nd->dentry = dentry_save; - nd->mnt = vfsmount_save; - return rc; -@@ -117,8 +117,8 @@ ecryptfs_do_create(struct inode *directo - rc = PTR_ERR(lower_dir_dentry); - goto out; - } -- rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode, -- ecryptfs_dentry, mode, nd); -+ rc = ecryptfs_create_underlying_file(lower_dir_dentry, ecryptfs_dentry, -+ mode, nd); - if (unlikely(rc)) { - ecryptfs_printk(KERN_ERR, - "Failure to create underlying file\n"); ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -1534,9 +1534,9 @@ void unlock_rename(struct dentry *p1, st - } - } - --int vfs_create(struct inode *dir, struct dentry *dentry, int mode, -- struct nameidata2 *nd) -+int vfs_create(struct nameidata2 *nd, struct dentry *dentry, int mode) - { -+ struct inode *dir = nd->dentry->d_inode; - int error = may_create(dir, dentry, nd); - - if (error) -@@ -1644,7 +1644,7 @@ static int open_namei_create(struct name - - if (!IS_POSIXACL(dir->d_inode)) - mode &= ~current->fs->umask; -- error = vfs_create(dir->d_inode, path->dentry, mode, ND2(nd)); -+ error = vfs_create(ND2(nd), path->dentry, mode); - mutex_unlock(&dir->d_inode->i_mutex); - dput(nd->dentry); - nd->dentry = path->dentry; -@@ -1930,8 +1930,7 @@ asmlinkage long sys_mknodat(int dfd, con - if (!IS_ERR(dentry)) { - switch (mode & S_IFMT) { - case 0: case S_IFREG: -- error = vfs_create(nd.dentry->d_inode, dentry, mode, -- ND2(&nd)); -+ error = vfs_create(ND2(&nd), dentry, mode); - break; - case S_IFCHR: case S_IFBLK: - error = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1194,7 +1194,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - err = 0; - switch (type) { - case S_IFREG: -- host_err = vfs_create(nd.dentry->d_inode, dchild, iap->ia_mode, &nd); -+ host_err = vfs_create(&nd, dchild, iap->ia_mode); - break; - case S_IFDIR: - host_err = vfs_mkdir(dirp, dchild, exp->ex_mnt, iap->ia_mode); -@@ -1340,7 +1340,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, s - goto out; - } - -- host_err = vfs_create(nd.dentry->d_inode, dchild, iap->ia_mode, &nd); -+ host_err = vfs_create(&nd, dchild, iap->ia_mode); - if (host_err < 0) - goto out_nfserr; - if (created) ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -988,7 +988,7 @@ extern void unlock_super(struct super_bl - * VFS helper functions.. - */ - extern int vfs_permission(struct nameidata2 *, int); --extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata2 *); -+extern int vfs_create(struct nameidata2 *, struct dentry *, int); - extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int); - extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t); - extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *, int); ---- a/ipc/mqueue.c -+++ b/ipc/mqueue.c -@@ -601,11 +601,11 @@ static int mq_attr_ok(struct mq_attr *at - /* - * Invoked when creating a new queue via sys_mq_open - */ --static struct file *do_create(struct dentry *dir, struct dentry *dentry, -- int oflag, mode_t mode, struct mq_attr __user *u_attr) -+static struct file *do_create(struct dentry *dentry, int oflag, mode_t mode, -+ struct mq_attr __user *u_attr) - { - struct nameidata2 nd = { -- .dentry = dir, -+ .dentry = mqueue_mnt->mnt_root, - /* Not a mounted filesystem, so set .mnt to NULL. */ - }; - struct mq_attr attr; -@@ -623,7 +623,7 @@ static struct file *do_create(struct den - } - - mode &= ~current->fs->umask; -- ret = vfs_create(dir->d_inode, dentry, mode, &nd); -+ ret = vfs_create(&nd, dentry, mode); - dentry->d_fsdata = NULL; - if (ret) - goto out; -@@ -691,8 +691,7 @@ asmlinkage long sys_mq_open(const char _ - goto out; - filp = do_open(dentry, oflag); - } else { -- filp = do_create(mqueue_mnt->mnt_root, dentry, -- oflag, mode, u_attr); -+ filp = do_create(dentry, oflag, mode, u_attr); - } - } else { - error = -ENOENT; diff --git a/kernel-patches/for-mainline/vfs_create-nameidata.diff b/kernel-patches/for-mainline/vfs_create-nameidata.diff deleted file mode 100644 index 49cfe36e3..000000000 --- a/kernel-patches/for-mainline/vfs_create-nameidata.diff +++ /dev/null @@ -1,183 +0,0 @@ -From: Andreas Gruenbacher -Subject: Never pass a NULL nameidata to vfs_create() - -Create a nameidata2 struct in nfsd and mqueue so that vfs_create does -need to conditionally pass the vfsmnt. - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/namei.c | 2 +- - fs/nfsd/vfs.c | 42 +++++++++++++++++++++++++----------------- - ipc/mqueue.c | 7 ++++++- - 3 files changed, 32 insertions(+), 19 deletions(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -1532,7 +1532,7 @@ int vfs_create(struct inode *dir, struct - return -EACCES; /* shouldn't it be ENOSYS? */ - mode &= S_IALLUGO; - mode |= S_IFREG; -- error = security_inode_create(dir, dentry, nd ? nd->mnt : NULL, mode); -+ error = security_inode_create(dir, dentry, nd->mnt, mode); - if (error) - return error; - DQUOT_INIT(dir); ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1121,7 +1121,8 @@ nfsd_create(struct svc_rqst *rqstp, stru - char *fname, int flen, struct iattr *iap, - int type, dev_t rdev, struct svc_fh *resfhp) - { -- struct dentry *dentry, *dchild = NULL; -+ struct nameidata2 nd; -+ struct dentry *dchild = NULL; - struct svc_export *exp; - struct inode *dirp; - __be32 err; -@@ -1138,9 +1139,11 @@ nfsd_create(struct svc_rqst *rqstp, stru - if (err) - goto out; - -- dentry = fhp->fh_dentry; -+ nd.dentry = fhp->fh_dentry; - exp = fhp->fh_export; -- dirp = dentry->d_inode; -+ nd.mnt = exp->ex_mnt; -+ nd.flags = 0; -+ dirp = nd.dentry->d_inode; - - err = nfserr_notdir; - if(!dirp->i_op || !dirp->i_op->lookup) -@@ -1152,7 +1155,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - if (!resfhp->fh_dentry) { - /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */ - fh_lock_nested(fhp, I_MUTEX_PARENT); -- dchild = lookup_one_len(fname, dentry, flen); -+ dchild = lookup_one_len(fname, nd.dentry, flen); - host_err = PTR_ERR(dchild); - if (IS_ERR(dchild)) - goto out_nfserr; -@@ -1166,8 +1169,8 @@ nfsd_create(struct svc_rqst *rqstp, stru - /* not actually possible */ - printk(KERN_ERR - "nfsd_create: parent %s/%s not locked!\n", -- dentry->d_parent->d_name.name, -- dentry->d_name.name); -+ nd.dentry->d_parent->d_name.name, -+ nd.dentry->d_name.name); - err = nfserr_io; - goto out; - } -@@ -1178,7 +1181,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - err = nfserr_exist; - if (dchild->d_inode) { - dprintk("nfsd_create: dentry %s/%s not negative!\n", -- dentry->d_name.name, dchild->d_name.name); -+ nd.dentry->d_name.name, dchild->d_name.name); - goto out; - } - -@@ -1192,7 +1195,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - err = 0; - switch (type) { - case S_IFREG: -- host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); -+ host_err = vfs_create(nd.dentry->d_inode, dchild, iap->ia_mode, &nd); - break; - case S_IFDIR: - host_err = vfs_mkdir(dirp, dchild, exp->ex_mnt, iap->ia_mode); -@@ -1212,7 +1215,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - goto out_nfserr; - - if (EX_ISSYNC(exp)) { -- err = nfserrno(nfsd_sync_dir(dentry)); -+ err = nfserrno(nfsd_sync_dir(nd.dentry)); - write_inode_now(dchild->d_inode, 1); - } - -@@ -1252,7 +1255,9 @@ nfsd_create_v3(struct svc_rqst *rqstp, s - struct svc_fh *resfhp, int createmode, u32 *verifier, - int *truncp, int *created) - { -- struct dentry *dentry, *dchild = NULL; -+ struct nameidata2 nd; -+ struct dentry *dchild = NULL; -+ struct svc_export *exp; - struct inode *dirp; - __be32 err; - int host_err; -@@ -1270,8 +1275,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, s - if (err) - goto out; - -- dentry = fhp->fh_dentry; -- dirp = dentry->d_inode; -+ nd.dentry = fhp->fh_dentry; -+ exp = fhp->fh_export; -+ nd.mnt = exp->ex_mnt; -+ nd.flags = 0; -+ dirp = nd.dentry->d_inode; - - /* Get all the sanity checks out of the way before - * we lock the parent. */ -@@ -1283,12 +1291,12 @@ nfsd_create_v3(struct svc_rqst *rqstp, s - /* - * Compose the response file handle. - */ -- dchild = lookup_one_len(fname, dentry, flen); -+ dchild = lookup_one_len(fname, nd.dentry, flen); - host_err = PTR_ERR(dchild); - if (IS_ERR(dchild)) - goto out_nfserr; - -- err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); -+ err = fh_compose(resfhp, exp, dchild, fhp); - if (err) - goto out; - -@@ -1334,14 +1342,14 @@ nfsd_create_v3(struct svc_rqst *rqstp, s - goto out; - } - -- host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); -+ host_err = vfs_create(nd.dentry->d_inode, dchild, iap->ia_mode, &nd); - if (host_err < 0) - goto out_nfserr; - if (created) - *created = 1; - -- if (EX_ISSYNC(fhp->fh_export)) { -- err = nfserrno(nfsd_sync_dir(dentry)); -+ if (EX_ISSYNC(exp)) { -+ err = nfserrno(nfsd_sync_dir(nd.dentry)); - /* setattr will sync the child (or not) */ - } - ---- a/ipc/mqueue.c -+++ b/ipc/mqueue.c -@@ -602,9 +602,14 @@ static int mq_attr_ok(struct mq_attr *at - static struct file *do_create(struct dentry *dir, struct dentry *dentry, - int oflag, mode_t mode, struct mq_attr __user *u_attr) - { -+ struct nameidata2 nd; - struct mq_attr attr; - int ret; - -+ nd.dentry = dir; -+ nd.mnt = NULL; /* Not a mounted filesystem */ -+ nd.flags = 0; -+ - if (u_attr) { - ret = -EFAULT; - if (copy_from_user(&attr, u_attr, sizeof(attr))) -@@ -617,7 +622,7 @@ static struct file *do_create(struct den - } - - mode &= ~current->fs->umask; -- ret = vfs_create(dir->d_inode, dentry, mode, NULL); -+ ret = vfs_create(dir->d_inode, dentry, mode, &nd); - dentry->d_fsdata = NULL; - if (ret) - goto out; diff --git a/kernel-patches/for-mainline/vfs_link-args.diff b/kernel-patches/for-mainline/vfs_link-args.diff deleted file mode 100644 index 5baa78226..000000000 --- a/kernel-patches/for-mainline/vfs_link-args.diff +++ /dev/null @@ -1,166 +0,0 @@ -From: Andreas Gruenbacher -Subject: Pass nameidata2 to vfs_link() - -Instead of passing independent dentry and vfsmount parameters, use -nameidata2. - -Signed-off-by: Andreas Gruenbacher - ---- - fs/ecryptfs/inode.c | 26 +++++++++++--------------- - fs/namei.c | 14 ++++++++------ - fs/nfsd/vfs.c | 22 ++++++++++++---------- - include/linux/fs.h | 2 +- - 4 files changed, 32 insertions(+), 32 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -410,25 +410,21 @@ out: - static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, - struct dentry *new_dentry) - { -- struct dentry *lower_old_dentry; -- struct vfsmount *lower_old_mnt; -+ struct nameidata2 old_nd = {}; -+ struct nameidata2 new_parent = {}; - struct dentry *lower_new_dentry; -- struct vfsmount *lower_new_mnt; -- struct dentry *lower_dir_dentry; - u64 file_size_save; - int rc; - - file_size_save = i_size_read(old_dentry->d_inode); -- lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); -- lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry); -+ old_nd.dentry = ecryptfs_dentry_to_lower(old_dentry); -+ old_nd.mnt = ecryptfs_dentry_to_lower_mnt(old_dentry); - lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); -- lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry); -- dget(lower_old_dentry); -+ new_parent.mnt = ecryptfs_dentry_to_lower_mnt(new_dentry); -+ dget(old_nd.dentry); - dget(lower_new_dentry); -- lower_dir_dentry = lock_parent(lower_new_dentry); -- rc = vfs_link(lower_old_dentry, lower_old_mnt, -- lower_dir_dentry->d_inode, lower_new_dentry, -- lower_new_mnt); -+ new_parent.dentry = lock_parent(lower_new_dentry); -+ rc = vfs_link(&old_nd, lower_new_dentry, &new_parent); - if (rc || !lower_new_dentry->d_inode) - goto out_lock; - rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); -@@ -440,10 +436,10 @@ static int ecryptfs_link(struct dentry * - ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink; - i_size_write(new_dentry->d_inode, file_size_save); - out_lock: -- unlock_dir(lower_dir_dentry); -+ unlock_dir(new_parent.dentry); - dput(lower_new_dentry); -- dput(lower_old_dentry); -- d_drop(lower_old_dentry); -+ dput(old_nd.dentry); -+ d_drop(old_nd.dentry); - d_drop(new_dentry); - d_drop(old_dentry); - return rc; ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2293,15 +2293,18 @@ asmlinkage long sys_symlink(const char _ - return sys_symlinkat(oldname, AT_FDCWD, newname); - } - --int vfs_link(struct dentry *old_dentry, struct vfsmount *old_mnt, struct inode *dir, struct dentry *new_dentry, struct vfsmount *new_mnt) -+int vfs_link(struct nameidata2 *old_nd, struct dentry *new_dentry, -+ struct nameidata2 *new_parent) - { -+ struct dentry *old_dentry = old_nd->dentry; - struct inode *inode = old_dentry->d_inode; -+ struct inode *dir = new_parent->dentry->d_inode; - int error; - - if (!inode) - return -ENOENT; - -- error = may_create(dir, new_dentry, NULL); -+ error = may_create(dir, new_dentry, new_parent); - if (error) - return error; - -@@ -2318,8 +2321,8 @@ int vfs_link(struct dentry *old_dentry, - if (S_ISDIR(old_dentry->d_inode->i_mode)) - return -EPERM; - -- error = security_inode_link(old_dentry, old_mnt, dir, new_dentry, -- new_mnt); -+ error = security_inode_link(old_dentry, old_nd->mnt, dir, new_dentry, -+ new_parent->mnt); - if (error) - return error; - -@@ -2372,8 +2375,7 @@ asmlinkage long sys_linkat(int olddfd, c - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto out_unlock; -- error = vfs_link(old_nd.dentry, old_nd.mnt, nd.dentry->d_inode, -- new_dentry, nd.mnt); -+ error = vfs_link(ND2(&old_nd), new_dentry, ND2(&nd)); - dput(new_dentry); - out_unlock: - mutex_unlock(&nd.dentry->d_inode->i_mutex); ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1517,8 +1517,10 @@ __be32 - nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, - char *name, int len, struct svc_fh *tfhp) - { -- struct dentry *ddir, *dnew, *dold; -- struct inode *dirp, *dest; -+ struct nameidata2 old_nd = {}; -+ struct nameidata2 new_parent = {}; -+ struct dentry *dnew; -+ struct inode *dest; - __be32 err; - int host_err; - -@@ -1537,22 +1539,22 @@ nfsd_link(struct svc_rqst *rqstp, struct - goto out; - - fh_lock_nested(ffhp, I_MUTEX_PARENT); -- ddir = ffhp->fh_dentry; -- dirp = ddir->d_inode; -+ new_parent.dentry = ffhp->fh_dentry; -+ new_parent.mnt = ffhp->fh_export->ex_mnt; - -- dnew = lookup_one_len(name, ddir, len); -+ dnew = lookup_one_len(name, new_parent.dentry, len); - host_err = PTR_ERR(dnew); - if (IS_ERR(dnew)) - goto out_nfserr; - -- dold = tfhp->fh_dentry; -- dest = dold->d_inode; -+ old_nd.dentry = tfhp->fh_dentry; -+ old_nd.mnt = tfhp->fh_export->ex_mnt; -+ dest = old_nd.dentry->d_inode; - -- host_err = vfs_link(dold, tfhp->fh_export->ex_mnt, dirp, -- dnew, ffhp->fh_export->ex_mnt); -+ host_err = vfs_link(&old_nd, dnew, &new_parent); - if (!host_err) { - if (EX_ISSYNC(ffhp->fh_export)) { -- err = nfserrno(nfsd_sync_dir(ddir)); -+ err = nfserrno(nfsd_sync_dir(new_parent.dentry)); - write_inode_now(dest, 1); - } - err = 0; ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -992,7 +992,7 @@ extern int vfs_create(struct nameidata2 - extern int vfs_mkdir(struct nameidata2 *, struct dentry *, int); - extern int vfs_mknod(struct nameidata2 *, struct dentry *, int, dev_t); - extern int vfs_symlink(struct nameidata2 *, struct dentry *, const char *, int); --extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); -+extern int vfs_link(struct nameidata2 *, struct dentry *, struct nameidata2 *); - extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *); - extern int vfs_unlink(struct inode *, struct dentry *, struct vfsmount *); - extern int vfs_rename(struct inode *, struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); diff --git a/kernel-patches/for-mainline/vfs_mkdir-args.diff b/kernel-patches/for-mainline/vfs_mkdir-args.diff deleted file mode 100644 index e739b241b..000000000 --- a/kernel-patches/for-mainline/vfs_mkdir-args.diff +++ /dev/null @@ -1,121 +0,0 @@ -From: Andreas Gruenbacher -Subject: Pass nameidata2 to vfs_mkdir() - -Instead of passing independent dentry and vfsmount parameters, use a -nameidata2. - -Signed-off-by: Andreas Gruenbacher - ---- - fs/ecryptfs/inode.c | 18 ++++++++---------- - fs/namei.c | 10 +++++----- - fs/nfsd/nfs4recover.c | 3 +-- - fs/nfsd/vfs.c | 2 +- - include/linux/fs.h | 2 +- - 5 files changed, 16 insertions(+), 19 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -515,26 +515,24 @@ out_lock: - - static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) - { -+ struct nameidata2 nd = {}; - int rc; - struct dentry *lower_dentry; -- struct vfsmount *lower_mnt; -- struct dentry *lower_dir_dentry; - - lower_dentry = ecryptfs_dentry_to_lower(dentry); -- lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); -- lower_dir_dentry = lock_parent(lower_dentry); -- rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, -- mode); -+ nd.mnt = ecryptfs_dentry_to_lower_mnt(dentry); -+ nd.dentry = lock_parent(lower_dentry); -+ rc = vfs_mkdir(&nd, lower_dentry, mode); - if (rc || !lower_dentry->d_inode) - goto out; - rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); - if (rc) - goto out; -- fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); -- fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); -- dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; -+ fsstack_copy_attr_times(dir, nd.dentry->d_inode); -+ fsstack_copy_inode_size(dir, nd.dentry->d_inode); -+ dir->i_nlink = nd.dentry->d_inode->i_nlink; - out: -- unlock_dir(lower_dir_dentry); -+ unlock_dir(nd.dentry); - if (!dentry->d_inode) - d_drop(dentry); - return rc; ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -1960,10 +1960,10 @@ asmlinkage long sys_mknod(const char __u - return sys_mknodat(AT_FDCWD, filename, mode, dev); - } - --int vfs_mkdir(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, -- int mode) -+int vfs_mkdir(struct nameidata2 *nd, struct dentry *dentry, int mode) - { -- int error = may_create(dir, dentry, NULL); -+ struct inode *dir = nd->dentry->d_inode; -+ int error = may_create(dir, dentry, nd); - - if (error) - return error; -@@ -1972,7 +1972,7 @@ int vfs_mkdir(struct inode *dir, struct - return -EPERM; - - mode &= (S_IRWXUGO|S_ISVTX); -- error = security_inode_mkdir(dir, dentry, mnt, mode); -+ error = security_inode_mkdir(dir, dentry, nd->mnt, mode); - if (error) - return error; - -@@ -2005,7 +2005,7 @@ asmlinkage long sys_mkdirat(int dfd, con - - if (!IS_POSIXACL(nd.dentry->d_inode)) - mode &= ~current->fs->umask; -- error = vfs_mkdir(nd.dentry->d_inode, dentry, nd.mnt, mode); -+ error = vfs_mkdir(ND2(&nd), dentry, mode); - dput(dentry); - out_unlock: - mutex_unlock(&nd.dentry->d_inode->i_mutex); ---- a/fs/nfsd/nfs4recover.c -+++ b/fs/nfsd/nfs4recover.c -@@ -156,8 +156,7 @@ nfsd4_create_clid_dir(struct nfs4_client - dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); - goto out_put; - } -- status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, rec_dir.mnt, -- S_IRWXU); -+ status = vfs_mkdir(ND2(&rec_dir), dentry, S_IRWXU); - out_put: - dput(dentry); - out_unlock: ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1197,7 +1197,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - host_err = vfs_create(&nd, dchild, iap->ia_mode); - break; - case S_IFDIR: -- host_err = vfs_mkdir(dirp, dchild, exp->ex_mnt, iap->ia_mode); -+ host_err = vfs_mkdir(&nd, dchild, iap->ia_mode); - break; - case S_IFCHR: - case S_IFBLK: ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -989,7 +989,7 @@ extern void unlock_super(struct super_bl - */ - extern int vfs_permission(struct nameidata2 *, int); - extern int vfs_create(struct nameidata2 *, struct dentry *, int); --extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int); -+extern int vfs_mkdir(struct nameidata2 *, struct dentry *, int); - extern int vfs_mknod(struct nameidata2 *, struct dentry *, int, dev_t); - extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *, int); - extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); diff --git a/kernel-patches/for-mainline/vfs_mknod-args.diff b/kernel-patches/for-mainline/vfs_mknod-args.diff deleted file mode 100644 index 0aa9582c7..000000000 --- a/kernel-patches/for-mainline/vfs_mknod-args.diff +++ /dev/null @@ -1,126 +0,0 @@ -From: Andreas Gruenbacher -Subject: Pass nameidata2 to vfs_mknod() - -Instead of passing independent dentry and vfsmount parameters, use a -nameidata2. - -Signed-off-by: Andreas Gruenbacher - ---- - fs/ecryptfs/inode.c | 16 +++++++--------- - fs/namei.c | 15 +++++++-------- - fs/nfsd/vfs.c | 3 +-- - include/linux/fs.h | 2 +- - net/unix/af_unix.c | 2 +- - 5 files changed, 17 insertions(+), 21 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -568,25 +568,23 @@ static int ecryptfs_rmdir(struct inode * - static int - ecryptfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) - { -+ struct nameidata2 nd = {}; - int rc; - struct dentry *lower_dentry; -- struct vfsmount *lower_mnt; -- struct dentry *lower_dir_dentry; - - lower_dentry = ecryptfs_dentry_to_lower(dentry); -- lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); -- lower_dir_dentry = lock_parent(lower_dentry); -- rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, mode, -- dev); -+ nd.mnt = ecryptfs_dentry_to_lower_mnt(dentry); -+ nd.dentry = lock_parent(lower_dentry); -+ rc = vfs_mknod(&nd, lower_dentry, mode, dev); - if (rc || !lower_dentry->d_inode) - goto out; - rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); - if (rc) - goto out; -- fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); -- fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); -+ fsstack_copy_attr_times(dir, nd.dentry->d_inode); -+ fsstack_copy_inode_size(dir, nd.dentry->d_inode); - out: -- unlock_dir(lower_dir_dentry); -+ unlock_dir(nd.dentry); - if (!dentry->d_inode) - d_drop(dentry); - return rc; ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -1880,10 +1880,10 @@ fail: - } - EXPORT_SYMBOL_GPL(lookup_create); - --int vfs_mknod(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, -- int mode, dev_t dev) -+int vfs_mknod(struct nameidata2 *nd, struct dentry *dentry, int mode, dev_t dev) - { -- int error = may_create(dir, dentry, NULL); -+ struct inode *dir = nd->dentry->d_inode; -+ int error = may_create(dir, dentry, nd); - - if (error) - return error; -@@ -1894,7 +1894,7 @@ int vfs_mknod(struct inode *dir, struct - if (!dir->i_op || !dir->i_op->mknod) - return -EPERM; - -- error = security_inode_mknod(dir, dentry, mnt, mode, dev); -+ error = security_inode_mknod(dir, dentry, nd->mnt, mode, dev); - if (error) - return error; - -@@ -1933,12 +1933,11 @@ asmlinkage long sys_mknodat(int dfd, con - error = vfs_create(ND2(&nd), dentry, mode); - break; - case S_IFCHR: case S_IFBLK: -- error = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, -- mode, new_decode_dev(dev)); -+ error = vfs_mknod(ND2(&nd), dentry, mode, -+ new_decode_dev(dev)); - break; - case S_IFIFO: case S_IFSOCK: -- error = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, -- mode, 0); -+ error = vfs_mknod(ND2(&nd), dentry, mode, 0); - break; - case S_IFDIR: - error = -EPERM; ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1203,8 +1203,7 @@ nfsd_create(struct svc_rqst *rqstp, stru - case S_IFBLK: - case S_IFIFO: - case S_IFSOCK: -- host_err = vfs_mknod(dirp, dchild, exp->ex_mnt, iap->ia_mode, -- rdev); -+ host_err = vfs_mknod(&nd, dchild, iap->ia_mode, rdev); - break; - default: - printk("nfsd: bad file type %o in nfsd_create\n", type); ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -990,7 +990,7 @@ extern void unlock_super(struct super_bl - extern int vfs_permission(struct nameidata2 *, int); - extern int vfs_create(struct nameidata2 *, struct dentry *, int); - extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int); --extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t); -+extern int vfs_mknod(struct nameidata2 *, struct dentry *, int, dev_t); - extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *, int); - extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); - extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *); ---- a/net/unix/af_unix.c -+++ b/net/unix/af_unix.c -@@ -808,7 +808,7 @@ static int unix_bind(struct socket *sock - */ - mode = S_IFSOCK | - (SOCK_INODE(sock)->i_mode & ~current->fs->umask); -- err = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, mode, 0); -+ err = vfs_mknod(ND2(&nd), dentry, mode, 0); - if (err) - goto out_mknod_dput; - mutex_unlock(&nd.dentry->d_inode->i_mutex); diff --git a/kernel-patches/for-mainline/vfs_rename-args.diff b/kernel-patches/for-mainline/vfs_rename-args.diff deleted file mode 100644 index 19436abee..000000000 --- a/kernel-patches/for-mainline/vfs_rename-args.diff +++ /dev/null @@ -1,261 +0,0 @@ -From: Andreas Gruenbacher -Subject: Pass nameidata2 to vfs_rename() - -Instead of passing independent dentry and vfsmount parameters, use a -nameidata2. - -Signed-off-by: Andreas Gruenbacher - ---- - fs/ecryptfs/inode.c | 26 +++++++++++--------------- - fs/namei.c | 45 ++++++++++++++++++++++++--------------------- - fs/nfsd/vfs.c | 31 +++++++++++++++++-------------- - include/linux/fs.h | 2 +- - 4 files changed, 53 insertions(+), 51 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -586,33 +586,29 @@ static int - ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) - { -+ struct nameidata2 old_nd = {}; -+ struct nameidata2 new_nd = {}; - int rc; - struct dentry *lower_old_dentry; -- struct vfsmount *lower_old_mnt; - struct dentry *lower_new_dentry; -- struct vfsmount *lower_new_mnt; -- struct dentry *lower_old_dir_dentry; -- struct dentry *lower_new_dir_dentry; - - lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); -- lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry); - lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); -- lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry); - dget(lower_old_dentry); - dget(lower_new_dentry); -- lower_old_dir_dentry = dget_parent(lower_old_dentry); -- lower_new_dir_dentry = dget_parent(lower_new_dentry); -- lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); -- rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry, -- lower_old_mnt, lower_new_dir_dentry->d_inode, -- lower_new_dentry, lower_new_mnt); -+ old_nd.dentry = dget_parent(lower_old_dentry); -+ old_nd.mnt = ecryptfs_dentry_to_lower_mnt(old_dentry); -+ new_nd.dentry = dget_parent(lower_new_dentry); -+ new_nd.mnt = ecryptfs_dentry_to_lower_mnt(new_dentry); -+ lock_rename(old_nd.dentry, new_nd.dentry); -+ rc = vfs_rename(&old_nd, lower_old_dentry, &new_nd, lower_new_dentry); - if (rc) - goto out_lock; -- fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL); -+ fsstack_copy_attr_all(new_dir, new_nd.dentry->d_inode, NULL); - if (new_dir != old_dir) -- fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode, NULL); -+ fsstack_copy_attr_all(old_dir, old_nd.dentry->d_inode, NULL); - out_lock: -- unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); -+ unlock_rename(old_nd.dentry, new_nd.dentry); - dput(lower_new_dentry->d_parent); - dput(lower_old_dentry->d_parent); - dput(lower_new_dentry); ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2426,10 +2426,11 @@ asmlinkage long sys_link(const char __us - * ->i_mutex on parents, which works but leads to some truely excessive - * locking]. - */ --static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, -- struct vfsmount *old_mnt, struct inode *new_dir, -- struct dentry *new_dentry, struct vfsmount *new_mnt) -+static int vfs_rename_dir(struct nameidata2 *old_nd, struct dentry *old_dentry, -+ struct nameidata2 *new_nd, struct dentry *new_dentry) - { -+ struct inode *old_dir = old_nd->dentry->d_inode; -+ struct inode *new_dir = new_nd->dentry->d_inode; - int error = 0; - struct inode *target; - -@@ -2438,13 +2439,13 @@ static int vfs_rename_dir(struct inode * - * we'll need to flip '..'. - */ - if (new_dir != old_dir) { -- error = permission(old_dentry->d_inode, MAY_WRITE, NULL); -+ error = permission(old_dentry->d_inode, MAY_WRITE, old_nd); - if (error) - return error; - } - -- error = security_inode_rename(old_dir, old_dentry, old_mnt, -- new_dir, new_dentry, new_mnt); -+ error = security_inode_rename(old_dir, old_dentry, old_nd->mnt, -+ new_dir, new_dentry, new_nd->mnt); - if (error) - return error; - -@@ -2471,15 +2472,18 @@ static int vfs_rename_dir(struct inode * - return error; - } - --static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, -- struct vfsmount *old_mnt, struct inode *new_dir, -- struct dentry *new_dentry, struct vfsmount *new_mnt) -+static int vfs_rename_other(struct nameidata2 *old_nd, -+ struct dentry *old_dentry, -+ struct nameidata2 *new_nd, -+ struct dentry *new_dentry) - { -+ struct inode *old_dir = old_nd->dentry->d_inode; -+ struct inode *new_dir = new_nd->dentry->d_inode; - struct inode *target; - int error; - -- error = security_inode_rename(old_dir, old_dentry, old_mnt, -- new_dir, new_dentry, new_mnt); -+ error = security_inode_rename(old_dir, old_dentry, old_nd->mnt, -+ new_dir, new_dentry, new_nd->mnt); - if (error) - return error; - -@@ -2501,10 +2505,11 @@ static int vfs_rename_other(struct inode - return error; - } - --int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -- struct vfsmount *old_mnt, struct inode *new_dir, -- struct dentry *new_dentry, struct vfsmount *new_mnt) -+int vfs_rename(struct nameidata2 *old_nd, struct dentry *old_dentry, -+ struct nameidata2 *new_nd, struct dentry *new_dentry) - { -+ struct inode *old_dir = old_nd->dentry->d_inode; -+ struct inode *new_dir = new_nd->dentry->d_inode; - int error; - int is_dir = S_ISDIR(old_dentry->d_inode->i_mode); - const char *old_name; -@@ -2517,7 +2522,7 @@ int vfs_rename(struct inode *old_dir, st - return error; - - if (!new_dentry->d_inode) -- error = may_create(new_dir, new_dentry, NULL); -+ error = may_create(new_dir, new_dentry, new_nd); - else - error = may_delete(new_dir, new_dentry, is_dir); - if (error) -@@ -2532,11 +2537,10 @@ int vfs_rename(struct inode *old_dir, st - old_name = fsnotify_oldname_init(old_dentry->d_name.name); - - if (is_dir) -- error = vfs_rename_dir(old_dir, old_dentry, old_mnt, -- new_dir, new_dentry, new_mnt); -+ error = vfs_rename_dir(old_nd, old_dentry, new_nd, new_dentry); - else -- error = vfs_rename_other(old_dir, old_dentry, old_mnt, -- new_dir, new_dentry, new_mnt); -+ error = vfs_rename_other(old_nd, old_dentry, new_nd, -+ new_dentry); - if (!error) { - const char *new_name = old_dentry->d_name.name; - fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir, -@@ -2608,8 +2612,7 @@ static int do_rename(int olddfd, const c - if (new_dentry == trap) - goto exit5; - -- error = vfs_rename(old_dir->d_inode, old_dentry, oldnd.mnt, -- new_dir->d_inode, new_dentry, newnd.mnt); -+ error = vfs_rename(ND2(&oldnd), old_dentry, ND2(&newnd), new_dentry); - exit5: - dput(new_dentry); - exit4: ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1584,7 +1584,9 @@ __be32 - nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, - struct svc_fh *tfhp, char *tname, int tlen) - { -- struct dentry *fdentry, *tdentry, *odentry, *ndentry, *trap; -+ struct nameidata2 old_nd = {}; -+ struct nameidata2 new_nd = {}; -+ struct dentry *odentry, *ndentry, *trap; - struct inode *fdir, *tdir; - __be32 err; - int host_err; -@@ -1596,11 +1598,13 @@ nfsd_rename(struct svc_rqst *rqstp, stru - if (err) - goto out; - -- fdentry = ffhp->fh_dentry; -- fdir = fdentry->d_inode; -- -- tdentry = tfhp->fh_dentry; -- tdir = tdentry->d_inode; -+ old_nd.dentry = ffhp->fh_dentry; -+ old_nd.mnt = ffhp->fh_export->ex_mnt; -+ fdir = old_nd.dentry->d_inode; -+ -+ new_nd.dentry = tfhp->fh_dentry; -+ new_nd.mnt = tfhp->fh_export->ex_mnt; -+ tdir = new_nd.dentry->d_inode; - - err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev; - if (ffhp->fh_export != tfhp->fh_export) -@@ -1612,12 +1616,12 @@ nfsd_rename(struct svc_rqst *rqstp, stru - - /* cannot use fh_lock as we need deadlock protective ordering - * so do it by hand */ -- trap = lock_rename(tdentry, fdentry); -+ trap = lock_rename(new_nd.dentry, old_nd.dentry); - ffhp->fh_locked = tfhp->fh_locked = 1; - fill_pre_wcc(ffhp); - fill_pre_wcc(tfhp); - -- odentry = lookup_one_len(fname, fdentry, flen); -+ odentry = lookup_one_len(fname, old_nd.dentry, flen); - host_err = PTR_ERR(odentry); - if (IS_ERR(odentry)) - goto out_nfserr; -@@ -1629,7 +1633,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru - if (odentry == trap) - goto out_dput_old; - -- ndentry = lookup_one_len(tname, tdentry, tlen); -+ ndentry = lookup_one_len(tname, new_nd.dentry, tlen); - host_err = PTR_ERR(ndentry); - if (IS_ERR(ndentry)) - goto out_dput_old; -@@ -1644,12 +1648,11 @@ nfsd_rename(struct svc_rqst *rqstp, stru - host_err = -EPERM; - } else - #endif -- host_err = vfs_rename(fdir, odentry, ffhp->fh_export->ex_mnt, -- tdir, ndentry, tfhp->fh_export->ex_mnt); -+ host_err = vfs_rename(&old_nd, odentry, &new_nd, ndentry); - if (!host_err && EX_ISSYNC(tfhp->fh_export)) { -- host_err = nfsd_sync_dir(tdentry); -+ host_err = nfsd_sync_dir(new_nd.dentry); - if (!host_err) -- host_err = nfsd_sync_dir(fdentry); -+ host_err = nfsd_sync_dir(old_nd.dentry); - } - - out_dput_new: -@@ -1665,7 +1668,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru - */ - fill_post_wcc(ffhp); - fill_post_wcc(tfhp); -- unlock_rename(tdentry, fdentry); -+ unlock_rename(new_nd.dentry, old_nd.dentry); - ffhp->fh_locked = tfhp->fh_locked = 0; - - out: ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -995,7 +995,7 @@ extern int vfs_symlink(struct nameidata2 - extern int vfs_link(struct nameidata2 *, struct dentry *, struct nameidata2 *); - extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *); - extern int vfs_unlink(struct inode *, struct dentry *, struct vfsmount *); --extern int vfs_rename(struct inode *, struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); -+extern int vfs_rename(struct nameidata2 *, struct dentry *, struct nameidata2 *, struct dentry *); - - /* - * VFS dentry helper functions. diff --git a/kernel-patches/for-mainline/vfs_rmdir-args.diff b/kernel-patches/for-mainline/vfs_rmdir-args.diff deleted file mode 100644 index ecbefdf4e..000000000 --- a/kernel-patches/for-mainline/vfs_rmdir-args.diff +++ /dev/null @@ -1,189 +0,0 @@ -From: Andreas Gruenbacher -Subject: Pass nameidata2 to vfs_rmdir() - -Instead of passing independent dentry and vfsmount parameters, use a -nameidata2. - -Signed-off-by: Andreas Gruenbacher - ---- - fs/ecryptfs/inode.c | 15 +++++++-------- - fs/namei.c | 7 ++++--- - fs/nfsd/nfs4recover.c | 6 +++++- - fs/nfsd/vfs.c | 14 ++++++++------ - fs/reiserfs/xattr.c | 11 +++++++---- - include/linux/fs.h | 2 +- - 6 files changed, 32 insertions(+), 23 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -534,23 +534,22 @@ out: - - static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) - { -+ struct nameidata2 nd = {}; - struct dentry *lower_dentry; -- struct vfsmount *lower_mnt; -- struct dentry *lower_dir_dentry; - int rc; - - lower_dentry = ecryptfs_dentry_to_lower(dentry); -- lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); - dget(dentry); -- lower_dir_dentry = lock_parent(lower_dentry); -+ nd.dentry = lock_parent(lower_dentry); -+ nd.mnt = ecryptfs_dentry_to_lower_mnt(dentry); - dget(lower_dentry); -- rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt); -+ rc = vfs_rmdir(&nd, lower_dentry); - dput(lower_dentry); - if (!rc) - d_delete(lower_dentry); -- fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); -- dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; -- unlock_dir(lower_dir_dentry); -+ fsstack_copy_attr_times(dir, nd.dentry->d_inode); -+ dir->i_nlink = nd.dentry->d_inode->i_nlink; -+ unlock_dir(nd.dentry); - if (!rc) - d_drop(dentry); - dput(dentry); ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2046,8 +2046,9 @@ void dentry_unhash(struct dentry *dentry - spin_unlock(&dcache_lock); - } - --int vfs_rmdir(struct inode *dir, struct dentry *dentry,struct vfsmount *mnt) -+int vfs_rmdir(struct nameidata2 *nd, struct dentry *dentry) - { -+ struct inode *dir = nd->dentry->d_inode; - int error = may_delete(dir, dentry, 1); - - if (error) -@@ -2056,7 +2057,7 @@ int vfs_rmdir(struct inode *dir, struct - if (!dir->i_op || !dir->i_op->rmdir) - return -EPERM; - -- error = security_inode_rmdir(dir, dentry, mnt); -+ error = security_inode_rmdir(dir, dentry, nd->mnt); - if (error) - return error; - -@@ -2111,7 +2112,7 @@ static long do_rmdir(int dfd, const char - error = PTR_ERR(dentry); - if (IS_ERR(dentry)) - goto exit2; -- error = vfs_rmdir(nd.dentry->d_inode, dentry, nd.mnt); -+ error = vfs_rmdir(ND2(&nd), dentry); - dput(dentry); - exit2: - mutex_unlock(&nd.dentry->d_inode->i_mutex); ---- a/fs/nfsd/nfs4recover.c -+++ b/fs/nfsd/nfs4recover.c -@@ -268,6 +268,10 @@ nfsd4_remove_clid_file(struct dentry *di - static int - nfsd4_clear_clid_dir(struct dentry *dir, struct dentry *dentry) - { -+ struct nameidata2 nd = { -+ .dentry = dir, -+ .mnt = rec_dir.mnt, -+ }; - int status; - - /* For now this directory should already be empty, but we empty it of -@@ -275,7 +279,7 @@ nfsd4_clear_clid_dir(struct dentry *dir, - * a kernel from the future.... */ - nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); - mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); -- status = vfs_rmdir(dir->d_inode, dentry, rec_dir.mnt); -+ status = vfs_rmdir(&nd, dentry); - mutex_unlock(&dir->d_inode->i_mutex); - return status; - } ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1683,7 +1683,8 @@ __be32 - nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, - char *fname, int flen) - { -- struct dentry *dentry, *rdentry; -+ struct nameidata2 nd = {}; -+ struct dentry *rdentry; - struct svc_export *exp; - struct inode *dirp; - __be32 err; -@@ -1697,11 +1698,12 @@ nfsd_unlink(struct svc_rqst *rqstp, stru - goto out; - - fh_lock_nested(fhp, I_MUTEX_PARENT); -- dentry = fhp->fh_dentry; -- dirp = dentry->d_inode; -+ nd.dentry = fhp->fh_dentry; - exp = fhp->fh_export; -+ nd.mnt = exp->ex_mnt; -+ dirp = nd.dentry->d_inode; - -- rdentry = lookup_one_len(fname, dentry, flen); -+ rdentry = lookup_one_len(fname, nd.dentry, flen); - host_err = PTR_ERR(rdentry); - if (IS_ERR(rdentry)) - goto out_nfserr; -@@ -1724,7 +1726,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru - #endif - host_err = vfs_unlink(dirp, rdentry, exp->ex_mnt); - } else { /* It's RMDIR */ -- host_err = vfs_rmdir(dirp, rdentry, exp->ex_mnt); -+ host_err = vfs_rmdir(&nd, rdentry); - } - - dput(rdentry); -@@ -1732,7 +1734,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru - if (host_err) - goto out_nfserr; - if (EX_ISSYNC(exp)) -- host_err = nfsd_sync_dir(dentry); -+ host_err = nfsd_sync_dir(nd.dentry); - - out_nfserr: - err = nfserrno(host_err); ---- a/fs/reiserfs/xattr.c -+++ b/fs/reiserfs/xattr.c -@@ -741,7 +741,7 @@ reiserfs_delete_xattrs_filler(void *buf, - int reiserfs_delete_xattrs(struct inode *inode) - { - struct file *fp; -- struct dentry *dir, *root; -+ struct dentry *dir; - int err = 0; - - /* Skip out, an xattr has no xattrs associated with it */ -@@ -777,11 +777,14 @@ int reiserfs_delete_xattrs(struct inode - - /* Leftovers besides . and .. -- that's not good. */ - if (dir->d_inode->i_nlink <= 2) { -- root = get_xa_root(inode->i_sb, XATTR_REPLACE); -+ struct nameidata2 nd = { -+ .dentry = get_xa_root(inode->i_sb, XATTR_REPLACE), -+ }; -+ - reiserfs_write_lock_xattrs(inode->i_sb); -- err = vfs_rmdir(root->d_inode, dir, NULL); -+ err = vfs_rmdir(&nd, dir); - reiserfs_write_unlock_xattrs(inode->i_sb); -- dput(root); -+ dput(nd.dentry); - } else { - reiserfs_warning(inode->i_sb, - "Couldn't remove all entries in directory"); ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -993,7 +993,7 @@ extern int vfs_mkdir(struct nameidata2 * - extern int vfs_mknod(struct nameidata2 *, struct dentry *, int, dev_t); - extern int vfs_symlink(struct nameidata2 *, struct dentry *, const char *, int); - extern int vfs_link(struct nameidata2 *, struct dentry *, struct nameidata2 *); --extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *); -+extern int vfs_rmdir(struct nameidata2 *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *, struct vfsmount *); - extern int vfs_rename(struct nameidata2 *, struct dentry *, struct nameidata2 *, struct dentry *); - diff --git a/kernel-patches/for-mainline/vfs_symlink-args.diff b/kernel-patches/for-mainline/vfs_symlink-args.diff deleted file mode 100644 index b550124ee..000000000 --- a/kernel-patches/for-mainline/vfs_symlink-args.diff +++ /dev/null @@ -1,163 +0,0 @@ -From: Andreas Gruenbacher -Subject: Pass nameidata2 to vfs_symlink() - -Instead of passing independent dentry and vfsmount parameters, use a -nameidata2. - -Signed-off-by: Andreas Gruenbacher - ---- - fs/ecryptfs/inode.c | 16 +++++++--------- - fs/namei.c | 10 +++++----- - fs/nfsd/vfs.c | 18 +++++++++--------- - include/linux/fs.h | 2 +- - 4 files changed, 22 insertions(+), 24 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -474,10 +474,9 @@ out_unlock: - static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, - const char *symname) - { -+ struct nameidata2 nd = {}; - int rc; - struct dentry *lower_dentry; -- struct vfsmount *lower_mnt; -- struct dentry *lower_dir_dentry; - umode_t mode; - char *encoded_symname; - unsigned int encoded_symlen; -@@ -485,8 +484,8 @@ static int ecryptfs_symlink(struct inode - - lower_dentry = ecryptfs_dentry_to_lower(dentry); - dget(lower_dentry); -- lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); -- lower_dir_dentry = lock_parent(lower_dentry); -+ nd.mnt = ecryptfs_dentry_to_lower_mnt(dentry); -+ nd.dentry = lock_parent(lower_dentry); - mode = S_IALLUGO; - encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname, - strlen(symname), -@@ -495,18 +494,17 @@ static int ecryptfs_symlink(struct inode - rc = encoded_symlen; - goto out_lock; - } -- rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, -- encoded_symname, mode); -+ rc = vfs_symlink(&nd, lower_dentry, encoded_symname, mode); - kfree(encoded_symname); - if (rc || !lower_dentry->d_inode) - goto out_lock; - rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); - if (rc) - goto out_lock; -- fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); -- fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); -+ fsstack_copy_attr_times(dir, nd.dentry->d_inode); -+ fsstack_copy_inode_size(dir, nd.dentry->d_inode); - out_lock: -- unlock_dir(lower_dir_dentry); -+ unlock_dir(nd.dentry); - dput(lower_dentry); - if (!dentry->d_inode) - d_drop(dentry); ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2228,10 +2228,11 @@ asmlinkage long sys_unlink(const char __ - return do_unlinkat(AT_FDCWD, pathname); - } - --int vfs_symlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, -+int vfs_symlink(struct nameidata2 *nd, struct dentry *dentry, - const char *oldname, int mode) - { -- int error = may_create(dir, dentry, NULL); -+ struct inode *dir = nd->dentry->d_inode; -+ int error = may_create(dir, dentry, nd); - - if (error) - return error; -@@ -2239,7 +2240,7 @@ int vfs_symlink(struct inode *dir, struc - if (!dir->i_op || !dir->i_op->symlink) - return -EPERM; - -- error = security_inode_symlink(dir, dentry, mnt, oldname); -+ error = security_inode_symlink(dir, dentry, nd->mnt, oldname); - if (error) - return error; - -@@ -2275,8 +2276,7 @@ asmlinkage long sys_symlinkat(const char - if (IS_ERR(dentry)) - goto out_unlock; - -- error = vfs_symlink(nd.dentry->d_inode, dentry, nd.mnt, from, -- S_IALLUGO); -+ error = vfs_symlink(ND2(&nd), dentry, from, S_IALLUGO); - dput(dentry); - out_unlock: - mutex_unlock(&nd.dentry->d_inode->i_mutex); ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1447,7 +1447,8 @@ nfsd_symlink(struct svc_rqst *rqstp, str - struct svc_fh *resfhp, - struct iattr *iap) - { -- struct dentry *dentry, *dnew; -+ struct nameidata2 nd = {}; -+ struct dentry *dnew; - struct svc_export *exp; - __be32 err, cerr; - int host_err; -@@ -1464,8 +1465,10 @@ nfsd_symlink(struct svc_rqst *rqstp, str - if (err) - goto out; - fh_lock(fhp); -- dentry = fhp->fh_dentry; -- dnew = lookup_one_len(fname, dentry, flen); -+ nd.dentry = fhp->fh_dentry; -+ exp = fhp->fh_export; -+ nd.mnt = exp->ex_mnt; -+ dnew = lookup_one_len(fname, nd.dentry, flen); - host_err = PTR_ERR(dnew); - if (IS_ERR(dnew)) - goto out_nfserr; -@@ -1475,7 +1478,6 @@ nfsd_symlink(struct svc_rqst *rqstp, str - if (iap && (iap->ia_valid & ATTR_MODE)) - mode = iap->ia_mode & S_IALLUGO; - -- exp = fhp->fh_export; - if (unlikely(path[plen] != 0)) { - char *path_alloced = kmalloc(plen+1, GFP_KERNEL); - if (path_alloced == NULL) -@@ -1483,17 +1485,15 @@ nfsd_symlink(struct svc_rqst *rqstp, str - else { - strncpy(path_alloced, path, plen); - path_alloced[plen] = 0; -- host_err = vfs_symlink(dentry->d_inode, dnew, -- exp->ex_mnt, path_alloced, mode); -+ host_err = vfs_symlink(&nd, dnew, path_alloced, mode); - kfree(path_alloced); - } - } else -- host_err = vfs_symlink(dentry->d_inode, dnew, exp->ex_mnt, path, -- mode); -+ host_err = vfs_symlink(&nd, dnew, path, mode); - - if (!host_err) { - if (EX_ISSYNC(exp)) -- host_err = nfsd_sync_dir(dentry); -+ host_err = nfsd_sync_dir(nd.dentry); - } - err = nfserrno(host_err); - fh_unlock(fhp); ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -991,7 +991,7 @@ extern int vfs_permission(struct nameida - extern int vfs_create(struct nameidata2 *, struct dentry *, int); - extern int vfs_mkdir(struct nameidata2 *, struct dentry *, int); - extern int vfs_mknod(struct nameidata2 *, struct dentry *, int, dev_t); --extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *, int); -+extern int vfs_symlink(struct nameidata2 *, struct dentry *, const char *, int); - extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); - extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *); - extern int vfs_unlink(struct inode *, struct dentry *, struct vfsmount *); diff --git a/kernel-patches/for-mainline/vfs_unlink-args.diff b/kernel-patches/for-mainline/vfs_unlink-args.diff deleted file mode 100644 index 5a3791649..000000000 --- a/kernel-patches/for-mainline/vfs_unlink-args.diff +++ /dev/null @@ -1,159 +0,0 @@ -From: Andreas Gruenbacher -Subject: Pass nameidata2 to vfs_unlink() - -Instead of passing independent dentry and vfsmount parameters, use a -nameidata2. - -Signed-off-by: Andreas Gruenbacher - ---- - fs/ecryptfs/inode.c | 18 ++++++------------ - fs/namei.c | 7 ++++--- - fs/nfsd/nfs4recover.c | 6 +++++- - fs/nfsd/vfs.c | 2 +- - include/linux/fs.h | 2 +- - ipc/mqueue.c | 6 +++++- - 6 files changed, 22 insertions(+), 19 deletions(-) - ---- a/fs/ecryptfs/inode.c -+++ b/fs/ecryptfs/inode.c -@@ -42,12 +42,6 @@ static struct dentry *lock_parent(struct - return dir; - } - --static void unlock_parent(struct dentry *dentry) --{ -- mutex_unlock(&(dentry->d_parent->d_inode->i_mutex)); -- dput(dentry->d_parent); --} -- - static void unlock_dir(struct dentry *dir) - { - mutex_unlock(&dir->d_inode->i_mutex); -@@ -447,23 +441,23 @@ out_lock: - - static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) - { -+ struct nameidata2 nd = {}; - int rc = 0; - struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); -- struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); -- struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); - -- lock_parent(lower_dentry); -- rc = vfs_unlink(lower_dir_inode, lower_dentry, lower_mnt); -+ nd.dentry = lock_parent(lower_dentry); -+ nd.mnt = ecryptfs_dentry_to_lower_mnt(dentry); -+ rc = vfs_unlink(&nd, lower_dentry); - if (rc) { - printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); - goto out_unlock; - } -- fsstack_copy_attr_times(dir, lower_dir_inode); -+ fsstack_copy_attr_times(dir, nd.dentry->d_inode); - dentry->d_inode->i_nlink = - ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink; - dentry->d_inode->i_ctime = dir->i_ctime; - out_unlock: -- unlock_parent(lower_dentry); -+ unlock_dir(nd.dentry); - return rc; - } - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2128,8 +2128,9 @@ asmlinkage long sys_rmdir(const char __u - return do_rmdir(AT_FDCWD, pathname); - } - --int vfs_unlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt) -+int vfs_unlink(struct nameidata2 *nd, struct dentry *dentry) - { -+ struct inode *dir = nd->dentry->d_inode; - int error = may_delete(dir, dentry, 0); - - if (error) -@@ -2144,7 +2145,7 @@ int vfs_unlink(struct inode *dir, struct - if (d_mountpoint(dentry)) - error = -EBUSY; - else { -- error = security_inode_unlink(dir, dentry, mnt); -+ error = security_inode_unlink(dir, dentry, nd->mnt); - if (!error) - error = dir->i_op->unlink(dir, dentry); - } -@@ -2192,7 +2193,7 @@ static long do_unlinkat(int dfd, const c - inode = dentry->d_inode; - if (inode) - atomic_inc(&inode->i_count); -- error = vfs_unlink(nd.dentry->d_inode, dentry, nd.mnt); -+ error = vfs_unlink(ND2(&nd), dentry); - exit2: - dput(dentry); - } ---- a/fs/nfsd/nfs4recover.c -+++ b/fs/nfsd/nfs4recover.c -@@ -253,6 +253,10 @@ out: - static int - nfsd4_remove_clid_file(struct dentry *dir, struct dentry *dentry) - { -+ struct nameidata2 nd = { -+ .dentry = dir, -+ .mnt = rec_dir.mnt, -+ }; - int status; - - if (!S_ISREG(dir->d_inode->i_mode)) { -@@ -260,7 +264,7 @@ nfsd4_remove_clid_file(struct dentry *di - return -EINVAL; - } - mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); -- status = vfs_unlink(dir->d_inode, dentry, rec_dir.mnt); -+ status = vfs_unlink(&nd, dentry); - mutex_unlock(&dir->d_inode->i_mutex); - return status; - } ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1724,7 +1724,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru - host_err = -EPERM; - } else - #endif -- host_err = vfs_unlink(dirp, rdentry, exp->ex_mnt); -+ host_err = vfs_unlink(&nd, rdentry); - } else { /* It's RMDIR */ - host_err = vfs_rmdir(&nd, rdentry); - } ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -994,7 +994,7 @@ extern int vfs_mknod(struct nameidata2 * - extern int vfs_symlink(struct nameidata2 *, struct dentry *, const char *, int); - extern int vfs_link(struct nameidata2 *, struct dentry *, struct nameidata2 *); - extern int vfs_rmdir(struct nameidata2 *, struct dentry *); --extern int vfs_unlink(struct inode *, struct dentry *, struct vfsmount *); -+extern int vfs_unlink(struct nameidata2 *, struct dentry *); - extern int vfs_rename(struct nameidata2 *, struct dentry *, struct nameidata2 *, struct dentry *); - - /* ---- a/ipc/mqueue.c -+++ b/ipc/mqueue.c -@@ -725,6 +725,10 @@ out_putname: - - asmlinkage long sys_mq_unlink(const char __user *u_name) - { -+ struct nameidata2 nd = { -+ .dentry = mqueue_mnt->mnt_root, -+ /* Not a mounted filesystem, so set .mnt to NULL. */ -+ }; - int err; - char *name; - struct dentry *dentry; -@@ -751,7 +755,7 @@ asmlinkage long sys_mq_unlink(const char - if (inode) - atomic_inc(&inode->i_count); - -- err = vfs_unlink(dentry->d_parent->d_inode, dentry, mqueue_mnt); -+ err = vfs_unlink(&nd, dentry); - out_err: - dput(dentry); - diff --git a/kernel-patches/for-mainline/xattr_permission.diff b/kernel-patches/for-mainline/xattr_permission.diff deleted file mode 100644 index b1876bc7f..000000000 --- a/kernel-patches/for-mainline/xattr_permission.diff +++ /dev/null @@ -1,69 +0,0 @@ -From: Andreas Gruenbacher -Subject: Don't use a NULL nameidata in xattr_permission() - -Create nameidata2 struct xattr_permission so that it does not pass NULL -to permission. - -Signed-off-by: Andreas Gruenbacher -Signed-off-by: John Johansen - ---- - fs/xattr.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -25,8 +25,16 @@ - * because different namespaces have very different rules. - */ - static int --xattr_permission(struct inode *inode, const char *name, int mask) -+xattr_permission(struct dentry *dentry, struct vfsmount *mnt, const char *name, -+ int mask) - { -+ struct inode *inode = dentry->d_inode; -+ struct nameidata2 nd; -+ -+ nd.dentry = dentry; -+ nd.mnt = mnt; -+ nd.flags = 0; -+ - /* - * We can never set or remove an extended attribute on a read-only - * filesystem or on an immutable / append-only inode. -@@ -65,7 +73,7 @@ xattr_permission(struct inode *inode, co - return -EPERM; - } - -- return permission(inode, mask, NULL); -+ return permission(inode, mask, &nd); - } - - int -@@ -75,7 +83,7 @@ vfs_setxattr(struct dentry *dentry, stru - struct inode *inode = dentry->d_inode; - int error; - -- error = xattr_permission(inode, name, MAY_WRITE); -+ error = xattr_permission(dentry, mnt, name, MAY_WRITE); - if (error) - return error; - -@@ -112,7 +120,7 @@ vfs_getxattr(struct dentry *dentry, stru - struct inode *inode = dentry->d_inode; - int error; - -- error = xattr_permission(inode, name, MAY_READ); -+ error = xattr_permission(dentry, mnt, name, MAY_READ); - if (error) - return error; - -@@ -174,7 +182,7 @@ vfs_removexattr(struct dentry *dentry, s - if (!inode->i_op->removexattr) - return -EOPNOTSUPP; - -- error = xattr_permission(inode, name, MAY_WRITE); -+ error = xattr_permission(dentry, mnt, name, MAY_WRITE); - if (error) - return error; -