• E
    KEYS: add missing permission check for request_key() destination · 4dca6ea1
    Eric Biggers 提交于
    When the request_key() syscall is not passed a destination keyring, it
    links the requested key (if constructed) into the "default" request-key
    keyring.  This should require Write permission to the keyring.  However,
    there is actually no permission check.
    
    This can be abused to add keys to any keyring to which only Search
    permission is granted.  This is because Search permission allows joining
    the keyring.  keyctl_set_reqkey_keyring(KEY_REQKEY_DEFL_SESSION_KEYRING)
    then will set the default request-key keyring to the session keyring.
    Then, request_key() can be used to add keys to the keyring.
    
    Both negatively and positively instantiated keys can be added using this
    method.  Adding negative keys is trivial.  Adding a positive key is a
    bit trickier.  It requires that either /sbin/request-key positively
    instantiates the key, or that another thread adds the key to the process
    keyring at just the right time, such that request_key() misses it
    initially but then finds it in construct_alloc_key().
    
    Fix this bug by checking for Write permission to the keyring in
    construct_get_dest_keyring() when the default keyring is being used.
    
    We don't do the permission check for non-default keyrings because that
    was already done by the earlier call to lookup_user_key().  Also,
    request_key_and_link() is currently passed a 'struct key *' rather than
    a key_ref_t, so the "possessed" bit is unavailable.
    
    We also don't do the permission check for the "requestor keyring", to
    continue to support the use case described by commit 8bbf4976
    ("KEYS: Alter use of key instantiation link-to-keyring argument") where
    /sbin/request-key recursively calls request_key() to add keys to the
    original requestor's destination keyring.  (I don't know of any users
    who actually do that, though...)
    
    Fixes: 3e30148c ("[PATCH] Keys: Make request-key create an authorisation key")
    Cc: <stable@vger.kernel.org>	# v2.6.13+
    Signed-off-by: NEric Biggers <ebiggers@google.com>
    Signed-off-by: NDavid Howells <dhowells@redhat.com>
    4dca6ea1
request_key.c 20.4 KB