02 Sep, 2009

1 commit

  • Add a keyctl to install a process's session keyring onto its parent. This
    replaces the parent's session keyring. Because the COW credential code does
    not permit one process to change another process's credentials directly, the
    change is deferred until userspace next starts executing again. Normally this
    will be after a wait*() syscall.

    To support this, three new security hooks have been provided:
    cred_alloc_blank() to allocate unset security creds, cred_transfer() to fill in
    the blank security creds and key_session_to_parent() - which asks the LSM if
    the process may replace its parent's session keyring.

    The replacement may only happen if the process has the same ownership details
    as its parent, and the process has LINK permission on the session keyring, and
    the session keyring is owned by the process, and the LSM permits it.

    Note that this requires alteration to each architecture's notify_resume path.
    This has been done for all arches barring blackfin, m68k* and xtensa, all of
    which need assembly alteration to support TIF_NOTIFY_RESUME. This allows the
    replacement to be performed at the point the parent process resumes userspace
    execution.

    This allows the userspace AFS pioctl emulation to fully emulate newpag() and
    the VIOCSETTOK and VIOCSETTOK2 pioctls, all of which require the ability to
    alter the parent process's PAG membership. However, since kAFS doesn't use
    PAGs per se, but rather dumps the keys into the session keyring, the session
    keyring of the parent must be replaced if, for example, VIOCSETTOK is passed
    the newpag flag.

    This can be tested with the following program:

    #include
    #include
    #include

    #define KEYCTL_SESSION_TO_PARENT 18

    #define OSERROR(X, S) do { if ((long)(X) == -1) { perror(S); exit(1); } } while(0)

    int main(int argc, char **argv)
    {
    key_serial_t keyring, key;
    long ret;

    keyring = keyctl_join_session_keyring(argv[1]);
    OSERROR(keyring, "keyctl_join_session_keyring");

    key = add_key("user", "a", "b", 1, keyring);
    OSERROR(key, "add_key");

    ret = keyctl(KEYCTL_SESSION_TO_PARENT);
    OSERROR(ret, "KEYCTL_SESSION_TO_PARENT");

    return 0;
    }

    Compiled and linked with -lkeyutils, you should see something like:

    [dhowells@andromeda ~]$ keyctl show
    Session Keyring
    -3 --alswrv 4043 4043 keyring: _ses
    355907932 --alswrv 4043 -1 \_ keyring: _uid.4043
    [dhowells@andromeda ~]$ /tmp/newpag
    [dhowells@andromeda ~]$ keyctl show
    Session Keyring
    -3 --alswrv 4043 4043 keyring: _ses
    1055658746 --alswrv 4043 4043 \_ user: a
    [dhowells@andromeda ~]$ /tmp/newpag hello
    [dhowells@andromeda ~]$ keyctl show
    Session Keyring
    -3 --alswrv 4043 4043 keyring: hello
    340417692 --alswrv 4043 4043 \_ user: a

    Where the test program creates a new session keyring, sticks a user key named
    'a' into it and then installs it on its parent.

    Signed-off-by: David Howells
    Signed-off-by: James Morris

    David Howells
     

14 Nov, 2008

