the problem with fork

Daniel R Risacher (magnus@alum.mit.edu)
Sat, 11 Jul 1998 17:24:57 GMT


the problem with fork (or, at least one of the problems) is not really
with fork, but with kmod.

The kernel keeps track of how many processes each user has running
with charge_uid(). Each time a user runs fork() it increments a
counter for that user. When the process hits exit() this counter is
decremented. If a user program requests a module then he gets
"charged" for forking kmod, but inside of kmod it sets the uid to
zero. When kmod exits, the counter is decremented for root instead of
for the user that caused it's invocation. After hitting kmod a few
times, eventually the kernel thinks the user is using too many
processes, and fork() fails.

in a related note, since the counter for root was being decremented
but never incremented, the sum of kmod-exits and root-exits would
underflow at 2^31, which I believe would prevent root from forking
more than about 2 billion times.

the following patch should fix both problems. root never gets charged
(or "refunded") for anything, and kmod "refunds" its user before
switching uid.

Daniel Risacher
magnus@alum.mit.edu

--- linux/kernel/kmod.c.orig Sat Jul 11 17:00:41 1998
+++ linux/kernel/kmod.c Sat Jul 11 17:03:30 1998
@@ -67,6 +67,8 @@
}

/* Give kmod all privileges.. */
+ charge_uid(current, -1);
+ /* root never gets charged for processes */
current->uid = current->euid = current->fsuid = 0;
cap_set_full(current->cap_inheritable);
cap_set_full(current->cap_effective);
--- linux/kernel/fork.c.orig Sat Jul 11 17:17:25 1998
+++ linux/kernel/fork.c Sat Jul 11 17:18:19 1998
@@ -97,6 +97,8 @@
unsigned int hashent = uidhashfn(p->uid);
struct uid_taskcount *up = uid_find(p->uid, hashent);

+ if (0 == p->uid) return 0;
+
if(up) {
int limit = p->rlim[RLIMIT_NPROC].rlim_cur;
int newcnt = up->task_count + count;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html