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 | 41 ++++++++++++++++++++++++++--------------- security/capability.c | 3 ++- security/commoncap.c | 5 +++-- security/security.c | 16 ++++++++++------ security/selinux/hooks.c | 8 +++++--- security/smack/smack_lsm.c | 12 ++++++++---- 7 files changed, 56 insertions(+), 33 deletions(-) --- a/fs/xattr.c +++ b/fs/xattr.c @@ -78,7 +78,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; @@ -86,7 +86,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 @@ -54,8 +54,9 @@ extern void cap_capset_set(struct task_s 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, const char *name, - const void *value, size_t size, int flags); +extern int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, + int flags); extern int cap_inode_removexattr(struct dentry *dentry, const char *name); extern int cap_inode_need_killpriv(struct dentry *dentry); extern int cap_inode_killpriv(struct dentry *dentry); @@ -438,11 +439,11 @@ static inline void security_free_mnt_opt * 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. @@ -1392,10 +1393,13 @@ 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, const char *name, - const void *value, size_t size, int flags); - void (*inode_post_setxattr) (struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); + int (*inode_setxattr) (struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, + int flags); + void (*inode_post_setxattr) (struct dentry *dentry, + struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags); int (*inode_getxattr) (struct dentry *dentry, const char *name); int (*inode_listxattr) (struct dentry *dentry); int (*inode_removexattr) (struct dentry *dentry, const char *name); @@ -1666,10 +1670,12 @@ 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, const char *name, - const void *value, size_t size, int flags); -void security_inode_post_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); +int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags); +void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags); int security_inode_getxattr(struct dentry *dentry, const char *name); int security_inode_listxattr(struct dentry *dentry); int security_inode_removexattr(struct dentry *dentry, const char *name); @@ -2092,13 +2098,18 @@ static inline void security_inode_delete { } static inline int security_inode_setxattr(struct dentry *dentry, - const char *name, const void *value, size_t size, int flags) + struct vfsmount *mnt, + const char *name, const 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, - const char *name, const void *value, size_t size, int flags) + struct vfsmount *mnt, + const char *name, + const void *value, + size_t size, int flags) { } static inline int security_inode_getxattr(struct dentry *dentry, --- a/security/capability.c +++ b/security/capability.c @@ -235,7 +235,8 @@ static void cap_inode_delete(struct inod { } -static void cap_inode_post_setxattr(struct dentry *dentry, const char *name, +static void cap_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, int flags) { } --- a/security/commoncap.c +++ b/security/commoncap.c @@ -411,8 +411,9 @@ int cap_bprm_secureexec (struct linux_bi current->egid != current->gid); } -int cap_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, + int flags) { if (!strcmp(name, XATTR_NAME_CAPS)) { if (!capable(CAP_SETFCAP)) --- a/security/security.c +++ b/security/security.c @@ -471,20 +471,24 @@ void security_inode_delete(struct inode security_ops->inode_delete(inode); } -int security_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const 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, const char *name, - const void *value, size_t size, int flags) +void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const 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, const char *name) --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2713,8 +2713,9 @@ static int selinux_inode_setotherxattr(s return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); } -static int selinux_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +static int selinux_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags) { struct task_security_struct *tsec = current->security; struct inode *inode = dentry->d_inode; @@ -2768,7 +2769,8 @@ static int selinux_inode_setxattr(struct &ad); } -static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, +static void selinux_inode_post_setxattr(struct dentry *dentry, + struct vfsmount *mnt, const char *name, const void *value, size_t size, int flags) { --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -595,6 +595,7 @@ static int smack_inode_getattr(struct vf /** * smack_inode_setxattr - Smack check for setting xattrs * @dentry: the object + * @mnt: unused * @name: name of the attribute * @value: unused * @size: unused @@ -604,8 +605,9 @@ static int smack_inode_getattr(struct vf * * Returns 0 if access is permitted, an error code otherwise */ -static int smack_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +static int smack_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags) { int rc = 0; @@ -615,7 +617,7 @@ static int smack_inode_setxattr(struct d if (!capable(CAP_MAC_ADMIN)) rc = -EPERM; } else - rc = cap_inode_setxattr(dentry, name, value, size, flags); + rc = cap_inode_setxattr(dentry, mnt, name, value, size, flags); if (rc == 0) rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); @@ -626,6 +628,7 @@ static int smack_inode_setxattr(struct d /** * smack_inode_post_setxattr - Apply the Smack update approved above * @dentry: object + * @mnt: unused * @name: attribute name * @value: attribute value * @size: attribute size @@ -634,7 +637,8 @@ static int smack_inode_setxattr(struct d * Set the pointer in the inode blob to the entry found * in the master label list. */ -static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, +static void smack_inode_post_setxattr(struct dentry *dentry, + struct vfsmount *mnt, const char *name, const void *value, size_t size, int flags) { struct inode_smack *isp;