xfs: take XFS_IOLOCK_EXCL if suid removal is required
PATCH 1/1 xfs: take XFS_IOLOCK_EXCL if suid removal is required
This sequence:
# rm -f sparsefile # truncate --size=1m sparsefile # chmod ugo+rws sparsefile # ls -l sparsefile -rwSrwSrw-. 1 root root 1048576 Mar 6 10:29 sparsefile # su tester
$ xfs_io -d -c "pwrite 0 4096" sparsefile wrote 4096/4096 bytes at offset 0 4 KiB, 1 ops; 0.0000 sec (21.505 KiB/sec and 5.3763 ops/sec) $ exit
will lead to a WARN_ON() in notify change, because i_mutex is not held, and we get to notify_change via suid removal with only XFS_IOLOCK_SHARED held, i.e. no i_mutex.
Upgrade the lock to XFS_IOLOCK_EXCL in this case.
---
fs/xfs/xfs_file.c +13 -6
@@ -541,7 +541,7 @@ xfs_zero_eof(* * Called with the iolocked held either shared and exclusive according to * @iolock, and returns with it held. Might upgrade the iolock to exclusive -* if called for a direct write beyond i_size. +* if called for a direct write beyond i_size or if suid removal is required. */ STATIC ssize_t xfs_file_aio_write_checks(
@@ -551,6 +551,7 @@ xfs_file_aio_write_checks( int *iolock) {struct inode *inode = file->f_mapping->host; +struct dentry *dentry = file->f_path.dentry;struct xfs_inode *ip =XFS_I (inode);int error =0 ;
@@ -569,9 +570,12 @@ restart:* write. If zeroing is needed and we are currently holding the * iolock shared, we need to update it to exclusive which implies * having to redo all checks before. +* +* We also must be locked exclusively if this write will require +* suid removal; notify_change expects i_mutex to be locked. */ -if (*pos >i_size_read (inode)) { -bool zero = false; +if (*pos >i_size_read (inode) ||should_remove_suid (dentry)) { +bool z = false;if (*iolock ==XFS_IOLOCK_SHARED ) {xfs_rw_iunlock (ip, *iolock);
@@ -579,9 +583,12 @@ restart:xfs_rw_ilock (ip, *iolock); goto restart; } - error =xfs_zero_eof (ip, *pos,i_size_read (inode), &zero); -if (error) -return error; + +if (*pos >i_size_read (inode) ) { + error =xfs_zero_eof (ip, *pos,i_size_read (inode), &z); +if (error) +return error; + } }/*
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 14 lines · Eric Sandeen
This sequence:
# rm -f sparsefile # truncate --size=1m sparsefile # chmod ugo+rws sparsefile # ls -l sparsefile -rwSrwSrw-. 1 root root 1048576 Mar 6 10:29 sparsefile # su tester$ xfs_io -d -c "pwrite 0 4096" sparsefile wrote 4096/4096 bytes at offset 0 4 KiB, 1 ops; 0.0000 sec (21.505 KiB/sec and 5.3763 ops/sec) $ exit
Quoted 7 lines
will lead to a
WARN_ON()in notify change, becausei_mutexis not held, and we get tonotify_changevia suid removal with onlyXFS_IOLOCK_SHAREDheld, i.e. noi_mutex.Upgrade the lock to
XFS_IOLOCK_EXCLin this case.Signed-off-by Eric Sandeen <[email protected]>
I believe Jan Kara has already addressed this problem in this patchset:
http://oss.sgi.com/archives/xfs/2015-03/msg00051.html
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
On 3/6/15 4:09 PM, Dave Chinner wrote:
...
Quoted 8 lines
Quoted 3 lines
Upgrade the lock to
XFS_IOLOCK_EXCLin this case.Signed-off-by Eric Sandeen <[email protected]>I believe Jan Kara has already addressed this problem in this patchset:
Ah, yes, that should fix it. Thanks Jan.
Sorry for missing it.
-Eric
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 19 lines · Dave Chinner
Quoted 18 lines · Eric Sandeen
This sequence:
# rm -f sparsefile # truncate --size=1m sparsefile # chmod ugo+rws sparsefile # ls -l sparsefile -rwSrwSrw-. 1 root root 1048576 Mar 6 10:29 sparsefile # su tester$ xfs_io -d -c "pwrite 0 4096" sparsefile wrote 4096/4096 bytes at offset 0 4 KiB, 1 ops; 0.0000 sec (21.505 KiB/sec and 5.3763 ops/sec) $ exitwill lead to a
WARN_ON()in notify change, becausei_mutexis not held, and we get tonotify_changevia suid removal with onlyXFS_IOLOCK_SHAREDheld, i.e. noi_mutex.
Quoted 8 lines
Quoted 3 lines
Upgrade the lock to
XFS_IOLOCK_EXCLin this case.Signed-off-by Eric Sandeen <[email protected]>I believe Jan Kara has already addressed this problem in this patchset:
Seems like that patchset never made it anywhere, though, so this is still an outstanding problem. :(
-Eric
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 24 lines · Eric Sandeen
Quoted 23 lines · Dave Chinner
Quoted 21 lines · Eric Sandeen
This sequence:
# rm -f sparsefile # truncate --size=1m sparsefile # chmod ugo+rws sparsefile # ls -l sparsefile -rwSrwSrw-. 1 root root 1048576 Mar 6 10:29 sparsefile # su tester$ xfs_io -d -c "pwrite 0 4096" sparsefile wrote 4096/4096 bytes at offset 0 4 KiB, 1 ops; 0.0000 sec (21.505 KiB/sec and 5.3763 ops/sec) $ exitwill lead to a
WARN_ON()in notify change, becausei_mutexis not held, and we get tonotify_changevia suid removal with onlyXFS_IOLOCK_SHAREDheld, i.e. noi_mutex.Upgrade the lock to
XFS_IOLOCK_EXCLin this case.Signed-off-by Eric Sandeen <[email protected]>
Quoted 7 lines
Quoted 4 lines
I believe Jan Kara has already addressed this problem in this patchset:
Seems like that patchset never made it anywhere, though, so this is still an outstanding problem. :(
Al just merged the patch set during this merge window. Hurray!
Honza
Signature · 7 lines
Jan Kara <[email protected]> SUSE Labs, CR _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs