Hacker News new | past | comments | ask | show | jobs | submit login

Just a friendly reminder that syscall() is a vararg function. Meaning, you can't just go throwing arguments at it (so maybe it's better to use this wrapper to avoid problems instead).

For example, on a 64-bit arch, this code would be sus.

syscall(__NR_syscall_taking_6_args, 1, 2, 3, 4, 5, 6);

Quiz: why

PS: it's a common mistake, so I thought I'd save you a trip down the debugging rabbit hole.




A quiz is the opposite of saving someone effort.


Exactly, I am now morally bound to figure out the answer instead of going to work.


The 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/ba60be873554ecd141b55ea...>), so I don't think there's anything sus about it.


> movq 8(%rsp),%r9

This is a huge edgecase but is 8(%rsp) guaranteed to be readable memory



The 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.


I 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.


I never get people who aren't grateful for pointers. Being shown which direction to walk is of no value, they must also be carried there.

They didn't claim to save work, they claimed to save hitting a bug, and having to debug it.

They said the word "vararg". They gave you everything.


They are not some professor in my school, some valued colleague, or known kernel expert. They are a stranger on the internet. No, I can't be bothered to research every person that claim to have some wisdom that they won't articulate to cultivate an air of mystery.

They gave me everything to dismiss their claim.


Professors get paid, we got a pointer and a lesson for free.

Here's a free dollar. "Only one?"

They said the word "vararg". That is everything. You take that, and you say "oh shit, right, thanks for the heads up" or if you don't already know what's so special about that, you do know they obviously said that for some reason so you fucking google it.

Either way, they pointed you in the right direction, and that is helpful.

The further reading that you find so unbearable takes you exactly the same time to read something that has already been written and is just sitting out there to look up for free, as to read something you demand they write again on the spot bespoke for you.

And since as you say they aren't a proffessor or colleague you personally know and respect, why do you care if they write out a full article or just a pointer? You just said you don't trust a rando. You don't trust their full article anyway.


How do I know if they are "pointing me in the right direction"?

Once again, you assume the conclusion that their comment is helpful and correct and meaningful, and you work backwards to excuse their poor explanation that they justified with "let's say it's a quiz".

And if you don't like my reply, take your own advice and go away. Why do you care what I think of their phrasing? You're not going to get me to stop anyway, or the dozens or people who upvoted me.

Or keep swearing at me and getting downvoted, whatever floats your boat.


"How do I know if they are "pointing me in the right direction"?"

How do you justify complaining about how little they wrote for you when you will ignore them anyway, because "how do I know they are pointing me in the right direction?"

You can't have it both ways at the same time.


Pointing out the problem in their comment is the opposite of "ignoring them".

This is such a weird discussion honestly. I don't know what you want of me, but I sure can't wait for your next strawman!


You pointed out no problem.



I guess if the arch’s varargs conventions do something other than put each 32-bit value in a 64-bit “slot” (likely for inputs that end up on the stack, at least), then some of the arguments will not line up. Probably some of the last args will get combined into high/low parts of a 64-bit register when moved into registers to pass to the kernel. And then subsequent register inputs will get garbage from the stack.

Need to cast them to long or size_t or whatever to prevent this.


Yes




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: