Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1541946 > unrolled thread

Re: Revised request_key(2) man page for review

Started by"Michael Kerrisk (man-pages)" <mtk.manpages@gmail.com>
First post2016-12-14 15:30 +0100
Last post2016-12-19 09:20 +0100
Articles 4 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Revised request_key(2) man page for review "Michael Kerrisk (man-pages)" <mtk.manpages@gmail.com> - 2016-12-14 15:30 +0100
    Re: Revised request_key(2) man page for review David Howells <dhowells@redhat.com> - 2016-12-15 11:20 +0100
      Re: Revised request_key(2) man page for review "Michael Kerrisk (man-pages)" <mtk.manpages@gmail.com> - 2016-12-17 11:40 +0100
        Re: Revised request_key(2) man page for review David Howells <dhowells@redhat.com> - 2016-12-19 09:20 +0100

#1541946 — Re: Revised request_key(2) man page for review

From"Michael Kerrisk (man-pages)" <mtk.manpages@gmail.com>
Date2016-12-14 15:30 +0100
SubjectRe: Revised request_key(2) man page for review
Message-ID<sOiJc-7xh-29@gated-at.bofh.it>
Hi David,

Might you also have a chance to take a look at this page?

Cheers,

Michael


On 4 November 2016 at 16:45, Michael Kerrisk (man-pages)
<mtk.manpages@gmail.com> wrote:
> Hi David (and anyone else with an interest to review)
>
> Triggered by Eugene Syromyatnikov's recent input for the keyctl(2)
> man page, I've been doing a fair bit of work on improving the key
> management syscall man pages, and wonder if I could ask you for
> some review  assistance?
>
> First off, below, I've pasted the current draft of the request_key(2)
> page, which has seen quite a a lot of changes (increasing from around
> 100 rendered lines to nearly 300). Could you take a look (and also take
> a look at the outstanding FIXME)? (The page source file is attached,
> in case you want to see all the formatting.)
>
> Thanks,
>
> Michael
>
> ====
>
> NAME
>        request_key  -  request  a key from the kernel's key management
>        facility
>
> SYNOPSIS
>        #include <sys/types.h>
>        #include <keyutils.h>
>
>        key_serial_t request_key(const char *type, const char *description,
>                                 const char *callout_info,
>                                 key_serial_t dest_keyring);
>
>        No glibc wrapper is provided for this system call; see NOTES.
>
> DESCRIPTION
>        request_key() attempts to find a key of the given type  with  a
>        description  (name) that matches the specified description.  If
>        such a key could not be found, then the key is optionally  cre‐
>        ated.   If  the key is found or created, request_key() attaches
>        it to the keyring whose ID is  specified  in  dest_keyring  and
>        returns the key's serial number.
>
>
>        ┌─────────────────────────────────────────────────────┐
>        │FIXME                                                │
>        ├─────────────────────────────────────────────────────┤
>        │Is 'keyring' allowed to be 0? Reading the source, it │
>        │appears so.  In this case, by default,  the  key  is │
>        │assigned   to   the   session   keyring.   But,  the │
>        │KEYCTL_SET_REQKEY_KEYRING  also  seems  to  have  an │
>        │influence here.  What are the details here?          │
>        │                                                     │
>        └─────────────────────────────────────────────────────┘
>
>        request_key()  first recursively searches for a matching key in
>        all of the keyrings  attached  to  the  calling  process.   The
>        keyrings  are  searched  in the order: thread-specific keyring,
>        process-specific keyring, and then session keyring.
>
>        If  request_key()  is  called  from  a   program   invoked   by
>        request_key()  on  behalf  of  some other process to generate a
>        key, then the keyrings of that other process will  be  searched
>        next,  using that other process's user ID, group ID, supplemen‐
>        tary group IDs, and security context to determine access.
>
>        The search of the keyring tree is breadth-first:  the  keys  in
>        each  keyring searched are checked for a match before any child
>        keyrings are recursed into.  Only keys for which the caller has
>        search  permission  be  found,  and only keyrings for which the
>        caller has search permission may be searched.
>
>        If the key is not found and callout  is  NULL,  then  the  call
>        fails with the error ENOKEY.
>
>        If  the key is not found and callout is not NULL, then the ker‐
>        nel attempts to invoke a user-space program to instantiate  the
>        key.  The details are given below.
>
>        The  dest_keyring  serial number may be that of a valid keyring
>        for which the caller has write permission, or it may be one  of
>        the following special keyring IDs:
>
>        KEY_SPEC_THREAD_KEYRING
>               This  specifies  the  caller's  thread-specific  keyring
>               (thread-keyring(7)).
>
>        KEY_SPEC_PROCESS_KEYRING
>               This specifies  the  caller's  process-specific  keyring
>               (process-keyring(7)).
>
>        KEY_SPEC_SESSION_KEYRING
>               This  specifies  the  caller's  session-specific keyring
>               (session-keyring(7)).
>
>        KEY_SPEC_USER_KEYRING
>               This specifies the caller's UID-specific keyring  (user-
>               keyring(7)).
>
>        KEY_SPEC_USER_SESSION_KEYRING
>               This  specifies  the caller's UID-session keyring (user-
>               session-keyring(7)).
>
>    Requesting user-space instantiation of a key
>        If the kernel cannot find a key matching type and  description,
>        and  callout  is not NULL, then the kernel attempts to invoke a
>        user-space program to instantiate a key with the given type and
>        description.  In this case, the following steps are performed:
>
>        a)  The  kernel  creates  an  uninstantiated  key,  U, with the
>            requested type and description.
>
>        b)  The kernel creates an authorization key, V, that refers  to
>            the  key  U  and  records  the  facts  that  the  caller of
>            request_key(2) is:
>
>            (1) the context in which the key U should  be  instantiated
>                and secured, and
>
>            (2) the  context  from which associated key requests may be
>                satisfied.
>
>            The authorization key is constructed as follows:
>
>            *  The key type is ".request_key_auth".
>
>            *  The key's UID and GID are the same as the  corresponding
>               filesystem IDs of the requesting process.
>
>            *  The key grants view, read, and search permissions to the
>               key possessor as well as view  permission  for  the  key
>               user.
>
>            *  The  description  (name)  of  the key is the hexadecimal
>               string representing the ID of the  key  that  is  to  be
>               instantiated in the requesting program.
>
>            *  The  payload of the key is taken from the data specified
>               in callout_info.
>
>            *  Internally, the kernel also records a record of the  PID
>               of the process that called request_key(2).
>
>        c)  The  kernel  creates  a  process that executes a user-space
>            service such as request-key(8) with a new  session  keyring
>            that contains a link to the authorization key, V.
>
>            This  program  is  supplied with the following command-line
>            arguments:
>
>            [0] The string "/sbin/request-key".
>
>            [1] The string "create" (indicating that a  key  is  to  be
>                created).
>
>            [2] The ID of the key that is to be instantiated.
>
>            [3] The filesystem UID of the caller of request_key().
>
>            [4] The filesystem GID of the caller of request_key().
>
>            [5] The   ID  of  the  thread  keyring  of  the  caller  of
>                request_key().  This may be zero if that keyring hasn't
>                been created.
>
>            [6] The  ID  of  the  process  keyring  of  the  caller  of
>                request_key().  This may be zero if that keyring hasn't
>                been created.
>
>            [7] The  ID  of  the  session  keyring  of  the  caller  of
>                request_key().
>
>            Note: each of the command-line arguments that is a  key  ID
>            is  encoded  in  decimal  (unlike  the  key  IDs  shown  in
>            /proc/keys, which are shown as hexadecimal values).
>
>        d)  The program spawned in the previous step:
>
>            *  Assumes the authority to instantiate the key U using the
>               keyctl(2)  KEYCTL_ASSUME_AUTHORITY  operation (typically
>               via the keyctl_assume_authority(3) function).
>
>            *  Obtains the callout data from the payload of the  autho‐
>               rization  key  V (using the keyctl(2) KEYCTL_READ opera‐
>               tion (or, more commonly,  the  keyctl_read(3)  function)
>               with a key ID value of KEY_SPEC_REQKEY_AUTH_KEY).
>
>            *  Instantiates the key (or execs another program that per‐
>               forms that task), specifying the payload and destination
>               keyring.   (The  destination  keyring that the requestor
>               specified when calling  request_key()  can  be  accessed
>               using  the  special  key ID KEY_SPEC_REQUESTOR_KEYRING.)
>               Instantiation   is   performed   using   the   keyctl(2)
>               KEYCTL_INSTANTIATE  operation  (or,  more  commonly, the
>               keyctl_instantiate(3) function).   At  this  point,  the
>               request_key(2)  call  completes, and the requesting pro‐
>               gram can continue execution.
>
>        If these steps are unsuccessful, then an ENOKEY error  will  be
>        returned  to  the caller of request_key() and a temporary nega‐
>        tive  key  will  be  installed  in  the  keyring  specified  by
>        dest_keyring.   This  will expire after a few seconds, but will
>        cause subsequent calls to request_key() to fail until it  does.
>        The  purpose  of this negatively instantiated key is to prevent
>        (possibly different) processes making repeated  requests  (that
>        require  expensive request-key(8) upcalls) for a key that can't
>        (at the moment) be positively instantiated.
>
>        Once the key  has  been  instantiated,  the  authorization  key
>        (KEY_SPEC_REQKEY_AUTH_KEY)  is  revoked,  and  the  destination
>        keyring (KEY_SPEC_REQUESTOR_KEYRING) is  no  longer  accessible
>        from the request-key(8) program.
>
>        If  a  key is created, then—regardless of whether it is a valid
>        key or a negative key—it will displace any other key  with  the
>        same  type  and  description  from  the  keyring  specified  in
>        dest_keyring.
>
> RETURN VALUE
>        On success, request_key() returns the serial number of the  key
>        it found or caused to be created.  On error, -1 is returned and
>        errno is set to indicate the cause of the error.
>
> ERRORS
>        EACCES The keyring wasn't available  for  modification  by  the
>               user.
>
>        EDQUOT The  key quota for this user would be exceeded by creat‐
>               ing this key or linking it to the keyring.
>
>        EINTR  The request was interrupted by a signal; see signal(7).
>
>        EINVAL The size of the string (including the  terminating  null
>               byte)  specified  in  type  or  description exceeded the
>               limit (32 bytes and 4096 bytes respectively).
>
>        EINVAL The size of the string (including the  terminating  null
>               byte) specified in callout_info exceeded the system page
>               size.
>
>        EKEYEXPIRED
>               An expired key was found, but no  replacement  could  be
>               obtained.
>
>        EKEYREJECTED
>               The attempt to generate a new key was rejected.
>
>        EKEYREVOKED
>               A  revoked  key  was  found, but no replacement could be
>               obtained.
>
>        ENOKEY No matching key was found.
>
>        ENOMEM Insufficient memory to create a key.
>
> VERSIONS
>        This system call first appeared in Linux 2.6.10.
>
> CONFORMING TO
>        This system call is a nonstandard Linux extension.
>
> NOTES
>        No wrapper for this system call is provided in glibc.  A  wrap‐
>        per is provided in the libkeyutils package.  When employing the
>        wrapper in that library, link with -lkeyutils.
>
> EXAMPLE
>        The program below demonstrates the use of  request_key().   The
>        type,  description,  and  callout_info arguments for the system
>        call are taken from the values supplied  in  the  command  line
>        arguments.   The call specifies the session keyring as the tar‐
>        get keyring.
>
>        In order to demonstrate this program, we first create  a  suit‐
>        able entry in the file /etc/request-key.conf.
>
>            $ sudo sh
>            # echo 'create user mtk:* *   /bin/keyctl instantiate %k %c %S' \
>                      > /etc/request-keys.conf
>            # exit
>
>        This entry specifies that when a new "user" key with the prefix
>        "mtk:" must be instantiated, that task should be performed  via
>        the  keyctl(1)  command's  instantiate operation.  (The program
>        could The arguments supplied to the instantiate operation  are:
>        the  ID  of  the uninstantiated key (%k); the callout data sup‐
>        plied to the request_key() call (%c); and the  session  keyring
>        (%S)  of  the  requestor  (i.e.,  the caller of request)key()).
>        i(See request-key.conf(5) for details of these % specifiers.)
>
>        Then we run the program and check the contents of /proc/keys to
>        verify that the requested kay has been instantiated:
>
>            $ ./a.out user mtk:key1 "Payload data"
>            $ grep '2dddaf50' /proc/keys
>            2dddaf50 I--Q---   1 perm 3f010000  1000  1000 user   mtk:key1: 12
>
>    Program source
>        The program below
>        #include <sys/types.h>
>        #include <keyutils.h>
>        #include <stdio.h>
>        #include <stdlib.h>
>        #include <string.h>
>
>        #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
>                                } while (0)
>
>        int
>        main(int argc, char *argv[])
>        {
>            key_serial_t key;
>
>            if (argc != 4) {
>                fprintf(stderr, "Usage: %s type description callout-data\n",
>                        argv[0]);
>                exit(EXIT_FAILURE);
>            }
>
>            key = request_key(argv[1], argv[2], argv[3],
>                              KEY_SPEC_SESSION_KEYRING);
>            if (key == -1)
>                errExit("request_key");
>
>            printf("Key ID is %lx\n", (long) key);
>
>            exit(EXIT_SUCCESS);
>        }
>
> SEE ALSO
>        keyctl(1), add_key(2), keyctl(2), keyctl(3), keyrings(7),
>        keyutils(7), capabilities(7), persistent-keyring(7),
>        process-keyring(7), session-keyring(7), thread-keyring(7),
>        user-keyring(7), user-session-keyring(7), request-key(8)
>
>        The kernel source files Documentation/security/keys.txt and
>        Documentation/security/keys-request-key.txt.
>
>
>
> Linux                         2016-10-08                REQUEST_KEY(2)
>
> --
> Michael Kerrisk
> Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
> Linux/UNIX System Programming Training: http://man7.org/training/



