UID is to capabilities as SUID is to ??; access(), # CAPs?

From: Linda Walsh (law@sgi.com)
Date: Thu May 25 2000 - 17:21:33 EST

A minor thorn.

This is my belief about the 'access' system call: It seems the purpose
was to decide if a given file was accessible by the 'real' user when
running an 'suid' program.

This implies that the 'euid' be saved off, the 'euid' should be set to
the 'real uid' (uid) and then we check for access.

I believe that the 'access' system call should check each pathname
component to ensure the 'real uid' has at least 'x' for every pathname
component except the last. (???)

Now, I throw in CAPABILITIES. Say I now run a "set-cap" program, but
the program wants to use 'access' for the same semantic reason (to determine
the process's access to a file before the new capabilities were enabled).

This would imply the need for 1 of 2 checks:

        1) check access with the process's Effective Caps *before* the
program loaded it's caps,


        2) check access with the process's Permitted caps *before* the
program loaded it's caps.

        I think 1) would be "safer", but either way implies the need
for a "saved capability set". No?

My belief on executable inheritance rules are below:
When a new program is loaded the inherited vector is set

    I-proc-new = I-file & I-proc-old

the permitted vector is set

    P-proc-new = P-file | (P-proc-old & I-proc-new)

the effective vector is set

    E-proc-new = E-file & P-proc-new

The new inherited vector is the intersection of the process inherited vector and the program inherited vector.

The new permitted vector is the union of the program permitted vector and the intersection of the new inherited vector and the process permitted vector.

The new effective vector is the intersection of the new permitted vector and the program effective vector.

        Is this correct?

        These would be applied within the execX system call.

I also anticipate the need for a 64 bit capability vector. Should we
fold this in now? I can see (from POSIX 1003.1e DS15) some of the
following needed caps (which is not to say this is an exhaustive list).

CAP_SETFCAP (ability to set a capability set on a file)

Mac related:
CAP_MAC_DOWNGRADE (possibly 1 for int

Audit related:
CAP_AUDIT_WRITE (CAP_AUDIT_READ is also defined, but I'm not sure normal DAC
        won't do)

        In the 2.3.99 source, 28 out of 32 caps are used. In IRIX, we
got by with 47 caps. So I'm just guestimating that 64 should be enough
for Linux for sometime to come.

        (I know...I just think too much).

        Second question would be how much of this (saved caps), extra
caps do we want in the kernel mainstream -- or should those treated
as 'configurable'? Maybe CAPS should be configurable as well -- considering
the complaints I've heard over adding security features -- maybe CAPS
should be taken to a CONFIG-OPTION, if "off", capable(x) becomes a
#define capable(x) ((int)(current->euid==0)). (Just taking the
security configurables to some logical point).

        Things like accounting are configurables, should caps be? That
way those who only want to use Linux in an isolated environment where
they need only speed can not be troubled by those pesky bit-mask ops,
or the extra memory needed to store the cap words (considering they aren't
being used by most people, I'm surprised they got in as anything other
than a configurable)... ???

Linda A Walsh                    | Trust Technology, Core Linux, SGI
law@sgi.com                      | Voice: (650) 933-5338

- 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:15 EST