I am working on containing different applications using Linux's seccomp and I got to an inconsistency I cannot explain.
I have tried to give you examples clear enough to reproduce the problem.
I am creating a "protector module" which disallows process calling set_robust_list
(for the sake of demoing the problem). Then I run processes where I inject this "protector module" using LD_PRELOAD and expect the process to stop when this system call is made.
I am making a shared object based on this code:
#include <seccomp.h>
#include <sys/prctl.h>
static void __attribute__((constructor)) Initialization(void) {
scmp_filter_ctx ctx;
prctl(PR_SET_NO_NEW_PRIVS, 1);
ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(set_robust_list), 0);
seccomp_load(ctx);
}
I am building it with gcc -shared seccompdemo.c -lseccomp -o libseccompdemo.so
.
Then to test it I'm building this executable:
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
int main() {
syscall(SYS_set_robust_list,0,0);
return 0;
}
I'm building this with gcc set_robust_list.c -o set_robust_list
.
Then as expected I'm runninig this executable with the above so and it gets killed with a signal:
$ LD_PRELOAD=./libseccompdemo.so ./set_robust_list
Bad system call (core dumped)
The problem is when I'm trying to do the same trick with Java.
I'm invoking the same "protector module" on java it does not seem to work despite I know Java is calling set_robust_list
from strace:
$ LD_PRELOAD=./libseccompdemo.so java FileWriterTest /tmp/hosts < /etc/hosts
$ echo $?
0
See the strace output proves that java is calling 'set_robust_list':
$ strace -f java FileWriterTest /tmp/hosts < /etc/hosts 2>&1 | grep set_robust_list
set_robust_list(0x7f0b168af660, 24) = 0
[pid 12847] set_robust_list(0x7f0b168ad9e0, 24 <unfinished ...>
[pid 12847] <... set_robust_list resumed> ) = 0
[pid 12848] set_robust_list(0x7f0b12b259e0, 24) = 0
I do see that java calls clone
system call essentially for creating threads. I thought maybe seccomp filters are not inherited, but according to the documentation they are.
I'd be very glad if someone could explain me why this is not working.
For reference here is the Java code:
import java.io.FileOutputStream;
import java.io.IOException;
public class FileWriterTest {
public static void main(String[] args) {
try {
FileOutputStream f = new FileOutputStream(args[0]);
f.write(System.in.readAllBytes());
}
catch (IOException e) {
System.out.format("Caught exception: "+e.toString());
}
}
}