02 Nov, 2020

1 commit


23 Oct, 2020

1 commit


03 Oct, 2020

1 commit


14 Jun, 2020

1 commit

  • …git/dhowells/linux-fs

    Pull notification queue from David Howells:
    "This adds a general notification queue concept and adds an event
    source for keys/keyrings, such as linking and unlinking keys and
    changing their attributes.

    Thanks to Debarshi Ray, we do have a pull request to use this to fix a
    problem with gnome-online-accounts - as mentioned last time:

    https://gitlab.gnome.org/GNOME/gnome-online-accounts/merge_requests/47

    Without this, g-o-a has to constantly poll a keyring-based kerberos
    cache to find out if kinit has changed anything.

    [ There are other notification pending: mount/sb fsinfo notifications
    for libmount that Karel Zak and Ian Kent have been working on, and
    Christian Brauner would like to use them in lxc, but let's see how
    this one works first ]

    LSM hooks are included:

    - A set of hooks are provided that allow an LSM to rule on whether or
    not a watch may be set. Each of these hooks takes a different
    "watched object" parameter, so they're not really shareable. The
    LSM should use current's credentials. [Wanted by SELinux & Smack]

    - A hook is provided to allow an LSM to rule on whether or not a
    particular message may be posted to a particular queue. This is
    given the credentials from the event generator (which may be the
    system) and the watch setter. [Wanted by Smack]

    I've provided SELinux and Smack with implementations of some of these
    hooks.

    WHY
    ===

    Key/keyring notifications are desirable because if you have your
    kerberos tickets in a file/directory, your Gnome desktop will monitor
    that using something like fanotify and tell you if your credentials
    cache changes.

    However, we also have the ability to cache your kerberos tickets in
    the session, user or persistent keyring so that it isn't left around
    on disk across a reboot or logout. Keyrings, however, cannot currently
    be monitored asynchronously, so the desktop has to poll for it - not
    so good on a laptop. This facility will allow the desktop to avoid the
    need to poll.

    DESIGN DECISIONS
    ================

    - The notification queue is built on top of a standard pipe. Messages
    are effectively spliced in. The pipe is opened with a special flag:

    pipe2(fds, O_NOTIFICATION_PIPE);

    The special flag has the same value as O_EXCL (which doesn't seem
    like it will ever be applicable in this context)[?]. It is given up
    front to make it a lot easier to prohibit splice&co from accessing
    the pipe.

    [?] Should this be done some other way? I'd rather not use up a new
    O_* flag if I can avoid it - should I add a pipe3() system call
    instead?

    The pipe is then configured::

    ioctl(fds[1], IOC_WATCH_QUEUE_SET_SIZE, queue_depth);
    ioctl(fds[1], IOC_WATCH_QUEUE_SET_FILTER, &filter);

    Messages are then read out of the pipe using read().

    - It should be possible to allow write() to insert data into the
    notification pipes too, but this is currently disabled as the
    kernel has to be able to insert messages into the pipe *without*
    holding pipe->mutex and the code to make this work needs careful
    auditing.

    - sendfile(), splice() and vmsplice() are disabled on notification
    pipes because of the pipe->mutex issue and also because they
    sometimes want to revert what they just did - but one or more
    notification messages might've been interleaved in the ring.

    - The kernel inserts messages with the wait queue spinlock held. This
    means that pipe_read() and pipe_write() have to take the spinlock
    to update the queue pointers.

    - Records in the buffer are binary, typed and have a length so that
    they can be of varying size.

    This allows multiple heterogeneous sources to share a common
    buffer; there are 16 million types available, of which I've used
    just a few, so there is scope for others to be used. Tags may be
    specified when a watchpoint is created to help distinguish the
    sources.

    - Records are filterable as types have up to 256 subtypes that can be
    individually filtered. Other filtration is also available.

    - Notification pipes don't interfere with each other; each may be
    bound to a different set of watches. Any particular notification
    will be copied to all the queues that are currently watching for it
    - and only those that are watching for it.

    - When recording a notification, the kernel will not sleep, but will
    rather mark a queue as having lost a message if there's
    insufficient space. read() will fabricate a loss notification
    message at an appropriate point later.

    - The notification pipe is created and then watchpoints are attached
    to it, using one of:

    keyctl_watch_key(KEY_SPEC_SESSION_KEYRING, fds[1], 0x01);
    watch_mount(AT_FDCWD, "/", 0, fd, 0x02);
    watch_sb(AT_FDCWD, "/mnt", 0, fd, 0x03);

    where in both cases, fd indicates the queue and the number after is
    a tag between 0 and 255.

    - Watches are removed if either the notification pipe is destroyed or
    the watched object is destroyed. In the latter case, a message will
    be generated indicating the enforced watch removal.

    Things I want to avoid:

    - Introducing features that make the core VFS dependent on the
    network stack or networking namespaces (ie. usage of netlink).

    - Dumping all this stuff into dmesg and having a daemon that sits
    there parsing the output and distributing it as this then puts the
    responsibility for security into userspace and makes handling
    namespaces tricky. Further, dmesg might not exist or might be
    inaccessible inside a container.

    - Letting users see events they shouldn't be able to see.

    TESTING AND MANPAGES
    ====================

    - The keyutils tree has a pipe-watch branch that has keyctl commands
    for making use of notifications. Proposed manual pages can also be
    found on this branch, though a couple of them really need to go to
    the main manpages repository instead.

    If the kernel supports the watching of keys, then running "make
    test" on that branch will cause the testing infrastructure to spawn
    a monitoring process on the side that monitors a notifications pipe
    for all the key/keyring changes induced by the tests and they'll
    all be checked off to make sure they happened.

    https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/keyutils.git/log/?h=pipe-watch

    - A test program is provided (samples/watch_queue/watch_test) that
    can be used to monitor for keyrings, mount and superblock events.
    Information on the notifications is simply logged to stdout"

    * tag 'notifications-20200601' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
    smack: Implement the watch_key and post_notification hooks
    selinux: Implement the watch_key security hook
    keys: Make the KEY_NEED_* perms an enum rather than a mask
    pipe: Add notification lossage handling
    pipe: Allow buffers to be marked read-whole-or-error for notifications
    Add sample notification program
    watch_queue: Add a key/keyring notification facility
    security: Add hooks to rule on setting a watch
    pipe: Add general notification queue support
    pipe: Add O_NOTIFICATION_PIPE
    security: Add a hook for the point of notification insertion
    uapi: General notification queue definitions

    Linus Torvalds
     

