diff options
author | Christoph Hellwig <hch@infradead.org> | 2010-02-03 14:43:31 -0500 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2010-02-12 14:43:57 -0500 |
commit | 87185517de81101da5afbc82cefdeed6eeaa38fb (patch) | |
tree | 29cb781d74d5e81d941e1a913222de90f6266477 /fs/xfs | |
parent | 5322892d867e186c6b4c5fff5c99ea4863696a60 (diff) |
xfs: only clear the suid bit once in xfs_write
file_remove_suid already calls into ->setattr to clear the suid and
sgid bits if needed, no need to start a second transaction to do it
ourselves.
Note that xfs_write_clear_setuid issues a sync transaction while the
path through ->setattr doesn't, but that is consistant with the
other filesystems.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Alex Elder <aelder@sgi.com>
Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.c | 15 | ||||
-rw-r--r-- | fs/xfs/xfs_rw.c | 42 | ||||
-rw-r--r-- | fs/xfs/xfs_rw.h | 1 |
3 files changed, 3 insertions, 55 deletions
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index c80fa00d2ad7..eac6f80d786d 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -630,18 +630,9 @@ start: | |||
630 | * by root. This keeps people from modifying setuid and | 630 | * by root. This keeps people from modifying setuid and |
631 | * setgid binaries. | 631 | * setgid binaries. |
632 | */ | 632 | */ |
633 | 633 | error = -file_remove_suid(file); | |
634 | if (((xip->i_d.di_mode & S_ISUID) || | 634 | if (unlikely(error)) |
635 | ((xip->i_d.di_mode & (S_ISGID | S_IXGRP)) == | 635 | goto out_unlock_internal; |
636 | (S_ISGID | S_IXGRP))) && | ||
637 | !capable(CAP_FSETID)) { | ||
638 | error = xfs_write_clear_setuid(xip); | ||
639 | if (likely(!error)) | ||
640 | error = -file_remove_suid(file); | ||
641 | if (unlikely(error)) { | ||
642 | goto out_unlock_internal; | ||
643 | } | ||
644 | } | ||
645 | 636 | ||
646 | /* We can write back this queue in page reclaim */ | 637 | /* We can write back this queue in page reclaim */ |
647 | current->backing_dev_info = mapping->backing_dev_info; | 638 | current->backing_dev_info = mapping->backing_dev_info; |
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c index abb2c458b148..e336742a58a4 100644 --- a/fs/xfs/xfs_rw.c +++ b/fs/xfs/xfs_rw.c | |||
@@ -47,48 +47,6 @@ | |||
47 | #include "xfs_trace.h" | 47 | #include "xfs_trace.h" |
48 | 48 | ||
49 | /* | 49 | /* |
50 | * This is a subroutine for xfs_write() and other writers (xfs_ioctl) | ||
51 | * which clears the setuid and setgid bits when a file is written. | ||
52 | */ | ||
53 | int | ||
54 | xfs_write_clear_setuid( | ||
55 | xfs_inode_t *ip) | ||
56 | { | ||
57 | xfs_mount_t *mp; | ||
58 | xfs_trans_t *tp; | ||
59 | int error; | ||
60 | |||
61 | mp = ip->i_mount; | ||
62 | tp = xfs_trans_alloc(mp, XFS_TRANS_WRITEID); | ||
63 | if ((error = xfs_trans_reserve(tp, 0, | ||
64 | XFS_WRITEID_LOG_RES(mp), | ||
65 | 0, 0, 0))) { | ||
66 | xfs_trans_cancel(tp, 0); | ||
67 | return error; | ||
68 | } | ||
69 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
70 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
71 | xfs_trans_ihold(tp, ip); | ||
72 | ip->i_d.di_mode &= ~S_ISUID; | ||
73 | |||
74 | /* | ||
75 | * Note that we don't have to worry about mandatory | ||
76 | * file locking being disabled here because we only | ||
77 | * clear the S_ISGID bit if the Group execute bit is | ||
78 | * on, but if it was on then mandatory locking wouldn't | ||
79 | * have been enabled. | ||
80 | */ | ||
81 | if (ip->i_d.di_mode & S_IXGRP) { | ||
82 | ip->i_d.di_mode &= ~S_ISGID; | ||
83 | } | ||
84 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
85 | xfs_trans_set_sync(tp); | ||
86 | error = xfs_trans_commit(tp, 0); | ||
87 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * Force a shutdown of the filesystem instantly while keeping | 50 | * Force a shutdown of the filesystem instantly while keeping |
93 | * the filesystem consistent. We don't do an unmount here; just shutdown | 51 | * the filesystem consistent. We don't do an unmount here; just shutdown |
94 | * the shop, make sure that absolutely nothing persistent happens to | 52 | * the shop, make sure that absolutely nothing persistent happens to |
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h index a54c3b7cd376..11c41ec6ed75 100644 --- a/fs/xfs/xfs_rw.h +++ b/fs/xfs/xfs_rw.h | |||
@@ -39,7 +39,6 @@ xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb) | |||
39 | /* | 39 | /* |
40 | * Prototypes for functions in xfs_rw.c. | 40 | * Prototypes for functions in xfs_rw.c. |
41 | */ | 41 | */ |
42 | extern int xfs_write_clear_setuid(struct xfs_inode *ip); | ||
43 | extern int xfs_read_buf(struct xfs_mount *mp, xfs_buftarg_t *btp, | 42 | extern int xfs_read_buf(struct xfs_mount *mp, xfs_buftarg_t *btp, |
44 | xfs_daddr_t blkno, int len, uint flags, | 43 | xfs_daddr_t blkno, int len, uint flags, |
45 | struct xfs_buf **bpp); | 44 | struct xfs_buf **bpp); |