修补unshare以使查杀工作可靠

修补unshare以使查杀工作可靠

这个答案我们了解到,您可以通过 Linux PID 命名空间实现对整个进程子树的可靠终止unshare -p

这是我不明白的问题:

  • -f仅当我使用/--fork选项取消共享时它才有效。

    unshare -fp -- bash -c "watch /bin/sleep 10000 && echo hi"
    

    当我运行这个时,kill -9那个的PID bash,然后观看,睡眠等都死了,正如我所希望的那样。

  • 但是当我使用它时没有-f

    unshare -p -- bash -c "watch /bin/sleep 10000 && echo hi"
    

    kill -9bash PID,然后watch将其重新设置为PID 1(在我的Ubuntu上是systemd),所以我没有达到杀死所有孩子的预期效果。

问题:

  • 为什么--fork必须要达到预期的效果?为什么不unshare使用exec()fork 还不够?
  • 有解决方法吗?我更希望能够方便地发送到通过开始杀死其下面的所有内容而kill -9创建的 PID 。unshare但是当我使用 时--fork,杀死我开始时返回的 pidunshare将简单地杀死unsharebash重新设置为 PID 1,因为unshare它不在我的 PID 命名空间中。

请注意,&& echo hi是必需的,因为如果您只向 发出一个命令bash -c,它就会exec()执行此操作,因此 bash 进程会消失(被替换),并且您无法杀死其 PID。

答案1

如上所述在这个有用的答案中-n( )的效果unshare(CLONE_NEWPID)仅对分叉的第一个子进程起作用。

尤其,男人2取消分享说的是CLONE_NEWPID

取消共享 PID 命名空间,以便调用进程为其子进程拥有一个新的 PID 命名空间,该命名空间不与任何先前存在的进程共享。

调用进程不会移动到新的命名空间中。

调用进程创建的第一个子进程init(1)将具有进程 ID 1 并将在新命名空间中承担 的角色。


修补unshare以使查杀工作可靠

自从问我的问题以来,在过去的几个小时里我写了一个补丁util-linux在这里拉取请求) 向 中添加一个--kill-child标志unshare

编辑:现在它已作为 util-linux 的一部分合并并发布v2.32

你可以这样使用它:

unshare -fp --kill-child -- bash -c "watch /bin/sleep 10000 && echo hi"

并且unshare终止将按预期撕毁整个进程树。

没有root

root如果您的内核CONFIG_USER_NS=y通过传递标志启用了用户命名空间 ( ),您甚至可以在没有特权的情况下使用它-U

unshare -Ufp --kill-child -- bash -c "watch /bin/sleep 10000 && echo hi"

相关内容