summaryrefslogtreecommitdiffstats
path: root/fs/ext2/ioctl.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-09-28 22:25:29 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-09-28 22:25:29 +0000
commit0ae8dceaebe3659ee0c3352c08125f403e77ebca (patch)
tree5085c389f09da78182b899d19fe1068b619a69dd /fs/ext2/ioctl.c
parent273767781288c35c9d679e908672b9996cda4c34 (diff)
Merge with 2.3.10.
Diffstat (limited to 'fs/ext2/ioctl.c')
-rw-r--r--fs/ext2/ioctl.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c
index ec21b0c4e..4d54fd354 100644
--- a/fs/ext2/ioctl.c
+++ b/fs/ext2/ioctl.c
@@ -27,28 +27,35 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
case EXT2_IOC_GETFLAGS:
flags = inode->u.ext2_i.i_flags & EXT2_FL_USER_VISIBLE;
return put_user(inode->u.ext2_i.i_flags, (int *) arg);
- case EXT2_IOC_SETFLAGS:
+ case EXT2_IOC_SETFLAGS: {
+ unsigned int oldflags;
+
+ if (IS_RDONLY(inode))
+ return -EROFS;
+
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+ return -EPERM;
+
if (get_user(flags, (int *) arg))
return -EFAULT;
- flags = flags & EXT2_FL_USER_MODIFIABLE;
+
+ oldflags = inode->u.ext2_i.i_flags;
+
/*
* The IMMUTABLE and APPEND_ONLY flags can only be changed by
- * the super user when the security level is zero.
+ * the relevant capability.
+ *
+ * This test looks nicer. Thanks to Pauline Middelink
*/
- if ((flags & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) ^
- (inode->u.ext2_i.i_flags &
- (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL))) {
- /* This test looks nicer. Thanks to Pauline Middelink */
+ if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
if (!capable(CAP_LINUX_IMMUTABLE))
return -EPERM;
- } else
- if ((current->fsuid != inode->i_uid) &&
- !capable(CAP_FOWNER))
- return -EPERM;
- if (IS_RDONLY(inode))
- return -EROFS;
- inode->u.ext2_i.i_flags = (inode->u.ext2_i.i_flags &
- ~EXT2_FL_USER_MODIFIABLE) | flags;
+ }
+
+ flags = flags & EXT2_FL_USER_MODIFIABLE;
+ flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE;
+ inode->u.ext2_i.i_flags = flags;
+
if (flags & EXT2_SYNC_FL)
inode->i_flags |= MS_SYNCHRONOUS;
else
@@ -68,6 +75,7 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
inode->i_ctime = CURRENT_TIME;
mark_inode_dirty(inode);
return 0;
+ }
case EXT2_IOC_GETVERSION:
return put_user(inode->i_generation, (int *) arg);
case EXT2_IOC_SETVERSION: