|
@@ -2814,16 +2814,22 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir)
|
|
|
* 1. We can't do it if child already exists (open has special treatment for
|
|
|
* this case, but since we are inlined it's OK)
|
|
|
* 2. We can't do it if dir is read-only (done in permission())
|
|
|
- * 3. We should have write and exec permissions on dir
|
|
|
- * 4. We can't do it if dir is immutable (done in permission())
|
|
|
+ * 3. We can't do it if the fs can't represent the fsuid or fsgid.
|
|
|
+ * 4. We should have write and exec permissions on dir
|
|
|
+ * 5. We can't do it if dir is immutable (done in permission())
|
|
|
*/
|
|
|
static inline int may_create(struct inode *dir, struct dentry *child)
|
|
|
{
|
|
|
+ struct user_namespace *s_user_ns;
|
|
|
audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE);
|
|
|
if (child->d_inode)
|
|
|
return -EEXIST;
|
|
|
if (IS_DEADDIR(dir))
|
|
|
return -ENOENT;
|
|
|
+ s_user_ns = dir->i_sb->s_user_ns;
|
|
|
+ if (!kuid_has_mapping(s_user_ns, current_fsuid()) ||
|
|
|
+ !kgid_has_mapping(s_user_ns, current_fsgid()))
|
|
|
+ return -EOVERFLOW;
|
|
|
return inode_permission(dir, MAY_WRITE | MAY_EXEC);
|
|
|
}
|
|
|
|