qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] linux-user/syscall: zero-init msghdr in do_sendrecvmsg_locke


From: Laurent Vivier
Subject: Re: [PATCH] linux-user/syscall: zero-init msghdr in do_sendrecvmsg_locked
Date: Sun, 20 Jun 2021 18:45:28 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0

Le 20/06/2021 à 17:09, Kenta Iwasaki a écrit :
> No worries, though I would also like to apologize as I find that the 
> explanation I gave in my last
> email was a little all over the place.
> 
> To clarify my last e-mail, I believe the current msghdr struct layout in QEMU 
> is libc-agnostic, but
> not kernel agnostic. Rather, the current msghdr struct layout defined in QEMU 
> follows the definition
> of the Linux kernel's own struct layout of msghdr, which isn't compliant with 
> POSIX.
> 
> Zeroing the bytes in the patch I provided, which is a trick used in musl libc 
> as well to be both
> kernel-agnostic and libc-agnostic, would make QEMU's struct layout definition 
> of msghdr be both
> kernel-agnostic to all kernels adhering to the POSIX standard, and 
> libc-agnostic as well.

Yes, linux-user is not kernel agnostic. It's why I would prefer to define a 
"host_msghdr"  and use
it as a parameter to the host outgoing syscall (we already define 
"target_msghdr" for target
incoming syscall). host_msghdr would be a copy of kernel user_msghdr.

But what do you mean by "all kernels": do we have linux kernels that use a 
different msghdr
definition (POSIX one)?

Thanks,
Laurent

> Best regards,
> Kenta Iwasaki
> 
> On Sun, 20 Jun 2021 at 23:56, Laurent Vivier <laurent@vivier.eu 
> <mailto:laurent@vivier.eu>> wrote:
> 
>     Le 16/05/2021 à 14:57, Kenta Iwasaki a écrit :
>     > Sure,
>     >
>     > The bytes of `msghdr` need to be cleared because the `msghdr` struct 
> layout specified in QEMU
>     > appears to generalize between the definitions of `msghdr` across 
> different libc's and kernels. To
>     > appropriately generalize `msghdr` across libc's and kernels would 
> either:
>     >
>     > 1. require specializing code in do_sendrecvmsg_locked() for each 
> individual libc and kernel
>     version, or
>     > 2. zeroing out all bytes of `msghdr`, b/c certain libc or kernel 
> versions may misinterpret the
>     > undefined padding bytes that come from misalignment in the struct as 
> actual syscall params.
>     >
>     > The patch I provided would be going for route #2, given that it's a 
> simpler fix for the underlying
>     > problem for the short term.
>     >
>     > What I believe is the background behind why the struct layout has been 
> a problem is because, since
>     > the beginning, the Linux kernel has always specified the layout of 
> `msghdr` differently from
>     POSIX.
>     > Given that this implies incompatibility between kernels on how `msghdr` 
> is specified,
>     different libc
>     > projects such as musl and glibc provide different workarounds by laying 
> out `msghdr` differently
>     > amongst one another.
>     >
>     > A few projects running tests/applications through QEMU have been bitten 
> by this, and a
>     solution that
>     > one of the projects discovered was that patching QEMU to 
> zero-initialize the bytes msghdr the same
>     > way my patch does allow for compatibility between different `msghdr` 
> layouts across glibc,
>     musl, and
>     > the Linux kernel:
>     
> https://github.com/void-linux/void-packages/issues/23557#issuecomment-718392360
>     
> <https://github.com/void-linux/void-packages/issues/23557#issuecomment-718392360>
>     > 
> <https://github.com/void-linux/void-packages/issues/23557#issuecomment-718392360
>     
> <https://github.com/void-linux/void-packages/issues/23557#issuecomment-718392360>>
>     >
>     > For some additional useful context, here's a link pointing changes musl 
> libc made to laying out
>     > `msghdr` b/c of Linux incorrectly laying out `msghdr` against the POSIX 
> standard:
>     > 
> http://git.musl-libc.org/cgit/musl/commit/?id=7168790763cdeb794df52be6e3b39fbb021c5a64
>     
> <http://git.musl-libc.org/cgit/musl/commit/?id=7168790763cdeb794df52be6e3b39fbb021c5a64>
>     > 
> <http://git.musl-libc.org/cgit/musl/commit/?id=7168790763cdeb794df52be6e3b39fbb021c5a64
>     
> <http://git.musl-libc.org/cgit/musl/commit/?id=7168790763cdeb794df52be6e3b39fbb021c5a64>>
>     >
>     > Also, here is a link to the `msghdr` struct layout in musl libc's 
> bleeding edge branch as of
>     > now: https://git.musl-libc.org/cgit/musl/tree/include/sys/socket.h#n22
>     <https://git.musl-libc.org/cgit/musl/tree/include/sys/socket.h#n22>
>     > <https://git.musl-libc.org/cgit/musl/tree/include/sys/socket.h#n22
>     <https://git.musl-libc.org/cgit/musl/tree/include/sys/socket.h#n22>>
>     >
>     > As for my rationale for sending in this patch, it is because I'm 
> currently implementing
>     > cross-platform networking in the standard library for the Zig 
> programming language, and have run
>     > into this exact same problem with EMSGSIZE being returned by sendmsg() 
> when tests are run through
>     > QEMU on x86_64-linux-musl.
>     >
>     > My discussions with the Zig community about it alongside debug logs 
> regarding the exact parameters
>     > being fed to the sendmsg() syscall can be found
>     > here: https://github.com/ziglang/zig/pull/8750#issuecomment-841641576
>     <https://github.com/ziglang/zig/pull/8750#issuecomment-841641576>
>     > <https://github.com/ziglang/zig/pull/8750#issuecomment-841641576
>     <https://github.com/ziglang/zig/pull/8750#issuecomment-841641576>>
>     >
>     > Hope this gives enough context about the problem and patch, but please 
> do let me know if there is
>     > any more information that I could provide which would help.
> 
>     Thank you for the explanation and sorry for the delay.
> 
>     As we use directly the kernel syscall rather than the libc wrapper we 
> should not use here the msghdr
>     definition from the libc but the one from the kernel.
> 
>     The one we receive is also the one from the kernel as we trap the kernel 
> syscall not the libc call.
> 
>     So the code should be libc-agnostic...
> 
>     The reference implementation in our case is 'struct user_msghdr' from the 
> kernel, and we need to
>     duplicate it in QEMU to be able to use it.
> 
>     Thanks,
>     LAurent
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]