Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5820f140 authored by Jann Horn's avatar Jann Horn Committed by Eric W. Biederman
Browse files

userns: move user access out of the mutex



The old code would hold the userns_state_mutex indefinitely if
memdup_user_nul stalled due to e.g. a userfault region. Prevent that by
moving the memdup_user_nul in front of the mutex_lock().

Note: This changes the error precedence of invalid buf/count/*ppos vs
map already written / capabilities missing.

Fixes: 22d917d8 ("userns: Rework the user_namespace adding uid/gid...")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarJann Horn <jannh@google.com>
Acked-by: default avatarChristian Brauner <christian@brauner.io>
Acked-by: default avatarSerge Hallyn <serge@hallyn.com>
Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
parent 355139a8
Loading
Loading
Loading
Loading
+10 −14
Original line number Diff line number Diff line
@@ -859,7 +859,16 @@ static ssize_t map_write(struct file *file, const char __user *buf,
	unsigned idx;
	struct uid_gid_extent extent;
	char *kbuf = NULL, *pos, *next_line;
	ssize_t ret = -EINVAL;
	ssize_t ret;

	/* Only allow < page size writes at the beginning of the file */
	if ((*ppos != 0) || (count >= PAGE_SIZE))
		return -EINVAL;

	/* Slurp in the user data */
	kbuf = memdup_user_nul(buf, count);
	if (IS_ERR(kbuf))
		return PTR_ERR(kbuf);

	/*
	 * The userns_state_mutex serializes all writes to any given map.
@@ -895,19 +904,6 @@ static ssize_t map_write(struct file *file, const char __user *buf,
	if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
		goto out;

	/* Only allow < page size writes at the beginning of the file */
	ret = -EINVAL;
	if ((*ppos != 0) || (count >= PAGE_SIZE))
		goto out;

	/* Slurp in the user data */
	kbuf = memdup_user_nul(buf, count);
	if (IS_ERR(kbuf)) {
		ret = PTR_ERR(kbuf);
		kbuf = NULL;
		goto out;
	}

	/* Parse the user data */
	ret = -EINVAL;
	pos = kbuf;