RFC: Enforcing process hierarchies (`prctl` related)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



    Hello all! I'm about to write quite a long-ish email, but I
provide a small summary first for the "busy". :)


== Quick summary

    The context is simple:
    * the developer wants to write a C application (call it a
"controller") that spawns other child processes, which in their turn
spawn other processes and so on;
    * some of these spawned processes might double fork (i.e. they daemonize);
    * these child processes are not written by the developer in
question; (thus we can't "fix" them...)
    * the controller will run with no special privileges (i.e.
non-root, no capabilities, etc.);
    * (for purely practical reasons, thus let's not start a flame war)
we can assume a Linux-only environment, thus portability is not an
issue; (the developer is also not scared in applying patches to the
kernel...)

    The problem I try to find a solution to is again quite simple, how
can the developer write the "controller" application such that the
following happens:
    (A) any orphaned child of a sub-process (i.e. double forking ones,
ones whose parent has exited, etc.) are reparented to the controller;
(this is already solved in 3.4;)
    (B) the controller should be able to kill all its subprocesses
(and their subprocesses, recursively);
    (C) if the controller dies (segfault, killed, etc.) all its
subprocesses are terminated (and recursively so);

    Thus, what "magic" :) should one invoke to obtain the above?


== Use cases

    To better put the problem into a context, the previous features
would allow one to implement something like:
    * "personal" service control systems (like `systemd`, `runit`,
`daemon-tools`, etc.);
    * constrain badly written `sh` scripts that if terminated leak
processes; or build systems (like `make`), or SSH sessions, or cron
jobs, etc.;
    * a building block in a PaaS underlaying;

    But certainly NOT for "security" purposes...


== Existing primitives

    I've really tried thinking about this for the last year or so, and
I've not managed to get a "good" enough solution... But I've found the
following partial solutions, but all of them have issues...

    (1) `clone (CLONE_NEWPID)` -> solves all the problems, but has
major drawbacks:
    * it requires special rights (root or capability);
    * it creates an alternative process namespace thus will confuse
the hell out of scripts assuming PID equivalence...

    (2) `prctl (PR_SET_CHILD_SUBREAPER)` -> solves the issue (A)
(reparenting), but that's it.

    (3) `prctl (PR_SET_PDEATHSIG)` -> solves the issue (C) (forced
termination), but it has the following issues:
    * it works only for the first level of sub-processes, as it must
be explicitly set after each `fork`;
    * thus it is not "inheritable" by new children;
    * it doesn't work for `setuid` processes (due to possible security issue);

    (4) `killpg (group)` -> solves the issue (B), but:
    * any child could choose to change its process group;
    * if the controller uses its own group it kills itself;

    Have I missed something?


== Brainstorming

    It would have been nice if either of the following would happen
(in order of preference):

    (a) maybe an additional `PR_SET_CHILD_SUBREAPER`-like flag that
would make the controller process really behave like a sub-init, that
is on its termination terminate all its children recursively;

    (b) `PR_SET_PDEATHSIG` would be inheritable at least for non
`setuid` processes; (maybe even better if the signal is `SIGKILL` keep
it even for `setuid` processes as I don't see too much harm there...)

    (c) have some way to send a signal to all a process children;

    (d) (last resort solution we have today) iterate through
`/proc/$PID` and find all the controller children, SIGKILL them, and
continue until no process is found, then die; but it doesn't solve
(C)...


    Something else?

    Hope I find some solution to this... (If this is not the mailing
list to send it to, please point me in the right direction.)

    Thanks in advance for feedback,
    Ciprian.

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux