[H.J. Lu Cc'ed as author of what looks like the problematic commit] On Wed, 15 Jul 2020 23:47:27 +0200 (CEST) Thorsten Glaser <t.gla...@tarent.de> wrote: > Some more analysis: > > We enter libc from openssh code with the correct values in rsi and rdi: > > > (gdb) u > => 0x56560e45 <main+12661>: call 0x5655d0b0 <setgroups@plt> > (gdb) info r > rax 0xfffe 65534 > rbx 0x5663a000 1449369600 > rcx 0x0 0 > rdx 0x0 0 > rsi 0xffffd2e0 4294955744 > rdi 0x1 1 > rbp 0x56641b50 1449401168 > rsp 0xffffd260 4294955616 > r8 0x0 0 > r9 0x0 0 > r10 0xf7a88888 4155017352 > r11 0x246 582 > r12 0x565d71d1 1448964561 > r13 0x3 3 > r14 0xe2cc 58060 > r15 0x5663c730 1449379632 > rip 0x56560e45 1448480325 > eflags 0x282 [ SF IF ] > cs 0x33 51 > ss 0x2b 43 > ds 0x2b 43 > es 0x2b 43 > fs 0x0 0 > gs 0x0 0 > > > Inside glibc, there’s an indirect call: > > > => 0xf79949f4 <__GI_setgroups+100>: call rax > rax 0xf7833500 4152571136 > => 0xf7833500 <__nptl_setxid>: push r15 > > > Some time in __nptl_setxid later, here’s the bug: > > > 1162 in allocatestack.c > rax 0xf77ca840 4152141888 > rbx 0xffffd230 4294955568 > rcx 0x0 0 > rdx 0x1 1 > rsi 0xffffd2e0 4294955744 > rdi 0xf77ca840 4152141888 > rbp 0xf77ca840 4152141888 > rsp 0xffffd1d0 4294955472 > r8 0x0 0 > r9 0x0 0 > r10 0xf77caac0 4152142528 > r11 0x246 582 > r12 0xf784a360 4152664928 > r13 0xf784a360 4152664928
Looks like df76ff3a446a787a95cf74cb15c285464d73a93d broke this upstream (x32: Properly pass long to syscall [BZ #25810]). setgroups uses INLINE_SETXID_SYSCALL, which in turn passes its arguments through the various id fields in xid_command. Unfortunately, those are `long int`, and so, when the `const gid_t *list` argument gets later passed through INTERNAL_SYSCALL_NCS, it's treated as an integer argument and thus sign-extended, despite actually being a pointer. I think xid_command's id fields need to become __kernel_ulong or equivalent, with ARGIFY happening inside INLINE_SETXID_SYSCALL when it still knows what the types are. Jess