2017-11-11 180 views
1

我正在尝试使用NETLINK和CN_IDX_PROC来监视我的进程。这可行,但需要使用root权限启动监视进程。我试图通过在我的监视可执行文件(包括CAP_AUDIT_READ,CAP_SYS_ADMIN,CAP_SYS_PTRACE和CAP_IPC_OWNER)上设置文件系统的功能来修复它,但它不起作用,bind()仍然失败,说“操作不允许“除非使用sudo开始。获取有关进程终止的通知

有没有办法让非根用我想要的方式使用netlink连接器套接字?

如果否,是否有其他可靠的方式来获得通知时,其他(非子,在不同的用户帐户下运行)进程终止?我不想调查:它是嵌入式软件,我没有太多资源,我希望尽快得到通知。如果目标进程异常终止,我特别希望得到通知,例如由于分段错误,所以我不能依赖目标进程的合作。

在Windows上,我只是创建了&在目标进程中锁定一个已命名的互斥锁,并使监视进程进入休眠状态,只要所有者进程死亡,互斥锁就会保证被释放。 Linux中是否有类似的IPC机制?

+0

你不能使用[waitpid(2)](http://man7.org/linux/man-pages/man2/waitpid.2.html)或类似的东西吗? –

+0

@BasileStarynkevitch不能。所有这些系统调用都用于等待状态更改'在调用进程的子进程中' – Soonts

+0

您可以将进程封装在另一个进程中(只是'fork'-s和'waitpid'-s) –

回答

1

所以,你要通知有关进程的终止,例如运行某些程序foo

顺便说一句,如果该进程如果该程序正确退出(通过明确地调用exit(3)或从main返回; crt0在这种情况下在刚刚返回main之后调用exit(3)),那么注册后的注册表中的atexit(3)例程在你想要的时候运行。但是这个foo过程可能会被一些signal(7)(例如segmentation fault,或一些外部的kill(1)命令等等)终止,那么当然_exit(2)没有发生(并且也不是exit(3) ....)。

所以写一个简单的包装程序(例如wrapfoo)在子​​然后fork(2) -s execve(2) -s foo,并在父waitpid(2)。那么你的wrapfoo总是通知foo的结尾(包括foo由某个信号终止时)。它的行为就好像它是一个运行foo的专用“外壳”(这里只是为了解释这里,wrapfoo而不是真的是Unix shell)。

(当然,你不希望运行wrapfoo将自身终止该进程)

编码是wrapfoo程序是非常简单的。你应该期待它是正确的。你可能(仔细)使用setuid技术让他们使用不同的用户(如果你需要的话)。请注意,setuid技巧是困难的,无小心可以打开security hole

在某些情况下,您可能会将wrapfoo的C源代码与foo的代码合并,但大多数时候您不想(separation of concerns原理)。特别是如果你使用危险的setuid技术,你希望你的wrapfoo.c尽可能地简单(并且能够证明它像你想要的那样工作)。

阅读一些有关Linux编程的好书,例如下载旧的Advanced Linux Programming(也here;它是合法免费下载)或更新的东西。 setuid技术和fork(2)execve(2)waitpid(2) ......背后的所有缺点很难解释(所以我甚至不会在这里尝试)。另见credentials(7)。也许你可以使用fifo(7),使用一些建议锁定(例如flock(2)lockf(3) ...);当一个进程死亡时,内核也会释放它们。

+0

谢谢,结束了这么做。我最初的基于pthread mutex的实现似乎太脆弱,太多可能的边缘情况。至少目前为止,这种方法似乎工作正常。顺便说一下,我在包装器中使用一个数据报unix域套接字来与真正的所有者进行通信。 无法合并包装程序,因为被封装的进程是Microsoft的运行我的C#代码的dotnet,那件事很大,我不想重新编译和修补程序。 – Soonts

0

在pthread mutex中实现了一个名为shared shared section的变通方法。

Funfact:当互斥被强制释放,因为所有者进程终止,其他进程的pthread_mutex_lock返回EOWNERDEAD代码,但是互斥这之后不再使用,对互斥随后的pthread_mutex_lock返回131 = EOTHER错误代码。幸运的是,我只同步2个进程,所以我可以在同一个共享内存部分重新创建互斥锁。

令人惊讶的代码量复制一个WaitForSingleObject的Win32 API的:-(