| Summary: | Missing recvmsg syscall in freebsd32 API causes sshd crash on amd64 | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Phil Regnauld <pr-gnats> |
| Component: | amd64 | Assignee: | freebsd-amd64 (Nobody) <amd64> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 5.4-STABLE | ||
| Hardware: | Any | ||
| OS: | Any | ||
I haven't tested it on amd64 at all (hopefully the freebsd32 part compiles :-P), but here is a patch to add a kern_recvit() function and use it to implement freebsd32_recvmsg(). Note that I'm not sure that some other functions like sendmsg() actually work correctly for freebsd32 as they are copying in a 32-bit msghdr and expecting it to be a 64-bit msghdr. http://www.FreeBSD.org/~jhb/patches/freebsd32_recvmsg.patch -- John Baldwin <jhb@FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/ "Power Users Use the Power to Serve" = http://www.FreeBSD.org State Changed From-To: open->closed ps@ just committed an enhanced (and tested!) update of my patch that mostly fixes recvmsg(), recvfrom(), and sendmsg() for freebsd32 emulation. The fixes are in HEAD and are likely too late for 6.0, but will probably be merged back to 6.x before 6.1. John Baldwin <jhb@FreeBSD.org> wrote: > > I haven't tested it on amd64 at all (hopefully the freebsd32 part > compiles :-P), but here is a patch to add a kern_recvit() function and use it > to implement freebsd32_recvmsg(). Note that I'm not sure that some other > functions like sendmsg() actually work correctly for freebsd32 as they are > copying in a 32-bit msghdr and expecting it to be a 64-bit msghdr. > > http://www.FreeBSD.org/~jhb/patches/freebsd32_recvmsg.patch Hi there, Didn't get to test on HEAD yet... I am attempting to patch 6.0 first (that's what I run on the production box). It fails there -- is it easily fixable or should I just drop it and try -CURRENT ? During kernel build: cc -c -O2 -frename-registers -pipe -fno-strict-aliasing -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual -fformat-extensions -std=c99 -nostdinc -I- -I. -I../../.. -I../../../contrib/dev/acpica -I../../../contrib/altq -I../../../contrib/ipfilter -I../../../contrib/pf -I../../../contrib/dev/ath -I../../../contrib/dev/ath/freebsd -I../../../contrib/ngatm -I../../../dev/twa -D_KERNEL -DHAVE_KERNEL_OPTION_HEADERS -include opt_global.h -f no-common -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000 -mcmodel=kernel -mno-red-zone -mfpmath=387 -mno-sse -mno-sse2 -mno-mmx -mno-3dnow -msoft-float -fno-asynchronous-unwind-tables -ffreestanding -Werror ../../../compat/freebsd32/freebsd32_misc.c ../../../compat/freebsd32/freebsd32_misc.c: In function `freebsd32_copyiniov': ../../../compat/freebsd32/freebsd32_misc.c:820: error: request for member `iov_base' in something not a structure or union ../../../compat/freebsd32/freebsd32_misc.c:821: error: request for member `iov_len' in something not a structure or union ../../../compat/freebsd32/freebsd32_misc.c: In function `freebsd32_copyinmsghdr': ../../../compat/freebsd32/freebsd32_misc.c:855: warning: passing arg 1 of `freebsd32_copyiniov' makes pointer from integer without a cast ../../../compat/freebsd32/freebsd32_misc.c: In function `freebsd32_copyoutmsghdr': ../../../compat/freebsd32/freebsd32_misc.c:870: error: `error' undeclared (first use in this function) ../../../compat/freebsd32/freebsd32_misc.c:870: error: (Each undeclared identifier is reported only once ../../../compat/freebsd32/freebsd32_misc.c:870: error: for each function it appears in.) ../../../compat/freebsd32/freebsd32_misc.c: At top level: ../../../compat/freebsd32/freebsd32_misc.c:877: warning: function declaration isn't a prototype ../../../compat/freebsd32/freebsd32_misc.c: In function `freebsd32_recvmsg': ../../../compat/freebsd32/freebsd32_misc.c:889: error: dereferencing pointer to incomplete type ../../../compat/freebsd32/freebsd32_misc.c:892: error: invalid type argument of `->' ../../../compat/freebsd32/freebsd32_misc.c:893: error: invalid type argument of `->' ../../../compat/freebsd32/freebsd32_misc.c:896: error: dereferencing pointer to incomplete type ../../../compat/freebsd32/freebsd32_misc.c:899: error: dereferencing pointer to incomplete type ../../../compat/freebsd32/freebsd32_misc.c:902: error: dereferencing pointer to incomplete type ../../../compat/freebsd32/freebsd32_misc.c:884: warning: unused variable `msg32' -- _ _ |_ | regnauld@catpipe.net catpipe Systems ApS | (_(_||_ | *BSD solutions, consulting, development | | Tlf.: +45 7021 0050 http://www.catpipe.net/ | |
recvmsg(2) is not implemented in the freebsd32 compatibility layer. From /sys/compat/freebsd32/syscalls.master: ; XXX implement 27 AUE_NULL UNIMPL recvmsg This is a problem when trying to run, among others sshd from i386/4-STABLE or 5-STABLE (for example in a jail): if privilege separation (the default) is used, then recvmsg is called by the child after the fork. The missing syscall causes a termination of sshd with SIGSYS (12): 14143 sshd CALL recvmsg 14143 sshd RET recvmsg -1 errno 78 Function not implemented [...] 14143 sshd PSIG SIGSYS SIG_DFL This is a problem as both i386 and amd64 are Tier 1 platforms, and the non availability of recvmsg() can be a problem for many applications. Fix: No known fix. In the case of sshd, disable privilege separation in /etc/ssh/sshd_config (not necessary if logging in as root). How-To-Repeat: Compile the following statically on 5.x/i386 or 4.x/i386 system and execute on an amd64 system with "options COMPAT_IA32" in the kernel. #include <sys/types.h> #include <sys/socket.h> #include <err.h> #include <stdio.h> int main(void) { fprintf(stderr, "moo1\n"); recvmsg(0, 0, 0); fprintf(stderr, "moo2\n"); err(1, "moo"); return 0; }