|
@@ -410,6 +410,14 @@ int __inode_permission(struct inode *inode, int mask)
|
|
|
*/
|
|
|
if (IS_IMMUTABLE(inode))
|
|
|
return -EACCES;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Updating mtime will likely cause i_uid and i_gid to be
|
|
|
+ * written back improperly if their true value is unknown
|
|
|
+ * to the vfs.
|
|
|
+ */
|
|
|
+ if (HAS_UNMAPPED_ID(inode))
|
|
|
+ return -EACCES;
|
|
|
}
|
|
|
|
|
|
retval = do_inode_permission(inode, mask);
|
|
@@ -2759,10 +2767,11 @@ EXPORT_SYMBOL(__check_sticky);
|
|
|
* c. have CAP_FOWNER capability
|
|
|
* 6. If the victim is append-only or immutable we can't do antyhing with
|
|
|
* links pointing to it.
|
|
|
- * 7. If we were asked to remove a directory and victim isn't one - ENOTDIR.
|
|
|
- * 8. If we were asked to remove a non-directory and victim isn't one - EISDIR.
|
|
|
- * 9. We can't remove a root or mountpoint.
|
|
|
- * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
|
|
|
+ * 7. If the victim has an unknown uid or gid we can't change the inode.
|
|
|
+ * 8. If we were asked to remove a directory and victim isn't one - ENOTDIR.
|
|
|
+ * 9. If we were asked to remove a non-directory and victim isn't one - EISDIR.
|
|
|
+ * 10. We can't remove a root or mountpoint.
|
|
|
+ * 11. We don't allow removal of NFS sillyrenamed files; it's handled by
|
|
|
* nfs_async_unlink().
|
|
|
*/
|
|
|
static int may_delete(struct inode *dir, struct dentry *victim, bool isdir)
|
|
@@ -2784,7 +2793,7 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir)
|
|
|
return -EPERM;
|
|
|
|
|
|
if (check_sticky(dir, inode) || IS_APPEND(inode) ||
|
|
|
- IS_IMMUTABLE(inode) || IS_SWAPFILE(inode))
|
|
|
+ IS_IMMUTABLE(inode) || IS_SWAPFILE(inode) || HAS_UNMAPPED_ID(inode))
|
|
|
return -EPERM;
|
|
|
if (isdir) {
|
|
|
if (!d_is_dir(victim))
|
|
@@ -4190,6 +4199,13 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
|
|
|
*/
|
|
|
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
|
|
|
return -EPERM;
|
|
|
+ /*
|
|
|
+ * Updating the link count will likely cause i_uid and i_gid to
|
|
|
+ * be writen back improperly if their true value is unknown to
|
|
|
+ * the vfs.
|
|
|
+ */
|
|
|
+ if (HAS_UNMAPPED_ID(inode))
|
|
|
+ return -EPERM;
|
|
|
if (!dir->i_op->link)
|
|
|
return -EPERM;
|
|
|
if (S_ISDIR(inode->i_mode))
|