1 commit

  • Alter the use of the key instantiation and negation functions' link-to-keyring
    arguments. Currently this specifies a keyring in the target process to link
    the key into, creating the keyring if it doesn't exist. This, however, can be
    a problem for copy-on-write credentials as it means that the instantiating
    process can alter the credentials of the requesting process.

    This patch alters the behaviour such that:

    (1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
    keyring by ID (ringid >= 0), then that keyring will be used.

    (2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
    special constants that refer to the requesting process's keyrings
    (KEY_SPEC_*_KEYRING, all | Instantiator |------->| Instantiator |
    | | | | | |
    +-----------+ +--------------+ +--------------+
    request_key() request_key()

    This might be useful, for example, in Kerberos, where the requestor requests a
    ticket, and then the ticket instantiator requests the TGT, which someone else
    then has to go and fetch. The TGT, however, should be retained in the
    keyrings of the requestor, not the first instantiator. To make this explict
    an extra special keyring constant is also added.

    Signed-off-by: David Howells
    Reviewed-by: James Morris
    Signed-off-by: James Morris

    David Howells
     

29 Apr, 2008

1 commit

  • Add a keyctl() function to get the security label of a key.

    The following is added to Documentation/keys.txt:

    (*) Get the LSM security context attached to a key.

    long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer,
    size_t buflen)

    This function returns a string that represents the LSM security context
    attached to a key in the buffer provided.

    Unless there's an error, it always returns the amount of data it could
    produce, even if that's too big for the buffer, but it won't copy more
    than requested to userspace. If the buffer pointer is NULL then no copy
    will take place.

    A NUL character is included at the end of the string if the buffer is
    sufficiently big. This is included in the returned count. If no LSM is
    in force then an empty string will be returned.

    A process must have view permission on the key for this function to be
    successful.

    [akpm@linux-foundation.org: declare keyctl_get_security()]
    Signed-off-by: David Howells
    Acked-by: Stephen Smalley
    Cc: Paul Moore
    Cc: Chris Wright
    Cc: James Morris
    Cc: Kevin Coffman
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     

09 Jan, 2006

2 commits

  • Make it possible for a running process (such as gssapid) to be able to
    instantiate a key, as was requested by Trond Myklebust for NFS4.

    The patch makes the following changes:

    (1) A new, optional key type method has been added. This permits a key type
    to intercept requests at the point /sbin/request-key is about to be
    spawned and do something else with them - passing them over the
    rpc_pipefs files or netlink sockets for instance.

    The uninstantiated key, the authorisation key and the intended operation
    name are passed to the method.

    (2) The callout_info is no longer passed as an argument to /sbin/request-key
    to prevent unauthorised viewing of this data using ps or by looking in
    /proc/pid/cmdline.

    This means that the old /sbin/request-key program will not work with the
    patched kernel as it will expect to see an extra argument that is no
    longer there.

    A revised keyutils package will be made available tomorrow.

    (3) The callout_info is now attached to the authorisation key. Reading this
    key will retrieve the information.

    (4) A new field has been added to the task_struct. This holds the
    authorisation key currently active for a thread. Searches now look here
    for the caller's set of keys rather than looking for an auth key in the
    lowest level of the session keyring.

    This permits a thread to be servicing multiple requests at once and to
    switch between them. Note that this is per-thread, not per-process, and
    so is usable in multithreaded programs.

    The setting of this field is inherited across fork and exec.

    (5) A new keyctl function (KEYCTL_ASSUME_AUTHORITY) has been added that
    permits a thread to assume the authority to deal with an uninstantiated
    key. Assumption is only permitted if the authorisation key associated
    with the uninstantiated key is somewhere in the thread's keyrings.

    This function can also clear the assumption.

    (6) A new magic key specifier has been added to refer to the currently
    assumed authorisation key (KEY_SPEC_REQKEY_AUTH_KEY).

    (7) Instantiation will only proceed if the appropriate authorisation key is
    assumed first. The assumed authorisation key is discarded if
    instantiation is successful.

    (8) key_validate() is moved from the file of request_key functions to the
    file of permissions functions.

    (9) The documentation is updated.

    From:

    Build fix.

    Signed-off-by: David Howells
    Cc: Trond Myklebust
    Cc: Alexander Zangerl
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     
  • Add a new keyctl function that allows the expiry time to be set on a key or
    removed from a key, provided the caller has attribute modification access.

    Signed-off-by: David Howells
    Cc: Trond Myklebust
    Cc: Alexander Zangerl
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     

24 Jun, 2005

1 commit

  • The attached patch makes the following changes:

    (1) There's a new special key type called ".request_key_auth".

    This is an authorisation key for when one process requests a key and
    another process is started to construct it. This type of key cannot be
    created by the user; nor can it be requested by kernel services.

    Authorisation keys hold two references:

    (a) Each refers to a key being constructed. When the key being
    constructed is instantiated the authorisation key is revoked,
    rendering it of no further use.

    (b) The "authorising process". This is either:

    (i) the process that called request_key(), or:

    (ii) if the process that called request_key() itself had an
    authorisation key in its session keyring, then the authorising
    process referred to by that authorisation key will also be
    referred to by the new authorisation key.

    This means that the process that initiated a chain of key requests
    will authorise the lot of them, and will, by default, wind up with
    the keys obtained from them in its keyrings.

    (2) request_key() creates an authorisation key which is then passed to
    /sbin/request-key in as part of a new session keyring.

    (3) When request_key() is searching for a key to hand back to the caller, if
    it comes across an authorisation key in the session keyring of the
    calling process, it will also search the keyrings of the process
    specified therein and it will use the specified process's credentials
    (fsuid, fsgid, groups) to do that rather than the calling process's
    credentials.

    This allows a process started by /sbin/request-key to find keys belonging
    to the authorising process.

    (4) A key can be read, even if the process executing KEYCTL_READ doesn't have
    direct read or search permission if that key is contained within the
    keyrings of a process specified by an authorisation key found within the
    calling process's session keyring, and is searchable using the
    credentials of the authorising process.

    This allows a process started by /sbin/request-key to read keys belonging
    to the authorising process.

    (5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
    KEYCTL_NEGATE will specify a keyring of the authorising process, rather
    than the process doing the instantiation.

    (6) One of the process keyrings can be nominated as the default to which
    request_key() should attach new keys if not otherwise specified. This is
    done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
    constants. The current setting can also be read using this call.

    (7) request_key() is partially interruptible. If it is waiting for another
    process to finish constructing a key, it can be interrupted. This permits
    a request-key cycle to be broken without recourse to rebooting.

    Signed-Off-By: David Howells
    Signed-Off-By: Benoit Boissinot
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     

17 Apr, 2005

1 commit

  • Initial git repository build. I'm not bothering with the full history,
    even though we have it. We can create a separate "historical" git
    archive of that later if we want to, and in the meantime it's about
    3.2GB when imported into git - space that would just make the early
    git days unnecessarily complicated, when we don't have a lot of good
    infrastructure for it.

    Let it rip!

    Linus Torvalds