18 Mar, 2016

2 commits

  • Pull security layer updates from James Morris:
    "There are a bunch of fixes to the TPM, IMA, and Keys code, with minor
    fixes scattered across the subsystem.

    IMA now requires signed policy, and that policy is also now measured
    and appraised"

    * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (67 commits)
    X.509: Make algo identifiers text instead of enum
    akcipher: Move the RSA DER encoding check to the crypto layer
    crypto: Add hash param to pkcs1pad
    sign-file: fix build with CMS support disabled
    MAINTAINERS: update tpmdd urls
    MODSIGN: linux/string.h should be #included to get memcpy()
    certs: Fix misaligned data in extra certificate list
    X.509: Handle midnight alternative notation in GeneralizedTime
    X.509: Support leap seconds
    Handle ISO 8601 leap seconds and encodings of midnight in mktime64()
    X.509: Fix leap year handling again
    PKCS#7: fix unitialized boolean 'want'
    firmware: change kernel read fail to dev_dbg()
    KEYS: Use the symbol value for list size, updated by scripts/insert-sys-cert
    KEYS: Reserve an extra certificate symbol for inserting without recompiling
    modsign: hide openssl output in silent builds
    tpm_tis: fix build warning with tpm_tis_resume
    ima: require signed IMA policy
    ima: measure and appraise the IMA policy itself
    ima: load policy using path
    ...

    Linus Torvalds
     
  • Pull crypto update from Herbert Xu:
    "Here is the crypto update for 4.6:

    API:
    - Convert remaining crypto_hash users to shash or ahash, also convert
    blkcipher/ablkcipher users to skcipher.
    - Remove crypto_hash interface.
    - Remove crypto_pcomp interface.
    - Add crypto engine for async cipher drivers.
    - Add akcipher documentation.
    - Add skcipher documentation.

    Algorithms:
    - Rename crypto/crc32 to avoid name clash with lib/crc32.
    - Fix bug in keywrap where we zero the wrong pointer.

    Drivers:
    - Support T5/M5, T7/M7 SPARC CPUs in n2 hwrng driver.
    - Add PIC32 hwrng driver.
    - Support BCM6368 in bcm63xx hwrng driver.
    - Pack structs for 32-bit compat users in qat.
    - Use crypto engine in omap-aes.
    - Add support for sama5d2x SoCs in atmel-sha.
    - Make atmel-sha available again.
    - Make sahara hashing available again.
    - Make ccp hashing available again.
    - Make sha1-mb available again.
    - Add support for multiple devices in ccp.
    - Improve DMA performance in caam.
    - Add hashing support to rockchip"

    * 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (116 commits)
    crypto: qat - remove redundant arbiter configuration
    crypto: ux500 - fix checks of error code returned by devm_ioremap_resource()
    crypto: atmel - fix checks of error code returned by devm_ioremap_resource()
    crypto: qat - Change the definition of icp_qat_uof_regtype
    hwrng: exynos - use __maybe_unused to hide pm functions
    crypto: ccp - Add abstraction for device-specific calls
    crypto: ccp - CCP versioning support
    crypto: ccp - Support for multiple CCPs
    crypto: ccp - Remove check for x86 family and model
    crypto: ccp - memset request context to zero during import
    lib/mpi: use "static inline" instead of "extern inline"
    lib/mpi: avoid assembler warning
    hwrng: bcm63xx - fix non device tree compatibility
    crypto: testmgr - allow rfc3686 aes-ctr variants in fips mode.
    crypto: qat - The AE id should be less than the maximal AE number
    lib/mpi: Endianness fix
    crypto: rockchip - add hash support for crypto engine in rk3288
    crypto: xts - fix compile errors
    crypto: doc - add skcipher API documentation
    crypto: doc - update AEAD AD handling
    ...

    Linus Torvalds
     

04 Mar, 2016

1 commit


18 Feb, 2016

1 commit

  • The Kconfig currently controlling compilation of this code is:

    config BIG_KEYS
    bool "Large payload keys"

    ...meaning that it currently is not being built as a module by anyone.

    Lets remove the modular code that is essentially orphaned, so that
    when reading the driver there is no doubt it is builtin-only.

    Since module_init translates to device_initcall in the non-modular
    case, the init ordering remains unchanged with this commit.

    We also delete the MODULE_LICENSE tag since all that information
    is already contained at the top of the file in the comments.

    Cc: James Morris
    Cc: "Serge E. Hallyn"
    Cc: keyrings@vger.kernel.org
    Cc: linux-security-module@vger.kernel.org
    Signed-off-by: Paul Gortmaker
    Signed-off-by: David Howells

    Paul Gortmaker
     

10 Feb, 2016

2 commits


28 Jan, 2016

1 commit

  • KEY_FLAG_KEEP should only be applied to a key if the keyring it is being
    linked into has KEY_FLAG_KEEP set.

    To this end, partially revert the following patch:

    commit 1d6d167c2efcfe9539d9cffb1a1be9c92e39c2c0
    Author: Mimi Zohar
    Date: Thu Jan 7 07:46:36 2016 -0500
    KEYS: refcount bug fix

    to undo the change that made it unconditional (Mimi got it right the first
    time).

    Without undoing this change, it becomes impossible to delete, revoke or
    invalidate keys added to keyrings through __key_instantiate_and_link()
    where the keyring has itself been linked to. To test this, run the
    following command sequence:

    keyctl newring foo @s
    keyctl add user a a %:foo
    keyctl unlink %user:a %:foo
    keyctl clear %:foo

    With the commit mentioned above the third and fourth commands fail with
    EPERM when they should succeed.

    Reported-by: Stephen Gallager
    Signed-off-by: David Howells
    Acked-by: Mimi Zohar
    cc: Mimi Zohar
    cc: keyrings@vger.kernel.org
    cc: stable@vger.kernel.org
    Signed-off-by: James Morris

    David Howells
     

27 Jan, 2016

1 commit


20 Jan, 2016

1 commit

  • This fixes CVE-2016-0728.

    If a thread is asked to join as a session keyring the keyring that's already
    set as its session, we leak a keyring reference.

    This can be tested with the following program:

    #include
    #include
    #include
    #include

    int main(int argc, const char *argv[])
    {
    int i = 0;
    key_serial_t serial;

    serial = keyctl(KEYCTL_JOIN_SESSION_KEYRING,
    "leaked-keyring");
    if (serial < 0) {
    perror("keyctl");
    return -1;
    }

    if (keyctl(KEYCTL_SETPERM, serial,
    KEY_POS_ALL | KEY_USR_ALL) < 0) {
    perror("keyctl");
    return -1;
    }

    for (i = 0; i < 100; i++) {
    serial = keyctl(KEYCTL_JOIN_SESSION_KEYRING,
    "leaked-keyring");
    if (serial < 0) {
    perror("keyctl");
    return -1;
    }
    }

    return 0;
    }

    If, after the program has run, there something like the following line in
    /proc/keys:

    3f3d898f I--Q--- 100 perm 3f3f0000 0 0 keyring leaked-keyring: empty

    with a usage count of 100 * the number of times the program has been run,
    then the kernel is malfunctioning. If leaked-keyring has zero usages or
    has been garbage collected, then the problem is fixed.

    Reported-by: Yevgeny Pats
    Signed-off-by: David Howells
    Acked-by: Don Zickus
    Acked-by: Prarit Bhargava
    Acked-by: Jarod Wilson
    Signed-off-by: James Morris

    Yevgeny Pats
     

18 Jan, 2016

1 commit

  • Pull security subsystem updates from James Morris:

    - EVM gains support for loading an x509 cert from the kernel
    (EVM_LOAD_X509), into the EVM trusted kernel keyring.

    - Smack implements 'file receive' process-based permission checking for
    sockets, rather than just depending on inode checks.

    - Misc enhancments for TPM & TPM2.

    - Cleanups and bugfixes for SELinux, Keys, and IMA.

    * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (41 commits)
    selinux: Inode label revalidation performance fix
    KEYS: refcount bug fix
    ima: ima_write_policy() limit locking
    IMA: policy can be updated zero times
    selinux: rate-limit netlink message warnings in selinux_nlmsg_perm()
    selinux: export validatetrans decisions
    gfs2: Invalid security labels of inodes when they go invalid
    selinux: Revalidate invalid inode security labels
    security: Add hook to invalidate inode security labels
    selinux: Add accessor functions for inode->i_security
    security: Make inode argument of inode_getsecid non-const
    security: Make inode argument of inode_getsecurity non-const
    selinux: Remove unused variable in selinux_inode_init_security
    keys, trusted: seal with a TPM2 authorization policy
    keys, trusted: select hash algorithm for TPM2 chips
    keys, trusted: fix: *do not* allow duplicate key options
    tpm_ibmvtpm: properly handle interrupted packet receptions
    tpm_tis: Tighten IRQ auto-probing
    tpm_tis: Refactor the interrupt setup
    tpm_tis: Get rid of the duplicate IRQ probing code
    ...

    Linus Torvalds
     

10 Jan, 2016

1 commit


08 Jan, 2016

1 commit

  • This patch fixes the key_ref leak, removes the unnecessary KEY_FLAG_KEEP
    test before setting the flag, and cleans up the if/then brackets style
    introduced in commit:
    d3600bc KEYS: prevent keys from being removed from specified keyrings

    Reported-by: David Howells
    Signed-off-by: Mimi Zohar
    Acked-by: David Howells

    Mimi Zohar
     

26 Dec, 2015

1 commit


20 Dec, 2015

3 commits

  • TPM2 supports authorization policies, which are essentially
    combinational logic statements repsenting the conditions where the data
    can be unsealed based on the TPM state. This patch enables to use
    authorization policies to seal trusted keys.

    Two following new options have been added for trusted keys:

    * 'policydigest=': provide an auth policy digest for sealing.
    * 'policyhandle=': provide a policy session handle for unsealing.

    If 'hash=' option is supplied after 'policydigest=' option, this
    will result an error because the state of the option would become
    mixed.

    Signed-off-by: Jarkko Sakkinen
    Tested-by: Colin Ian King
    Reviewed-by: Mimi Zohar
    Acked-by: Peter Huewe

    Jarkko Sakkinen
     
  • Added 'hash=' option for selecting the hash algorithm for add_key()
    syscall and documentation for it.

    Added entry for sm3-256 to the following tables in order to support
    TPM_ALG_SM3_256:

    * hash_algo_name
    * hash_digest_size

    Includes support for the following hash algorithms:

    * sha1
    * sha256
    * sha384
    * sha512
    * sm3-256

    Signed-off-by: Jarkko Sakkinen
    Tested-by: Colin Ian King
    Reviewed-by: James Morris
    Reviewed-by: Mimi Zohar
    Acked-by: Peter Huewe

    Jarkko Sakkinen
     
  • The trusted keys option parsing allows specifying the same option
    multiple times. The last option value specified is used.

    This is problematic because:

    * No gain.
    * This makes complicated to specify options that are dependent on other
    options.

    This patch changes the behavior in a way that option can be specified
    only once.

    Reported-by: James Morris James Morris
    Reviewed-by: Mimi Zohar
    Signed-off-by: Jarkko Sakkinen
    Acked-by: Peter Huewe

    Jarkko Sakkinen
     

19 Dec, 2015

1 commit

  • This fixes CVE-2015-7550.

    There's a race between keyctl_read() and keyctl_revoke(). If the revoke
    happens between keyctl_read() checking the validity of a key and the key's
    semaphore being taken, then the key type read method will see a revoked key.

    This causes a problem for the user-defined key type because it assumes in
    its read method that there will always be a payload in a non-revoked key
    and doesn't check for a NULL pointer.

    Fix this by making keyctl_read() check the validity of a key after taking
    semaphore instead of before.

    I think the bug was introduced with the original keyrings code.

    This was discovered by a multithreaded test program generated by syzkaller
    (http://github.com/google/syzkaller). Here's a cleaned up version:

    #include
    #include
    #include
    void *thr0(void *arg)
    {
    key_serial_t key = (unsigned long)arg;
    keyctl_revoke(key);
    return 0;
    }
    void *thr1(void *arg)
    {
    key_serial_t key = (unsigned long)arg;
    char buffer[16];
    keyctl_read(key, buffer, 16);
    return 0;
    }
    int main()
    {
    key_serial_t key = add_key("user", "%", "foo", 3, KEY_SPEC_USER_KEYRING);
    pthread_t th[5];
    pthread_create(&th[0], 0, thr0, (void *)(unsigned long)key);
    pthread_create(&th[1], 0, thr1, (void *)(unsigned long)key);
    pthread_create(&th[2], 0, thr0, (void *)(unsigned long)key);
    pthread_create(&th[3], 0, thr1, (void *)(unsigned long)key);
    pthread_join(th[0], 0);
    pthread_join(th[1], 0);
    pthread_join(th[2], 0);
    pthread_join(th[3], 0);
    return 0;
    }

    Build as:

    cc -o keyctl-race keyctl-race.c -lkeyutils -lpthread

    Run as:

    while keyctl-race; do :; done

    as it may need several iterations to crash the kernel. The crash can be
    summarised as:

    BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
    IP: [] user_read+0x56/0xa3
    ...
    Call Trace:
    [] keyctl_read_key+0xb6/0xd7
    [] SyS_keyctl+0x83/0xe0
    [] entry_SYSCALL_64_fastpath+0x12/0x6f

    Reported-by: Dmitry Vyukov
    Signed-off-by: David Howells
    Tested-by: Dmitry Vyukov
    Cc: stable@vger.kernel.org
    Signed-off-by: James Morris

    David Howells
     

15 Dec, 2015

1 commit

  • Userspace should not be allowed to remove keys from certain keyrings
    (eg. blacklist), though the keys themselves can expire.

    This patch defines a new key flag named KEY_FLAG_KEEP to prevent
    userspace from being able to unlink, revoke, invalidate or timed
    out a key on a keyring. When this flag is set on the keyring, all
    keys subsequently added are flagged.

    In addition, when this flag is set, the keyring itself can not be
    cleared.

    Signed-off-by: Mimi Zohar
    Cc: David Howells

    Mimi Zohar
     

25 Nov, 2015

1 commit

  • If a user key gets negatively instantiated, an error code is cached in the
    payload area. A negatively instantiated key may be then be positively
    instantiated by updating it with valid data. However, the ->update key
    type method must be aware that the error code may be there.

    The following may be used to trigger the bug in the user key type:

    keyctl request2 user user "" @u
    keyctl add user user "a" @u

    which manifests itself as:

    BUG: unable to handle kernel paging request at 00000000ffffff8a
    IP: [] __call_rcu.constprop.76+0x1f/0x280 kernel/rcu/tree.c:3046
    PGD 7cc30067 PUD 0
    Oops: 0002 [#1] SMP
    Modules linked in:
    CPU: 3 PID: 2644 Comm: a.out Not tainted 4.3.0+ #49
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
    task: ffff88003ddea700 ti: ffff88003dd88000 task.ti: ffff88003dd88000
    RIP: 0010:[] [] __call_rcu.constprop.76+0x1f/0x280
    [] __call_rcu.constprop.76+0x1f/0x280 kernel/rcu/tree.c:3046
    RSP: 0018:ffff88003dd8bdb0 EFLAGS: 00010246
    RAX: 00000000ffffff82 RBX: 0000000000000000 RCX: 0000000000000001
    RDX: ffffffff81e3fe40 RSI: 0000000000000000 RDI: 00000000ffffff82
    RBP: ffff88003dd8bde0 R08: ffff88007d2d2da0 R09: 0000000000000000
    R10: 0000000000000000 R11: ffff88003e8073c0 R12: 00000000ffffff82
    R13: ffff88003dd8be68 R14: ffff88007d027600 R15: ffff88003ddea700
    FS: 0000000000b92880(0063) GS:ffff88007fd00000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
    CR2: 00000000ffffff8a CR3: 000000007cc5f000 CR4: 00000000000006e0
    Stack:
    ffff88003dd8bdf0 ffffffff81160a8a 0000000000000000 00000000ffffff82
    ffff88003dd8be68 ffff88007d027600 ffff88003dd8bdf0 ffffffff810a39e5
    ffff88003dd8be20 ffffffff812a31ab ffff88007d027600 ffff88007d027620
    Call Trace:
    [] kfree_call_rcu+0x15/0x20 kernel/rcu/tree.c:3136
    [] user_update+0x8b/0xb0 security/keys/user_defined.c:129
    [< inline >] __key_update security/keys/key.c:730
    [] key_create_or_update+0x291/0x440 security/keys/key.c:908
    [< inline >] SYSC_add_key security/keys/keyctl.c:125
    [] SyS_add_key+0x101/0x1e0 security/keys/keyctl.c:60
    [] entry_SYSCALL_64_fastpath+0x12/0x6a arch/x86/entry/entry_64.S:185

    Note the error code (-ENOKEY) in EDX.

    A similar bug can be tripped by:

    keyctl request2 trusted user "" @u
    keyctl add trusted user "a" @u

    This should also affect encrypted keys - but that has to be correctly
    parameterised or it will fail with EINVAL before getting to the bit that
    will crashes.

    Reported-by: Dmitry Vyukov
    Signed-off-by: David Howells
    Acked-by: Mimi Zohar
    Signed-off-by: James Morris

    David Howells
     

06 Nov, 2015

1 commit

  • Pull security subsystem update from James Morris:
    "This is mostly maintenance updates across the subsystem, with a
    notable update for TPM 2.0, and addition of Jarkko Sakkinen as a
    maintainer of that"

    * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (40 commits)
    apparmor: clarify CRYPTO dependency
    selinux: Use a kmem_cache for allocation struct file_security_struct
    selinux: ioctl_has_perm should be static
    selinux: use sprintf return value
    selinux: use kstrdup() in security_get_bools()
    selinux: use kmemdup in security_sid_to_context_core()
    selinux: remove pointless cast in selinux_inode_setsecurity()
    selinux: introduce security_context_str_to_sid
    selinux: do not check open perm on ftruncate call
    selinux: change CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE default
    KEYS: Merge the type-specific data with the payload data
    KEYS: Provide a script to extract a module signature
    KEYS: Provide a script to extract the sys cert list from a vmlinux file
    keys: Be more consistent in selection of union members used
    certs: add .gitignore to stop git nagging about x509_certificate_list
    KEYS: use kvfree() in add_key
    Smack: limited capability for changing process label
    TPM: remove unnecessary little endian conversion
    vTPM: support little endian guests
    char: Drop owner assignment from i2c_driver
    ...

    Linus Torvalds
     

21 Oct, 2015

3 commits

  • Merge the type-specific data with the payload data into one four-word chunk
    as it seems pointless to keep them separate.

    Use user_key_payload() for accessing the payloads of overloaded
    user-defined keys.

    Signed-off-by: David Howells
    cc: linux-cifs@vger.kernel.org
    cc: ecryptfs@vger.kernel.org
    cc: linux-ext4@vger.kernel.org
    cc: linux-f2fs-devel@lists.sourceforge.net
    cc: linux-nfs@vger.kernel.org
    cc: ceph-devel@vger.kernel.org
    cc: linux-ima-devel@lists.sourceforge.net

    David Howells
     
  • key->description and key->index_key.description are same because
    they are unioned. But, for readability, using same name for
    duplication and validation seems better.

    Signed-off-by: Insu Yun
    Signed-off-by: David Howells

    Insu Yun
     
  • There is no need to make a flag to tell that this memory is allocated by
    kmalloc or vmalloc. Just use kvfree to free the memory.

    Signed-off-by: Geliang Tang
    Signed-off-by: David Howells

    Geliang Tang
     

19 Oct, 2015

3 commits

  • If request_key() is used to find a keyring, only do the search part - don't
    do the construction part if the keyring was not found by the search. We
    don't really want keyrings in the negative instantiated state since the
    rejected/negative instantiation error value in the payload is unioned with
    keyring metadata.

    Now the kernel gives an error:

    request_key("keyring", "#selinux,bdekeyring", "keyring", KEY_SPEC_USER_SESSION_KEYRING) = -1 EPERM (Operation not permitted)

    Signed-off-by: David Howells

    David Howells
     
  • Call tpm_seal_trusted() and tpm_unseal_trusted() for TPM 2.0 chips.
    We require explicit 'keyhandle=' option because there's no a fixed
    storage root key inside TPM2 chips.

    Signed-off-by: Jarkko Sakkinen
    Reviewed-by: Andreas Fuchs
    Tested-by: Mimi Zohar (on TPM 1.2)
    Tested-by: Chris J Arges
    Tested-by: Colin Ian King
    Tested-by: Kevin Strasser
    Signed-off-by: Peter Huewe

    Jarkko Sakkinen
     
  • Moved struct trusted_key_options to trustes-type.h so that the fields
    can be accessed from drivers/char/tpm.

    Signed-off-by: Jarkko Sakkinen
    Signed-off-by: Peter Huewe

    Jarkko Sakkinen
     

16 Oct, 2015

1 commit

  • The following sequence of commands:

    i=`keyctl add user a a @s`
    keyctl request2 keyring foo bar @t
    keyctl unlink $i @s

    tries to invoke an upcall to instantiate a keyring if one doesn't already
    exist by that name within the user's keyring set. However, if the upcall
    fails, the code sets keyring->type_data.reject_error to -ENOKEY or some
    other error code. When the key is garbage collected, the key destroy
    function is called unconditionally and keyring_destroy() uses list_empty()
    on keyring->type_data.link - which is in a union with reject_error.
    Subsequently, the kernel tries to unlink the keyring from the keyring names
    list - which oopses like this:

    BUG: unable to handle kernel paging request at 00000000ffffff8a
    IP: [] keyring_destroy+0x3d/0x88
    ...
    Workqueue: events key_garbage_collector
    ...
    RIP: 0010:[] keyring_destroy+0x3d/0x88
    RSP: 0018:ffff88003e2f3d30 EFLAGS: 00010203
    RAX: 00000000ffffff82 RBX: ffff88003bf1a900 RCX: 0000000000000000
    RDX: 0000000000000000 RSI: 000000003bfc6901 RDI: ffffffff81a73a40
    RBP: ffff88003e2f3d38 R08: 0000000000000152 R09: 0000000000000000
    R10: ffff88003e2f3c18 R11: 000000000000865b R12: ffff88003bf1a900
    R13: 0000000000000000 R14: ffff88003bf1a908 R15: ffff88003e2f4000
    ...
    CR2: 00000000ffffff8a CR3: 000000003e3ec000 CR4: 00000000000006f0
    ...
    Call Trace:
    [] key_gc_unused_keys.constprop.1+0x5d/0x10f
    [] key_garbage_collector+0x1fa/0x351
    [] process_one_work+0x28e/0x547
    [] worker_thread+0x26e/0x361
    [] ? rescuer_thread+0x2a8/0x2a8
    [] kthread+0xf3/0xfb
    [] ? kthread_create_on_node+0x1c2/0x1c2
    [] ret_from_fork+0x3f/0x70
    [] ? kthread_create_on_node+0x1c2/0x1c2

    Note the value in RAX. This is a 32-bit representation of -ENOKEY.

    The solution is to only call ->destroy() if the key was successfully
    instantiated.

    Reported-by: Dmitry Vyukov
    Signed-off-by: David Howells
    Tested-by: Dmitry Vyukov

    David Howells
     

25 Sep, 2015

1 commit

  • There appears to be a race between:

    (1) key_gc_unused_keys() which frees key->security and then calls
    keyring_destroy() to unlink the name from the name list

    (2) find_keyring_by_name() which calls key_permission(), thus accessing
    key->security, on a key before checking to see whether the key usage is 0
    (ie. the key is dead and might be cleaned up).

    Fix this by calling ->destroy() before cleaning up the core key data -
    including key->security.

    Reported-by: Petr Matousek
    Signed-off-by: David Howells

    David Howells
     

05 Sep, 2015

1 commit

  • Credit where credit is due: this idea comes from Christoph Lameter with
    a lot of valuable input from Serge Hallyn. This patch is heavily based
    on Christoph's patch.

    ===== The status quo =====

    On Linux, there are a number of capabilities defined by the kernel. To
    perform various privileged tasks, processes can wield capabilities that
    they hold.

    Each task has four capability masks: effective (pE), permitted (pP),
    inheritable (pI), and a bounding set (X). When the kernel checks for a
    capability, it checks pE. The other capability masks serve to modify
    what capabilities can be in pE.

    Any task can remove capabilities from pE, pP, or pI at any time. If a
    task has a capability in pP, it can add that capability to pE and/or pI.
    If a task has CAP_SETPCAP, then it can add any capability to pI, and it
    can remove capabilities from X.

    Tasks are not the only things that can have capabilities; files can also
    have capabilities. A file can have no capabilty information at all [1].
    If a file has capability information, then it has a permitted mask (fP)
    and an inheritable mask (fI) as well as a single effective bit (fE) [2].
    File capabilities modify the capabilities of tasks that execve(2) them.

    A task that successfully calls execve has its capabilities modified for
    the file ultimately being excecuted (i.e. the binary itself if that
    binary is ELF or for the interpreter if the binary is a script.) [3] In
    the capability evolution rules, for each mask Z, pZ represents the old
    value and pZ' represents the new value. The rules are:

    pP' = (X & fP) | (pI & fI)
    pI' = pI
    pE' = (fE ? pP' : 0)
    X is unchanged

    For setuid binaries, fP, fI, and fE are modified by a moderately
    complicated set of rules that emulate POSIX behavior. Similarly, if
    euid == 0 or ruid == 0, then fP, fI, and fE are modified differently
    (primary, fP and fI usually end up being the full set). For nonroot
    users executing binaries with neither setuid nor file caps, fI and fP
    are empty and fE is false.

    As an extra complication, if you execute a process as nonroot and fE is
    set, then the "secure exec" rules are in effect: AT_SECURE gets set,
    LD_PRELOAD doesn't work, etc.

    This is rather messy. We've learned that making any changes is
    dangerous, though: if a new kernel version allows an unprivileged
    program to change its security state in a way that persists cross
    execution of a setuid program or a program with file caps, this
    persistent state is surprisingly likely to allow setuid or file-capped
    programs to be exploited for privilege escalation.

    ===== The problem =====

    Capability inheritance is basically useless.

    If you aren't root and you execute an ordinary binary, fI is zero, so
    your capabilities have no effect whatsoever on pP'. This means that you
    can't usefully execute a helper process or a shell command with elevated
    capabilities if you aren't root.

    On current kernels, you can sort of work around this by setting fI to
    the full set for most or all non-setuid executable files. This causes
    pP' = pI for nonroot, and inheritance works. No one does this because
    it's a PITA and it isn't even supported on most filesystems.

    If you try this, you'll discover that every nonroot program ends up with
    secure exec rules, breaking many things.

    This is a problem that has bitten many people who have tried to use
    capabilities for anything useful.

    ===== The proposed change =====

    This patch adds a fifth capability mask called the ambient mask (pA).
    pA does what most people expect pI to do.

    pA obeys the invariant that no bit can ever be set in pA if it is not
    set in both pP and pI. Dropping a bit from pP or pI drops that bit from
    pA. This ensures that existing programs that try to drop capabilities
    still do so, with a complication. Because capability inheritance is so
    broken, setting KEEPCAPS, using setresuid to switch to nonroot uids, and
    then calling execve effectively drops capabilities. Therefore,
    setresuid from root to nonroot conditionally clears pA unless
    SECBIT_NO_SETUID_FIXUP is set. Processes that don't like this can
    re-add bits to pA afterwards.

    The capability evolution rules are changed:

    pA' = (file caps or setuid or setgid ? 0 : pA)
    pP' = (X & fP) | (pI & fI) | pA'
    pI' = pI
    pE' = (fE ? pP' : pA')
    X is unchanged

    If you are nonroot but you have a capability, you can add it to pA. If
    you do so, your children get that capability in pA, pP, and pE. For
    example, you can set pA = CAP_NET_BIND_SERVICE, and your children can
    automatically bind low-numbered ports. Hallelujah!

    Unprivileged users can create user namespaces, map themselves to a
    nonzero uid, and create both privileged (relative to their namespace)
    and unprivileged process trees. This is currently more or less
    impossible. Hallelujah!

    You cannot use pA to try to subvert a setuid, setgid, or file-capped
    program: if you execute any such program, pA gets cleared and the
    resulting evolution rules are unchanged by this patch.

    Users with nonzero pA are unlikely to unintentionally leak that
    capability. If they run programs that try to drop privileges, dropping
    privileges will still work.

    It's worth noting that the degree of paranoia in this patch could
    possibly be reduced without causing serious problems. Specifically, if
    we allowed pA to persist across executing non-pA-aware setuid binaries
    and across setresuid, then, naively, the only capabilities that could
    leak as a result would be the capabilities in pA, and any attacker
    *already* has those capabilities. This would make me nervous, though --
    setuid binaries that tried to privilege-separate might fail to do so,
    and putting CAP_DAC_READ_SEARCH or CAP_DAC_OVERRIDE into pA could have
    unexpected side effects. (Whether these unexpected side effects would
    be exploitable is an open question.) I've therefore taken the more
    paranoid route. We can revisit this later.

    An alternative would be to require PR_SET_NO_NEW_PRIVS before setting
    ambient capabilities. I think that this would be annoying and would
    make granting otherwise unprivileged users minor ambient capabilities
    (CAP_NET_BIND_SERVICE or CAP_NET_RAW for example) much less useful than
    it is with this patch.

    ===== Footnotes =====

    [1] Files that are missing the "security.capability" xattr or that have
    unrecognized values for that xattr end up with has_cap set to false.
    The code that does that appears to be complicated for no good reason.

    [2] The libcap capability mask parsers and formatters are dangerously
    misleading and the documentation is flat-out wrong. fE is *not* a mask;
    it's a single bit. This has probably confused every single person who
    has tried to use file capabilities.

    [3] Linux very confusingly processes both the script and the interpreter
    if applicable, for reasons that elude me. The results from thinking
    about a script's file capabilities and/or setuid bits are mostly
    discarded.

    Preliminary userspace code is here, but it needs updating:
    https://git.kernel.org/cgit/linux/kernel/git/luto/util-linux-playground.git/commit/?h=cap_ambient&id=7f5afbd175d2

    Here is a test program that can be used to verify the functionality
    (from Christoph):

    /*
    * Test program for the ambient capabilities. This program spawns a shell
    * that allows running processes with a defined set of capabilities.
    *
    * (C) 2015 Christoph Lameter
    * Released under: GPL v3 or later.
    *
    *
    * Compile using:
    *
    * gcc -o ambient_test ambient_test.o -lcap-ng
    *
    * This program must have the following capabilities to run properly:
    * Permissions for CAP_NET_RAW, CAP_NET_ADMIN, CAP_SYS_NICE
    *
    * A command to equip the binary with the right caps is:
    *
    * setcap cap_net_raw,cap_net_admin,cap_sys_nice+p ambient_test
    *
    *
    * To get a shell with additional caps that can be inherited by other processes:
    *
    * ./ambient_test /bin/bash
    *
    *
    * Verifying that it works:
    *
    * From the bash spawed by ambient_test run
    *
    * cat /proc/$$/status
    *
    * and have a look at the capabilities.
    */

    #include
    #include
    #include
    #include
    #include
    #include

    /*
    * Definitions from the kernel header files. These are going to be removed
    * when the /usr/include files have these defined.
    */
    #define PR_CAP_AMBIENT 47
    #define PR_CAP_AMBIENT_IS_SET 1
    #define PR_CAP_AMBIENT_RAISE 2
    #define PR_CAP_AMBIENT_LOWER 3
    #define PR_CAP_AMBIENT_CLEAR_ALL 4

    static void set_ambient_cap(int cap)
    {
    int rc;

    capng_get_caps_process();
    rc = capng_update(CAPNG_ADD, CAPNG_INHERITABLE, cap);
    if (rc) {
    printf("Cannot add inheritable cap\n");
    exit(2);
    }
    capng_apply(CAPNG_SELECT_CAPS);

    /* Note the two 0s at the end. Kernel checks for these */
    if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0)) {
    perror("Cannot set cap");
    exit(1);
    }
    }

    int main(int argc, char **argv)
    {
    int rc;

    set_ambient_cap(CAP_NET_RAW);
    set_ambient_cap(CAP_NET_ADMIN);
    set_ambient_cap(CAP_SYS_NICE);

    printf("Ambient_test forking shell\n");
    if (execv(argv[1], argv + 1))
    perror("Cannot exec");

    return 0;
    }

    Signed-off-by: Christoph Lameter # Original author
    Signed-off-by: Andy Lutomirski
    Acked-by: Serge E. Hallyn
    Acked-by: Kees Cook
    Cc: Jonathan Corbet
    Cc: Aaron Jones
    Cc: Ted Ts'o
    Cc: Andrew G. Morgan
    Cc: Mimi Zohar
    Cc: Austin S Hemmelgarn
    Cc: Markku Savela
    Cc: Jarkko Sakkinen
    Cc: Michael Kerrisk
    Cc: James Morris
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andy Lutomirski
     

