UNIX ptrace () blocks child system calls

I am developing a grader for programming contests. Basically, a grader should run a solution program in an "isolated" process. Therefore, I would like the solution to not cause any malicious system calls (such as system (), fork (), etc.). Can I use ptrace () to achieve this?

+3
source share
2 answers

I think there are two possible solutions:

  • Using the LD_PRELOAD mechanism to create a strip to replace the system calls you want to stop.
  • Use setrlimit () to limit the calling process. Unfortunately, these restrictions seem to be for each user, and not for each process, which makes calculating the correct value very difficult.

EDIT: I have the first work option and have included the necessary code in it. Create binaries with make all, and then check with make runtests:

$ make all
gcc -fPIC -shared -Wl,-soname,libmy.so.1 -o libmy.so.1.0 lib.c
ln -sf libmy.so.1.0 libmy.so.1
ln -sf libmy.so.1 libmy.so
gcc -o test test.c

$ make runtests
Without LD_PRELOAD:
./test
in child: retval=9273
in parent: retval=0
With LD_PRELOAD:
LD_PRELOAD=./libmy.so ./test
libmy.so fork!
fork error: error=Operation not permitted (1)

Makefile:

all: libs test

runtests:
    @echo Without LD_PRELOAD:
    ./test
    @echo With LD_PRELOAD:
    LD_PRELOAD=./libmy.so ./test


libs: lib.c
    gcc -fPIC -shared -Wl,-soname,libmy.so.1 -o libmy.so.1.0 lib.c
    ln -sf libmy.so.1.0 libmy.so.1
    ln -sf libmy.so.1 libmy.so

test: test.c
    gcc -o test test.c

clean:
    rm -f test libmy.so.1.0 libmy.so.1 libmy.so lib.o

lib.c:

#include <stdio.h>
#include <unistd.h>
#include <errno.h>

pid_t fork()
{
    printf("libmy.so fork!\n");
    errno = EPERM;
    return (pid_t)-1;
}

test.c:

#include <stdio.h>
#include <string.h>
#include <errno.h>

int main(int argc, char **argv)
{
    int retval = fork();
    if (retval == 0)
        printf("in parent: retval=%d\n", retval);
    else if (retval > 0)
        printf("in child: retval=%d\n", retval);
    else
        printf("fork error: error=%s (%d)\n", strerror(errno), errno);
    return 0;
}
+1
source

Yes, you can use ptrace () to block specific system calls using the PTRACE_SYSCALL parameter. Here is a project using this function:

https://github.com/t00sh/p-sandbox/blob/master/p-sandbox.c

Linux, seccomp, , / .

Google . - .

, LXC, .

LD_PRELOAD , syscall libc.

0

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


All Articles