|
@@ -2711,12 +2711,18 @@ static int selinux_inode_permission(struct inode *inode, int mask)
|
|
|
static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
|
|
|
{
|
|
|
const struct cred *cred = current_cred();
|
|
|
+ unsigned int ia_valid = iattr->ia_valid;
|
|
|
+
|
|
|
+ /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */
|
|
|
+ if (ia_valid & ATTR_FORCE) {
|
|
|
+ ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_MODE |
|
|
|
+ ATTR_FORCE);
|
|
|
+ if (!ia_valid)
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
|
|
|
- if (iattr->ia_valid & ATTR_FORCE)
|
|
|
- return 0;
|
|
|
-
|
|
|
- if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
|
|
|
- ATTR_ATIME_SET | ATTR_MTIME_SET))
|
|
|
+ if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
|
|
|
+ ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
|
|
|
return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR);
|
|
|
|
|
|
return dentry_has_perm(cred, NULL, dentry, FILE__WRITE);
|