05 Jun, 2020

1 commit

  • For kvmalloc'ed data object that contains sensitive information like
    cryptographic keys, we need to make sure that the buffer is always cleared
    before freeing it. Using memset() alone for buffer clearing may not
    provide certainty as the compiler may compile it away. To be sure, the
    special memzero_explicit() has to be used.

    This patch introduces a new kvfree_sensitive() for freeing those sensitive
    data objects allocated by kvmalloc(). The relevant places where
    kvfree_sensitive() can be used are modified to use it.

    Fixes: 4f0882491a14 ("KEYS: Avoid false positive ENOMEM error on key read")
    Suggested-by: Linus Torvalds
    Signed-off-by: Waiman Long
    Signed-off-by: Andrew Morton
    Reviewed-by: Eric Biggers
    Acked-by: David Howells
    Cc: Jarkko Sakkinen
    Cc: James Morris
    Cc: "Serge E. Hallyn"
    Cc: Joe Perches
    Cc: Matthew Wilcox
    Cc: David Rientjes
    Cc: Uladzislau Rezki
    Link: http://lkml.kernel.org/r/20200407200318.11711-1-longman@redhat.com
    Signed-off-by: Linus Torvalds

    Waiman Long
     

19 May, 2020

2 commits

  • Since the meaning of combining the KEY_NEED_* constants is undefined, make
    it so that you can't do that by turning them into an enum.

    The enum is also given some extra values to represent special
    circumstances, such as:

    (1) The '0' value is reserved and causes a warning to trap the parameter
    being unset.

    (2) The key is to be unlinked and we require no permissions on it, only
    the keyring, (this replaces the KEY_LOOKUP_FOR_UNLINK flag).

    (3) An override due to CAP_SYS_ADMIN.

    (4) An override due to an instantiation token being present.

    (5) The permissions check is being deferred to later key_permission()
    calls.

    The extra values give the opportunity for LSMs to audit these situations.

    [Note: This really needs overhauling so that lookup_user_key() tells
    key_task_permission() and the LSM what operation is being done and leaves
    it to those functions to decide how to map that onto the available
    permits. However, I don't really want to make these change in the middle
    of the notifications patchset.]

    Signed-off-by: David Howells
    cc: Jarkko Sakkinen
    cc: Paul Moore
    cc: Stephen Smalley
    cc: Casey Schaufler
    cc: keyrings@vger.kernel.org
    cc: selinux@vger.kernel.org

    David Howells
     
  • Add a key/keyring change notification facility whereby notifications about
    changes in key and keyring content and attributes can be received.

    Firstly, an event queue needs to be created:

    pipe2(fds, O_NOTIFICATION_PIPE);
    ioctl(fds[1], IOC_WATCH_QUEUE_SET_SIZE, 256);

    then a notification can be set up to report notifications via that queue:

    struct watch_notification_filter filter = {
    .nr_filters = 1,
    .filters = {
    [0] = {
    .type = WATCH_TYPE_KEY_NOTIFY,
    .subtype_filter[0] = UINT_MAX,
    },
    },
    };
    ioctl(fds[1], IOC_WATCH_QUEUE_SET_FILTER, &filter);
    keyctl_watch_key(KEY_SPEC_SESSION_KEYRING, fds[1], 0x01);

    After that, records will be placed into the queue when events occur in
    which keys are changed in some way. Records are of the following format:

    struct key_notification {
    struct watch_notification watch;
    __u32 key_id;
    __u32 aux;
    } *n;

    Where:

    n->watch.type will be WATCH_TYPE_KEY_NOTIFY.

    n->watch.subtype will indicate the type of event, such as
    NOTIFY_KEY_REVOKED.

    n->watch.info & WATCH_INFO_LENGTH will indicate the length of the
    record.

    n->watch.info & WATCH_INFO_ID will be the second argument to
    keyctl_watch_key(), shifted.

    n->key will be the ID of the affected key.

    n->aux will hold subtype-dependent information, such as the key
    being linked into the keyring specified by n->key in the case of
    NOTIFY_KEY_LINKED.

    Note that it is permissible for event records to be of variable length -
    or, at least, the length may be dependent on the subtype. Note also that
    the queue can be shared between multiple notifications of various types.

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

    David Howells
     

29 Mar, 2020

1 commit

  • By allocating a kernel buffer with a user-supplied buffer length, it
    is possible that a false positive ENOMEM error may be returned because
    the user-supplied length is just too large even if the system do have
    enough memory to hold the actual key data.

    Moreover, if the buffer length is larger than the maximum amount of
    memory that can be returned by kmalloc() (2^(MAX_ORDER-1) number of
    pages), a warning message will also be printed.

    To reduce this possibility, we set a threshold (PAGE_SIZE) over which we
    do check the actual key length first before allocating a buffer of the
    right size to hold it. The threshold is arbitrary, it is just used to
    trigger a buffer length check. It does not limit the actual key length
    as long as there is enough memory to satisfy the memory request.

    To further avoid large buffer allocation failure due to page
    fragmentation, kvmalloc() is used to allocate the buffer so that vmapped
    pages can be used when there is not a large enough contiguous set of
    pages available for allocation.

    In the extremely unlikely scenario that the key keeps on being changed
    and made longer (still
    Signed-off-by: David Howells

    Waiman Long
     

13 Dec, 2019

1 commit

  • KEYS_COMPAT now always takes the value of COMPAT && KEYS. But the
    security/keys/ directory is only compiled if KEYS is enabled, so in
    practice KEYS_COMPAT is the same as COMPAT. Therefore, remove the
    unnecessary KEYS_COMPAT and just use COMPAT directly.

    (Also remove an outdated comment from compat.c.)

    Reviewed-by: James Morris
    Signed-off-by: Eric Biggers
    Reviewed-by: Jarkko Sakkinen
    Tested-by: Jarkko Sakkinen
    Signed-off-by: Jarkko Sakkinen

    Eric Biggers
     

11 Jul, 2019

1 commit

  • …el/git/dhowells/linux-fs"

    This reverts merge 0f75ef6a9cff49ff612f7ce0578bced9d0b38325 (and thus
    effectively commits

    7a1ade847596 ("keys: Provide KEYCTL_GRANT_PERMISSION")
    2e12256b9a76 ("keys: Replace uid/gid/perm permissions checking with an ACL")

    that the merge brought in).

    It turns out that it breaks booting with an encrypted volume, and Eric
    biggers reports that it also breaks the fscrypt tests [1] and loading of
    in-kernel X.509 certificates [2].

    The root cause of all the breakage is likely the same, but David Howells
    is off email so rather than try to work it out it's getting reverted in
    order to not impact the rest of the merge window.

    [1] https://lore.kernel.org/lkml/20190710011559.GA7973@sol.localdomain/
    [2] https://lore.kernel.org/lkml/20190710013225.GB7973@sol.localdomain/

    Link: https://lore.kernel.org/lkml/CAHk-=wjxoeMJfeBahnWH=9zShKp2bsVy527vo3_y8HfOdhwAAw@mail.gmail.com/
    Reported-by: Eric Biggers <ebiggers@kernel.org>
    Cc: David Howells <dhowells@redhat.com>
    Cc: James Morris <jmorris@namei.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

    Linus Torvalds
     

09 Jul, 2019

4 commits

  • Pull keyring ACL support from David Howells:
    "This changes the permissions model used by keys and keyrings to be
    based on an internal ACL by the following means:

    - Replace the permissions mask internally with an ACL that contains a
    list of ACEs, each with a specific subject with a permissions mask.
    Potted default ACLs are available for new keys and keyrings.

    ACE subjects can be macroised to indicate the UID and GID specified
    on the key (which remain). Future commits will be able to add
    additional subject types, such as specific UIDs or domain
    tags/namespaces.

    Also split a number of permissions to give finer control. Examples
    include splitting the revocation permit from the change-attributes
    permit, thereby allowing someone to be granted permission to revoke
    a key without allowing them to change the owner; also the ability
    to join a keyring is split from the ability to link to it, thereby
    stopping a process accessing a keyring by joining it and thus
    acquiring use of possessor permits.

    - Provide a keyctl to allow the granting or denial of one or more
    permits to a specific subject. Direct access to the ACL is not
    granted, and the ACL cannot be viewed"

    * tag 'keys-acl-20190703' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
    keys: Provide KEYCTL_GRANT_PERMISSION
    keys: Replace uid/gid/perm permissions checking with an ACL

    Linus Torvalds
     
  • …/git/dhowells/linux-fs

    Pull keyring namespacing from David Howells:
    "These patches help make keys and keyrings more namespace aware.

    Firstly some miscellaneous patches to make the process easier:

    - Simplify key index_key handling so that the word-sized chunks
    assoc_array requires don't have to be shifted about, making it
    easier to add more bits into the key.

    - Cache the hash value in the key so that we don't have to calculate
    on every key we examine during a search (it involves a bunch of
    multiplications).

    - Allow keying_search() to search non-recursively.

    Then the main patches:

    - Make it so that keyring names are per-user_namespace from the point
    of view of KEYCTL_JOIN_SESSION_KEYRING so that they're not
    accessible cross-user_namespace.

    keyctl_capabilities() shows KEYCTL_CAPS1_NS_KEYRING_NAME for this.

    - Move the user and user-session keyrings to the user_namespace
    rather than the user_struct. This prevents them propagating
    directly across user_namespaces boundaries (ie. the KEY_SPEC_*
    flags will only pick from the current user_namespace).

    - Make it possible to include the target namespace in which the key
    shall operate in the index_key. This will allow the possibility of
    multiple keys with the same description, but different target
    domains to be held in the same keyring.

    keyctl_capabilities() shows KEYCTL_CAPS1_NS_KEY_TAG for this.

    - Make it so that keys are implicitly invalidated by removal of a
    domain tag, causing them to be garbage collected.

    - Institute a network namespace domain tag that allows keys to be
    differentiated by the network namespace in which they operate. New
    keys that are of a type marked 'KEY_TYPE_NET_DOMAIN' are assigned
    the network domain in force when they are created.

    - Make it so that the desired network namespace can be handed down
    into the request_key() mechanism. This allows AFS, NFS, etc. to
    request keys specific to the network namespace of the superblock.

    This also means that the keys in the DNS record cache are
    thenceforth namespaced, provided network filesystems pass the
    appropriate network namespace down into dns_query().

    For DNS, AFS and NFS are good, whilst CIFS and Ceph are not. Other
    cache keyrings, such as idmapper keyrings, also need to set the
    domain tag - for which they need access to the network namespace of
    the superblock"

    * tag 'keys-namespace-20190627' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
    keys: Pass the network namespace into request_key mechanism
    keys: Network namespace domain tag
    keys: Garbage collect keys for which the domain has been removed
    keys: Include target namespace in match criteria
    keys: Move the user and user-session keyrings to the user_namespace
    keys: Namespace keyring names
    keys: Add a 'recurse' flag for keyring searches
    keys: Cache the hash value to avoid lots of recalculation
    keys: Simplify key description management

    Linus Torvalds
     
  • Pull request_key improvements from David Howells:
    "These are all request_key()-related, including a fix and some improvements:

    - Fix the lack of a Link permission check on a key found by
    request_key(), thereby enabling request_key() to link keys that
    don't grant this permission to the target keyring (which must still
    grant Write permission).

    Note that the key must be in the caller's keyrings already to be
    found.

    - Invalidate used request_key authentication keys rather than
    revoking them, so that they get cleaned up immediately rather than
    hanging around till the expiry time is passed.

    - Move the RCU locks outwards from the keyring search functions so
    that a request_key_rcu() can be provided. This can be called in RCU
    mode, so it can't sleep and can't upcall - but it can be called
    from LOOKUP_RCU pathwalk mode.

    - Cache the latest positive result of request_key*() temporarily in
    task_struct so that filesystems that make a lot of request_key()
    calls during pathwalk can take advantage of it to avoid having to
    redo the searching. This requires CONFIG_KEYS_REQUEST_CACHE=y.

    It is assumed that the key just found is likely to be used multiple
    times in each step in an RCU pathwalk, and is likely to be reused
    for the next step too.

    Note that the cleanup of the cache is done on TIF_NOTIFY_RESUME,
    just before userspace resumes, and on exit"

    * tag 'keys-request-20190626' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
    keys: Kill off request_key_async{,_with_auxdata}
    keys: Cache result of request_key*() temporarily in task_struct
    keys: Provide request_key_rcu()
    keys: Move the RCU locks outwards from the keyring search functions
    keys: Invalidate used request_key authentication keys
    keys: Fix request_key() lack of Link perm check on found key

    Linus Torvalds
     
  • Pull misc keyring updates from David Howells:
    "These are some miscellaneous keyrings fixes and improvements:

    - Fix a bunch of warnings from sparse, including missing RCU bits and
    kdoc-function argument mismatches

    - Implement a keyctl to allow a key to be moved from one keyring to
    another, with the option of prohibiting key replacement in the
    destination keyring.

    - Grant Link permission to possessors of request_key_auth tokens so
    that upcall servicing daemons can more easily arrange things such
    that only the necessary auth key is passed to the actual service
    program, and not all the auth keys a daemon might possesss.

    - Improvement in lookup_user_key().

    - Implement a keyctl to allow keyrings subsystem capabilities to be
    queried.

    The keyutils next branch has commits to make available, document and
    test the move-key and capabilities code:

    https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/keyutils.git/log

    They're currently on the 'next' branch"

    * tag 'keys-misc-20190619' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
    keys: Add capability-checking keyctl function
    keys: Reuse keyring_index_key::desc_len in lookup_user_key()
    keys: Grant Link permission to possessers of request_key auth keys
    keys: Add a keyctl to move a key between keyrings
    keys: Hoist locking out of __key_link_begin()
    keys: Break bits out of key_unlink()
    keys: Change keyring_serialise_link_sem to a mutex
    keys: sparse: Fix kdoc mismatches
    keys: sparse: Fix incorrect RCU accesses
    keys: sparse: Fix key_fs[ug]id_changed()

    Linus Torvalds
     

