[RFC PATCH v2 9/9] um: pass FD for memory operations when needed

Tiwei Bie tiwei.btw at antgroup.com
Thu Oct 24 06:52:37 PDT 2024


On 2024/10/23 22:08, Benjamin Berg wrote:
[...]
> diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
> index c663b67c3fd3..a29957e021f3 100644
> --- a/arch/um/os-Linux/skas/process.c
> +++ b/arch/um/os-Linux/skas/process.c
> @@ -16,6 +16,7 @@
>  #include <sys/mman.h>
>  #include <sys/wait.h>
>  #include <sys/stat.h>
> +#include <sys/socket.h>
>  #include <asm/unistd.h>
>  #include <as-layout.h>
>  #include <init.h>
> @@ -153,7 +154,39 @@ void wait_stub_done_seccomp(struct mm_id *mm_idp, int running, int wait_sigsys)
>  	int ret;
>  
>  	do {
> +		const char byte = 0;
> +		struct iovec iov = {
> +			.iov_base = (void *)&byte,
> +			.iov_len = sizeof(byte),
> +		};
> +		union {
> +			char data[CMSG_SPACE(sizeof(mm_idp->syscall_fd_map))];
> +			struct cmsghdr align;
> +		} ctrl;
> +		struct msghdr msgh = {
> +			.msg_iov = &iov,
> +			.msg_iovlen = 1,
> +		};
> +
>  		if (!running) {
> +			if (mm_idp->syscall_fd_num) {
> +				unsigned int fds_size =
> +					sizeof(int) * mm_idp->syscall_fd_num;
> +				struct cmsghdr *cmsg;
> +
> +				msgh.msg_control = ctrl.data;
> +				msgh.msg_controllen = CMSG_SPACE(fds_size);
> +				cmsg = CMSG_FIRSTHDR(&msgh);
> +				cmsg->cmsg_level = SOL_SOCKET;
> +				cmsg->cmsg_type = SCM_RIGHTS;
> +				cmsg->cmsg_len = CMSG_LEN(fds_size);
> +				memcpy(CMSG_DATA(cmsg), mm_idp->syscall_fd_map,
> +				       fds_size);

It looks the memcpy could trigger a crash when UML_SECCOMP is enabled:

Run /sbin/init as init process
*** buffer overflow detected ***: terminated

Thread 1 "linux" received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140737353807680) at ./nptl/pthread_kill.c:44
44      ./nptl/pthread_kill.c: No such file or directory.
(gdb) bt
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737353807680) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=140737353807680) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=140737353807680, signo=signo at entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007ffff7c42476 in __GI_raise (sig=sig at entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff7c287f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x00007ffff7c89676 in __libc_message (action=action at entry=do_abort, fmt=fmt at entry=0x7ffff7ddb92e "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:155
#6  0x00007ffff7d3659a in __GI___fortify_fail (msg=msg at entry=0x7ffff7ddb8d4 "buffer overflow detected") at ./debug/fortify_fail.c:26
#7  0x00007ffff7d34f16 in __GI___chk_fail () at ./debug/chk_fail.c:28
#8  0x00000000600376ee in memcpy (__len=4, __src=<optimized out>, __dest=0xe0803e60) at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:29
#9  wait_stub_done_seccomp (mm_idp=mm_idp at entry=0x608e69e0, running=<optimized out>, running at entry=0, wait_sigsys=wait_sigsys at entry=0) at arch/um/os-Linux/skas/process.c:183
#10 0x0000000060037cc6 in userspace (regs=0x60828788) at arch/um/os-Linux/skas/process.c:605
#11 0x00000000600228c1 in new_thread_handler () at arch/um/kernel/process.c:119

It can be fixed with changes like below on my machine:

diff --git a/arch/um/include/shared/skas/mm_id.h b/arch/um/include/shared/skas/mm_id.h
index f2d4c383c958..26d922443454 100644
--- a/arch/um/include/shared/skas/mm_id.h
+++ b/arch/um/include/shared/skas/mm_id.h
@@ -6,6 +6,8 @@
 #ifndef __MM_ID_H
 #define __MM_ID_H
 
+#include <linux/kconfig.h>
+
 #ifdef CONFIG_UML_SECCOMP
 #define STUB_MAX_FDS 4
 #else

Regards,
Tiwei



More information about the linux-um mailing list