C - 如何检查进程是否是系统进程?

时间:2016-04-01 06:02:30

标签: c linux-kernel kernel task ubuntu-14.04

我正在尝试检测一个叉炸弹,并且通过该过程我试图计算每个进程的后代数。但是,我只想计算非系统进程的后代计数,因为fork炸弹将是一个非系统进程。但是,我不确定该怎么做。这就是我到目前为止所做的:

struct task_struct *pTask;
for_each_process(pTask)
{
    struct task_struct *p; 
    *p = *pTask; 

    //trace back to every ancestor 
    for(p = current; p != &init_task; p->parent)
    {
        //increment the descendant count of p's parent            
    }
} 

这个循环适用于init任务正确,因为它是&init_task?有没有办法转而去第一个系统进程并停止?例如,叉炸弹将成为系统进程的直接子进程。任何帮助将不胜感激,谢谢!

[编辑] 通过系统过程,我的意思是像bash之类的东西。我应该更清楚地解释一下,但在基本级别,我不想删除任何从启动运行的进程。从启动后运行的用户空间开始的任何进程都是合理的游戏,但其他进程则不然。我不会检查tomcathttpd之类的内容,因为我100%知道这些进程不会运行。

2 个答案:

答案 0 :(得分:1)

登录bash shell由另一个进程exec编写(该进程取决于它是否是控制台登录shell,ssh登录shell,gnome-terminal shell等)进程{{ 1}} exec bashexec initinit启动的其他进程,而不是内核。

用户可以轻松创建一个自行分析的bash脚本,因此如果您从检查中免除/bin/bash,则无法检测到用bash编写的fork炸弹。例如,以下脚本放在名为foo的文件中并在当前目录中执行,将创建一个fork炸弹。

#!/bin/bash
while [ /bin/true ]
do
    ./foo &
done

如果您想限制特定用户可以投放的流程数,请查看bash(1)setrlimit(2)中的ulimit

或者,您可以为触发查杀进程的后代计数设置一个非常高的阈值。如果返回init的父母链数百深,那么可能会发生一些可疑的事情。

答案 1 :(得分:1)

您可以使用logind / ConsoleKit2 D-Bus API通过其PID确定进程的会话。 "系统"进程(IIRC)将没有会议。

显然这需要logind(Systemd的一部分)或ConsoleKit2正在运行。

如果没有跟踪用户会话的服务,可能没有可靠的方法来区分"系统"来自用户进程的进程,除了user-id之外(假设你的fork炸弹不能作为系统用户运行)。在许多发行版上,系统用户ID小于1000,常规用户ID>&= 1000,除了" nobody"用户(通常为65534)。