28 Jul, 2015

1 commit

  • __key_link_end is not freeing the associated array edit structure
    and this leads to a 512 byte memory leak each time an identical
    existing key is added with add_key().

    The reason the add_key() system call returns okay is that
    key_create_or_update() calls __key_link_begin() before checking to see
    whether it can update a key directly rather than adding/replacing - which
    it turns out it can. Thus __key_link() is not called through
    __key_instantiate_and_link() and __key_link_end() must cancel the edit.

    CVE-2015-1333

    Signed-off-by: Colin Ian King
    Signed-off-by: David Howells
    Signed-off-by: James Morris

    Colin Ian King
     

12 Apr, 2015

1 commit


16 Feb, 2015

1 commit

  • If a request_key() call to allocate and fill out a key attempts to insert the
    key structure into a revoked keyring, the key will leak, using memory and part
    of the user's key quota until the system reboots. This is from a failure of
    construct_alloc_key() to decrement the key's reference count after the attempt
    to insert into the requested keyring is rejected.

    key_put() needs to be called in the link_prealloc_failed callpath to ensure
    the unused key is released.

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

    David Jeffery
     

23 Jan, 2015

1 commit


05 Jan, 2015

1 commit

  • When a key is being garbage collected, it's key->user would get put before
    the ->destroy() callback is called, where the key is removed from it's
    respective tracking structures.

    This leaves a key hanging in a semi-invalid state which leaves a window open
    for a different task to try an access key->user. An example is
    find_keyring_by_name() which would dereference key->user for a key that is
    in the process of being garbage collected (where key->user was freed but
    ->destroy() wasn't called yet - so it's still present in the linked list).

    This would cause either a panic, or corrupt memory.

    Fixes CVE-2014-9529.

    Signed-off-by: Sasha Levin
    Signed-off-by: David Howells

    Sasha Levin
     

