Re: Bug in how capability inheritance is handled in "fs/exec.c", 2.3.99

From: Theodore Y. Ts'o (tytso@MIT.EDU)
Date: Sun May 28 2000 - 07:06:01 EST


   From: "Linda Walsh" <law@sgi.com>
   Date: Sun, 28 May 2000 00:36:41 -0700

           Hmmm..
   The Posix draft under section 25.1.1.2 "Capability Inheritance" says:
   "Folling the _exec_() of a program, the capabilities that have their
   _permitted_ flags set in the new process image depend on the
   capability states of both the previous process image and the exec'd
   program file. Each capability marked as _permitted_ may have been
   forced to be set by the progra file or inherited from the previous
   image (if the capability attributes of the program file allow the
   inheritance [read this as meaning inheritance bits of both the
   previous process as well as the inheritance bits of the new].

   This implies an 'or' of the Permitted sets. I also read the inheritance
   check in the more restrictive fashion as needing to be set as inheritable
   in both the current process and the new file.

   What part of the draft standard where you referring to that says all
   previous Permitted bits are dropped? That is supposed to be a function
   of the 'inheritable' vector. I.e. you don't have to "drop" privileges,
   they dropped automatically by setting the inheritable set to 0.

Check section 3.1.2.2 of Draft 17 (on page 18, lines 36-28):

It explicitly specifies what happens to the inheritable, effective, and
permitted flags of the new process image after an exec call. As near as
I can tell the Linux implementation follows the requirements Draft 17.

        I_1 = I_0
        P_1 = (P_f && X) | (I_F && I_0)
        E_1 = E_F && P_1

Where I_1, E_1, and P_1 represent the inheritable, effective, and
permitted flags of the new process image, I_0 is the inheritable flag of
the current process image, and I_F, E_F, and P_F, are the inhertiable,
effective, and permitted flags of the executable, and X represents
possible additional implementation-defined restrictions.

As far as the wording in section 25.1.1.2 is concerned, it talks about
the permitted flags depending on the capability *states* (which covers
all three capmasks, not just the permitted bitmask).

So the Draft 17 model specifies that flags in the inheritable bitmask
will be inherited across an exec **if** the executable allows it to be
inherited. The basic idea seems to be that an executable should never
have permissions shoved down its throat that it's not prepared to
handle. Or put another way, if the system administrator considers a
particular program to be untrusted because it hasn't been audited yet to
make sure it doesn't do bone-headed things, it should under no
circumstances be allowed to any capabilities that the system
administrator hasn't authorized that capability to have.

This doesn't allow you to do what you'd like to do, I know. If you
really want it, I'd probably do it by defining a new cpamask which
contained additional privileges which are or'ed into the permitted mask
unconditionally across the exec. This would be a *dangerous* capmask,
since if it is ever set, it basically violates the guarantee which POSIX
1.e gave you --- namely, that programs that had a null inheritable and
executable bitmasks can never run with raised capabilities, and so
therefore they don't need to be audited for security problems. (In
Unix, a **lot** of problems are caused by running programs as root that
weren't designed to be run as root. POSIX 1.e prevents this, but in
order to provide the functionality you want, we have to break this
guarantee.)

                                                        - Ted

-
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.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed May 31 2000 - 21:00:19 EST