Skip to content

Commit f82a9e7

Browse files
benzearichardweinberger
authored andcommitted
um: fix execve stub execution on old host OSs
The stub execution uses the somewhat new close_range and execveat syscalls. Of these two, the execveat call is essential, but the close_range call is more about stub process hygiene rather than safety (and its result is ignored). Replace both calls with a raw syscall as older machines might not have a recent enough kernel for close_range (with CLOSE_RANGE_CLOEXEC) or a libc that does not yet expose both of the syscalls. Fixes: 32e8eaf ("um: use execveat to create userspace MMs") Reported-by: Glenn Washburn <[email protected]> Closes: https://lore.kernel.org/20250108022404.05e0de1e@crass-HP-ZBook-15-G2 Signed-off-by: Benjamin Berg <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Johannes Berg <[email protected]> Signed-off-by: Richard Weinberger <[email protected]>
1 parent 3c2fc74 commit f82a9e7

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

arch/um/os-Linux/skas/process.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ extern char __syscall_stub_start[];
181181

182182
static int stub_exe_fd;
183183

184+
#ifndef CLOSE_RANGE_CLOEXEC
185+
#define CLOSE_RANGE_CLOEXEC (1U << 2)
186+
#endif
187+
184188
static int userspace_tramp(void *stack)
185189
{
186190
char *const argv[] = { "uml-userspace", NULL };
@@ -202,8 +206,12 @@ static int userspace_tramp(void *stack)
202206
init_data.stub_data_fd = phys_mapping(uml_to_phys(stack), &offset);
203207
init_data.stub_data_offset = MMAP_OFFSET(offset);
204208

205-
/* Set CLOEXEC on all FDs and then unset on all memory related FDs */
206-
close_range(0, ~0U, CLOSE_RANGE_CLOEXEC);
209+
/*
210+
* Avoid leaking unneeded FDs to the stub by setting CLOEXEC on all FDs
211+
* and then unsetting it on all memory related FDs.
212+
* This is not strictly necessary from a safety perspective.
213+
*/
214+
syscall(__NR_close_range, 0, ~0U, CLOSE_RANGE_CLOEXEC);
207215

208216
fcntl(init_data.stub_data_fd, F_SETFD, 0);
209217
for (iomem = iomem_regions; iomem; iomem = iomem->next)
@@ -224,7 +232,9 @@ static int userspace_tramp(void *stack)
224232
if (ret != sizeof(init_data))
225233
exit(4);
226234

227-
execveat(stub_exe_fd, "", argv, NULL, AT_EMPTY_PATH);
235+
/* Raw execveat for compatibility with older libc versions */
236+
syscall(__NR_execveat, stub_exe_fd, (unsigned long)"",
237+
(unsigned long)argv, NULL, AT_EMPTY_PATH);
228238

229239
exit(5);
230240
}

0 commit comments

Comments
 (0)