Does anyone tell me how to block some specific system calls within a program, please? I am building a system which takes a piece of C source code, compiles it with gcc and runs
You could run the compiled program by forking it from a wrapper and use the Linux ptrace(2) facility to intercept and inspect all system calls invoked by the program.
The following example code shows a wrapper that runs the /usr/bin/w command, prints each system call invoked by the command, and terminates the command if it tries to invoke the write(2) system call.
#include#include #include #include #include #include #include #define BAD_SYSCALL __NR_write int main(int argc, char *argv) { pid_t child; int status, syscall_nr; child = fork(); if (child == 0) { /* In child. */ ptrace(PTRACE_TRACEME, 0, NULL, NULL); execl("/usr/bin/w", NULL, NULL); // not reached } /* In parent. */ while (1) { wait(&status); /* Abort loop if child has exited. */ if (WIFEXITED(status) || WIFSIGNALED(status)) break; /* Obtain syscall number from the child's process context. */ syscall_nr = ptrace(PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL); printf("Child wants to execute system call %d: ", syscall_nr); if (syscall_nr != BAD_SYSCALL) { /* Allow system call. */ printf("allowed.\n"); ptrace(PTRACE_SYSCALL, child, NULL, NULL); } else { /* Terminate child. */ printf("not allowed. Terminating child.\n"); ptrace(PTRACE_KILL, child, NULL, NULL); } } exit(EXIT_SUCCESS); }
You can do much more powerful things using ptrace, such as inspect and change a process' address space (e.g., to obtain and modify the parameters passed to a system call).
A good introduction can be found in this Linux Journal Article and its follow-up.