03 Jul, 2019

1 commit

  • Provide a keyctl() operation to grant/remove permissions. The grant
    operation, wrapped by libkeyutils, looks like:

    int ret = keyctl_grant_permission(key_serial_t key,
    enum key_ace_subject_type type,
    unsigned int subject,
    unsigned int perm);

    Where key is the key to be modified, type and subject represent the subject
    to which permission is to be granted (or removed) and perm is the set of
    permissions to be granted. 0 is returned on success. SET_SECURITY
    permission is required for this.

    The subject type currently must be KEY_ACE_SUBJ_STANDARD for the moment
    (other subject types will come along later).

    For subject type KEY_ACE_SUBJ_STANDARD, the following subject values are
    available:

    KEY_ACE_POSSESSOR The possessor of the key
    KEY_ACE_OWNER The owner of the key
    KEY_ACE_GROUP The key's group
    KEY_ACE_EVERYONE Everyone

    perm lists the permissions to be granted:

    KEY_ACE_VIEW Can view the key metadata
    KEY_ACE_READ Can read the key content
    KEY_ACE_WRITE Can update/modify the key content
    KEY_ACE_SEARCH Can find the key by searching/requesting
    KEY_ACE_LINK Can make a link to the key
    KEY_ACE_SET_SECURITY Can set security
    KEY_ACE_INVAL Can invalidate
    KEY_ACE_REVOKE Can revoke
    KEY_ACE_JOIN Can join this keyring
    KEY_ACE_CLEAR Can clear this keyring

    If an ACE already exists for the subject, then the permissions mask will be
    overwritten; if perm is 0, it will be deleted.

    Currently, the internal ACL is limited to a maximum of 16 entries.

    For example:

    int ret = keyctl_grant_permission(key,
    KEY_ACE_SUBJ_STANDARD,
    KEY_ACE_OWNER,
    KEY_ACE_VIEW | KEY_ACE_READ);

    Signed-off-by: David Howells

    David Howells
     

28 Jun, 2019

2 commits

  • Replace the uid/gid/perm permissions checking on a key with an ACL to allow
    the SETATTR and SEARCH permissions to be split. This will also allow a
    greater range of subjects to represented.

    ============
    WHY DO THIS?
    ============

    The problem is that SETATTR and SEARCH cover a slew of actions, not all of
    which should be grouped together.

    For SETATTR, this includes actions that are about controlling access to a
    key:

    (1) Changing a key's ownership.

    (2) Changing a key's security information.

    (3) Setting a keyring's restriction.

    And actions that are about managing a key's lifetime:

    (4) Setting an expiry time.

    (5) Revoking a key.

    and (proposed) managing a key as part of a cache:

    (6) Invalidating a key.

    Managing a key's lifetime doesn't really have anything to do with
    controlling access to that key.

    Expiry time is awkward since it's more about the lifetime of the content
    and so, in some ways goes better with WRITE permission. It can, however,
    be set unconditionally by a process with an appropriate authorisation token
    for instantiating a key, and can also be set by the key type driver when a
    key is instantiated, so lumping it with the access-controlling actions is
    probably okay.

    As for SEARCH permission, that currently covers:

    (1) Finding keys in a keyring tree during a search.

    (2) Permitting keyrings to be joined.

    (3) Invalidation.

    But these don't really belong together either, since these actions really
    need to be controlled separately.

    Finally, there are number of special cases to do with granting the
    administrator special rights to invalidate or clear keys that I would like
    to handle with the ACL rather than key flags and special checks.

    ===============
    WHAT IS CHANGED
    ===============

    The SETATTR permission is split to create two new permissions:

    (1) SET_SECURITY - which allows the key's owner, group and ACL to be
    changed and a restriction to be placed on a keyring.

    (2) REVOKE - which allows a key to be revoked.

    The SEARCH permission is split to create:

    (1) SEARCH - which allows a keyring to be search and a key to be found.

    (2) JOIN - which allows a keyring to be joined as a session keyring.

    (3) INVAL - which allows a key to be invalidated.

    The WRITE permission is also split to create:

    (1) WRITE - which allows a key's content to be altered and links to be
    added, removed and replaced in a keyring.

    (2) CLEAR - which allows a keyring to be cleared completely. This is
    split out to make it possible to give just this to an administrator.

    (3) REVOKE - see above.

    Keys acquire ACLs which consist of a series of ACEs, and all that apply are
    unioned together. An ACE specifies a subject, such as:

    (*) Possessor - permitted to anyone who 'possesses' a key
    (*) Owner - permitted to the key owner
    (*) Group - permitted to the key group
    (*) Everyone - permitted to everyone

    Note that 'Other' has been replaced with 'Everyone' on the assumption that
    you wouldn't grant a permit to 'Other' that you wouldn't also grant to
    everyone else.

    Further subjects may be made available by later patches.

    The ACE also specifies a permissions mask. The set of permissions is now:

    VIEW Can view the key metadata
    READ Can read the key content
    WRITE Can update/modify the key content
    SEARCH Can find the key by searching/requesting
    LINK Can make a link to the key
    SET_SECURITY Can change owner, ACL, expiry
    INVAL Can invalidate
    REVOKE Can revoke
    JOIN Can join this keyring
    CLEAR Can clear this keyring

    The KEYCTL_SETPERM function is then deprecated.

    The KEYCTL_SET_TIMEOUT function then is permitted if SET_SECURITY is set,
    or if the caller has a valid instantiation auth token.

    The KEYCTL_INVALIDATE function then requires INVAL.

    The KEYCTL_REVOKE function then requires REVOKE.

    The KEYCTL_JOIN_SESSION_KEYRING function then requires JOIN to join an
    existing keyring.

    The JOIN permission is enabled by default for session keyrings and manually
    created keyrings only.

    ======================
    BACKWARD COMPATIBILITY
    ======================

    To maintain backward compatibility, KEYCTL_SETPERM will translate the
    permissions mask it is given into a new ACL for a key - unless
    KEYCTL_SET_ACL has been called on that key, in which case an error will be
    returned.

    It will convert possessor, owner, group and other permissions into separate
    ACEs, if each portion of the mask is non-zero.

    SETATTR permission turns on all of INVAL, REVOKE and SET_SECURITY. WRITE
    permission turns on WRITE, REVOKE and, if a keyring, CLEAR. JOIN is turned
    on if a keyring is being altered.

    The KEYCTL_DESCRIBE function translates the ACL back into a permissions
    mask to return depending on possessor, owner, group and everyone ACEs.

    It will make the following mappings:

    (1) INVAL, JOIN -> SEARCH

    (2) SET_SECURITY -> SETATTR

    (3) REVOKE -> WRITE if SETATTR isn't already set

    (4) CLEAR -> WRITE

    Note that the value subsequently returned by KEYCTL_DESCRIBE may not match
    the value set with KEYCTL_SETATTR.

    =======
    TESTING
    =======

    This passes the keyutils testsuite for all but a couple of tests:

    (1) tests/keyctl/dh_compute/badargs: The first wrong-key-type test now
    returns EOPNOTSUPP rather than ENOKEY as READ permission isn't removed
    if the type doesn't have ->read(). You still can't actually read the
    key.

    (2) tests/keyctl/permitting/valid: The view-other-permissions test doesn't
    work as Other has been replaced with Everyone in the ACL.

    Signed-off-by: David Howells

    David Howells
     
  • Create a request_key_net() function and use it to pass the network
    namespace domain tag into DNS revolver keys and rxrpc/AFS keys so that keys
    for different domains can coexist in the same keyring.

    Signed-off-by: David Howells
    cc: netdev@vger.kernel.org
    cc: linux-nfs@vger.kernel.org
    cc: linux-cifs@vger.kernel.org
    cc: linux-afs@lists.infradead.org

    David Howells
     

27 Jun, 2019

5 commits

  • If a key operation domain (such as a network namespace) has been removed
    then attempt to garbage collect all the keys that use it.

    Signed-off-by: David Howells

    David Howells
     
  • Move the user and user-session keyrings to the user_namespace struct rather
    than pinning them from the user_struct struct. This prevents these
    keyrings from propagating across user-namespaces boundaries with regard to
    the KEY_SPEC_* flags, thereby making them more useful in a containerised
    environment.

    The issue is that a single user_struct may be represent UIDs in several
    different namespaces.

    The way the patch does this is by attaching a 'register keyring' in each
    user_namespace and then sticking the user and user-session keyrings into
    that. It can then be searched to retrieve them.

    Signed-off-by: David Howells
    cc: Jann Horn

    David Howells
     
  • Add a 'recurse' flag for keyring searches so that the flag can be omitted
    and recursion disabled, thereby allowing just the nominated keyring to be
    searched and none of the children.

    Signed-off-by: David Howells

    David Howells
     
  • Cache the hash of the key's type and description in the index key so that
    we're not recalculating it every time we look at a key during a search.
    The hash function does a bunch of multiplications, so evading those is
    probably worthwhile - especially as this is done for every key examined
    during a search.

    This also allows the methods used by assoc_array to get chunks of index-key
    to be simplified.

    Signed-off-by: David Howells

    David Howells
     
  • Simplify key description management by cramming the word containing the
    length with the first few chars of the description also. This simplifies
    the code that generates the index-key used by assoc_array. It should speed
    up key searching a bit too.

    Signed-off-by: David Howells

    David Howells
     

19 Jun, 2019

2 commits


31 May, 2019

3 commits

  • Add a keyctl to atomically move a link to a key from one keyring to
    another. The key must exist in "from" keyring and a flag can be given to
    cause the operation to fail if there's a matching key already in the "to"
    keyring.

    This can be done with:

    keyctl(KEYCTL_MOVE,
    key_serial_t key,
    key_serial_t from_keyring,
    key_serial_t to_keyring,
    unsigned int flags);

    The key being moved must grant Link permission and both keyrings must grant
    Write permission.

    flags should be 0 or KEYCTL_MOVE_EXCL, with the latter preventing
    displacement of a matching key from the "to" keyring.

    Signed-off-by: David Howells

    David Howells
     
  • Hoist the locking of out of __key_link_begin() and into its callers. This
    is necessary to allow the upcoming key_move() operation to correctly order
    taking of the source keyring semaphore, the destination keyring semaphore
    and the keyring serialisation lock.

    Signed-off-by: David Howells

    David Howells
     
  • Based on 1 normalized pattern(s):

    this program is free software you can redistribute it and or modify
    it under the terms of the gnu general public license as published by
    the free software foundation either version 2 of the license or at
    your option any later version

    extracted by the scancode license scanner the SPDX license identifier

    GPL-2.0-or-later

    has been chosen to replace the boilerplate/reference in 3029 file(s).

    Signed-off-by: Thomas Gleixner
    Reviewed-by: Allison Randal
    Cc: linux-spdx@vger.kernel.org
    Link: https://lkml.kernel.org/r/20190527070032.746973796@linutronix.de
    Signed-off-by: Greg Kroah-Hartman

    Thomas Gleixner
     

16 Feb, 2019

