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 16:56:54 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0

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>
> 
> 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>
> 
> 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>
> 
> 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>
> 
> 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]