24 Mar, 2019

1 commit

  • [ Upstream commit 822ad64d7e46a8e2c8b8a796738d7b657cbb146d ]

    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
    Signed-off-by: Sasha Levin

    David Howells
     

27 Feb, 2019

2 commits

  • commit ede0fa98a900e657d1fcd80b50920efc896c1a4c upstream.

    syzbot hit the 'BUG_ON(index_key->desc_len == 0);' in __key_link_begin()
    called from construct_alloc_key() during sys_request_key(), because the
    length of the key description was never calculated.

    The problem is that we rely on ->desc_len being initialized by
    search_process_keyrings(), specifically by search_nested_keyrings().
    But, if the process isn't subscribed to any keyrings that never happens.

    Fix it by always initializing keyring_index_key::desc_len as soon as the
    description is set, like we already do in some places.

    The following program reproduces the BUG_ON() when it's run as root and
    no session keyring has been installed. If it doesn't work, try removing
    pam_keyinit.so from /etc/pam.d/login and rebooting.

    #include
    #include
    #include

    int main(void)
    {
    int id = add_key("keyring", "syz", NULL, 0, KEY_SPEC_USER_KEYRING);

    keyctl_setperm(id, KEY_OTH_WRITE);
    setreuid(5000, 5000);
    request_key("user", "desc", "", id);
    }

    Reported-by: syzbot+ec24e95ea483de0a24da@syzkaller.appspotmail.com
    Fixes: b2a4df200d57 ("KEYS: Expand the capacity of a keyring")
    Signed-off-by: Eric Biggers
    Signed-off-by: David Howells
    Cc: stable@vger.kernel.org
    Signed-off-by: James Morris
    Signed-off-by: Greg Kroah-Hartman

    Eric Biggers
     
  • commit a08bf91ce28ed3ae7b6fef35d843fef8dc8c2cd9 upstream.

    If the sysctl 'kernel.keys.maxkeys' is set to some number n, then
    actually users can only add up to 'n - 1' keys. Likewise for
    'kernel.keys.maxbytes' and the root_* versions of these sysctls. But
    these sysctls are apparently supposed to be *maximums*, as per their
    names and all documentation I could find -- the keyrings(7) man page,
    Documentation/security/keys/core.rst, and all the mentions of EDQUOT
    meaning that the key quota was *exceeded* (as opposed to reached).

    Thus, fix the code to allow reaching the quotas exactly.

    Fixes: 0b77f5bfb45c ("keys: make the keyring quotas controllable through /proc/sys")
    Cc: stable@vger.kernel.org
    Signed-off-by: Eric Biggers
    Signed-off-by: David Howells
    Signed-off-by: James Morris
    Signed-off-by: Greg Kroah-Hartman

    Eric Biggers
     

25 Sep, 2018

1 commit

  • This changes UAPI, breaking iwd and libell:

    ell/key.c: In function 'kernel_dh_compute':
    ell/key.c:205:38: error: 'struct keyctl_dh_params' has no member named 'private'; did you mean 'dh_private'?
    struct keyctl_dh_params params = { .private = private,
    ^~~~~~~
    dh_private

    This reverts commit 8a2336e549d385bb0b46880435b411df8d8200e8.

    Fixes: 8a2336e549d3 ("uapi/linux/keyctl.h: don't use C++ reserved keyword as a struct member name")
    Signed-off-by: Lubomir Rintel
    Signed-off-by: David Howells
    cc: Randy Dunlap
    cc: Mat Martineau
    cc: Stephan Mueller
    cc: James Morris
    cc: "Serge E. Hallyn"
    cc: Mat Martineau
    cc: Andrew Morton
    cc: Linus Torvalds
    cc:
    Signed-off-by: James Morris
    Signed-off-by: Greg Kroah-Hartman

    Lubomir Rintel
     

05 Sep, 2018

1 commit

  • Since this header is in "include/uapi/linux/", apparently people want to
    use it in userspace programs -- even in C++ ones. However, the header
    uses a C++ reserved keyword ("private"), so change that to "dh_private"
    instead to allow the header file to be used in C++ userspace.

    Fixes https://bugzilla.kernel.org/show_bug.cgi?id=191051
    Link: http://lkml.kernel.org/r/0db6c314-1ef4-9bfa-1baa-7214dd2ee061@infradead.org
    Fixes: ddbb41148724 ("KEYS: Add KEYCTL_DH_COMPUTE command")
    Signed-off-by: Randy Dunlap
    Reviewed-by: Andrew Morton
    Cc: David Howells
    Cc: James Morris
    Cc: "Serge E. Hallyn"
    Cc: Mat Martineau
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Randy Dunlap
     

03 Aug, 2018

1 commit


09 Jul, 2018

1 commit

  • Some crypto API users allocating a tfm with crypto_alloc_$FOO() are also
    specifying the type flags for $FOO, e.g. crypto_alloc_shash() with
    CRYPTO_ALG_TYPE_SHASH. But, that's redundant since the crypto API will
    override any specified type flag/mask with the correct ones.

    So, remove the unneeded flags.

    This patch shouldn't change any actual behavior.

    Signed-off-by: Eric Biggers
    Signed-off-by: Herbert Xu

    Eric Biggers
     

27 Jun, 2018

1 commit

  • Commit 383203eff718 ("dh key: get rid of stack allocated array") changed
    kdf_ctr() to assume that the length of key material to derive is a
    multiple of the digest size. The length was supposed to be rounded up
    accordingly. However, the round_up() macro was used which only gives
    the correct result on power-of-2 arguments, whereas not all hash
    algorithms have power-of-2 digest sizes. In some cases this resulted in
    a write past the end of the 'outbuf' buffer.

    Fix it by switching to roundup(), which works for non-power-of-2 inputs.

    Reported-by: syzbot+486f97f892efeb2075a3@syzkaller.appspotmail.com
    Reported-by: syzbot+29d17b7898b41ee120a5@syzkaller.appspotmail.com
    Reported-by: syzbot+8a608baf8751184ec727@syzkaller.appspotmail.com
    Reported-by: syzbot+d04e58bd384f1fe0b112@syzkaller.appspotmail.com
    Fixes: 383203eff718 ("dh key: get rid of stack allocated array")
    Signed-off-by: Eric Biggers
    Acked-by: Kees Cook
    Acked-by: Tycho Andersen
    Signed-off-by: James Morris

    Eric Biggers
     

13 Jun, 2018

1 commit

  • The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
    patch replaces cases of:

    kmalloc(a * b, gfp)

    with:
    kmalloc_array(a * b, gfp)

    as well as handling cases of:

    kmalloc(a * b * c, gfp)

    with:

    kmalloc(array3_size(a, b, c), gfp)

    as it's slightly less ugly than:

    kmalloc_array(array_size(a, b), c, gfp)

    This does, however, attempt to ignore constant size factors like:

    kmalloc(4 * 1024, gfp)

    though any constants defined via macros get caught up in the conversion.

    Any factors with a sizeof() of "unsigned char", "char", and "u8" were
    dropped, since they're redundant.

    The tools/ directory was manually excluded, since it has its own
    implementation of kmalloc().

    The Coccinelle script used for this was:

    // Fix redundant parens around sizeof().
    @@
    type TYPE;
    expression THING, E;
    @@

    (
    kmalloc(
    - (sizeof(TYPE)) * E
    + sizeof(TYPE) * E
    , ...)
    |
    kmalloc(
    - (sizeof(THING)) * E
    + sizeof(THING) * E
    , ...)
    )

    // Drop single-byte sizes and redundant parens.
    @@
    expression COUNT;
    typedef u8;
    typedef __u8;
    @@

    (
    kmalloc(
    - sizeof(u8) * (COUNT)
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(__u8) * (COUNT)
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(char) * (COUNT)
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(unsigned char) * (COUNT)
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(u8) * COUNT
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(__u8) * COUNT
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(char) * COUNT
    + COUNT
    , ...)
    |
    kmalloc(
    - sizeof(unsigned char) * COUNT
    + COUNT
    , ...)
    )

    // 2-factor product with sizeof(type/expression) and identifier or constant.
    @@
    type TYPE;
    expression THING;
    identifier COUNT_ID;
    constant COUNT_CONST;
    @@

    (
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * (COUNT_ID)
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * COUNT_ID
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * (COUNT_CONST)
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * COUNT_CONST
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * (COUNT_ID)
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * COUNT_ID
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * (COUNT_CONST)
    + COUNT_CONST, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * COUNT_CONST
    + COUNT_CONST, sizeof(THING)
    , ...)
    )

    // 2-factor product, only identifiers.
    @@
    identifier SIZE, COUNT;
    @@

    - kmalloc
    + kmalloc_array
    (
    - SIZE * COUNT
    + COUNT, SIZE
    , ...)

    // 3-factor product with 1 sizeof(type) or sizeof(expression), with
    // redundant parens removed.
    @@
    expression THING;
    identifier STRIDE, COUNT;
    type TYPE;
    @@

    (
    kmalloc(
    - sizeof(TYPE) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kmalloc(
    - sizeof(THING) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kmalloc(
    - sizeof(THING) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kmalloc(
    - sizeof(THING) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kmalloc(
    - sizeof(THING) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    )

    // 3-factor product with 2 sizeof(variable), with redundant parens removed.
    @@
    expression THING1, THING2;
    identifier COUNT;
    type TYPE1, TYPE2;
    @@

    (
    kmalloc(
    - sizeof(TYPE1) * sizeof(TYPE2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kmalloc(
    - sizeof(THING1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kmalloc(
    - sizeof(THING1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    |
    kmalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    )

    // 3-factor product, only identifiers, with redundant parens removed.
    @@
    identifier STRIDE, SIZE, COUNT;
    @@

    (
    kmalloc(
    - (COUNT) * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - COUNT * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - COUNT * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - (COUNT) * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - COUNT * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - (COUNT) * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - (COUNT) * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kmalloc(
    - COUNT * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    )

    // Any remaining multi-factor products, first at least 3-factor products,
    // when they're not all constants...
    @@
    expression E1, E2, E3;
    constant C1, C2, C3;
    @@

    (
    kmalloc(C1 * C2 * C3, ...)
    |
    kmalloc(
    - (E1) * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kmalloc(
    - (E1) * (E2) * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kmalloc(
    - (E1) * (E2) * (E3)
    + array3_size(E1, E2, E3)
    , ...)
    |
    kmalloc(
    - E1 * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    )

    // And then all remaining 2 factors products when they're not all constants,
    // keeping sizeof() as the second factor argument.
    @@
    expression THING, E1, E2;
    type TYPE;
    constant C1, C2, C3;
    @@

    (
    kmalloc(sizeof(THING) * C2, ...)
    |
    kmalloc(sizeof(TYPE) * C2, ...)
    |
    kmalloc(C1 * C2 * C3, ...)
    |
    kmalloc(C1 * C2, ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * (E2)
    + E2, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(TYPE) * E2
    + E2, sizeof(TYPE)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * (E2)
    + E2, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - sizeof(THING) * E2
    + E2, sizeof(THING)
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - (E1) * E2
    + E1, E2
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - (E1) * (E2)
    + E1, E2
    , ...)
    |
    - kmalloc
    + kmalloc_array
    (
    - E1 * E2
    + E1, E2
    , ...)
    )

    Signed-off-by: Kees Cook

    Kees Cook
     

07 Jun, 2018

1 commit

  • Pull security system updates from James Morris:

    - incorporate new socketpair() hook into LSM and wire up the SELinux
    and Smack modules. From David Herrmann:

    "The idea is to allow SO_PEERSEC to be called on AF_UNIX sockets
    created via socketpair(2), and return the same information as if
    you emulated socketpair(2) via a temporary listener socket.

    Right now SO_PEERSEC will return the unlabeled credentials for a
    socketpair, rather than the actual credentials of the creating
    process."

    - remove the unused security_settime LSM hook (Sargun Dhillon).

    - remove some stack allocated arrays from the keys code (Tycho
    Andersen)

    * 'next-general' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
    dh key: get rid of stack allocated array for zeroes
    dh key: get rid of stack allocated array
    big key: get rid of stack array allocation
    smack: provide socketpair callback
    selinux: provide socketpair callback
    net: hook socketpair() into LSM
    security: add hook for socketpair()
    security: remove security_settime

    Linus Torvalds
     

16 May, 2018

1 commit


12 May, 2018

3 commits

  • We're interested in getting rid of all of the stack allocated arrays in
    the kernel: https://lkml.org/lkml/2018/3/7/621

    This case is interesting, since we really just need an array of bytes that
    are zero. The loop already ensures that if the array isn't exactly the
    right size that enough zero bytes will be copied in. So, instead of
    choosing this value to be the size of the hash, let's just choose it to be
    32, since that is a common size, is not too big, and will not result in too
    many extra iterations of the loop.

    v2: split out from other patch, just hardcode array size instead of
    dynamically allocating something the right size
    v3: fix typo of 256 -> 32

    Signed-off-by: Tycho Andersen
    Reviewed-by: Kees Cook
    CC: David Howells
    CC: James Morris
    CC: "Serge E. Hallyn"
    CC: Eric Biggers
    Signed-off-by: James Morris

    Tycho Andersen
     
  • We're interested in getting rid of all of the stack allocated arrays in the
    kernel: https://lkml.org/lkml/2018/3/7/621

    This particular vla is used as a temporary output buffer in case there is
    too much hash output for the destination buffer. Instead, let's just
    allocate a buffer that's big enough initially, but only copy back to
    userspace the amount that was originally asked for.

    v2: allocate enough in the original output buffer vs creating a temporary
    output buffer

    Signed-off-by: Tycho Andersen
    Reviewed-by: Kees Cook
    CC: David Howells
    CC: James Morris
    CC: "Serge E. Hallyn"
    CC: Eric Biggers
    Signed-off-by: James Morris

    Tycho Andersen
     
  • We're interested in getting rid of all of the stack allocated arrays in the
    kernel [1]. This patch simply hardcodes the iv length to match that of the
    hardcoded cipher.

    [1]: https://lkml.org/lkml/2018/3/7/621

    v2: hardcode the length of the nonce to be the GCM AES IV length, and do a
    sanity check in init(), Eric Biggers
    v3: * remember to free big_key_aead when sanity check fails
    * define a constant for big key IV size so it can be changed along side
    the algorithm in the code

    Signed-off-by: Tycho Andersen
    Reviewed-by: Kees Cook
    CC: David Howells
    CC: James Morris
    CC: "Serge E. Hallyn"
    CC: Jason A. Donenfeld
    CC: Eric Biggers
    Signed-off-by: James Morris

    Tycho Andersen
     

06 Apr, 2018

1 commit

  • Currently #includes for no obvious
    reason. It looks like it's only a convenience, so remove kmemleak.h
    from slab.h and add to any users of kmemleak_* that
    don't already #include it. Also remove from source
    files that do not use it.

    This is tested on i386 allmodconfig and x86_64 allmodconfig. It would
    be good to run it through the 0day bot for other $ARCHes. I have
    neither the horsepower nor the storage space for the other $ARCHes.

    Update: This patch has been extensively build-tested by both the 0day
    bot & kisskb/ozlabs build farms. Both of them reported 2 build failures
    for which patches are included here (in v2).

    [ slab.h is the second most used header file after module.h; kernel.h is
    right there with slab.h. There could be some minor error in the
    counting due to some #includes having comments after them and I didn't
    combine all of those. ]

    [akpm@linux-foundation.org: security/keys/big_key.c needs vmalloc.h, per sfr]
    Link: http://lkml.kernel.org/r/e4309f98-3749-93e1-4bb7-d9501a39d015@infradead.org
    Link: http://kisskb.ellerman.id.au/kisskb/head/13396/
    Signed-off-by: Randy Dunlap
    Reviewed-by: Ingo Molnar
    Reported-by: Michael Ellerman [2 build failures]
    Reported-by: Fengguang Wu [2 build failures]
    Reviewed-by: Andrew Morton
    Cc: Wei Yongjun
    Cc: Luis R. Rodriguez
    Cc: Greg Kroah-Hartman
    Cc: Mimi Zohar
    Cc: John Johansen
    Cc: Stephen Rothwell
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Randy Dunlap
     

22 Feb, 2018

1 commit

  • kmalloc() can't always allocate large enough buffers for big_key to use for
    crypto (1MB + some metadata) so we cannot use that to allocate the buffer.
    Further, vmalloc'd pages can't be passed to sg_init_one() and the aead
    crypto accessors cannot be called progressively and must be passed all the
    data in one go (which means we can't pass the data in one block at a time).

    Fix this by allocating the buffer pages individually and passing them
    through a multientry scatterlist to the crypto layer. This has the bonus
    advantage that we don't have to allocate a contiguous series of pages.

    We then vmap() the page list and pass that through to the VFS read/write
    routines.

    This can trigger a warning:

    WARNING: CPU: 0 PID: 60912 at mm/page_alloc.c:3883 __alloc_pages_nodemask+0xb7c/0x15f8
    ([] __alloc_pages_nodemask+0x1ee/0x15f8)
    [] kmalloc_order+0x46/0x90
    [] kmalloc_order_trace+0x40/0x1f8
    [] __kmalloc+0x430/0x4c0
    [] big_key_preparse+0x7c/0x210
    [] key_create_or_update+0x128/0x420
    [] SyS_add_key+0x124/0x220
    [] system_call+0xc4/0x2b0

    from the keyctl/padd/useradd test of the keyutils testsuite on s390x.

    Note that it might be better to shovel data through in page-sized lumps
    instead as there's no particular need to use a monolithic buffer unless the
    kernel itself wants to access the data.

    Fixes: 13100a72f40f ("Security: Keys: Big keys stored encrypted")
    Reported-by: Paul Bunyan
    Signed-off-by: David Howells
    cc: Kirill Marinushkin

    David Howells
     

01 Feb, 2018

1 commit

  • Pull tpm updates from James Morris:

    - reduce polling delays in tpm_tis

    - support retrieving TPM 2.0 Event Log through EFI before
    ExitBootServices

    - replace tpm-rng.c with a hwrng device managed by the driver for each
    TPM device

    - TPM resource manager synthesizes TPM_RC_COMMAND_CODE response instead
    of returning -EINVAL for unknown TPM commands. This makes user space
    more sound.

    - CLKRUN fixes:

    * Keep #CLKRUN disable through the entier TPM command/response flow

    * Check whether #CLKRUN is enabled before disabling and enabling it
    again because enabling it breaks PS/2 devices on a system where it
    is disabled

    * 'next-tpm' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
    tpm: remove unused variables
    tpm: remove unused data fields from I2C and OF device ID tables
    tpm: only attempt to disable the LPC CLKRUN if is already enabled
    tpm: follow coding style for variable declaration in tpm_tis_core_init()
    tpm: delete the TPM_TIS_CLK_ENABLE flag
    tpm: Update MAINTAINERS for Jason Gunthorpe
    tpm: Keep CLKRUN enabled throughout the duration of transmit_cmd()
    tpm_tis: Move ilb_base_addr to tpm_tis_data
    tpm2-cmd: allow more attempts for selftest execution
    tpm: return a TPM_RC_COMMAND_CODE response if command is not implemented
    tpm: Move Linux RNG connection to hwrng
    tpm: use struct tpm_chip for tpm_chip_find_get()
    tpm: parse TPM event logs based on EFI table
    efi: call get_event_log before ExitBootServices
    tpm: add event log format version
    tpm: rename event log provider files
    tpm: move tpm_eventlog.h outside of drivers folder
    tpm: use tpm_msleep() value as max delay
    tpm: reduce tpm polling delay in tpm_tis_core
    tpm: move wait_for_tpm_stat() to respective driver files

    Linus Torvalds
     

08 Jan, 2018

1 commit

  • Device number (the character device index) is not a stable identifier
    for a TPM chip. That is the reason why every call site passes
    TPM_ANY_NUM to tpm_chip_find_get().

    This commit changes the API in a way that instead a struct tpm_chip
    instance is given and NULL means the default chip. In addition, this
    commit refines the documentation to be up to date with the
    implementation.

    Suggested-by: Jason Gunthorpe (@chip_num -> @chip part)
    Signed-off-by: Jarkko Sakkinen
    Reviewed-by: Jason Gunthorpe
    Tested-by: PrasannaKumar Muralidharan

    Jarkko Sakkinen
     

03 Jan, 2018

1 commit

  • …k/linux-rcu into core/rcu

    Pull RCU updates from Paul E. McKenney:

    - Updates to use cond_resched() instead of cond_resched_rcu_qs()
    where feasible (currently everywhere except in kernel/rcu and
    in kernel/torture.c). Also a couple of fixes to avoid sending
    IPIs to offline CPUs.

    - Updates to simplify RCU's dyntick-idle handling.

    - Updates to remove almost all uses of smp_read_barrier_depends()
    and read_barrier_depends().

    - Miscellaneous fixes.

    - Torture-test updates.

    Signed-off-by: Ingo Molnar <mingo@kernel.org>

    Ingo Molnar
     

08 Dec, 2017

4 commits

  • keyctl_restrict_keyring() allows through a NULL restriction when the
    "type" is non-NULL, which causes a NULL pointer dereference in
    asymmetric_lookup_restriction() when it calls strcmp() on the
    restriction string.

    But no key types actually use a "NULL restriction" to mean anything, so
    update keyctl_restrict_keyring() to reject it with EINVAL.

    Reported-by: syzbot
    Fixes: 97d3aa0f3134 ("KEYS: Add a lookup_restriction function for the asymmetric key type")
    Cc: # v4.12+
    Signed-off-by: Eric Biggers
    Signed-off-by: David Howells

    Eric Biggers
     
  • Variable key_ref is being assigned a value that is never read;
    key_ref is being re-assigned a few statements later. Hence this
    assignment is redundant and can be removed.

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

    Colin Ian King
     
  • 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 8bbf4976b59f
    ("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: 3e30148c3d52 ("[PATCH] Keys: Make request-key create an authorisation key")
    Cc: # v2.6.13+
    Signed-off-by: Eric Biggers
    Signed-off-by: David Howells

    Eric Biggers
     
  • In request_key_and_link(), in the case where the dest_keyring was
    explicitly specified, there is no need to get another reference to
    dest_keyring before calling key_link(), then drop it afterwards. This
    is because by definition, we already have a reference to dest_keyring.

    This change is useful because we'll be making
    construct_get_dest_keyring() able to return an error code, and we don't
    want to have to handle that error here for no reason.

    Signed-off-by: Eric Biggers
    Signed-off-by: David Howells

    Eric Biggers
     

05 Dec, 2017

1 commit


26 Nov, 2017

1 commit

  • Pull timer updates from Thomas Gleixner:

    - The final conversion of timer wheel timers to timer_setup().

    A few manual conversions and a large coccinelle assisted sweep and
    the removal of the old initialization mechanisms and the related
    code.

    - Remove the now unused VSYSCALL update code

    - Fix permissions of /proc/timer_list. I still need to get rid of that
    file completely

    - Rename a misnomed clocksource function and remove a stale declaration

    * 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (27 commits)
    m68k/macboing: Fix missed timer callback assignment
    treewide: Remove TIMER_FUNC_TYPE and TIMER_DATA_TYPE casts
    timer: Remove redundant __setup_timer*() macros
    timer: Pass function down to initialization routines
    timer: Remove unused data arguments from macros
    timer: Switch callback prototype to take struct timer_list * argument
    timer: Pass timer_list pointer to callbacks unconditionally
    Coccinelle: Remove setup_timer.cocci
    timer: Remove setup_*timer() interface
    timer: Remove init_timer() interface
    treewide: setup_timer() -> timer_setup() (2 field)
    treewide: setup_timer() -> timer_setup()
    treewide: init_timer() -> setup_timer()
    treewide: Switch DEFINE_TIMER callbacks to struct timer_list *
    s390: cmm: Convert timers to use timer_setup()
    lightnvm: Convert timers to use timer_setup()
    drivers/net: cris: Convert timers to use timer_setup()
    drm/vc4: Convert timers to use timer_setup()
    block/laptop_mode: Convert timers to use timer_setup()
    net/atm/mpc: Avoid open-coded assignment of timer callback function
    ...

    Linus Torvalds
     

22 Nov, 2017

1 commit

  • This changes all DEFINE_TIMER() callbacks to use a struct timer_list
    pointer instead of unsigned long. Since the data argument has already been
    removed, none of these callbacks are using their argument currently, so
    this renames the argument to "unused".

    Done using the following semantic patch:

    @match_define_timer@
    declarer name DEFINE_TIMER;
    identifier _timer, _callback;
    @@

    DEFINE_TIMER(_timer, _callback);

    @change_callback depends on match_define_timer@
    identifier match_define_timer._callback;
    type _origtype;
    identifier _origarg;
    @@

    void
    -_callback(_origtype _origarg)
    +_callback(struct timer_list *unused)
    { ... }

    Signed-off-by: Kees Cook

    Kees Cook
     

16 Nov, 2017

2 commits

  • The 'struct key_preparsed_payload' will use 'time_t' which we will
    try to remove in the kernel, since 'time_t' is not year 2038 safe on
    32bits systems.

    Thus this patch replaces 'time_t' with 'time64_t' which is year 2038
    safe on 32 bits system for 'struct key_preparsed_payload', moreover
    we should use the 'TIME64_MAX' macro to initialize the 'time64_t'
    type variable.

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

    Baolin Wang
     
  • 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
     

14 Nov, 2017

1 commit

  • Pull timer updates from Thomas Gleixner:
    "Yet another big pile of changes:

    - More year 2038 work from Arnd slowly reaching the point where we
    need to think about the syscalls themself.

    - A new timer function which allows to conditionally (re)arm a timer
    only when it's either not running or the new expiry time is sooner
    than the armed expiry time. This allows to use a single timer for
    multiple timeout requirements w/o caring about the first expiry
    time at the call site.

    - A new NMI safe accessor to clock real time for the printk timestamp
    work. Can be used by tracing, perf as well if required.

    - A large number of timer setup conversions from Kees which got
    collected here because either maintainers requested so or they
    simply got ignored. As Kees pointed out already there are a few
    trivial merge conflicts and some redundant commits which was
    unavoidable due to the size of this conversion effort.

    - Avoid a redundant iteration in the timer wheel softirq processing.

    - Provide a mechanism to treat RTC implementations depending on their
    hardware properties, i.e. don't inflict the write at the 0.5
    seconds boundary which originates from the PC CMOS RTC to all RTCs.
    No functional change as drivers need to be updated separately.

    - The usual small updates to core code clocksource drivers. Nothing
    really exciting"

    * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (111 commits)
    timers: Add a function to start/reduce a timer
    pstore: Use ktime_get_real_fast_ns() instead of __getnstimeofday()
    timer: Prepare to change all DEFINE_TIMER() callbacks
    netfilter: ipvs: Convert timers to use timer_setup()
    scsi: qla2xxx: Convert timers to use timer_setup()
    block/aoe: discover_timer: Convert timers to use timer_setup()
    ide: Convert timers to use timer_setup()
    drbd: Convert timers to use timer_setup()
    mailbox: Convert timers to use timer_setup()
    crypto: Convert timers to use timer_setup()
    drivers/pcmcia: omap1: Fix error in automated timer conversion
    ARM: footbridge: Fix typo in timer conversion
    drivers/sgi-xp: Convert timers to use timer_setup()
    drivers/pcmcia: Convert timers to use timer_setup()
    drivers/memstick: Convert timers to use timer_setup()
    drivers/macintosh: Convert timers to use timer_setup()
    hwrng/xgene-rng: Convert timers to use timer_setup()
    auxdisplay: Convert timers to use timer_setup()
    sparc/led: Convert timers to use timer_setup()
    mips: ip22/32: Convert timers to use timer_setup()
    ...

    Linus Torvalds
     

03 Nov, 2017

1 commit

  • …el/git/gregkh/driver-core

    Pull initial SPDX identifiers from Greg KH:
    "License cleanup: add SPDX license identifiers to some files

    Many source files in the tree are missing licensing information, which
    makes it harder for compliance tools to determine the correct license.

    By default all files without license information are under the default
    license of the kernel, which is GPL version 2.

    Update the files which contain no license information with the
    'GPL-2.0' SPDX license identifier. The SPDX identifier is a legally
    binding shorthand, which can be used instead of the full boiler plate
    text.

    This patch is based on work done by Thomas Gleixner and Kate Stewart
    and Philippe Ombredanne.

    How this work was done:

    Patches were generated and checked against linux-4.14-rc6 for a subset
    of the use cases:

    - file had no licensing information it it.

    - file was a */uapi/* one with no licensing information in it,

    - file was a */uapi/* one with existing licensing information,

    Further patches will be generated in subsequent months to fix up cases
    where non-standard license headers were used, and references to
    license had to be inferred by heuristics based on keywords.

    The analysis to determine which SPDX License Identifier to be applied
    to a file was done in a spreadsheet of side by side results from of
    the output of two independent scanners (ScanCode & Windriver)
    producing SPDX tag:value files created by Philippe Ombredanne.
    Philippe prepared the base worksheet, and did an initial spot review
    of a few 1000 files.

    The 4.13 kernel was the starting point of the analysis with 60,537
    files assessed. Kate Stewart did a file by file comparison of the
    scanner results in the spreadsheet to determine which SPDX license
    identifier(s) to be applied to the file. She confirmed any
    determination that was not immediately clear with lawyers working with
    the Linux Foundation.

    Criteria used to select files for SPDX license identifier tagging was:

    - Files considered eligible had to be source code files.

    - Make and config files were included as candidates if they contained
    >5 lines of source

    - File already had some variant of a license header in it (even if <5
    lines).

    All documentation files were explicitly excluded.

    The following heuristics were used to determine which SPDX license
    identifiers to apply.

    - when both scanners couldn't find any license traces, file was
    considered to have no license information in it, and the top level
    COPYING file license applied.

    For non */uapi/* files that summary was:

    SPDX license identifier # files
    ---------------------------------------------------|-------
    GPL-2.0 11139

    and resulted in the first patch in this series.

    If that file was a */uapi/* path one, it was "GPL-2.0 WITH
    Linux-syscall-note" otherwise it was "GPL-2.0". Results of that
    was:

    SPDX license identifier # files
    ---------------------------------------------------|-------
    GPL-2.0 WITH Linux-syscall-note 930

    and resulted in the second patch in this series.

    - if a file had some form of licensing information in it, and was one
    of the */uapi/* ones, it was denoted with the Linux-syscall-note if
    any GPL family license was found in the file or had no licensing in
    it (per prior point). Results summary:

    SPDX license identifier # files
    ---------------------------------------------------|------
    GPL-2.0 WITH Linux-syscall-note 270
    GPL-2.0+ WITH Linux-syscall-note 169
    ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21
    ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17
    LGPL-2.1+ WITH Linux-syscall-note 15
    GPL-1.0+ WITH Linux-syscall-note 14
    ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5
    LGPL-2.0+ WITH Linux-syscall-note 4
    LGPL-2.1 WITH Linux-syscall-note 3
    ((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3
    ((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1

    and that resulted in the third patch in this series.

    - when the two scanners agreed on the detected license(s), that
    became the concluded license(s).

    - when there was disagreement between the two scanners (one detected
    a license but the other didn't, or they both detected different
    licenses) a manual inspection of the file occurred.

    - In most cases a manual inspection of the information in the file
    resulted in a clear resolution of the license that should apply
    (and which scanner probably needed to revisit its heuristics).

    - When it was not immediately clear, the license identifier was
    confirmed with lawyers working with the Linux Foundation.

    - If there was any question as to the appropriate license identifier,
    the file was flagged for further research and to be revisited later
    in time.

    In total, over 70 hours of logged manual review was done on the
    spreadsheet to determine the SPDX license identifiers to apply to the
    source files by Kate, Philippe, Thomas and, in some cases,
    confirmation by lawyers working with the Linux Foundation.

    Kate also obtained a third independent scan of the 4.13 code base from
    FOSSology, and compared selected files where the other two scanners
    disagreed against that SPDX file, to see if there was new insights.
    The Windriver scanner is based on an older version of FOSSology in
    part, so they are related.

    Thomas did random spot checks in about 500 files from the spreadsheets
    for the uapi headers and agreed with SPDX license identifier in the
    files he inspected. For the non-uapi files Thomas did random spot
    checks in about 15000 files.

    In initial set of patches against 4.14-rc6, 3 files were found to have
    copy/paste license identifier errors, and have been fixed to reflect
    the correct identifier.

    Additionally Philippe spent 10 hours this week doing a detailed manual
    inspection and review of the 12,461 patched files from the initial
    patch version early this week with:

    - a full scancode scan run, collecting the matched texts, detected
    license ids and scores

    - reviewing anything where there was a license detected (about 500+
    files) to ensure that the applied SPDX license was correct

    - reviewing anything where there was no detection but the patch
    license was not GPL-2.0 WITH Linux-syscall-note to ensure that the
    applied SPDX license was correct

    This produced a worksheet with 20 files needing minor correction. This
    worksheet was then exported into 3 different .csv files for the
    different types of files to be modified.

    These .csv files were then reviewed by Greg. Thomas wrote a script to
    parse the csv files and add the proper SPDX tag to the file, in the
    format that the file expected. This script was further refined by Greg
    based on the output to detect more types of files automatically and to
    distinguish between header and source .c files (which need different
    comment types.) Finally Greg ran the script using the .csv files to
    generate the patches.

    Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
    Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
    Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"

    * tag 'spdx_identifiers-4.14-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
    License cleanup: add SPDX license identifier to uapi header files with a license
    License cleanup: add SPDX license identifier to uapi header files with no license
    License cleanup: add SPDX GPL-2.0 license identifier to files with no license

    Linus Torvalds
     

02 Nov, 2017

3 commits

  • Many source files in the tree are missing licensing information, which
    makes it harder for compliance tools to determine the correct license.

    By default all files without license information are under the default
    license of the kernel, which is GPL version 2.

    Update the files which contain no license information with the 'GPL-2.0'
    SPDX license identifier. The SPDX identifier is a legally binding
    shorthand, which can be used instead of the full boiler plate text.

    This patch is based on work done by Thomas Gleixner and Kate Stewart and
    Philippe Ombredanne.

    How this work was done:

    Patches were generated and checked against linux-4.14-rc6 for a subset of
    the use cases:
    - file had no licensing information it it.
    - file was a */uapi/* one with no licensing information in it,
    - file was a */uapi/* one with existing licensing information,

    Further patches will be generated in subsequent months to fix up cases
    where non-standard license headers were used, and references to license
    had to be inferred by heuristics based on keywords.

    The analysis to determine which SPDX License Identifier to be applied to
    a file was done in a spreadsheet of side by side results from of the
    output of two independent scanners (ScanCode & Windriver) producing SPDX
    tag:value files created by Philippe Ombredanne. Philippe prepared the
    base worksheet, and did an initial spot review of a few 1000 files.

    The 4.13 kernel was the starting point of the analysis with 60,537 files
    assessed. Kate Stewart did a file by file comparison of the scanner
    results in the spreadsheet to determine which SPDX license identifier(s)
    to be applied to the file. She confirmed any determination that was not
    immediately clear with lawyers working with the Linux Foundation.

    Criteria used to select files for SPDX license identifier tagging was:
    - Files considered eligible had to be source code files.
    - Make and config files were included as candidates if they contained >5
    lines of source
    - File already had some variant of a license header in it (even if
    Reviewed-by: Philippe Ombredanne
    Reviewed-by: Thomas Gleixner
    Signed-off-by: Greg Kroah-Hartman

    Greg Kroah-Hartman
     
  • When calling keyctl_read() on a key of type "trusted", if the
    user-supplied buffer was too small, the kernel ignored the buffer length
    and just wrote past the end of the buffer, potentially corrupting
    userspace memory. Fix it by instead returning the size required, as per
    the documentation for keyctl_read().

    We also don't even fill the buffer at all in this case, as this is
    slightly easier to implement than doing a short read, and either
    behavior appears to be permitted. It also makes it match the behavior
    of the "encrypted" key type.

    Fixes: d00a1c72f7f4 ("keys: add new trusted key-type")
    Reported-by: Ben Hutchings
    Cc: # v2.6.38+
    Signed-off-by: Eric Biggers
    Signed-off-by: David Howells
    Reviewed-by: Mimi Zohar
    Reviewed-by: James Morris
    Signed-off-by: James Morris

    Eric Biggers
     
  • Commit e645016abc80 ("KEYS: fix writing past end of user-supplied buffer
    in keyring_read()") made keyring_read() stop corrupting userspace memory
    when the user-supplied buffer is too small. However it also made the
    return value in that case be the short buffer size rather than the size
    required, yet keyctl_read() is actually documented to return the size
    required. Therefore, switch it over to the documented behavior.

    Note that for now we continue to have it fill the short buffer, since it
    did that before (pre-v3.13) and dump_key_tree_aux() in keyutils arguably
    relies on it.

    Fixes: e645016abc80 ("KEYS: fix writing past end of user-supplied buffer in keyring_read()")
    Reported-by: Ben Hutchings
    Cc: # v3.13+
    Signed-off-by: Eric Biggers
    Signed-off-by: David Howells
    Reviewed-by: James Morris
    Signed-off-by: James Morris

    Eric Biggers
     

18 Oct, 2017

6 commits

  • In proc_keys_show(), the key semaphore is not held, so the key ->flags
    and ->expiry can be changed concurrently. We therefore should read them
    atomically just once.

    Signed-off-by: Eric Biggers
    Signed-off-by: David Howells

    Eric Biggers
     
  • Similar to the case for key_validate(), we should load the key ->expiry
    once atomically in keyring_search_iterator(), since it can be changed
    concurrently with the flags whenever the key semaphore isn't held.

    Signed-off-by: Eric Biggers
    Signed-off-by: David Howells

    Eric Biggers
     
  • In key_validate(), load the flags and expiry time once atomically, since
    these can change concurrently if key_validate() is called without the
    key semaphore held. And we don't want to get inconsistent results if a
    variable is referenced multiple times. For example, key->expiry was
    referenced in both 'if (key->expiry)' and in 'if (now.tv_sec >=
    key->expiry)', making it theoretically possible to see a spurious
    EKEYEXPIRED while the expiration time was being removed, i.e. set to 0.

    Signed-off-by: Eric Biggers
    Signed-off-by: David Howells

    Eric Biggers
     
  • Currently, when passed a key that already exists, add_key() will call the
    key's ->update() method if such exists. But this is heavily broken in the
    case where the key is uninstantiated because it doesn't call
    __key_instantiate_and_link(). Consequently, it doesn't do most of the
    things that are supposed to happen when the key is instantiated, such as
    setting the instantiation state, clearing KEY_FLAG_USER_CONSTRUCT and
    awakening tasks waiting on it, and incrementing key->user->nikeys.

    It also never takes key_construction_mutex, which means that
    ->instantiate() can run concurrently with ->update() on the same key. In
    the case of the "user" and "logon" key types this causes a memory leak, at
    best. Maybe even worse, the ->update() methods of the "encrypted" and
    "trusted" key types actually just dereference a NULL pointer when passed an
    uninstantiated key.

    Change key_create_or_update() to wait interruptibly for the key to finish
    construction before continuing.

    This patch only affects *uninstantiated* keys. For now we still allow a
    negatively instantiated key to be updated (thereby positively
    instantiating it), although that's broken too (the next patch fixes it)
    and I'm not sure that anyone actually uses that functionality either.

    Here is a simple reproducer for the bug using the "encrypted" key type
    (requires CONFIG_ENCRYPTED_KEYS=y), though as noted above the bug
    pertained to more than just the "encrypted" key type:

    #include
    #include
    #include

    int main(void)
    {
    int ringid = keyctl_join_session_keyring(NULL);

    if (fork()) {
    for (;;) {
    const char payload[] = "update user:foo 32";

    usleep(rand() % 10000);
    add_key("encrypted", "desc", payload, sizeof(payload), ringid);
    keyctl_clear(ringid);
    }
    } else {
    for (;;)
    request_key("encrypted", "desc", "callout_info", ringid);
    }
    }

    It causes:

    BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
    IP: encrypted_update+0xb0/0x170
    PGD 7a178067 P4D 7a178067 PUD 77269067 PMD 0
    PREEMPT SMP
    CPU: 0 PID: 340 Comm: reproduce Tainted: G D 4.14.0-rc1-00025-g428490e38b2e #796
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
    task: ffff8a467a39a340 task.stack: ffffb15c40770000
    RIP: 0010:encrypted_update+0xb0/0x170
    RSP: 0018:ffffb15c40773de8 EFLAGS: 00010246
    RAX: 0000000000000000 RBX: ffff8a467a275b00 RCX: 0000000000000000
    RDX: 0000000000000005 RSI: ffff8a467a275b14 RDI: ffffffffb742f303
    RBP: ffffb15c40773e20 R08: 0000000000000000 R09: ffff8a467a275b17
    R10: 0000000000000020 R11: 0000000000000000 R12: 0000000000000000
    R13: 0000000000000000 R14: ffff8a4677057180 R15: ffff8a467a275b0f
    FS: 00007f5d7fb08700(0000) GS:ffff8a467f200000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 0000000000000018 CR3: 0000000077262005 CR4: 00000000001606f0
    Call Trace:
    key_create_or_update+0x2bc/0x460
    SyS_add_key+0x10c/0x1d0
    entry_SYSCALL_64_fastpath+0x1f/0xbe
    RIP: 0033:0x7f5d7f211259
    RSP: 002b:00007ffed03904c8 EFLAGS: 00000246 ORIG_RAX: 00000000000000f8
    RAX: ffffffffffffffda RBX: 000000003b2a7955 RCX: 00007f5d7f211259
    RDX: 00000000004009e4 RSI: 00000000004009ff RDI: 0000000000400a04
    RBP: 0000000068db8bad R08: 000000003b2a7955 R09: 0000000000000004
    R10: 000000000000001a R11: 0000000000000246 R12: 0000000000400868
    R13: 00007ffed03905d0 R14: 0000000000000000 R15: 0000000000000000
    Code: 77 28 e8 64 34 1f 00 45 31 c0 31 c9 48 8d 55 c8 48 89 df 48 8d 75 d0 e8 ff f9 ff ff 85 c0 41 89 c4 0f 88 84 00 00 00 4c 8b 7d c8 8b 75 18 4c 89 ff e8 24 f8 ff ff 85 c0 41 89 c4 78 6d 49 8b
    RIP: encrypted_update+0xb0/0x170 RSP: ffffb15c40773de8
    CR2: 0000000000000018

    Cc: # v2.6.12+
    Reported-by: Eric Biggers
    Signed-off-by: David Howells
    cc: Eric Biggers

    David Howells
     
  • Consolidate KEY_FLAG_INSTANTIATED, KEY_FLAG_NEGATIVE and the rejection
    error into one field such that:

    (1) The instantiation state can be modified/read atomically.

    (2) The error can be accessed atomically with the state.

    (3) The error isn't stored unioned with the payload pointers.

    This deals with the problem that the state is spread over three different
    objects (two bits and a separate variable) and reading or updating them
    atomically isn't practical, given that not only can uninstantiated keys
    change into instantiated or rejected keys, but rejected keys can also turn
    into instantiated keys - and someone accessing the key might not be using
    any locking.

    The main side effect of this problem is that what was held in the payload
    may change, depending on the state. For instance, you might observe the
    key to be in the rejected state. You then read the cached error, but if
    the key semaphore wasn't locked, the key might've become instantiated
    between the two reads - and you might now have something in hand that isn't
    actually an error code.

    The state is now KEY_IS_UNINSTANTIATED, KEY_IS_POSITIVE or a negative error
    code if the key is negatively instantiated. The key_is_instantiated()
    function is replaced with key_is_positive() to avoid confusion as negative
    keys are also 'instantiated'.

    Additionally, barriering is included:

    (1) Order payload-set before state-set during instantiation.

    (2) Order state-read before payload-read when using the key.

    Further separate barriering is necessary if RCU is being used to access the
    payload content after reading the payload pointers.

    Fixes: 146aa8b1453b ("KEYS: Merge the type-specific data with the payload data")
    Cc: stable@vger.kernel.org # v4.4+
    Reported-by: Eric Biggers
    Signed-off-by: David Howells
    Reviewed-by: Eric Biggers

    David Howells
     
  • The recent rework introduced a possible randconfig build failure
    when CONFIG_CRYPTO configured to only allow modules:

    security/keys/big_key.o: In function `big_key_crypt':
    big_key.c:(.text+0x29f): undefined reference to `crypto_aead_setkey'
    security/keys/big_key.o: In function `big_key_init':
    big_key.c:(.init.text+0x1a): undefined reference to `crypto_alloc_aead'
    big_key.c:(.init.text+0x45): undefined reference to `crypto_aead_setauthsize'
    big_key.c:(.init.text+0x77): undefined reference to `crypto_destroy_tfm'
    crypto/gcm.o: In function `gcm_hash_crypt_remain_continue':
    gcm.c:(.text+0x167): undefined reference to `crypto_ahash_finup'
    crypto/gcm.o: In function `crypto_gcm_exit_tfm':
    gcm.c:(.text+0x847): undefined reference to `crypto_destroy_tfm'

    When we 'select CRYPTO' like the other users, we always get a
    configuration that builds.

    Fixes: 428490e38b2e ("security/keys: rewrite all of big_key crypto")
    Signed-off-by: Arnd Bergmann
    Signed-off-by: David Howells

    Arnd Bergmann
     

12 Oct, 2017

1 commit

  • A key of type "encrypted" references a "master key" which is used to
    encrypt and decrypt the encrypted key's payload. However, when we
    accessed the master key's payload, we failed to handle the case where
    the master key has been revoked, which sets the payload pointer to NULL.
    Note that request_key() *does* skip revoked keys, but there is still a
    window where the key can be revoked before we acquire its semaphore.

    Fix it by checking for a NULL payload, treating it like a key which was
    already revoked at the time it was requested.

    This was an issue for master keys of type "user" only. Master keys can
    also be of type "trusted", but those cannot be revoked.

    Fixes: 7e70cb497850 ("keys: add new key-type encrypted")
    Reviewed-by: James Morris
    Cc: [v2.6.38+]
    Cc: Mimi Zohar
    Cc: David Safford
    Signed-off-by: Eric Biggers
    Signed-off-by: David Howells

    Eric Biggers