Message ID | 20231107134012.682009-12-roberto.sassu@huaweicloud.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | security: Move IMA and EVM to the LSM infrastructure | expand |
On 11/7/2023 5:40 AM, Roberto Sassu wrote: > From: Roberto Sassu <roberto.sassu@huawei.com> > > In preparation for moving IMA and EVM to the LSM infrastructure, introduce > the inode_post_removexattr hook. > > At inode_removexattr hook, EVM verifies the file's existing HMAC value. At > inode_post_removexattr, EVM re-calculates the file's HMAC with the passed > xattr removed and other file metadata. > > Other LSMs could similarly take some action after successful xattr removal. > > The new hook cannot return an error and cannot cause the operation to be > reverted. > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> > Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> > Reviewed-by: Mimi Zohar <zohar@linux.ibm.com> > --- > fs/xattr.c | 9 +++++---- > include/linux/lsm_hook_defs.h | 2 ++ > include/linux/security.h | 5 +++++ > security/security.c | 14 ++++++++++++++ > 4 files changed, 26 insertions(+), 4 deletions(-) > > diff --git a/fs/xattr.c b/fs/xattr.c > index 09d927603433..84a4aa566c02 100644 > --- a/fs/xattr.c > +++ b/fs/xattr.c > @@ -552,11 +552,12 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap, > goto out; > > error = __vfs_removexattr(idmap, dentry, name); > + if (error) > + goto out; Shouldn't this be simply "return error" rather than a goto to nothing but "return error"? > > - if (!error) { > - fsnotify_xattr(dentry); > - evm_inode_post_removexattr(dentry, name); > - } > + fsnotify_xattr(dentry); > + security_inode_post_removexattr(dentry, name); > + evm_inode_post_removexattr(dentry, name); > > out: > return error; > diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h > index 67410e085205..88452e45025c 100644 > --- a/include/linux/lsm_hook_defs.h > +++ b/include/linux/lsm_hook_defs.h > @@ -149,6 +149,8 @@ LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name) > LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry) > LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap, > struct dentry *dentry, const char *name) > +LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry, > + const char *name) > LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap, > struct dentry *dentry, const char *acl_name, struct posix_acl *kacl) > LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap, > diff --git a/include/linux/security.h b/include/linux/security.h > index 664df46b22a9..922ea7709bae 100644 > --- a/include/linux/security.h > +++ b/include/linux/security.h > @@ -380,6 +380,7 @@ int security_inode_getxattr(struct dentry *dentry, const char *name); > int security_inode_listxattr(struct dentry *dentry); > int security_inode_removexattr(struct mnt_idmap *idmap, > struct dentry *dentry, const char *name); > +void security_inode_post_removexattr(struct dentry *dentry, const char *name); > int security_inode_need_killpriv(struct dentry *dentry); > int security_inode_killpriv(struct mnt_idmap *idmap, struct dentry *dentry); > int security_inode_getsecurity(struct mnt_idmap *idmap, > @@ -940,6 +941,10 @@ static inline int security_inode_removexattr(struct mnt_idmap *idmap, > return cap_inode_removexattr(idmap, dentry, name); > } > > +static inline void security_inode_post_removexattr(struct dentry *dentry, > + const char *name) > +{ } > + > static inline int security_inode_need_killpriv(struct dentry *dentry) > { > return cap_inode_need_killpriv(dentry); > diff --git a/security/security.c b/security/security.c > index ce3bc7642e18..8aa6e9f316dd 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -2452,6 +2452,20 @@ int security_inode_removexattr(struct mnt_idmap *idmap, > return evm_inode_removexattr(idmap, dentry, name); > } > > +/** > + * security_inode_post_removexattr() - Update the inode after a removexattr op > + * @dentry: file > + * @name: xattr name > + * > + * Update the inode after a successful removexattr operation. > + */ > +void security_inode_post_removexattr(struct dentry *dentry, const char *name) > +{ > + if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) > + return; > + call_void_hook(inode_post_removexattr, dentry, name); > +} > + > /** > * security_inode_need_killpriv() - Check if security_inode_killpriv() required > * @dentry: associated dentry
On Tue, 2023-11-07 at 09:33 -0800, Casey Schaufler wrote: > On 11/7/2023 5:40 AM, Roberto Sassu wrote: > > From: Roberto Sassu <roberto.sassu@huawei.com> > > > > In preparation for moving IMA and EVM to the LSM infrastructure, introduce > > the inode_post_removexattr hook. > > > > At inode_removexattr hook, EVM verifies the file's existing HMAC value. At > > inode_post_removexattr, EVM re-calculates the file's HMAC with the passed > > xattr removed and other file metadata. > > > > Other LSMs could similarly take some action after successful xattr removal. > > > > The new hook cannot return an error and cannot cause the operation to be > > reverted. > > > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> > > Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> > > Reviewed-by: Mimi Zohar <zohar@linux.ibm.com> > > --- > > fs/xattr.c | 9 +++++---- > > include/linux/lsm_hook_defs.h | 2 ++ > > include/linux/security.h | 5 +++++ > > security/security.c | 14 ++++++++++++++ > > 4 files changed, 26 insertions(+), 4 deletions(-) > > > > diff --git a/fs/xattr.c b/fs/xattr.c > > index 09d927603433..84a4aa566c02 100644 > > --- a/fs/xattr.c > > +++ b/fs/xattr.c > > @@ -552,11 +552,12 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap, > > goto out; > > > > error = __vfs_removexattr(idmap, dentry, name); > > + if (error) > > + goto out; > > Shouldn't this be simply "return error" rather than a goto to nothing > but "return error"? Ok, no problem. I can change that. Thanks Roberto > > > > - if (!error) { > > - fsnotify_xattr(dentry); > > - evm_inode_post_removexattr(dentry, name); > > - } > > + fsnotify_xattr(dentry); > > + security_inode_post_removexattr(dentry, name); > > + evm_inode_post_removexattr(dentry, name); > > > > out: > > return error; > > diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h > > index 67410e085205..88452e45025c 100644 > > --- a/include/linux/lsm_hook_defs.h > > +++ b/include/linux/lsm_hook_defs.h > > @@ -149,6 +149,8 @@ LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name) > > LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry) > > LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap, > > struct dentry *dentry, const char *name) > > +LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry, > > + const char *name) > > LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap, > > struct dentry *dentry, const char *acl_name, struct posix_acl *kacl) > > LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap, > > diff --git a/include/linux/security.h b/include/linux/security.h > > index 664df46b22a9..922ea7709bae 100644 > > --- a/include/linux/security.h > > +++ b/include/linux/security.h > > @@ -380,6 +380,7 @@ int security_inode_getxattr(struct dentry *dentry, const char *name); > > int security_inode_listxattr(struct dentry *dentry); > > int security_inode_removexattr(struct mnt_idmap *idmap, > > struct dentry *dentry, const char *name); > > +void security_inode_post_removexattr(struct dentry *dentry, const char *name); > > int security_inode_need_killpriv(struct dentry *dentry); > > int security_inode_killpriv(struct mnt_idmap *idmap, struct dentry *dentry); > > int security_inode_getsecurity(struct mnt_idmap *idmap, > > @@ -940,6 +941,10 @@ static inline int security_inode_removexattr(struct mnt_idmap *idmap, > > return cap_inode_removexattr(idmap, dentry, name); > > } > > > > +static inline void security_inode_post_removexattr(struct dentry *dentry, > > + const char *name) > > +{ } > > + > > static inline int security_inode_need_killpriv(struct dentry *dentry) > > { > > return cap_inode_need_killpriv(dentry); > > diff --git a/security/security.c b/security/security.c > > index ce3bc7642e18..8aa6e9f316dd 100644 > > --- a/security/security.c > > +++ b/security/security.c > > @@ -2452,6 +2452,20 @@ int security_inode_removexattr(struct mnt_idmap *idmap, > > return evm_inode_removexattr(idmap, dentry, name); > > } > > > > +/** > > + * security_inode_post_removexattr() - Update the inode after a removexattr op > > + * @dentry: file > > + * @name: xattr name > > + * > > + * Update the inode after a successful removexattr operation. > > + */ > > +void security_inode_post_removexattr(struct dentry *dentry, const char *name) > > +{ > > + if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) > > + return; > > + call_void_hook(inode_post_removexattr, dentry, name); > > +} > > + > > /** > > * security_inode_need_killpriv() - Check if security_inode_killpriv() required > > * @dentry: associated dentry
On Nov 7, 2023 Roberto Sassu <roberto.sassu@huaweicloud.com> wrote: > > In preparation for moving IMA and EVM to the LSM infrastructure, introduce > the inode_post_removexattr hook. > > At inode_removexattr hook, EVM verifies the file's existing HMAC value. At > inode_post_removexattr, EVM re-calculates the file's HMAC with the passed > xattr removed and other file metadata. > > Other LSMs could similarly take some action after successful xattr removal. > > The new hook cannot return an error and cannot cause the operation to be > reverted. > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> > Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> > Reviewed-by: Mimi Zohar <zohar@linux.ibm.com> > --- > fs/xattr.c | 9 +++++---- > include/linux/lsm_hook_defs.h | 2 ++ > include/linux/security.h | 5 +++++ > security/security.c | 14 ++++++++++++++ > 4 files changed, 26 insertions(+), 4 deletions(-) ... > diff --git a/security/security.c b/security/security.c > index ce3bc7642e18..8aa6e9f316dd 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -2452,6 +2452,20 @@ int security_inode_removexattr(struct mnt_idmap *idmap, > return evm_inode_removexattr(idmap, dentry, name); > } > > +/** > + * security_inode_post_removexattr() - Update the inode after a removexattr op > + * @dentry: file > + * @name: xattr name > + * > + * Update the inode after a successful removexattr operation. > + */ > +void security_inode_post_removexattr(struct dentry *dentry, const char *name) > +{ > + if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) > + return; Similar comment about the S_PRIVATE check as was in patch 10/23. > + call_void_hook(inode_post_removexattr, dentry, name); > +} > + > /** > * security_inode_need_killpriv() - Check if security_inode_killpriv() required > * @dentry: associated dentry > -- > 2.34.1 -- paul-moore.com
On Tue, 2023-11-07 at 09:33 -0800, Casey Schaufler wrote: > On 11/7/2023 5:40 AM, Roberto Sassu wrote: > > From: Roberto Sassu <roberto.sassu@huawei.com> > > > > In preparation for moving IMA and EVM to the LSM infrastructure, introduce > > the inode_post_removexattr hook. > > > > At inode_removexattr hook, EVM verifies the file's existing HMAC value. At > > inode_post_removexattr, EVM re-calculates the file's HMAC with the passed > > xattr removed and other file metadata. > > > > Other LSMs could similarly take some action after successful xattr removal. > > > > The new hook cannot return an error and cannot cause the operation to be > > reverted. > > > > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> > > Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> > > Reviewed-by: Mimi Zohar <zohar@linux.ibm.com> > > --- > > fs/xattr.c | 9 +++++---- > > include/linux/lsm_hook_defs.h | 2 ++ > > include/linux/security.h | 5 +++++ > > security/security.c | 14 ++++++++++++++ > > 4 files changed, 26 insertions(+), 4 deletions(-) > > > > diff --git a/fs/xattr.c b/fs/xattr.c > > index 09d927603433..84a4aa566c02 100644 > > --- a/fs/xattr.c > > +++ b/fs/xattr.c > > @@ -552,11 +552,12 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap, > > goto out; > > > > error = __vfs_removexattr(idmap, dentry, name); > > + if (error) > > + goto out; > > Shouldn't this be simply "return error" rather than a goto to nothing > but "return error"? I got a review from Andrew Morton. His argument seems convincing, that having less return places makes the code easier to handle. Thanks Roberto > > - if (!error) { > > - fsnotify_xattr(dentry); > > - evm_inode_post_removexattr(dentry, name); > > - } > > + fsnotify_xattr(dentry); > > + security_inode_post_removexattr(dentry, name); > > + evm_inode_post_removexattr(dentry, name); > > > > out: > > return error; > > diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h > > index 67410e085205..88452e45025c 100644 > > --- a/include/linux/lsm_hook_defs.h > > +++ b/include/linux/lsm_hook_defs.h > > @@ -149,6 +149,8 @@ LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name) > > LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry) > > LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap, > > struct dentry *dentry, const char *name) > > +LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry, > > + const char *name) > > LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap, > > struct dentry *dentry, const char *acl_name, struct posix_acl *kacl) > > LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap, > > diff --git a/include/linux/security.h b/include/linux/security.h > > index 664df46b22a9..922ea7709bae 100644 > > --- a/include/linux/security.h > > +++ b/include/linux/security.h > > @@ -380,6 +380,7 @@ int security_inode_getxattr(struct dentry *dentry, const char *name); > > int security_inode_listxattr(struct dentry *dentry); > > int security_inode_removexattr(struct mnt_idmap *idmap, > > struct dentry *dentry, const char *name); > > +void security_inode_post_removexattr(struct dentry *dentry, const char *name); > > int security_inode_need_killpriv(struct dentry *dentry); > > int security_inode_killpriv(struct mnt_idmap *idmap, struct dentry *dentry); > > int security_inode_getsecurity(struct mnt_idmap *idmap, > > @@ -940,6 +941,10 @@ static inline int security_inode_removexattr(struct mnt_idmap *idmap, > > return cap_inode_removexattr(idmap, dentry, name); > > } > > > > +static inline void security_inode_post_removexattr(struct dentry *dentry, > > + const char *name) > > +{ } > > + > > static inline int security_inode_need_killpriv(struct dentry *dentry) > > { > > return cap_inode_need_killpriv(dentry); > > diff --git a/security/security.c b/security/security.c > > index ce3bc7642e18..8aa6e9f316dd 100644 > > --- a/security/security.c > > +++ b/security/security.c > > @@ -2452,6 +2452,20 @@ int security_inode_removexattr(struct mnt_idmap *idmap, > > return evm_inode_removexattr(idmap, dentry, name); > > } > > > > +/** > > + * security_inode_post_removexattr() - Update the inode after a removexattr op > > + * @dentry: file > > + * @name: xattr name > > + * > > + * Update the inode after a successful removexattr operation. > > + */ > > +void security_inode_post_removexattr(struct dentry *dentry, const char *name) > > +{ > > + if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) > > + return; > > + call_void_hook(inode_post_removexattr, dentry, name); > > +} > > + > > /** > > * security_inode_need_killpriv() - Check if security_inode_killpriv() required > > * @dentry: associated dentry
On 11/20/2023 9:31 AM, Roberto Sassu wrote: > On Tue, 2023-11-07 at 09:33 -0800, Casey Schaufler wrote: >> On 11/7/2023 5:40 AM, Roberto Sassu wrote: >>> From: Roberto Sassu <roberto.sassu@huawei.com> >>> >>> In preparation for moving IMA and EVM to the LSM infrastructure, introduce >>> the inode_post_removexattr hook. >>> >>> At inode_removexattr hook, EVM verifies the file's existing HMAC value. At >>> inode_post_removexattr, EVM re-calculates the file's HMAC with the passed >>> xattr removed and other file metadata. >>> >>> Other LSMs could similarly take some action after successful xattr removal. >>> >>> The new hook cannot return an error and cannot cause the operation to be >>> reverted. >>> >>> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> >>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> >>> Reviewed-by: Mimi Zohar <zohar@linux.ibm.com> >>> --- >>> fs/xattr.c | 9 +++++---- >>> include/linux/lsm_hook_defs.h | 2 ++ >>> include/linux/security.h | 5 +++++ >>> security/security.c | 14 ++++++++++++++ >>> 4 files changed, 26 insertions(+), 4 deletions(-) >>> >>> diff --git a/fs/xattr.c b/fs/xattr.c >>> index 09d927603433..84a4aa566c02 100644 >>> --- a/fs/xattr.c >>> +++ b/fs/xattr.c >>> @@ -552,11 +552,12 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap, >>> goto out; >>> >>> error = __vfs_removexattr(idmap, dentry, name); >>> + if (error) >>> + goto out; >> Shouldn't this be simply "return error" rather than a goto to nothing >> but "return error"? > I got a review from Andrew Morton. His argument seems convincing, that > having less return places makes the code easier to handle. That was in a case where you did more than just "return". Nonetheless, I think it's a matter of style that's not worth debating. Do as you will. > > Thanks > > Roberto > >>> - if (!error) { >>> - fsnotify_xattr(dentry); >>> - evm_inode_post_removexattr(dentry, name); >>> - } >>> + fsnotify_xattr(dentry); >>> + security_inode_post_removexattr(dentry, name); >>> + evm_inode_post_removexattr(dentry, name); >>> >>> out: >>> return error; >>> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h >>> index 67410e085205..88452e45025c 100644 >>> --- a/include/linux/lsm_hook_defs.h >>> +++ b/include/linux/lsm_hook_defs.h >>> @@ -149,6 +149,8 @@ LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name) >>> LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry) >>> LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap, >>> struct dentry *dentry, const char *name) >>> +LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry, >>> + const char *name) >>> LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap, >>> struct dentry *dentry, const char *acl_name, struct posix_acl *kacl) >>> LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap, >>> diff --git a/include/linux/security.h b/include/linux/security.h >>> index 664df46b22a9..922ea7709bae 100644 >>> --- a/include/linux/security.h >>> +++ b/include/linux/security.h >>> @@ -380,6 +380,7 @@ int security_inode_getxattr(struct dentry *dentry, const char *name); >>> int security_inode_listxattr(struct dentry *dentry); >>> int security_inode_removexattr(struct mnt_idmap *idmap, >>> struct dentry *dentry, const char *name); >>> +void security_inode_post_removexattr(struct dentry *dentry, const char *name); >>> int security_inode_need_killpriv(struct dentry *dentry); >>> int security_inode_killpriv(struct mnt_idmap *idmap, struct dentry *dentry); >>> int security_inode_getsecurity(struct mnt_idmap *idmap, >>> @@ -940,6 +941,10 @@ static inline int security_inode_removexattr(struct mnt_idmap *idmap, >>> return cap_inode_removexattr(idmap, dentry, name); >>> } >>> >>> +static inline void security_inode_post_removexattr(struct dentry *dentry, >>> + const char *name) >>> +{ } >>> + >>> static inline int security_inode_need_killpriv(struct dentry *dentry) >>> { >>> return cap_inode_need_killpriv(dentry); >>> diff --git a/security/security.c b/security/security.c >>> index ce3bc7642e18..8aa6e9f316dd 100644 >>> --- a/security/security.c >>> +++ b/security/security.c >>> @@ -2452,6 +2452,20 @@ int security_inode_removexattr(struct mnt_idmap *idmap, >>> return evm_inode_removexattr(idmap, dentry, name); >>> } >>> >>> +/** >>> + * security_inode_post_removexattr() - Update the inode after a removexattr op >>> + * @dentry: file >>> + * @name: xattr name >>> + * >>> + * Update the inode after a successful removexattr operation. >>> + */ >>> +void security_inode_post_removexattr(struct dentry *dentry, const char *name) >>> +{ >>> + if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) >>> + return; >>> + call_void_hook(inode_post_removexattr, dentry, name); >>> +} >>> + >>> /** >>> * security_inode_need_killpriv() - Check if security_inode_killpriv() required >>> * @dentry: associated dentry
On Mon, Nov 20, 2023 at 1:04 PM Casey Schaufler <casey@schaufler-ca.com> wrote: > On 11/20/2023 9:31 AM, Roberto Sassu wrote: > > On Tue, 2023-11-07 at 09:33 -0800, Casey Schaufler wrote: > >> On 11/7/2023 5:40 AM, Roberto Sassu wrote: > >>> From: Roberto Sassu <roberto.sassu@huawei.com> > >>> > >>> In preparation for moving IMA and EVM to the LSM infrastructure, introduce > >>> the inode_post_removexattr hook. > >>> > >>> At inode_removexattr hook, EVM verifies the file's existing HMAC value. At > >>> inode_post_removexattr, EVM re-calculates the file's HMAC with the passed > >>> xattr removed and other file metadata. > >>> > >>> Other LSMs could similarly take some action after successful xattr removal. > >>> > >>> The new hook cannot return an error and cannot cause the operation to be > >>> reverted. > >>> > >>> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> > >>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> > >>> Reviewed-by: Mimi Zohar <zohar@linux.ibm.com> > >>> --- > >>> fs/xattr.c | 9 +++++---- > >>> include/linux/lsm_hook_defs.h | 2 ++ > >>> include/linux/security.h | 5 +++++ > >>> security/security.c | 14 ++++++++++++++ > >>> 4 files changed, 26 insertions(+), 4 deletions(-) > >>> > >>> diff --git a/fs/xattr.c b/fs/xattr.c > >>> index 09d927603433..84a4aa566c02 100644 > >>> --- a/fs/xattr.c > >>> +++ b/fs/xattr.c > >>> @@ -552,11 +552,12 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap, > >>> goto out; > >>> > >>> error = __vfs_removexattr(idmap, dentry, name); > >>> + if (error) > >>> + goto out; > >> Shouldn't this be simply "return error" rather than a goto to nothing > >> but "return error"? > > I got a review from Andrew Morton. His argument seems convincing, that > > having less return places makes the code easier to handle. > > That was in a case where you did more than just "return". Nonetheless, > I think it's a matter of style that's not worth debating. Do as you will. I'm not too bothered by this in the VFS code, that's up to the VFS maintainers, but for future reference, in the LSM layer I really dislike jumping to a label simply to return.
diff --git a/fs/xattr.c b/fs/xattr.c index 09d927603433..84a4aa566c02 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -552,11 +552,12 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap, goto out; error = __vfs_removexattr(idmap, dentry, name); + if (error) + goto out; - if (!error) { - fsnotify_xattr(dentry); - evm_inode_post_removexattr(dentry, name); - } + fsnotify_xattr(dentry); + security_inode_post_removexattr(dentry, name); + evm_inode_post_removexattr(dentry, name); out: return error; diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 67410e085205..88452e45025c 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -149,6 +149,8 @@ LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name) LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry) LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap, struct dentry *dentry, const char *name) +LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry, + const char *name) LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name, struct posix_acl *kacl) LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap, diff --git a/include/linux/security.h b/include/linux/security.h index 664df46b22a9..922ea7709bae 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -380,6 +380,7 @@ int security_inode_getxattr(struct dentry *dentry, const char *name); int security_inode_listxattr(struct dentry *dentry); int security_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry, const char *name); +void security_inode_post_removexattr(struct dentry *dentry, const char *name); int security_inode_need_killpriv(struct dentry *dentry); int security_inode_killpriv(struct mnt_idmap *idmap, struct dentry *dentry); int security_inode_getsecurity(struct mnt_idmap *idmap, @@ -940,6 +941,10 @@ static inline int security_inode_removexattr(struct mnt_idmap *idmap, return cap_inode_removexattr(idmap, dentry, name); } +static inline void security_inode_post_removexattr(struct dentry *dentry, + const char *name) +{ } + static inline int security_inode_need_killpriv(struct dentry *dentry) { return cap_inode_need_killpriv(dentry); diff --git a/security/security.c b/security/security.c index ce3bc7642e18..8aa6e9f316dd 100644 --- a/security/security.c +++ b/security/security.c @@ -2452,6 +2452,20 @@ int security_inode_removexattr(struct mnt_idmap *idmap, return evm_inode_removexattr(idmap, dentry, name); } +/** + * security_inode_post_removexattr() - Update the inode after a removexattr op + * @dentry: file + * @name: xattr name + * + * Update the inode after a successful removexattr operation. + */ +void security_inode_post_removexattr(struct dentry *dentry, const char *name) +{ + if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) + return; + call_void_hook(inode_post_removexattr, dentry, name); +} + /** * security_inode_need_killpriv() - Check if security_inode_killpriv() required * @dentry: associated dentry