Skip to content

Commit 5820f14

Browse files
thejhebiederm
authored andcommitted
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: 22d917d ("userns: Rework the user_namespace adding uid/gid...") Cc: [email protected] Signed-off-by: Jann Horn <[email protected]> Acked-by: Christian Brauner <[email protected]> Acked-by: Serge Hallyn <[email protected]> Signed-off-by: Eric W. Biederman <[email protected]>
1 parent 355139a commit 5820f14

File tree

1 file changed

+10
-14
lines changed

1 file changed

+10
-14
lines changed

kernel/user_namespace.c

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,16 @@ static ssize_t map_write(struct file *file, const char __user *buf,
859859
unsigned idx;
860860
struct uid_gid_extent extent;
861861
char *kbuf = NULL, *pos, *next_line;
862-
ssize_t ret = -EINVAL;
862+
ssize_t ret;
863+
864+
/* Only allow < page size writes at the beginning of the file */
865+
if ((*ppos != 0) || (count >= PAGE_SIZE))
866+
return -EINVAL;
867+
868+
/* Slurp in the user data */
869+
kbuf = memdup_user_nul(buf, count);
870+
if (IS_ERR(kbuf))
871+
return PTR_ERR(kbuf);
863872

864873
/*
865874
* 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,
895904
if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
896905
goto out;
897906

898-
/* Only allow < page size writes at the beginning of the file */
899-
ret = -EINVAL;
900-
if ((*ppos != 0) || (count >= PAGE_SIZE))
901-
goto out;
902-
903-
/* Slurp in the user data */
904-
kbuf = memdup_user_nul(buf, count);
905-
if (IS_ERR(kbuf)) {
906-
ret = PTR_ERR(kbuf);
907-
kbuf = NULL;
908-
goto out;
909-
}
910-
911907
/* Parse the user data */
912908
ret = -EINVAL;
913909
pos = kbuf;

0 commit comments

Comments
 (0)