ocean800
ocean800

Reputation: 3737

C - How to check if a process is a system process?

I'm trying to detect a fork bomb, and through that process I am trying to caluclate the descendant count of each process. However, I only want to calculate the descendant count for non-system processes, as the fork bomb will be a non-system process. However, I'm unsure how do do that. This is what I have so far:

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            
    }
} 

This loop goes up to the init task correct, since it's &init_task? Is there any way to instead to go to the first system process and stop? Because for example, the fork bomb will be the immediate child of a system process. Any help would be greatly appreciated, thank you!!

[EDIT] And by system process, I mean like things like for example, bash. I should have explained more clearly, but at the basic level, I don't want to delete any process that runs from boot-up. Any processes orginating from user-space that is run after boot up is fair game, but other processes are not. And I will not be checking for anything like tomcat,httpd, because I know 100% that those processes will not be running.

Upvotes: 1

Views: 253

Answers (2)

davmac
davmac

Reputation: 20631

You can use the logind / ConsoleKit2 D-Bus APIs to determine the session of a process by its PID. "System" processes (IIRC) will have no session.

Obviously this requires that logind (part of Systemd) or ConsoleKit2 are running.

Without such a service that tracks user sessions, there may be no reliable way to differentiate a "system" process from a user process, except perhaps by user-id (assuming that your fork bomb won't be running as a system user). On many distributions system user IDs are less than 1000, and regular user IDs are >= 1000, except for the "nobody" user (normally 65534).

Upvotes: 1

wrdieter
wrdieter

Reputation: 3156

A login bash shell is execed by another process (which process depends on whether it is a console login shell, ssh login shell, gnome-terminal shell, etc.) The process execing bash is execed by init or some other process launched by init, not by the kernel.

A user can easily create a bash script that forks itself, so if you exempt /bin/bash from your checking then fork bombs written in bash will not be detected. For example, the following script, put in a file called foo and executed in the current directory, will create a fork bomb.

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

Take a look at ulimit in bash(1) or setrlimit(2) if you want to limit the number of processes a particular user can run.

Or, you could set a really high threshold for the descendant count that triggers killing a process. If the chain of parents back to init is several hundred deep, then probably something fishy is going on.

Upvotes: 1

Related Questions