Messages in this thread Patch in this message |  | | From | Neil Brown <> | Date | Mon, 12 May 2003 12:11:59 +1000 | Subject | PATCH/RFC - process limits problem |
| |
Here is the problem: We have a multi-user server that has lots of people logging on to it and doing all sorts of weird things. To help keep them contained we set the per-user process limit to 256. If this server happens to have 256 or more processes running as root (which happens from time to time), then ordinary users cannot run "lpr" (lprng version) because it tries to fork and fails: EAGAIN.
What appears to be happening is lpr tries to fork while it has it's effective uid restored to the calling user's uid, but it's real user is still root.
Because real uid is root, process accounting is done against root's processes, and because euid is not root, capabilities have been dropped and the process is not allowed to exceed this limit.
This doesn't seem fair: to count the usage as though the process were root, but to limit it as though the process wasn't root.
It is not obvious to me how best to fix this problem. One approach would be to modify lpr to use capset(2) to claim CAP_SYS_RESOURCE before forking, but this seems to be fixing the symptom rather than the problem.
Another approach is embodied in the patch below which makes a special case for root_user and not to impose any limits on root. I think this is better but I would appreciate hearing other perspectives.
In brief, my view is that it seems odd to use per-process attibutes (such as capabilites and even rlim) when limiting a per-user resource, such as number of processes. I appreciate that for compatability reasons we really have to store the limit per-process rather than per-user, but I don't think it makes sense to use a per-process capability to over-ride a per-user limit. It should be a per-user capability.
NeilBrown
diff ./kernel/fork.c~current~ ./kernel/fork.c --- ./kernel/fork.c~current~ 2003-05-12 11:51:28.000000000 +1000 +++ ./kernel/fork.c 2003-05-12 11:53:44.000000000 +1000 @@ -636,6 +636,7 @@ int do_fork(unsigned long clone_flags, u * than the amount of processes root is running. -- Rik */ if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur + && p->user != &root_user && !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) goto bad_fork_free; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |