Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 11748
b: refs/heads/master
c: d381d8a
h: refs/heads/master
v: v3
  • Loading branch information
James Morris authored and Linus Torvalds committed Oct 31, 2005
1 parent 7780853 commit 48b96be
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 25 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 89d155ef62e5e0c10e4b37aaa5056f0beafe10e6
refs/heads/master: d381d8a9a08cac9824096213069159be17fd2e2f
14 changes: 9 additions & 5 deletions trunk/fs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
if (size) {
if (size > XATTR_SIZE_MAX)
size = XATTR_SIZE_MAX;
kvalue = kmalloc(size, GFP_KERNEL);
kvalue = kzalloc(size, GFP_KERNEL);
if (!kvalue)
return -ENOMEM;
}
Expand All @@ -154,11 +154,15 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
error = -EOPNOTSUPP;
if (d->d_inode->i_op && d->d_inode->i_op->getxattr)
error = d->d_inode->i_op->getxattr(d, kname, kvalue, size);
else if (!strncmp(kname, XATTR_SECURITY_PREFIX,
sizeof XATTR_SECURITY_PREFIX - 1)) {

if (!strncmp(kname, XATTR_SECURITY_PREFIX,
sizeof XATTR_SECURITY_PREFIX - 1)) {
const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1;
error = security_inode_getsecurity(d->d_inode, suffix, kvalue,
size);
int rv = security_inode_getsecurity(d->d_inode, suffix, kvalue,
size, error);
/* Security module active: overwrite error value */
if (rv != -EOPNOTSUPP)
error = rv;
}
if (error > 0) {
if (size && copy_to_user(value, kvalue, error))
Expand Down
11 changes: 7 additions & 4 deletions trunk/include/linux/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ struct swap_info_struct;
* NULL to request the size of the buffer required. @size indicates
* the size of @buffer in bytes. Note that @name is the remainder
* of the attribute name after the security. prefix has been removed.
* @err is the return value from the preceding fs getxattr call,
* and can be used by the security module to determine whether it
* should try and canonicalize the attribute value.
* Return number of bytes used/required on success.
* @inode_setsecurity:
* Set the security label associated with @name for @inode from the
Expand Down Expand Up @@ -1091,7 +1094,7 @@ struct security_operations {
int (*inode_getxattr) (struct dentry *dentry, char *name);
int (*inode_listxattr) (struct dentry *dentry);
int (*inode_removexattr) (struct dentry *dentry, char *name);
int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size);
int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size, int err);
int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);

Expand Down Expand Up @@ -1580,11 +1583,11 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return security_ops->inode_removexattr (dentry, name);
}

static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
if (unlikely (IS_PRIVATE (inode)))
return 0;
return security_ops->inode_getsecurity(inode, name, buffer, size);
return security_ops->inode_getsecurity(inode, name, buffer, size, err);
}

static inline int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
Expand Down Expand Up @@ -2222,7 +2225,7 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return cap_inode_removexattr(dentry, name);
}

static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
return -EOPNOTSUPP;
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/security/dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ static int dummy_inode_removexattr (struct dentry *dentry, char *name)
return 0;
}

static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
return -EOPNOTSUPP;
}
Expand Down
46 changes: 32 additions & 14 deletions trunk/security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -2208,9 +2208,6 @@ static int selinux_inode_getxattr (struct dentry *dentry, char *name)
struct inode *inode = dentry->d_inode;
struct superblock_security_struct *sbsec = inode->i_sb->s_security;

if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
return -EOPNOTSUPP;

return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
}

Expand Down Expand Up @@ -2241,33 +2238,54 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
return -EACCES;
}

static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
/*
* Copy the in-core inode security context value to the user. If the
* getxattr() prior to this succeeded, check to see if we need to
* canonicalize the value to be finally returned to the user.
*
* Permission check is handled by selinux_inode_getxattr hook.
*/
static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
struct inode_security_struct *isec = inode->i_security;
char *context;
unsigned len;
int rc;

/* Permission check handled by selinux_inode_getxattr hook.*/

if (strcmp(name, XATTR_SELINUX_SUFFIX))
return -EOPNOTSUPP;
if (strcmp(name, XATTR_SELINUX_SUFFIX)) {
rc = -EOPNOTSUPP;
goto out;
}

rc = security_sid_to_context(isec->sid, &context, &len);
if (rc)
return rc;
goto out;

/* Probe for required buffer size */
if (!buffer || !size) {
kfree(context);
return len;
rc = len;
goto out_free;
}

if (size < len) {
kfree(context);
return -ERANGE;
rc = -ERANGE;
goto out_free;
}

if (err > 0) {
if ((len == err) && !(memcmp(context, buffer, len))) {
/* Don't need to canonicalize value */
rc = err;
goto out_free;
}
memset(buffer, 0, size);
}
memcpy(buffer, context, len);
rc = len;
out_free:
kfree(context);
return len;
out:
return rc;
}

static int selinux_inode_setsecurity(struct inode *inode, const char *name,
Expand Down

0 comments on commit 48b96be

Please sign in to comment.