aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xattr.c
diff options
context:
space:
mode:
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 395635100f..38646132ab 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -48,14 +48,21 @@ xattr_permission(struct inode *inode, const char *name, int mask)
48 return 0; 48 return 0;
49 49
50 /* 50 /*
51 * The trusted.* namespace can only accessed by a privilegued user. 51 * The trusted.* namespace can only be accessed by a privileged user.
52 */ 52 */
53 if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) 53 if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
54 return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); 54 return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);
55 55
56 /* In user.* namespace, only regular files and directories can have
57 * extended attributes. For sticky directories, only the owner and
58 * privileged user can write attributes.
59 */
56 if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { 60 if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
57 if (!S_ISREG(inode->i_mode) && 61 if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
58 (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) 62 return -EPERM;
63 if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
64 (mask & MAY_WRITE) && (current->fsuid != inode->i_uid) &&
65 !capable(CAP_FOWNER))
59 return -EPERM; 66 return -EPERM;
60 } 67 }
61 68
@@ -261,7 +268,7 @@ sys_fsetxattr(int fd, char __user *name, void __user *value,
261 f = fget(fd); 268 f = fget(fd);
262 if (!f) 269 if (!f)
263 return error; 270 return error;
264 dentry = f->f_dentry; 271 dentry = f->f_path.dentry;
265 audit_inode(NULL, dentry->d_inode); 272 audit_inode(NULL, dentry->d_inode);
266 error = setxattr(dentry, name, value, size, flags); 273 error = setxattr(dentry, name, value, size, flags);
267 fput(f); 274 fput(f);
@@ -344,7 +351,7 @@ sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size)
344 f = fget(fd); 351 f = fget(fd);
345 if (!f) 352 if (!f)
346 return error; 353 return error;
347 error = getxattr(f->f_dentry, name, value, size); 354 error = getxattr(f->f_path.dentry, name, value, size);
348 fput(f); 355 fput(f);
349 return error; 356 return error;
350} 357}
@@ -416,7 +423,7 @@ sys_flistxattr(int fd, char __user *list, size_t size)
416 f = fget(fd); 423 f = fget(fd);
417 if (!f) 424 if (!f)
418 return error; 425 return error;
419 error = listxattr(f->f_dentry, list, size); 426 error = listxattr(f->f_path.dentry, list, size);
420 fput(f); 427 fput(f);
421 return error; 428 return error;
422} 429}
@@ -477,7 +484,7 @@ sys_fremovexattr(int fd, char __user *name)
477 f = fget(fd); 484 f = fget(fd);
478 if (!f) 485 if (!f)
479 return error; 486 return error;
480 dentry = f->f_dentry; 487 dentry = f->f_path.dentry;
481 audit_inode(NULL, dentry->d_inode); 488 audit_inode(NULL, dentry->d_inode);
482 error = removexattr(dentry, name); 489 error = removexattr(dentry, name);
483 fput(f); 490 fput(f);