|
@@ -47,7 +47,7 @@ int setattr_prepare(struct dentry *dentry, struct iattr *attr)
|
|
|
|
|
|
/* If force is set do it anyway. */
|
|
|
if (ia_valid & ATTR_FORCE)
|
|
|
- return 0;
|
|
|
+ goto kill_priv;
|
|
|
|
|
|
/* Make sure a caller can chown. */
|
|
|
if ((ia_valid & ATTR_UID) &&
|
|
@@ -80,6 +80,16 @@ int setattr_prepare(struct dentry *dentry, struct iattr *attr)
|
|
|
return -EPERM;
|
|
|
}
|
|
|
|
|
|
+kill_priv:
|
|
|
+ /* User has permission for the change */
|
|
|
+ if (ia_valid & ATTR_KILL_PRIV) {
|
|
|
+ int error;
|
|
|
+
|
|
|
+ error = security_inode_killpriv(dentry);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL(setattr_prepare);
|
|
@@ -220,13 +230,11 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
|
|
|
if (!(ia_valid & ATTR_MTIME_SET))
|
|
|
attr->ia_mtime = now;
|
|
|
if (ia_valid & ATTR_KILL_PRIV) {
|
|
|
- attr->ia_valid &= ~ATTR_KILL_PRIV;
|
|
|
- ia_valid &= ~ATTR_KILL_PRIV;
|
|
|
error = security_inode_need_killpriv(dentry);
|
|
|
- if (error > 0)
|
|
|
- error = security_inode_killpriv(dentry);
|
|
|
- if (error)
|
|
|
+ if (error < 0)
|
|
|
return error;
|
|
|
+ if (error == 0)
|
|
|
+ ia_valid = attr->ia_valid &= ~ATTR_KILL_PRIV;
|
|
|
}
|
|
|
|
|
|
/*
|