Commit a090d9132c1e53e3517111123680c15afb25c0a4

Authored by Al Viro
Committed by Linus Torvalds
1 parent 6ad0013b31

[PATCH] protect ext3 ioctl modifying append_only, immutable, etc. with i_mutex

All modifications of ->i_flags in inodes that might be visible to
somebody else must be under ->i_mutex.  That patch fixes ext3 ioctl()
setting S_APPEND and friends.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 1 changed file with 14 additions and 4 deletions Side-by-side Diff

... ... @@ -48,6 +48,7 @@
48 48 if (!S_ISDIR(inode->i_mode))
49 49 flags &= ~EXT3_DIRSYNC_FL;
50 50  
  51 + mutex_lock(&inode->i_mutex);
51 52 oldflags = ei->i_flags;
52 53  
53 54 /* The JOURNAL_DATA flag is modifiable only by root */
54 55  
... ... @@ -60,8 +61,10 @@
60 61 * This test looks nicer. Thanks to Pauline Middelink
61 62 */
62 63 if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
63   - if (!capable(CAP_LINUX_IMMUTABLE))
  64 + if (!capable(CAP_LINUX_IMMUTABLE)) {
  65 + mutex_unlock(&inode->i_mutex);
64 66 return -EPERM;
  67 + }
65 68 }
66 69  
67 70 /*
68 71  
69 72  
70 73  
... ... @@ -69,14 +72,18 @@
69 72 * the relevant capability.
70 73 */
71 74 if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) {
72   - if (!capable(CAP_SYS_RESOURCE))
  75 + if (!capable(CAP_SYS_RESOURCE)) {
  76 + mutex_unlock(&inode->i_mutex);
73 77 return -EPERM;
  78 + }
74 79 }
75 80  
76 81  
77 82 handle = ext3_journal_start(inode, 1);
78   - if (IS_ERR(handle))
  83 + if (IS_ERR(handle)) {
  84 + mutex_unlock(&inode->i_mutex);
79 85 return PTR_ERR(handle);
  86 + }
80 87 if (IS_SYNC(inode))
81 88 handle->h_sync = 1;
82 89 err = ext3_reserve_inode_write(handle, inode, &iloc);
83 90  
84 91  
... ... @@ -93,11 +100,14 @@
93 100 err = ext3_mark_iloc_dirty(handle, inode, &iloc);
94 101 flags_err:
95 102 ext3_journal_stop(handle);
96   - if (err)
  103 + if (err) {
  104 + mutex_unlock(&inode->i_mutex);
97 105 return err;
  106 + }
98 107  
99 108 if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL))
100 109 err = ext3_change_inode_journal_flag(inode, jflag);
  110 + mutex_unlock(&inode->i_mutex);
101 111 return err;
102 112 }
103 113 case EXT3_IOC_GETVERSION: