diff options
author | David P. Quigley <dpquigl@tycho.nsa.gov> | 2008-02-04 22:29:39 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-05 09:44:20 -0800 |
commit | 42492594043d621a7910ff5877c3eb9202870b45 (patch) | |
tree | 9188d112c019a189606847dc1d90ccc63c1bacf2 /security | |
parent | 3729145821e3088a0c3c4183037fde356204bf97 (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.c | 2 | ||||
-rw-r--r-- | security/security.c | 4 | ||||
-rw-r--r-- | security/selinux/hooks.c | 43 |
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) return 0; } -static int dummy_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err) +static int dummy_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc) { return -EOPNOTSUPP; } 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) return security_ops->inode_killpriv(dentry); } -int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err) +int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc) { if (unlikely(IS_PRIVATE(inode))) return 0; - return security_ops->inode_getsecurity(inode, name, buffer, size, err); + return security_ops->inode_getsecurity(inode, name, buffer, alloc); } int 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); static struct kmem_cache *sel_inode_cache; -/* Return security context for a given sid or just the context - length if the buffer is null or length is 0 */ -static int selinux_getsecurity(u32 sid, void *buffer, size_t size) -{ - char *context; - unsigned len; - int rc; - - rc = security_sid_to_context(sid, &context, &len); - if (rc) - return rc; - - if (!buffer || !size) - goto getsecurity_exit; - - if (size < len) { - len = -ERANGE; - goto getsecurity_exit; - } - memcpy(buffer, context, len); - -getsecurity_exit: - kfree(context); - return len; -} - /** * selinux_secmark_enabled - Check to see if SECMARK is currently enabled * @@ -2675,14 +2649,27 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name) * * Permission check is handled by selinux_inode_getxattr hook. */ -static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err) +static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc) { + u32 size; + int error; + char *context = NULL; struct inode_security_struct *isec = inode->i_security; if (strcmp(name, XATTR_SELINUX_SUFFIX)) return -EOPNOTSUPP; - return selinux_getsecurity(isec->sid, buffer, size); + error = security_sid_to_context(isec->sid, &context, &size); + if (error) + return error; + error = size; + if (alloc) { + *buffer = context; + goto out_nofree; + } + kfree(context); +out_nofree: + return error; } static int selinux_inode_setsecurity(struct inode *inode, const char *name, |