summaryrefslogtreecommitdiff
path: root/fs/xattr.c
diff options
context:
space:
mode:
authorDave Jones <davej@redhat.com>2006-12-12 17:41:41 -0500
committerDave Jones <davej@redhat.com>2006-12-12 17:41:41 -0500
commitc4366889dda8110247be59ca41fddb82951a8c26 (patch)
tree705c1a996bed8fd48ce94ff33ec9fd00f9b94875 /fs/xattr.c
parentdb2fb9db5735cc532fd4fc55e94b9a3c3750378e (diff)
parente1036502e5263851259d147771226161e5ccc85a (diff)
downloadlwn-c4366889dda8110247be59ca41fddb82951a8c26.tar.gz
lwn-c4366889dda8110247be59ca41fddb82951a8c26.zip
Merge ../linus
Conflicts: drivers/cpufreq/cpufreq.c
Diffstat (limited to 'fs/xattr.c')
-rw-r--r--fs/xattr.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/fs/xattr.c b/fs/xattr.c
index 395635100f77..38646132ab0e 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -48,14 +48,21 @@ xattr_permission(struct inode *inode, const char *name, int mask)
return 0;
/*
- * The trusted.* namespace can only accessed by a privilegued user.
+ * The trusted.* namespace can only be accessed by a privileged user.
*/
if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);
+ /* In user.* namespace, only regular files and directories can have
+ * extended attributes. For sticky directories, only the owner and
+ * privileged user can write attributes.
+ */
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))
+ if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
+ return -EPERM;
+ if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
+ (mask & MAY_WRITE) && (current->fsuid != inode->i_uid) &&
+ !capable(CAP_FOWNER))
return -EPERM;
}
@@ -261,7 +268,7 @@ sys_fsetxattr(int fd, char __user *name, void __user *value,
f = fget(fd);
if (!f)
return error;
- dentry = f->f_dentry;
+ dentry = f->f_path.dentry;
audit_inode(NULL, dentry->d_inode);
error = setxattr(dentry, name, value, size, flags);
fput(f);
@@ -344,7 +351,7 @@ sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size)
f = fget(fd);
if (!f)
return error;
- error = getxattr(f->f_dentry, name, value, size);
+ error = getxattr(f->f_path.dentry, name, value, size);
fput(f);
return error;
}
@@ -416,7 +423,7 @@ sys_flistxattr(int fd, char __user *list, size_t size)
f = fget(fd);
if (!f)
return error;
- error = listxattr(f->f_dentry, list, size);
+ error = listxattr(f->f_path.dentry, list, size);
fput(f);
return error;
}
@@ -477,7 +484,7 @@ sys_fremovexattr(int fd, char __user *name)
f = fget(fd);
if (!f)
return error;
- dentry = f->f_dentry;
+ dentry = f->f_path.dentry;
audit_inode(NULL, dentry->d_inode);
error = removexattr(dentry, name);
fput(f);