3

我正在使用 Linux 的 seccomp 包含不同的应用程序,但我遇到了无法解释的不一致。

我试图给你提供足够清晰的例子来重现这个问题。

我正在创建一个“保护器模块”,它不允许进程调用set_robust_list(为了演示问题)。然后我运行使用 LD_PRELOAD 注入这个“保护器模块”的进程,并期望在进行这个系统调用时进程停止。

我正在基于此代码制作一个共享对象:

#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);
}

我正在用gcc -shared seccompdemo.c -lseccomp -o libseccompdemo.so.

然后为了测试它,我正在构建这个可执行文件:

#define _GNU_SOURCE       
#include <unistd.h>
#include <sys/syscall.h>  

int main() {
   syscall(SYS_set_robust_list,0,0);
   return 0;
}

我正在用gcc set_robust_list.c -o set_robust_list.

然后正如预期的那样,我正在使用上面的代码运行这个可执行文件,它会被一个信号杀死:

$ LD_PRELOAD=./libseccompdemo.so ./set_robust_list
Bad system call (core dumped)

问题是当我试图用 Java 做同样的伎俩时。

我在 java 上调用了相同的“保护模块”,尽管我知道 Java 是从 strace调用的,但它似乎不起作用:set_robust_list

$ LD_PRELOAD=./libseccompdemo.so java FileWriterTest /tmp/hosts < /etc/hosts
$ echo $?
0

查看 strace 输出证明 java 正在调用 '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

我确实看到java调用clone系统调用本质上是为了创建线程。我想也许 seccomp 过滤器不是继承的,但根据他们的文档。

如果有人能解释我为什么这不起作用,我会很高兴。

这里的参考是Java代码:

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());
        }
    }
}
4

1 回答 1

1

Bad system call (core dumped)消息是您的 shell 告诉您子进程由于SIGSYS信号而退出。但是如果SIGSYS被阻塞,系统调用只会返回一个错误,这将以特定于应用程序的方式进行处理。

我猜想pthread_create在执行时会阻塞信号,因此set_robust_list只会被SIGSYS阻塞调用,这与您的示例代码不同,它不会修改信号掩码。

无论如何,它不应该真正影响您要完成的工作:将 a 添加System.out.println("Hello from Java!");到您的 java 中main,如果您预加载 segcomp 过滤器,您将看到它不会打印,因为main它永远不会按预期调用。

于 2018-03-21T17:44:08.850 回答