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;
}
source
share