Reputation: 3737
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
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
Reputation: 3156
A login bash
shell is exec
ed by another process (which process depends on whether it is a console login shell, ssh login shell, gnome-terminal shell, etc.) The process exec
ing bash
is exec
ed 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