4 ms·
Exactly, I am now morally bound to figure out the answer instead of going to work.
by eddd-ddde 2y ago
Exactly, I am now morally bound to figure out the answer instead of going to work.
- oguz-ismail 2y agoThe last argument would be on the stack instead of in a register which is where the kernel expects to find the arguments. But a proper syscall implementation would handle this just fine (e.g. <https://github.com/bminor/glibc/blob/ba60be873554ecd141b55ea82647714933c0dbd4/sysdeps/unix/sysv/linux/x86_64/syscall.S https://github.com/bminor/glibc/blob/ba60be873554ecd141b55ea...>), so I don't think there's anything sus about it.
- im3w1l 2y ago> movq 8(%rsp),%r9 This is a huge edgecase but is 8(%rsp) guaranteed to be readable memory
- achierius 2y agoYes, see https://en.wikipedia.org/wiki/Red_zone_(computing) https://en.wikipedia.org/wiki/Red_zone_(computing)
- jagrsw 2y agoThe problem is something a bit else (jstarks figured it out somewhere below). I'm not a compiler/abi eng, but it seems to depend on a compiler, eg. consider this with clang-16: #include <sys/syscall.h> #include <unistd.h> #include <alloca.h> #include <string.h> void s(long a, long b, long c, long d, long e, long f, long g) { } int main(void) { long a = 0xFFFFFFFFFFFFFFFF; s(a, a, a, a, a, a, a); syscall(9999, 1, 2, 3, 4, 5, 6); return 0; } Now, strace shows: $ strace -e process_vm_readv ./a process_vm_readv(1, 0x2, 3, 0x4, 5, 18446744069414584326) = -1 EINVAL (Invalid argument) objdump -d a 117f: 48 c7 45 f0 ff ff ff movq $0xffffffffffffffff,-0x10(%rbp) 1186: ff 1187: 48 8b 7d f0 mov -0x10(%rbp),%rdi 118b: 48 8b 75 f0 mov -0x10(%rbp),%rsi 118f: 48 8b 55 f0 mov -0x10(%rbp),%rdx 1193: 48 8b 4d f0 mov -0x10(%rbp),%rcx 1197: 4c 8b 45 f0 mov -0x10(%rbp),%r8 119b: 4c 8b 4d f0 mov -0x10(%rbp),%r9 119f: 48 8b 45 f0 mov -0x10(%rbp),%rax 11a3: 48 89 04 24 mov %rax,(%rsp) 11a7: e8 94 ff ff ff call 1140 <s> 11ac: bf 36 01 00 00 mov $0x136,%edi 11b1: be 01 00 00 00 mov $0x1,%esi 11b6: ba 02 00 00 00 mov $0x2,%edx 11bb: b9 03 00 00 00 mov $0x3,%ecx 11c0: 41 b8 04 00 00 00 mov $0x4,%r8d 11c6: 41 b9 05 00 00 00 mov $0x5,%r9d 11cc: c7 04 24 06 00 00 00 movl $0x6,(%rsp) 11d3: b0 00 mov $0x0,%al 11d5: e8 56 fe ff ff call 1030 <syscall@plt> Only 4 bytes are put on the stack, but syscall will read 8. It's tricky if one doesn't control types of arguments used in vararg.
- im3w1l 2y agoI think you misunderstand. The red zone is on the opposite side of rsp. This line is trying to read an argument that may not exist, relying on the fact that this will put garbage in the register which syscall then ignores. But this only works if the memory is readable.