1

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?

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.