16 Dec, 2014

2 commits


07 Dec, 2014

1 commit

  • When loading encrypted-keys module, if the last check of
    aes_get_sizes() in init_encrypted() fails, the driver just returns an
    error without unregistering its key type. This results in the stale
    entry in the list. In addition to memory leaks, this leads to a kernel
    crash when registering a new key type later.

    This patch fixes the problem by swapping the calls of aes_get_sizes()
    and register_key_type(), and releasing resources properly at the error
    paths.

    Bugzilla: https://bugzilla.opensuse.org/show_bug.cgi?id=908163
    Cc:
    Signed-off-by: Takashi Iwai
    Signed-off-by: Mimi Zohar

    Takashi Iwai
     

02 Dec, 2014

3 commits

  • Since the keyring facility can be viewed as a cache (at least in some
    applications), the local expiration time on the key should probably be viewed
    as a 'needs updating after this time' property rather than an absolute 'anyone
    now wanting to use this object is out of luck' property.

    Since request_key() is the main interface for the usage of keys, this should
    update or replace an expired key rather than issuing EKEYEXPIRED if the local
    expiration has been reached (ie. it should refresh the cache).

    For absolute conditions where refreshing the cache probably doesn't help, the
    key can be negatively instantiated using KEYCTL_REJECT_KEY with EKEYEXPIRED
    given as the error to issue. This will still cause request_key() to return
    EKEYEXPIRED as that was explicitly set.

    In the future, if the key type has an update op available, we might want to
    upcall with the expired key and allow the upcall to update it. We would pass
    a different operation name (the first column in /etc/request-key.conf) to the
    request-key program.

    request_key() returning EKEYEXPIRED is causing an NFS problem which Chuck
    Lever describes thusly:

    After about 10 minutes, my NFSv4 functional tests fail because the
    ownership of the test files goes to "-2". Looking at /proc/keys
    shows that the id_resolv keys that map to my test user ID have
    expired. The ownership problem persists until the expired keys are
    purged from the keyring, and fresh keys are obtained.

    I bisected the problem to 3.13 commit b2a4df200d57 ("KEYS: Expand
    the capacity of a keyring"). This commit inadvertantly changes the
    API contract of the internal function keyring_search_aux().

    The root cause appears to be that b2a4df200d57 made "no state check"
    the default behavior. "No state check" means the keyring search
    iterator function skips checking the key's expiry timeout, and
    returns expired keys. request_key_and_link() depends on getting
    an -EAGAIN result code to know when to perform an upcall to refresh
    an expired key.

    This patch can be tested directly by:

    keyctl request2 user debug:fred a @s
    keyctl timeout %user:debug:fred 3
    sleep 4
    keyctl request2 user debug:fred a @s

    Without the patch, the last command gives error EKEYEXPIRED, but with the
    command it gives a new key.

    Reported-by: Carl Hetherington
    Reported-by: Chuck Lever
    Signed-off-by: David Howells
    Tested-by: Chuck Lever

    David Howells
     
  • Simplify KEYRING_SEARCH_{NO,DO}_STATE_CHECK flags to be two variations of the
    same flag. They are effectively mutually exclusive and one or the other
    should be provided, but not both.

    Keyring cycle detection and key possession determination are the only things
    that set NO_STATE_CHECK, except that neither flag really does anything there
    because neither purpose makes use of the keyring_search_iterator() function,
    but rather provides their own.

    For cycle detection we definitely want to check inside of expired keyrings,
    just so that we don't create a cycle we can't get rid of. Revoked keyrings
    are cleared at revocation time and can't then be reused, so shouldn't be a
    problem either way.

    For possession determination, we *might* want to validate each keyring before
    searching it: do you possess a key that's hidden behind an expired or just
    plain inaccessible keyring? Currently, the answer is yes. Note that you
    cannot, however, possess a key behind a revoked keyring because they are
    cleared on revocation.

    keyring_search() sets DO_STATE_CHECK, which is correct.

    request_key_and_link() currently doesn't specify whether to check the key
    state or not - but it should set DO_STATE_CHECK.

    key_get_instantiation_authkey() also currently doesn't specify whether to
    check the key state or not - but it probably should also set DO_STATE_CHECK.

    Signed-off-by: David Howells
    Tested-by: Chuck Lever

    David Howells
     
  • When a key description argument is imported into the kernel from userspace, as
    happens in add_key(), request_key(), KEYCTL_JOIN_SESSION_KEYRING,
    KEYCTL_SEARCH, the description is copied into a buffer up to PAGE_SIZE in size.
    PAGE_SIZE, however, is a variable quantity, depending on the arch. Fix this at
    4096 instead (ie. 4095 plus a NUL termination) and define a constant
    (KEY_MAX_DESC_SIZE) to this end.

    When reading the description back with KEYCTL_DESCRIBE, a PAGE_SIZE internal
    buffer is allocated into which the information and description will be
    rendered. This means that the description will get truncated if an extremely
    long description it has to be crammed into the buffer with the stringified
    information. There is no particular need to copy the description into the
    buffer, so just copy it directly to userspace in a separate operation.

    Reported-by: Christian Kastner
    Signed-off-by: David Howells
    Tested-by: Christian Kastner

    David Howells