aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorDavid P. Quigley <dpquigl@tycho.nsa.gov>2008-02-05 01:29:39 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-05 12:44:20 -0500
commit42492594043d621a7910ff5877c3eb9202870b45 (patch)
tree9188d112c019a189606847dc1d90ccc63c1bacf2 /security
parent3729145821e3088a0c3c4183037fde356204bf97 (diff)
VFS/Security: Rework inode_getsecurity and callers to return resulting buffer
This patch modifies the interface to inode_getsecurity to have the function return a buffer containing the security blob and its length via parameters instead of relying on the calling function to give it an appropriately sized buffer. Security blobs obtained with this function should be freed using the release_secctx LSM hook. This alleviates the problem of the caller having to guess a length and preallocate a buffer for this function allowing it to be used elsewhere for Labeled NFS. The patch also removed the unused err parameter. The conversion is similar to the one performed by Al Viro for the security_getprocattr hook. Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov> Cc: Stephen Smalley <sds@tycho.nsa.gov> Cc: Chris Wright <chrisw@sous-sol.org> Acked-by: James Morris <jmorris@namei.org> Acked-by: Serge Hallyn <serue@us.ibm.com> Cc: Casey Schaufler <casey@schaufler-ca.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security')
-rw-r--r--security/dummy.c2
-rw-r--r--security/security.c4
-rw-r--r--security/selinux/hooks.c43
3 files changed, 18 insertions, 31 deletions
diff --git a/security/dummy.c b/security/dummy.c
index 48d4b0a52737..c505122e22db 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -402,7 +402,7 @@ static int dummy_inode_killpriv(struct dentry *dentry)
402 return 0; 402 return 0;
403} 403}
404 404
405static int dummy_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err) 405static int dummy_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc)
406{ 406{
407 return -EOPNOTSUPP; 407 return -EOPNOTSUPP;
408} 408}
diff --git a/security/security.c b/security/security.c
index ca475ca206e4..b6c57a6b2ff5 100644
--- a/security/security.c
+++ b/security/security.c
@@ -493,11 +493,11 @@ int security_inode_killpriv(struct dentry *dentry)
493 return security_ops->inode_killpriv(dentry); 493 return security_ops->inode_killpriv(dentry);
494} 494}
495 495
496int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err) 496int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc)
497{ 497{
498 if (unlikely(IS_PRIVATE(inode))) 498 if (unlikely(IS_PRIVATE(inode)))
499 return 0; 499 return 0;
500 return security_ops->inode_getsecurity(inode, name, buffer, size, err); 500 return security_ops->inode_getsecurity(inode, name, buffer, alloc);
501} 501}
502 502
503int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) 503int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index be6de0b8734f..e5ed07510309 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -136,32 +136,6 @@ static DEFINE_SPINLOCK(sb_security_lock);
136 136
137static struct kmem_cache *sel_inode_cache; 137static struct kmem_cache *sel_inode_cache;
138 138
139/* Return security context for a given sid or just the context
140 length if the buffer is null or length is 0 */
141static int selinux_getsecurity(u32 sid, void *buffer, size_t size)
142{
143 char *context;
144 unsigned len;
145 int rc;
146
147 rc = security_sid_to_context(sid, &context, &len);
148 if (rc)
149 return rc;
150
151 if (!buffer || !size)
152 goto getsecurity_exit;
153
154 if (size < len) {
155 len = -ERANGE;
156 goto getsecurity_exit;
157 }
158 memcpy(buffer, context, len);
159
160getsecurity_exit:
161 kfree(context);
162 return len;
163}
164
165/** 139/**
166 * selinux_secmark_enabled - Check to see if SECMARK is currently enabled 140 * selinux_secmark_enabled - Check to see if SECMARK is currently enabled
167 * 141 *
@@ -2675,14 +2649,27 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
2675 * 2649 *
2676 * Permission check is handled by selinux_inode_getxattr hook. 2650 * Permission check is handled by selinux_inode_getxattr hook.
2677 */ 2651 */
2678static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err) 2652static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc)
2679{ 2653{
2654 u32 size;
2655 int error;
2656 char *context = NULL;
2680 struct inode_security_struct *isec = inode->i_security; 2657 struct inode_security_struct *isec = inode->i_security;
2681 2658
2682 if (strcmp(name, XATTR_SELINUX_SUFFIX)) 2659 if (strcmp(name, XATTR_SELINUX_SUFFIX))
2683 return -EOPNOTSUPP; 2660 return -EOPNOTSUPP;
2684 2661
2685 return selinux_getsecurity(isec->sid, buffer, size); 2662 error = security_sid_to_context(isec->sid, &context, &size);
2663 if (error)
2664 return error;
2665 error = size;
2666 if (alloc) {
2667 *buffer = context;
2668 goto out_nofree;
2669 }
2670 kfree(context);
2671out_nofree:
2672 return error;
2686} 2673}
2687 2674
2688static int selinux_inode_setsecurity(struct inode *inode, const char *name, 2675static int selinux_inode_setsecurity(struct inode *inode, const char *name,