Making system calls for Linux without a stack

On Linux i386, int $0x80syscall ABI makes it easy to make system calls without having a valid user space stack. The vdso / vsyscall interface, on the other hand, requires access to the stack. How are other Linux rates in this regard, especially x86_64? Do they have ways to make syscalls without a stack? Is there a link to the available syscall methods for each arch?

+3
source share
1 answer

In general: I have no idea. Even on i386, if there is a 6th argument, it must be passed onto the stack (for example, for mmap).

, x86_64: syscall %rax ( : - 32-), 6 %rdi, %rsi, %rdx, %r10, %r8 %r9 ( , , ABI - %r10 %rcx) syscall . %rax, %rcx %r11 .

x86_64 ABI http://www.x86-64.org/documentation/abi.pdf; Linux ABI . , 64- Windows ABI.


, syscall . , , ; , %rsp syscall, :

$ cat syscall_sig.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>

#define __NR_nanosleep 35

static sig_atomic_t alrm = 0;

void handler(int sig)
{
    if (sig == SIGALRM)
        alrm = 1;
}

int main(void)
{
    stack_t ss;
    struct sigaction sa;
    struct timespec req, rem;
    long ret;

    ss.ss_flags = 0;
    ss.ss_size = SIGSTKSZ;
    ss.ss_sp = malloc(ss.ss_size);
    sigaltstack(&ss, NULL);

    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = handler;
    sa.sa_flags = SA_ONSTACK;
    sigaction(SIGALRM, &sa, NULL);

    alarm(1);

    req.tv_sec = 5;
    req.tv_nsec = 0;
    asm("xorq $0x12345678, %%rsp ; syscall ; xorq $0x12345678, %%rsp"
        : "=a" (ret)
        : "0" (__NR_nanosleep), "D" (&req), "S" (&rem)
        : "rcx", "r11", "memory");

    printf("syscall return code %ld, alarm flag %d\n", ret, alrm);

    return 0;
}

$ gcc -Wall -o syscall_sig syscall_sig.c
$ ./syscall_sig
syscall return code -4, alarm flag 1
$ 
+4

Source: https://habr.com/ru/post/1791359/


All Articles