1 commit

  • In the request_key() upcall mechanism there's a dependency loop by which if
    a key type driver overrides the ->request_key hook and the userspace side
    manages to lose the authorisation key, the auth key and the internal
    construction record (struct key_construction) can keep each other pinned.

    Fix this by the following changes:

    (1) Killing off the construction record and using the auth key instead.

    (2) Including the operation name in the auth key payload and making the
    payload available outside of security/keys/.

    (3) The ->request_key hook is given the authkey instead of the cons
    record and operation name.

    Changes (2) and (3) allow the auth key to naturally be cleaned up if the
    keyring it is in is destroyed or cleared or the auth key is unlinked.

    Fixes: 7ee02a316600 ("keys: Fix dependency loop between construction record and auth key")
    Signed-off-by: David Howells
    Signed-off-by: James Morris

    David Howells
     

14 Dec, 2018

1 commit


26 Oct, 2018

1 commit

  • Provide five keyctl functions that permit userspace to make use of the new
    key type ops for accessing and driving asymmetric keys.

    (*) Query an asymmetric key.

    long keyctl(KEYCTL_PKEY_QUERY,
    key_serial_t key, unsigned long reserved,
    struct keyctl_pkey_query *info);

    Get information about an asymmetric key. The information is returned
    in the keyctl_pkey_query struct:

    __u32 supported_ops;

    A bit mask of flags indicating which ops are supported. This is
    constructed from a bitwise-OR of:

    KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}

    __u32 key_size;

    The size in bits of the key.

    __u16 max_data_size;
    __u16 max_sig_size;
    __u16 max_enc_size;
    __u16 max_dec_size;

    The maximum sizes in bytes of a blob of data to be signed, a signature
    blob, a blob to be encrypted and a blob to be decrypted.

    reserved must be set to 0. This is intended for future use to hand
    over one or more passphrases needed unlock a key.

    If successful, 0 is returned. If the key is not an asymmetric key,
    EOPNOTSUPP is returned.

    (*) Encrypt, decrypt, sign or verify a blob using an asymmetric key.

    long keyctl(KEYCTL_PKEY_ENCRYPT,
    const struct keyctl_pkey_params *params,
    const char *info,
    const void *in,
    void *out);

    long keyctl(KEYCTL_PKEY_DECRYPT,
    const struct keyctl_pkey_params *params,
    const char *info,
    const void *in,
    void *out);

    long keyctl(KEYCTL_PKEY_SIGN,
    const struct keyctl_pkey_params *params,
    const char *info,
    const void *in,
    void *out);

    long keyctl(KEYCTL_PKEY_VERIFY,
    const struct keyctl_pkey_params *params,
    const char *info,
    const void *in,
    const void *in2);

    Use an asymmetric key to perform a public-key cryptographic operation
    a blob of data.

    The parameter block pointed to by params contains a number of integer
    values:

    __s32 key_id;
    __u32 in_len;
    __u32 out_len;
    __u32 in2_len;

    For a given operation, the in and out buffers are used as follows:

    Operation ID in,in_len out,out_len in2,in2_len
    ======================= =============== =============== ===========
    KEYCTL_PKEY_ENCRYPT Raw data Encrypted data -
    KEYCTL_PKEY_DECRYPT Encrypted data Raw data -
    KEYCTL_PKEY_SIGN Raw data Signature -
    KEYCTL_PKEY_VERIFY Raw data - Signature

    info is a string of key=value pairs that supply supplementary
    information.

    The __spare space in the parameter block must be set to 0. This is
    intended, amongst other things, to allow the passing of passphrases
    required to unlock a key.

    If successful, encrypt, decrypt and sign all return the amount of data
    written into the output buffer. Verification returns 0 on success.

    Signed-off-by: David Howells
    Tested-by: Marcel Holtmann
    Reviewed-by: Marcel Holtmann
    Reviewed-by: Denis Kenzior
    Tested-by: Denis Kenzior
    Signed-off-by: James Morris

    David Howells
     

16 Nov, 2017

1 commit

  • The 'struct key' will use 'time_t' which we try to remove in the
    kernel, since 'time_t' is not year 2038 safe on 32bit systems.
    Also the 'struct keyring_search_context' will use 'timespec' type
    to record current time, which is also not year 2038 safe on 32bit
    systems.

    Thus this patch replaces 'time_t' with 'time64_t' which is year 2038
    safe for 'struct key', and replace 'timespec' with 'time64_t' for the
    'struct keyring_search_context', since we only look at the the seconds
    part of 'timespec' variable. Moreover we also change the codes where
    using the 'time_t' and 'timespec', and we can get current time by
    ktime_get_real_seconds() instead of current_kernel_time(), and use
    'TIME64_MAX' macro to initialize the 'time64_t' type variable.

    Especially in proc.c file, we have replaced 'unsigned long' and 'timespec'
    type with 'u64' and 'time64_t' type to save the timeout value, which means
    user will get one 'u64' type timeout value by issuing proc_keys_show()
    function.

    Signed-off-by: Baolin Wang
    Reviewed-by: Arnd Bergmann
    Signed-off-by: David Howells
    Reviewed-by: James Morris

    Baolin Wang
     

25 Sep, 2017

1 commit

  • It was possible for an unprivileged user to create the user and user
    session keyrings for another user. For example:

    sudo -u '#3000' sh -c 'keyctl add keyring _uid.4000 "" @u
    keyctl add keyring _uid_ses.4000 "" @u
    sleep 15' &
    sleep 1
    sudo -u '#4000' keyctl describe @u
    sudo -u '#4000' keyctl describe @us

    This is problematic because these "fake" keyrings won't have the right
    permissions. In particular, the user who created them first will own
    them and will have full access to them via the possessor permissions,
    which can be used to compromise the security of a user's keys:

    -4: alswrv-----v------------ 3000 0 keyring: _uid.4000
    -5: alswrv-----v------------ 3000 0 keyring: _uid_ses.4000

    Fix it by marking user and user session keyrings with a flag
    KEY_FLAG_UID_KEYRING. Then, when searching for a user or user session
    keyring by name, skip all keyrings that don't have the flag set.

    Fixes: 69664cf16af4 ("keys: don't generate user and user session keyrings unless they're accessed")
    Cc: [v2.6.26+]
    Signed-off-by: Eric Biggers
    Signed-off-by: David Howells

    Eric Biggers
     

19 Jul, 2017

1 commit

  • Pull structure randomization updates from Kees Cook:
    "Now that IPC and other changes have landed, enable manual markings for
    randstruct plugin, including the task_struct.

    This is the rest of what was staged in -next for the gcc-plugins, and
    comes in three patches, largest first:

    - mark "easy" structs with __randomize_layout

    - mark task_struct with an optional anonymous struct to isolate the
    __randomize_layout section

    - mark structs to opt _out_ of automated marking (which will come
    later)

    And, FWIW, this continues to pass allmodconfig (normal and patched to
    enable gcc-plugins) builds of x86_64, i386, arm64, arm, powerpc, and
    s390 for me"

    * tag 'gcc-plugins-v4.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
    randstruct: opt-out externally exposed function pointer structs
    task_struct: Allow randomized layout
    randstruct: Mark various structs for randomization

    Linus Torvalds
     

01 Jul, 2017

1 commit

  • This marks many critical kernel structures for randomization. These are
    structures that have been targeted in the past in security exploits, or
    contain functions pointers, pointers to function pointer tables, lists,
    workqueues, ref-counters, credentials, permissions, or are otherwise
    sensitive. This initial list was extracted from Brad Spengler/PaX Team's
    code in the last public patch of grsecurity/PaX based on my understanding
    of the code. Changes or omissions from the original code are mine and
    don't reflect the original grsecurity/PaX code.

    Left out of this list is task_struct, which requires special handling
    and will be covered in a subsequent patch.

    Signed-off-by: Kees Cook

    Kees Cook
     

20 Jun, 2017

1 commit

  • The wait_bit*() types and APIs are mixed into wait.h, but they
    are a pretty orthogonal extension of wait-queues.

    Furthermore, only about 50 kernel files use these APIs, while
    over 1000 use the regular wait-queue functionality.

    So clean up the main wait.h by moving the wait-bit functionality
    out of it, into a separate .h and .c file:

    include/linux/wait_bit.h for types and APIs
    kernel/sched/wait_bit.c for the implementation

    Update all header dependencies.

    This reduces the size of wait.h rather significantly, by about 30%.

    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: Ingo Molnar

    Ingo Molnar
     

05 Apr, 2017

3 commits

  • SP800-56A defines the use of DH with key derivation function based on a
    counter. The input to the KDF is defined as (DH shared secret || other
    information). The value for the "other information" is to be provided by
    the caller.

    The KDF is implemented using the hash support from the kernel crypto API.
    The implementation uses the symmetric hash support as the input to the
    hash operation is usually very small. The caller is allowed to specify
    the hash name that he wants to use to derive the key material allowing
    the use of all supported hashes provided with the kernel crypto API.

    As the KDF implements the proper truncation of the DH shared secret to
    the requested size, this patch fills the caller buffer up to its size.

    The patch is tested with a new test added to the keyutils user space
    code which uses a CAVS test vector testing the compliance with
    SP800-56A.

    Signed-off-by: Stephan Mueller
    Signed-off-by: David Howells

    Stephan Mueller
     
  • Keyrings recently gained restrict_link capabilities that allow
    individual keys to be validated prior to linking. This functionality
    was only available using internal kernel APIs.

    With the KEYCTL_RESTRICT_KEYRING command existing keyrings can be
    configured to check the content of keys before they are linked, and
    then allow or disallow linkage of that key to the keyring.

    To restrict a keyring, call:

    keyctl(KEYCTL_RESTRICT_KEYRING, key_serial_t keyring, const char *type,
    const char *restriction)

    where 'type' is the name of a registered key type and 'restriction' is a
    string describing how key linkage is to be restricted. The restriction
    option syntax is specific to each key type.

    Signed-off-by: Mat Martineau

    Mat Martineau
     
  • Replace struct key's restrict_link function pointer with a pointer to
    the new struct key_restriction. The structure contains pointers to the
    restriction function as well as relevant data for evaluating the
    restriction.

    The garbage collector checks restrict_link->keytype when key types are
    unregistered. Restrictions involving a removed key type are converted
    to use restrict_link_reject so that restrictions cannot be removed by
    unregistering key types.

    Signed-off-by: Mat Martineau

    Mat Martineau
     

03 Apr, 2017

1 commit

  • refcount_t type and corresponding API should be
    used instead of atomic_t when the variable is used as
    a reference counter. This allows to avoid accidental
    refcounter overflows that might lead to use-after-free
    situations.

    Signed-off-by: Elena Reshetova
    Signed-off-by: Hans Liljestrand
    Signed-off-by: Kees Cook
    Signed-off-by: David Windsor
    Acked-by: David Howells
    Signed-off-by: James Morris

    Elena Reshetova
     

02 Mar, 2017

1 commit