Skip to content

Commit

Permalink
xattr: Fix setting security xattrs on sockfs
Browse files Browse the repository at this point in the history
The IOP_XATTR flag is set on sockfs because sockfs supports getting the
"system.sockprotoname" xattr.  Since commit 6c6ef9f, this flag is checked for
setxattr support as well.  This is wrong on sockfs because security xattr
support there is supposed to be provided by security_inode_setsecurity.  The
smack security module relies on socket labels (xattrs).

Fix this by adding a security xattr handler on sockfs that returns
-EAGAIN, and by checking for -EAGAIN in setxattr.

We cannot simply check for -EOPNOTSUPP in setxattr because there are
filesystems that neither have direct security xattr support nor support
via security_inode_setsecurity.  A more proper fix might be to move the
call to security_inode_setsecurity into sockfs, but it's not clear to me
if that is safe: we would end up calling security_inode_post_setxattr after
that as well.

Signed-off-by: Andreas Gruenbacher <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Andreas Gruenbacher authored and Al Viro committed Nov 17, 2016
1 parent 961b708 commit 4a59015
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 8 deletions.
22 changes: 14 additions & 8 deletions fs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags)
{
struct inode *inode = dentry->d_inode;
int error = -EOPNOTSUPP;
int error = -EAGAIN;
int issec = !strncmp(name, XATTR_SECURITY_PREFIX,
XATTR_SECURITY_PREFIX_LEN);

Expand All @@ -183,15 +183,21 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
security_inode_post_setxattr(dentry, name, value,
size, flags);
}
} else if (issec) {
const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;

} else {
if (unlikely(is_bad_inode(inode)))
return -EIO;
error = security_inode_setsecurity(inode, suffix, value,
size, flags);
if (!error)
fsnotify_xattr(dentry);
}
if (error == -EAGAIN) {
error = -EOPNOTSUPP;

if (issec) {
const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;

error = security_inode_setsecurity(inode, suffix, value,
size, flags);
if (!error)
fsnotify_xattr(dentry);
}
}

return error;
Expand Down
15 changes: 15 additions & 0 deletions net/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,23 @@ static const struct xattr_handler sockfs_xattr_handler = {
.get = sockfs_xattr_get,
};

static int sockfs_security_xattr_set(const struct xattr_handler *handler,
struct dentry *dentry, struct inode *inode,
const char *suffix, const void *value,
size_t size, int flags)
{
/* Handled by LSM. */
return -EAGAIN;
}

static const struct xattr_handler sockfs_security_xattr_handler = {
.prefix = XATTR_SECURITY_PREFIX,
.set = sockfs_security_xattr_set,
};

static const struct xattr_handler *sockfs_xattr_handlers[] = {
&sockfs_xattr_handler,
&sockfs_security_xattr_handler,
NULL
};

Expand Down

0 comments on commit 4a59015

Please sign in to comment.