Giuseppe Pes
Giuseppe Pes

Reputation: 7912

inline assembler for calling a system call and retrieve its result

I want to call a system call (prctl) in assembly inline and retrieve the result of the system call. But I cannot make it work.

This is the code I am using:

int install_filter(void)
{

   long int res  =-1; 
   void *prg_ptr  = NULL; 

  struct sock_filter filter[] = {
    BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
        /* If a trap is not generate, the application is killed */
        BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
    };
    struct sock_fprog prog = {
        .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
        .filter = filter,
    };

  prg_ptr = &prog; 

  no_permis(); 

  __asm__ (
        "mov  %1,    %%rdx\n"
        "mov  $0x2,  %%rsi \n"
        "mov  $0x16, %%rdi \n"
        "mov  $0x9d, %%rax\n"
        "syscall\n"
        "mov %%rax, %0\n"
        : "=r"(res)
        : "r"(prg_ptr)    
        :  "%rdx", "%rsi", "%rdi", "%rax" 
        );

   if ( res < 0 ){
    perror("prctl");
    exit(EXIT_FAILURE);
    }

  return 0;
}

The address of the filter should be the input (prg_ptr) and I want to save the result in res.

Can you help me?

Upvotes: 1

Views: 744

Answers (1)

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215487

For inline assembly, you don't use movs like this unless you have to, and even then you have to do ugly shiffling. That's because you have no idea what registers arguments arrive in. Instead, you should use:

__asm__ __volatile__ ("syscall" : "=a"(res) : "d"(prg_ptr), "S"(0x2), "D"(0x16), "a"(0x9d) : "memory");

I also added __volatile__, which you should use for any asm with side-effects other than its output, and a memory clobber (memory barrier), which you should use for any asm with side-effects on memory or for which reordering it with respect to memory accesses would be invalid. It's good practice to always use both of these for syscalls unless you know you don't need them.

If you're still having problems, use strace to observe the syscall attempt and see what's going wrong.

Upvotes: 4

Related Questions