diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/attr.c | 9 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 4 | ||||
-rw-r--r-- | fs/open.c | 3 | ||||
-rw-r--r-- | fs/splice.c | 13 |
4 files changed, 22 insertions, 7 deletions
@@ -116,6 +116,15 @@ int notify_change(struct dentry * dentry, struct iattr * attr) | |||
116 | attr->ia_atime = now; | 116 | attr->ia_atime = now; |
117 | if (!(ia_valid & ATTR_MTIME_SET)) | 117 | if (!(ia_valid & ATTR_MTIME_SET)) |
118 | attr->ia_mtime = now; | 118 | attr->ia_mtime = now; |
119 | if (ia_valid & ATTR_KILL_PRIV) { | ||
120 | attr->ia_valid &= ~ATTR_KILL_PRIV; | ||
121 | ia_valid &= ~ATTR_KILL_PRIV; | ||
122 | error = security_inode_need_killpriv(dentry); | ||
123 | if (error > 0) | ||
124 | error = security_inode_killpriv(dentry); | ||
125 | if (error) | ||
126 | return error; | ||
127 | } | ||
119 | if (ia_valid & ATTR_KILL_SUID) { | 128 | if (ia_valid & ATTR_KILL_SUID) { |
120 | attr->ia_valid &= ~ATTR_KILL_SUID; | 129 | attr->ia_valid &= ~ATTR_KILL_SUID; |
121 | if (mode & S_ISUID) { | 130 | if (mode & S_ISUID) { |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 1d72f993b66e..819545d21670 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -368,7 +368,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, | |||
368 | 368 | ||
369 | /* Revoke setuid/setgid bit on chown/chgrp */ | 369 | /* Revoke setuid/setgid bit on chown/chgrp */ |
370 | if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) | 370 | if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) |
371 | iap->ia_valid |= ATTR_KILL_SUID; | 371 | iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV; |
372 | if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) | 372 | if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) |
373 | iap->ia_valid |= ATTR_KILL_SGID; | 373 | iap->ia_valid |= ATTR_KILL_SGID; |
374 | 374 | ||
@@ -937,7 +937,7 @@ out: | |||
937 | static void kill_suid(struct dentry *dentry) | 937 | static void kill_suid(struct dentry *dentry) |
938 | { | 938 | { |
939 | struct iattr ia; | 939 | struct iattr ia; |
940 | ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID; | 940 | ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; |
941 | 941 | ||
942 | mutex_lock(&dentry->d_inode->i_mutex); | 942 | mutex_lock(&dentry->d_inode->i_mutex); |
943 | notify_change(dentry, &ia); | 943 | notify_change(dentry, &ia); |
@@ -658,7 +658,8 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group) | |||
658 | newattrs.ia_gid = group; | 658 | newattrs.ia_gid = group; |
659 | } | 659 | } |
660 | if (!S_ISDIR(inode->i_mode)) | 660 | if (!S_ISDIR(inode->i_mode)) |
661 | newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID; | 661 | newattrs.ia_valid |= |
662 | ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; | ||
662 | mutex_lock(&inode->i_mutex); | 663 | mutex_lock(&inode->i_mutex); |
663 | error = notify_change(dentry, &newattrs); | 664 | error = notify_change(dentry, &newattrs); |
664 | mutex_unlock(&inode->i_mutex); | 665 | mutex_unlock(&inode->i_mutex); |
diff --git a/fs/splice.c b/fs/splice.c index 59a941d404d9..6bdcb6107bc3 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -824,13 +824,18 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
824 | { | 824 | { |
825 | struct address_space *mapping = out->f_mapping; | 825 | struct address_space *mapping = out->f_mapping; |
826 | struct inode *inode = mapping->host; | 826 | struct inode *inode = mapping->host; |
827 | int killsuid, killpriv; | ||
827 | ssize_t ret; | 828 | ssize_t ret; |
828 | int err; | 829 | int err = 0; |
829 | 830 | ||
830 | err = should_remove_suid(out->f_path.dentry); | 831 | killpriv = security_inode_need_killpriv(out->f_path.dentry); |
831 | if (unlikely(err)) { | 832 | killsuid = should_remove_suid(out->f_path.dentry); |
833 | if (unlikely(killsuid || killpriv)) { | ||
832 | mutex_lock(&inode->i_mutex); | 834 | mutex_lock(&inode->i_mutex); |
833 | err = __remove_suid(out->f_path.dentry, err); | 835 | if (killpriv) |
836 | err = security_inode_killpriv(out->f_path.dentry); | ||
837 | if (!err && killsuid) | ||
838 | err = __remove_suid(out->f_path.dentry, killsuid); | ||
834 | mutex_unlock(&inode->i_mutex); | 839 | mutex_unlock(&inode->i_mutex); |
835 | if (err) | 840 | if (err) |
836 | return err; | 841 | return err; |