On Tue, May 31, 2016 at 05:24:15PM -0700, Casey Schaufler wrote: > Subject: [PATCH] LSM: Fix for security_inode_getsecurity and -EOPNOTSUPP > > Serge Hallyn pointed out that the current implementation of > security_inode_getsecurity() works if there is only one hook > provided for it, but will fail if there is more than one and > the attribute requested isn't supplied by the first module. > This isn't a problem today, since only SELinux and Smack > provide this hook and there is (currently) no way to enable > both of those modules at the same time. Serge, however, wants > to introduce a capability attribute and an inode_getsecurity > hook in the capability security module to handle it. This > addresses that upcoming problem, will be required for "extreme > stacking" and is just a better implementation. > > Signed-off-by: Casey Schaufler <ca...@schaufler-ca.com>
Thanks, Casey. Acked-by: Serge Hallyn <se...@hallyn.com> > --- > > security/security.c | 29 +++++++++++++++++++++++++---- > 1 file changed, 25 insertions(+), 4 deletions(-) > > diff --git a/security/security.c b/security/security.c > index 3644b03..5a749ed 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -699,18 +699,39 @@ int security_inode_killpriv(struct dentry *dentry) > > int security_inode_getsecurity(struct inode *inode, const char *name, void > **buffer, bool alloc) > { > + struct security_hook_list *hp; > + int rc; > + > if (unlikely(IS_PRIVATE(inode))) > return -EOPNOTSUPP; > - return call_int_hook(inode_getsecurity, -EOPNOTSUPP, inode, name, > - buffer, alloc); > + /* > + * Only one module will provide an attribute with a given name. > + */ > + list_for_each_entry(hp, &security_hook_heads.inode_getsecurity, list) { > + rc = hp->hook.inode_getsecurity(inode, name, buffer, alloc); > + if (rc != -EOPNOTSUPP) > + return rc; > + } > + return -EOPNOTSUPP; > } > > int security_inode_setsecurity(struct inode *inode, const char *name, const > void *value, size_t size, int flags) > { > + struct security_hook_list *hp; > + int rc; > + > if (unlikely(IS_PRIVATE(inode))) > return -EOPNOTSUPP; > - return call_int_hook(inode_setsecurity, -EOPNOTSUPP, inode, name, > - value, size, flags); > + /* > + * Only one module will provide an attribute with a given name. > + */ > + list_for_each_entry(hp, &security_hook_heads.inode_setsecurity, list) { > + rc = hp->hook.inode_setsecurity(inode, name, value, size, > + flags); > + if (rc != -EOPNOTSUPP) > + return rc; > + } > + return -EOPNOTSUPP; > } > > int security_inode_listsecurity(struct inode *inode, char *buffer, size_t > buffer_size)