Skip to content

Commit 2885c1e

Browse files
cschauflerJames Morris
authored andcommitted
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 <[email protected]> Acked-by: Serge Hallyn <[email protected]> Signed-off-by: James Morris <[email protected]>
1 parent 39baa7e commit 2885c1e

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

security/security.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -700,18 +700,39 @@ int security_inode_killpriv(struct dentry *dentry)
700700

701701
int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc)
702702
{
703+
struct security_hook_list *hp;
704+
int rc;
705+
703706
if (unlikely(IS_PRIVATE(inode)))
704707
return -EOPNOTSUPP;
705-
return call_int_hook(inode_getsecurity, -EOPNOTSUPP, inode, name,
706-
buffer, alloc);
708+
/*
709+
* Only one module will provide an attribute with a given name.
710+
*/
711+
list_for_each_entry(hp, &security_hook_heads.inode_getsecurity, list) {
712+
rc = hp->hook.inode_getsecurity(inode, name, buffer, alloc);
713+
if (rc != -EOPNOTSUPP)
714+
return rc;
715+
}
716+
return -EOPNOTSUPP;
707717
}
708718

709719
int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
710720
{
721+
struct security_hook_list *hp;
722+
int rc;
723+
711724
if (unlikely(IS_PRIVATE(inode)))
712725
return -EOPNOTSUPP;
713-
return call_int_hook(inode_setsecurity, -EOPNOTSUPP, inode, name,
714-
value, size, flags);
726+
/*
727+
* Only one module will provide an attribute with a given name.
728+
*/
729+
list_for_each_entry(hp, &security_hook_heads.inode_setsecurity, list) {
730+
rc = hp->hook.inode_setsecurity(inode, name, value, size,
731+
flags);
732+
if (rc != -EOPNOTSUPP)
733+
return rc;
734+
}
735+
return -EOPNOTSUPP;
715736
}
716737

717738
int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)

0 commit comments

Comments
 (0)