[Devel,rh7,08/11] ms/vfs: Don't create inodes with a uid or gid unknown to the vfs

Submitted by Konstantin Khorenko on June 22, 2017, 2:47 p.m.

Details

Message ID 1498142878-2222-9-git-send-email-khorenko@virtuozzo.com
State New
Series "Revert "ms/cred: Reject inodes with invalid ids in set_create_file_as()""
Headers show

Commit Message

Konstantin Khorenko June 22, 2017, 2:47 p.m.
From: "Eric W. Biederman" <ebiederm@xmission.com>

It is expected that filesystems can not represent uids and gids from
outside of their user namespace.  Keep things simple by not even
trying to create filesystem nodes with non-sense uids and gids.

Acked-by: Seth Forshee <seth.forshee@canonical.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
(cherry picked from commit 036d523641c66bef713042894a17f4335f199e49)

https://jira.sw.ru/browse/PSBM-40075

Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
 fs/namei.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/namei.c b/fs/namei.c
index 74abaeb..42a0e6b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2636,16 +2636,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);
 }