aboutsummaryrefslogtreecommitdiffstats
path: root/security/security.c
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2016-05-31 20:24:15 -0400
committerJames Morris <james.l.morris@oracle.com>2016-06-06 05:59:18 -0400
commit2885c1e3e0c29e4a1915214ddc9673925f538299 (patch)
treeb7529a81d1580fe37dae577530a1cbc4e52bd86c /security/security.c
parent39baa7e6add5062bebf7cf1bdf6ecb4f380386bc (diff)
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 <casey@schaufler-ca.com> Acked-by: Serge Hallyn <serge@hallyn.com> Signed-off-by: James Morris <james.l.morris@oracle.com>
Diffstat (limited to 'security/security.c')
-rw-r--r--security/security.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/security/security.c b/security/security.c
index 709569305d32..c4bb47db30ee 100644
--- a/security/security.c
+++ b/security/security.c
@@ -700,18 +700,39 @@ int security_inode_killpriv(struct dentry *dentry)
700 700
701int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc) 701int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc)
702{ 702{
703 struct security_hook_list *hp;
704 int rc;
705
703 if (unlikely(IS_PRIVATE(inode))) 706 if (unlikely(IS_PRIVATE(inode)))
704 return -EOPNOTSUPP; 707 return -EOPNOTSUPP;
705 return call_int_hook(inode_getsecurity, -EOPNOTSUPP, inode, name, 708 /*
706 buffer, alloc); 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;
707} 717}
708 718
709int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) 719int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
710{ 720{
721 struct security_hook_list *hp;
722 int rc;
723
711 if (unlikely(IS_PRIVATE(inode))) 724 if (unlikely(IS_PRIVATE(inode)))
712 return -EOPNOTSUPP; 725 return -EOPNOTSUPP;
713 return call_int_hook(inode_setsecurity, -EOPNOTSUPP, inode, name, 726 /*
714 value, size, flags); 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;
715} 736}
716 737
717int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) 738int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)