Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 17555
b: refs/heads/master
c: e0ad7b0
h: refs/heads/master
i:
  17553: 7298de2
  17551: db535de
v: v3
  • Loading branch information
akpm@osdl.org authored and Linus Torvalds committed Jan 10, 2006
1 parent 5a1f3eb commit cacd40c
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 20 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: 5be196e5f925dab2309530fabce69c2e562b9791
refs/heads/master: e0ad7b073eb7317e5afe0385b02dcb1d52a1eedf
15 changes: 0 additions & 15 deletions trunk/fs/jfs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,6 @@ struct ea_buffer {
#define EA_NEW 0x0004
#define EA_MALLOC 0x0008

/* Namespaces */
#define XATTR_SYSTEM_PREFIX "system."
#define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)

#define XATTR_USER_PREFIX "user."
#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)

#define XATTR_OS2_PREFIX "os2."
#define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1)

/* XATTR_SECURITY_PREFIX is defined in include/linux/xattr.h */
#define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1)

#define XATTR_TRUSTED_PREFIX "trusted."
#define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1)

/*
* These three routines are used to recognize on-disk extended attributes
Expand Down
61 changes: 57 additions & 4 deletions trunk/fs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,58 @@
#include <asm/uaccess.h>


/*
* Check permissions for extended attribute access. This is a bit complicated
* because different namespaces have very different rules.
*/
static int
xattr_permission(struct inode *inode, const char *name, int mask)
{
/*
* We can never set or remove an extended attribute on a read-only
* filesystem or on an immutable / append-only inode.
*/
if (mask & MAY_WRITE) {
if (IS_RDONLY(inode))
return -EROFS;
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
return -EPERM;
}

/*
* No restriction for security.* and system.* from the VFS. Decision
* on these is left to the underlying filesystem / security module.
*/
if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) ||
!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
return 0;

/*
* The trusted.* namespace can only accessed by a privilegued user.
*/
if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);

if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
if (!S_ISREG(inode->i_mode) &&
(!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
return -EPERM;
}

return permission(inode, mask, NULL);
}

int
vfs_setxattr(struct dentry *dentry, char *name, void *value,
size_t size, int flags)
{
struct inode *inode = dentry->d_inode;
int error;

error = xattr_permission(inode, name, MAY_WRITE);
if (error)
return error;

mutex_lock(&inode->i_mutex);
error = security_inode_setxattr(dentry, name, value, size, flags);
if (error)
Expand All @@ -40,8 +85,8 @@ vfs_setxattr(struct dentry *dentry, char *name, void *value,
size, flags);
}
} else if (!strncmp(name, XATTR_SECURITY_PREFIX,
sizeof XATTR_SECURITY_PREFIX - 1)) {
const char *suffix = name + sizeof XATTR_SECURITY_PREFIX - 1;
XATTR_SECURITY_PREFIX_LEN)) {
const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
error = security_inode_setsecurity(inode, suffix, value,
size, flags);
if (!error)
Expand All @@ -59,6 +104,10 @@ vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size)
struct inode *inode = dentry->d_inode;
int error;

error = xattr_permission(inode, name, MAY_READ);
if (error)
return error;

error = security_inode_getxattr(dentry, name);
if (error)
return error;
Expand All @@ -69,8 +118,8 @@ vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size)
error = -EOPNOTSUPP;

if (!strncmp(name, XATTR_SECURITY_PREFIX,
sizeof XATTR_SECURITY_PREFIX - 1)) {
const char *suffix = name + sizeof XATTR_SECURITY_PREFIX - 1;
XATTR_SECURITY_PREFIX_LEN)) {
const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
int ret = security_inode_getsecurity(inode, suffix, value,
size, error);
/*
Expand All @@ -94,6 +143,10 @@ vfs_removexattr(struct dentry *dentry, char *name)
if (!inode->i_op->removexattr)
return -EOPNOTSUPP;

error = xattr_permission(inode, name, MAY_WRITE);
if (error)
return error;

error = security_inode_removexattr(dentry, name);
if (error)
return error;
Expand Down
15 changes: 15 additions & 0 deletions trunk/include/linux/xattr.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,22 @@
#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */

/* Namespaces */
#define XATTR_OS2_PREFIX "os2."
#define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1)

#define XATTR_SECURITY_PREFIX "security."
#define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1)

#define XATTR_SYSTEM_PREFIX "system."
#define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)

#define XATTR_TRUSTED_PREFIX "trusted."
#define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1)

#define XATTR_USER_PREFIX "user."
#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)


struct xattr_handler {
char *prefix;
Expand Down

0 comments on commit cacd40c

Please sign in to comment.