aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/attr.c9
-rw-r--r--fs/nfsd/vfs.c4
-rw-r--r--fs/open.c3
-rw-r--r--fs/splice.c13
4 files changed, 22 insertions, 7 deletions
diff --git a/fs/attr.c b/fs/attr.c
index f8dfc2269d85..ae58bd3f875f 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -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:
937static void kill_suid(struct dentry *dentry) 937static 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);
diff --git a/fs/open.c b/fs/open.c
index cdbb94a9efc2..75385144df7d 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -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;