-
Notifications
You must be signed in to change notification settings - Fork 386
check that all syscall arguments are scalars #1570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Looks good to me!
At least for x86_64, those go on the stack. This already happens for the sixth argument to a syscall: when calling the libc syscall() variadic function with 7 arguments (the syscall number plus 6 arguments to the sycall), the arguments are passed to this function through:
This wrapper then needs to invoke the
Glibc's syscall() wrapper on x86_64 has to move all these arguments over to 'convert' to the Linux syscall calling convention: ENTRY (syscall)
movq %rdi, %rax /* Syscall number -> rax. */
movq %rsi, %rdi /* shift arg1 - arg5. */
movq %rdx, %rsi
movq %rcx, %rdx
movq %r8, %r10
movq %r9, %r8
movq 8(%rsp),%r9 /* arg6 is on the stack. */
syscall /* Do the system call. */
cmpq $-4095, %rax /* Check %rax for error. */
jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
ret /* Return to caller. */
Yes, I'd assume the same. For the same reason It's safe to call |
The docs say that for x86-64, 6 arguments are passed via registers:
I think this excludes the syscall number, which it says is passed via EDIT: Oh, there's the variadic wrapper and then the actual syscall? Ouch... because things were not complicated enough yet.^^ |
Doesn't this just drop arg7+ though? I guess there are no syscalls with that many arguments? But some platforms specify a register for arg7...
So 6 arguments are always okay; I guess what we need here is that this works for any number of extra arguments, even if they spill onto the stack. |
Yeah, the syscall number (in
Yeah :( The variadic wrapper is only variadic in the C header (and Rust's
Yup. Afaik there's no syscalls that take more than 6 arguments, at least not on x86_64.
Yup, they just stand there untouched. Stack arguments to variadic functions are always cleaned up by the caller. The C standard even requires this for functions like ISO/IEC 9899:2011 - 7.21.6.1: (...) If the format is exhausted while arguments remain, the excess arguments are evaluated (as always) but are otherwise ignored. (...) |
That is reassuring. :) Thanks! We could probably also do something similar for other variadic functions that we implement ( @bors r+ |
📌 Commit 2b2a3a0 has been approved by |
☀️ Test successful - checks-travis, status-appveyor |
@m-ou-se do you think this check makes sense?
The
abi
of a layout contains everything needed for the calling convention (as far as I know), so this should ensure that all the ignored arguments are passed like integers and do not otherwise mess up argument passing.The one thing I am not sure about is what happens when more arguments are passed than fit in registers. The
syscall
man page says that all calling conventions support at least 6 arguments, except for "mips/o32" where it says thatIf we assume that passing these extra arguments to futex is legal even with that calling convention, that would mean that those user stack arguments are just silently ignored as well, which seems plausible to me -- but I know very little about calling conventions.