-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

[toc] | [next] | [standalone]


#1542618

FromDavid Howells <dhowells@redhat.com>
Date2016-12-15 11:20 +0100
Message-ID<sOBiO-4xG-25@gated-at.bofh.it>
In reply to#1541946
Michael Kerrisk (man-pages) <mtk.manpages@gmail.com> wrote:

> >        │Is 'keyring' allowed to be 0? Reading the source, it │
> >        │appears so.  In this case, by default,  the  key  is │
> >        │assigned   to   the   session   keyring.   But,  the │
> >        │KEYCTL_SET_REQKEY_KEYRING  also  seems  to  have  an │
> >        │influence here.  What are the details here?          │

Yes, the destination keyring can be 0.  If you don't specify a destination
keyring, then:

 (1) If the key is found to already exist, the serial number is returned, but
     no extra link is made.

 (2) If an error occurs other than "this key doesn't exist", then you'll just
     get the error.

 (3) If we have to construct a new key, this will be attached to the default
     keyring (as there's no destination keyring to attach to).

> >            # echo 'create user mtk:* *   /bin/keyctl instantiate %k %c %S' \
> >                      > /etc/request-keys.conf

There's a /etc/request-keys.d/ directory now.

David

[toc] | [prev] | [next] | [standalone]


#1543950

From"Michael Kerrisk (man-pages)" <mtk.manpages@gmail.com>
Date2016-12-17 11:40 +0100
Message-ID<sPkzf-8q7-1@gated-at.bofh.it>
In reply to#1542618
Hello David,

On 12/15/2016 11:10 AM, David Howells wrote:
> Michael Kerrisk (man-pages) <mtk.manpages@gmail.com> wrote:
> 
>>>        │Is 'keyring' allowed to be 0? Reading the source, it │
>>>        │appears so.  In this case, by default,  the  key  is │
>>>        │assigned   to   the   session   keyring.   But,  the │
>>>        │KEYCTL_SET_REQKEY_KEYRING  also  seems  to  have  an │
>>>        │influence here.  What are the details here?          │
> 
> Yes, the destination keyring can be 0.  If you don't specify a destination
> keyring, then:
> 
>  (1) If the key is found to already exist, the serial number is returned, but
>      no extra link is made.
> 
>  (2) If an error occurs other than "this key doesn't exist", then you'll just
>      get the error.
> 
>  (3) If we have to construct a new key, this will be attached to the default
>      keyring (as there's no destination keyring to attach to).

Okay. Please take a look at the revised text that I'll send out
after applying Eugene's patch. (Mail in a few minutes.)

>>>            # echo 'create user mtk:* *   /bin/keyctl instantiate %k %c %S' \
>>>                      > /etc/request-keys.conf
> 
> There's a /etc/request-keys.d/ directory now.

Yes, I'm aware. Did you mean I should fix something on this page?

Cheers,

Michael


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/

[toc] | [prev] | [next] | [standalone]


#1544366

FromDavid Howells <dhowells@redhat.com>
Date2016-12-19 09:20 +0100
Message-ID<sQ1kS-5f4-33@gated-at.bofh.it>
In reply to#1543950
Michael Kerrisk (man-pages) <mtk.manpages@gmail.com> wrote:

> >>>            # echo 'create user mtk:* *   /bin/keyctl instantiate %k %c %S' \
> >>>                      > /etc/request-keys.conf
> > 
> > There's a /etc/request-keys.d/ directory now.
> 
> Yes, I'm aware. Did you mean I should fix something on this page?

I mean you probably shouldn't modify /etc/request-keys.conf, but rather put
something in the .d dir.

David

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web