1. 16 2月, 2019 1 次提交
    • D
      keys: Fix dependency loop between construction record and auth key · 822ad64d
      David Howells 提交于
      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: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <james.morris@microsoft.com>
      822ad64d
  2. 13 12月, 2018 1 次提交
    • P
      security: audit and remove any unnecessary uses of module.h · 876979c9
      Paul Gortmaker 提交于
      Historically a lot of these existed because we did not have
      a distinction between what was modular code and what was providing
      support to modules via EXPORT_SYMBOL and friends.  That changed
      when we forked out support for the latter into the export.h file.
      This means we should be able to reduce the usage of module.h
      in code that is obj-y Makefile or bool Kconfig.
      
      The advantage in removing such instances is that module.h itself
      sources about 15 other headers; adding significantly to what we feed
      cpp, and it can obscure what headers we are effectively using.
      
      Since module.h might have been the implicit source for init.h
      (for __init) and for export.h (for EXPORT_SYMBOL) we consider each
      instance for the presence of either and replace as needed.
      
      Cc: James Morris <jmorris@namei.org>
      Cc: "Serge E. Hallyn" <serge@hallyn.com>
      Cc: John Johansen <john.johansen@canonical.com>
      Cc: Mimi Zohar <zohar@linux.ibm.com>
      Cc: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
      Cc: David Howells <dhowells@redhat.com>
      Cc: linux-security-module@vger.kernel.org
      Cc: linux-integrity@vger.kernel.org
      Cc: keyrings@vger.kernel.org
      Signed-off-by: NPaul Gortmaker <paul.gortmaker@windriver.com>
      Signed-off-by: NJames Morris <james.morris@microsoft.com>
      876979c9
  3. 26 10月, 2018 1 次提交
    • D
      KEYS: Provide keyctls to drive the new key type ops for asymmetric keys [ver #2] · 00d60fd3
      David Howells 提交于
      Provide five keyctl functions that permit userspace to make use of the new
      key type ops for accessing and driving asymmetric keys.
      
       (*) Query an asymmetric key.
      
      	long keyctl(KEYCTL_PKEY_QUERY,
      		    key_serial_t key, unsigned long reserved,
      		    struct keyctl_pkey_query *info);
      
           Get information about an asymmetric key.  The information is returned
           in the keyctl_pkey_query struct:
      
      	__u32	supported_ops;
      
           A bit mask of flags indicating which ops are supported.  This is
           constructed from a bitwise-OR of:
      
      	KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}
      
      	__u32	key_size;
      
           The size in bits of the key.
      
      	__u16	max_data_size;
      	__u16	max_sig_size;
      	__u16	max_enc_size;
      	__u16	max_dec_size;
      
           The maximum sizes in bytes of a blob of data to be signed, a signature
           blob, a blob to be encrypted and a blob to be decrypted.
      
           reserved must be set to 0.  This is intended for future use to hand
           over one or more passphrases needed unlock a key.
      
           If successful, 0 is returned.  If the key is not an asymmetric key,
           EOPNOTSUPP is returned.
      
       (*) Encrypt, decrypt, sign or verify a blob using an asymmetric key.
      
      	long keyctl(KEYCTL_PKEY_ENCRYPT,
      		    const struct keyctl_pkey_params *params,
      		    const char *info,
      		    const void *in,
      		    void *out);
      
      	long keyctl(KEYCTL_PKEY_DECRYPT,
      		    const struct keyctl_pkey_params *params,
      		    const char *info,
      		    const void *in,
      		    void *out);
      
      	long keyctl(KEYCTL_PKEY_SIGN,
      		    const struct keyctl_pkey_params *params,
      		    const char *info,
      		    const void *in,
      		    void *out);
      
      	long keyctl(KEYCTL_PKEY_VERIFY,
      		    const struct keyctl_pkey_params *params,
      		    const char *info,
      		    const void *in,
      		    const void *in2);
      
           Use an asymmetric key to perform a public-key cryptographic operation
           a blob of data.
      
           The parameter block pointed to by params contains a number of integer
           values:
      
      	__s32		key_id;
      	__u32		in_len;
      	__u32		out_len;
      	__u32		in2_len;
      
           For a given operation, the in and out buffers are used as follows:
      
      	Operation ID		in,in_len	out,out_len	in2,in2_len
      	=======================	===============	===============	===========
      	KEYCTL_PKEY_ENCRYPT	Raw data	Encrypted data	-
      	KEYCTL_PKEY_DECRYPT	Encrypted data	Raw data	-
      	KEYCTL_PKEY_SIGN	Raw data	Signature	-
      	KEYCTL_PKEY_VERIFY	Raw data	-		Signature
      
           info is a string of key=value pairs that supply supplementary
           information.
      
           The __spare space in the parameter block must be set to 0.  This is
           intended, amongst other things, to allow the passing of passphrases
           required to unlock a key.
      
           If successful, encrypt, decrypt and sign all return the amount of data
           written into the output buffer.  Verification returns 0 on success.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NMarcel Holtmann <marcel@holtmann.org>
      Reviewed-by: NMarcel Holtmann <marcel@holtmann.org>
      Reviewed-by: NDenis Kenzior <denkenz@gmail.com>
      Tested-by: NDenis Kenzior <denkenz@gmail.com>
      Signed-off-by: NJames Morris <james.morris@microsoft.com>
      00d60fd3
  4. 08 12月, 2017 1 次提交
  5. 18 10月, 2017 1 次提交
    • D
      KEYS: Fix race between updating and finding a negative key · 363b02da
      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: 146aa8b1 ("KEYS: Merge the type-specific data with the payload data")
      Cc: stable@vger.kernel.org # v4.4+
      Reported-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-by: NEric Biggers <ebiggers@google.com>
      363b02da
  6. 25 9月, 2017 3 次提交
    • E
      KEYS: prevent KEYCTL_READ on negative key · 37863c43
      Eric Biggers 提交于
      Because keyctl_read_key() looks up the key with no permissions
      requested, it may find a negatively instantiated key.  If the key is
      also possessed, we went ahead and called ->read() on the key.  But the
      key payload will actually contain the ->reject_error rather than the
      normal payload.  Thus, the kernel oopses trying to read the
      user_key_payload from memory address (int)-ENOKEY = 0x00000000ffffff82.
      
      Fortunately the payload data is stored inline, so it shouldn't be
      possible to abuse this as an arbitrary memory read primitive...
      
      Reproducer:
          keyctl new_session
          keyctl request2 user desc '' @s
          keyctl read $(keyctl show | awk '/user: desc/ {print $1}')
      
      It causes a crash like the following:
           BUG: unable to handle kernel paging request at 00000000ffffff92
           IP: user_read+0x33/0xa0
           PGD 36a54067 P4D 36a54067 PUD 0
           Oops: 0000 [#1] SMP
           CPU: 0 PID: 211 Comm: keyctl Not tainted 4.14.0-rc1 #337
           Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-20170228_101828-anatol 04/01/2014
           task: ffff90aa3b74c3c0 task.stack: ffff9878c0478000
           RIP: 0010:user_read+0x33/0xa0
           RSP: 0018:ffff9878c047bee8 EFLAGS: 00010246
           RAX: 0000000000000001 RBX: ffff90aa3d7da340 RCX: 0000000000000017
           RDX: 0000000000000000 RSI: 00000000ffffff82 RDI: ffff90aa3d7da340
           RBP: ffff9878c047bf00 R08: 00000024f95da94f R09: 0000000000000000
           R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
           R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
           FS:  00007f58ece69740(0000) GS:ffff90aa3e200000(0000) knlGS:0000000000000000
           CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
           CR2: 00000000ffffff92 CR3: 0000000036adc001 CR4: 00000000003606f0
           Call Trace:
            keyctl_read_key+0xac/0xe0
            SyS_keyctl+0x99/0x120
            entry_SYSCALL_64_fastpath+0x1f/0xbe
           RIP: 0033:0x7f58ec787bb9
           RSP: 002b:00007ffc8d401678 EFLAGS: 00000206 ORIG_RAX: 00000000000000fa
           RAX: ffffffffffffffda RBX: 00007ffc8d402800 RCX: 00007f58ec787bb9
           RDX: 0000000000000000 RSI: 00000000174a63ac RDI: 000000000000000b
           RBP: 0000000000000004 R08: 00007ffc8d402809 R09: 0000000000000020
           R10: 0000000000000000 R11: 0000000000000206 R12: 00007ffc8d402800
           R13: 00007ffc8d4016e0 R14: 0000000000000000 R15: 0000000000000000
           Code: e5 41 55 49 89 f5 41 54 49 89 d4 53 48 89 fb e8 a4 b4 ad ff 85 c0 74 09 80 3d b9 4c 96 00 00 74 43 48 8b b3 20 01 00 00 4d 85 ed <0f> b7 5e 10 74 29 4d 85 e4 74 24 4c 39 e3 4c 89 e2 4c 89 ef 48
           RIP: user_read+0x33/0xa0 RSP: ffff9878c047bee8
           CR2: 00000000ffffff92
      
      Fixes: 61ea0c0b ("KEYS: Skip key state checks when checking for possession")
      Cc: <stable@vger.kernel.org>	[v3.13+]
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      37863c43
    • E
      KEYS: fix key refcount leak in keyctl_read_key() · 7fc0786d
      Eric Biggers 提交于
      In keyctl_read_key(), if key_permission() were to return an error code
      other than EACCES, we would leak a the reference to the key.  This can't
      actually happen currently because key_permission() can only return an
      error code other than EACCES if security_key_permission() does, only
      SELinux and Smack implement that hook, and neither can return an error
      code other than EACCES.  But it should still be fixed, as it is a bug
      waiting to happen.
      
      Fixes: 29db9190 ("[PATCH] Keys: Add LSM hooks for key management [try #3]")
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      7fc0786d
    • E
      KEYS: fix key refcount leak in keyctl_assume_authority() · 884bee02
      Eric Biggers 提交于
      In keyctl_assume_authority(), if keyctl_change_reqkey_auth() were to
      fail, we would leak the reference to the 'authkey'.  Currently this can
      only happen if prepare_creds() fails to allocate memory.  But it still
      should be fixed, as it is a more severe bug waiting to happen.
      
      This patch also moves the read of 'authkey->serial' to before the
      reference to the authkey is dropped.  Doing the read after dropping the
      reference is very fragile because it assumes we still hold another
      reference to the key.  (Which we do, in current->cred->request_key_auth,
      but there's no reason not to write it in the "obviously correct" way.)
      
      Fixes: d84f4f99 ("CRED: Inaugurate COW credentials")
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      884bee02
  7. 09 6月, 2017 2 次提交
  8. 09 5月, 2017 1 次提交
    • M
      treewide: use kv[mz]alloc* rather than opencoded variants · 752ade68
      Michal Hocko 提交于
      There are many code paths opencoding kvmalloc.  Let's use the helper
      instead.  The main difference to kvmalloc is that those users are
      usually not considering all the aspects of the memory allocator.  E.g.
      allocation requests <= 32kB (with 4kB pages) are basically never failing
      and invoke OOM killer to satisfy the allocation.  This sounds too
      disruptive for something that has a reasonable fallback - the vmalloc.
      On the other hand those requests might fallback to vmalloc even when the
      memory allocator would succeed after several more reclaim/compaction
      attempts previously.  There is no guarantee something like that happens
      though.
      
      This patch converts many of those places to kv[mz]alloc* helpers because
      they are more conservative.
      
      Link: http://lkml.kernel.org/r/20170306103327.2766-2-mhocko@kernel.orgSigned-off-by: NMichal Hocko <mhocko@suse.com>
      Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> # Xen bits
      Acked-by: NKees Cook <keescook@chromium.org>
      Acked-by: NVlastimil Babka <vbabka@suse.cz>
      Acked-by: Andreas Dilger <andreas.dilger@intel.com> # Lustre
      Acked-by: Christian Borntraeger <borntraeger@de.ibm.com> # KVM/s390
      Acked-by: Dan Williams <dan.j.williams@intel.com> # nvdim
      Acked-by: David Sterba <dsterba@suse.com> # btrfs
      Acked-by: Ilya Dryomov <idryomov@gmail.com> # Ceph
      Acked-by: Tariq Toukan <tariqt@mellanox.com> # mlx4
      Acked-by: Leon Romanovsky <leonro@mellanox.com> # mlx5
      Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
      Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
      Cc: Herbert Xu <herbert@gondor.apana.org.au>
      Cc: Anton Vorontsov <anton@enomsg.org>
      Cc: Colin Cross <ccross@android.com>
      Cc: Tony Luck <tony.luck@intel.com>
      Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
      Cc: Ben Skeggs <bskeggs@redhat.com>
      Cc: Kent Overstreet <kent.overstreet@gmail.com>
      Cc: Santosh Raspatur <santosh@chelsio.com>
      Cc: Hariprasad S <hariprasad@chelsio.com>
      Cc: Yishai Hadas <yishaih@mellanox.com>
      Cc: Oleg Drokin <oleg.drokin@intel.com>
      Cc: "Yan, Zheng" <zyan@redhat.com>
      Cc: Alexander Viro <viro@zeniv.linux.org.uk>
      Cc: Alexei Starovoitov <ast@kernel.org>
      Cc: Eric Dumazet <eric.dumazet@gmail.com>
      Cc: David Miller <davem@davemloft.net>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      752ade68
  9. 18 4月, 2017 2 次提交
    • E
      KEYS: fix keyctl_set_reqkey_keyring() to not leak thread keyrings · c9f838d1
      Eric Biggers 提交于
      This fixes CVE-2017-7472.
      
      Running the following program as an unprivileged user exhausts kernel
      memory by leaking thread keyrings:
      
      	#include <keyutils.h>
      
      	int main()
      	{
      		for (;;)
      			keyctl_set_reqkey_keyring(KEY_REQKEY_DEFL_THREAD_KEYRING);
      	}
      
      Fix it by only creating a new thread keyring if there wasn't one before.
      To make things more consistent, make install_thread_keyring_to_cred()
      and install_process_keyring_to_cred() both return 0 if the corresponding
      keyring is already present.
      
      Fixes: d84f4f99 ("CRED: Inaugurate COW credentials")
      Cc: stable@vger.kernel.org # 2.6.29+
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      c9f838d1
    • D
      KEYS: Disallow keyrings beginning with '.' to be joined as session keyrings · ee8f844e
      David Howells 提交于
      This fixes CVE-2016-9604.
      
      Keyrings whose name begin with a '.' are special internal keyrings and so
      userspace isn't allowed to create keyrings by this name to prevent
      shadowing.  However, the patch that added the guard didn't fix
      KEYCTL_JOIN_SESSION_KEYRING.  Not only can that create dot-named keyrings,
      it can also subscribe to them as a session keyring if they grant SEARCH
      permission to the user.
      
      This, for example, allows a root process to set .builtin_trusted_keys as
      its session keyring, at which point it has full access because now the
      possessor permissions are added.  This permits root to add extra public
      keys, thereby bypassing module verification.
      
      This also affects kexec and IMA.
      
      This can be tested by (as root):
      
      	keyctl session .builtin_trusted_keys
      	keyctl add user a a @s
      	keyctl list @s
      
      which on my test box gives me:
      
      	2 keys in keyring:
      	180010936: ---lswrv     0     0 asymmetric: Build time autogenerated kernel key: ae3d4a31b82daa8e1a75b49dc2bba949fd992a05
      	801382539: --alswrv     0     0 user: a
      
      
      Fix this by rejecting names beginning with a '.' in the keyctl.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NMimi Zohar <zohar@linux.vnet.ibm.com>
      cc: linux-ima-devel@lists.sourceforge.net
      cc: stable@vger.kernel.org
      ee8f844e
  10. 05 4月, 2017 2 次提交
    • S
      KEYS: add SP800-56A KDF support for DH · f1c316a3
      Stephan Mueller 提交于
      SP800-56A defines the use of DH with key derivation function based on a
      counter. The input to the KDF is defined as (DH shared secret || other
      information). The value for the "other information" is to be provided by
      the caller.
      
      The KDF is implemented using the hash support from the kernel crypto API.
      The implementation uses the symmetric hash support as the input to the
      hash operation is usually very small. The caller is allowed to specify
      the hash name that he wants to use to derive the key material allowing
      the use of all supported hashes provided with the kernel crypto API.
      
      As the KDF implements the proper truncation of the DH shared secret to
      the requested size, this patch fills the caller buffer up to its size.
      
      The patch is tested with a new test added to the keyutils user space
      code which uses a CAVS test vector testing the compliance with
      SP800-56A.
      Signed-off-by: NStephan Mueller <smueller@chronox.de>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      f1c316a3
    • M
      KEYS: Add KEYCTL_RESTRICT_KEYRING · 6563c91f
      Mat Martineau 提交于
      Keyrings recently gained restrict_link capabilities that allow
      individual keys to be validated prior to linking.  This functionality
      was only available using internal kernel APIs.
      
      With the KEYCTL_RESTRICT_KEYRING command existing keyrings can be
      configured to check the content of keys before they are linked, and
      then allow or disallow linkage of that key to the keyring.
      
      To restrict a keyring, call:
      
        keyctl(KEYCTL_RESTRICT_KEYRING, key_serial_t keyring, const char *type,
               const char *restriction)
      
      where 'type' is the name of a registered key type and 'restriction' is a
      string describing how key linkage is to be restricted. The restriction
      option syntax is specific to each key type.
      Signed-off-by: NMat Martineau <mathew.j.martineau@linux.intel.com>
      6563c91f
  11. 02 3月, 2017 2 次提交
  12. 25 12月, 2016 1 次提交
  13. 06 12月, 2016 1 次提交
    • A
      [iov_iter] new primitives - copy_from_iter_full() and friends · cbbd26b8
      Al Viro 提交于
      copy_from_iter_full(), copy_from_iter_full_nocache() and
      csum_and_copy_from_iter_full() - counterparts of copy_from_iter()
      et.al., advancing iterator only in case of successful full copy
      and returning whether it had been successful or not.
      
      Convert some obvious users.  *NOTE* - do not blindly assume that
      something is a good candidate for those unless you are sure that
      not advancing iov_iter in failure case is the right thing in
      this case.  Anything that does short read/short write kind of
      stuff (or is in a loop, etc.) is unlikely to be a good one.
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      cbbd26b8
  14. 03 6月, 2016 1 次提交
  15. 13 4月, 2016 1 次提交
    • M
      KEYS: Add KEYCTL_DH_COMPUTE command · ddbb4114
      Mat Martineau 提交于
      This adds userspace access to Diffie-Hellman computations through a
      new keyctl() syscall command to calculate shared secrets or public
      keys using input parameters stored in the keyring.
      
      Input key ids are provided in a struct due to the current 5-arg limit
      for the keyctl syscall. Only user keys are supported in order to avoid
      exposing the content of logon or encrypted keys.
      
      The output is written to the provided buffer, based on the assumption
      that the values are only needed in userspace.
      
      Future support for other types of key derivation would involve a new
      command, like KEYCTL_ECDH_COMPUTE.
      
      Once Diffie-Hellman support is included in the crypto API, this code
      can be converted to use the crypto API to take advantage of possible
      hardware acceleration and reduce redundant code.
      Signed-off-by: NMat Martineau <mathew.j.martineau@linux.intel.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      ddbb4114
  16. 08 1月, 2016 1 次提交
  17. 19 12月, 2015 1 次提交
    • D
      KEYS: Fix race between read and revoke · b4a1b4f5
      David Howells 提交于
      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 <sys/types.h>
      	#include <keyutils.h>
      	#include <pthread.h>
      	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: [<ffffffff81279b08>] user_read+0x56/0xa3
      	...
      	Call Trace:
      	 [<ffffffff81276aa9>] keyctl_read_key+0xb6/0xd7
      	 [<ffffffff81277815>] SyS_keyctl+0x83/0xe0
      	 [<ffffffff815dbb97>] entry_SYSCALL_64_fastpath+0x12/0x6f
      Reported-by: NDmitry Vyukov <dvyukov@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NDmitry Vyukov <dvyukov@google.com>
      Cc: stable@vger.kernel.org
      Signed-off-by: NJames Morris <james.l.morris@oracle.com>
      b4a1b4f5
  18. 15 12月, 2015 1 次提交
    • M
      KEYS: prevent keys from being removed from specified keyrings · d3600bcf
      Mimi Zohar 提交于
      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: NMimi Zohar <zohar@linux.vnet.ibm.com>
      Cc: David Howells <dhowells@redhat.com>
      d3600bcf
  19. 21 10月, 2015 2 次提交
  20. 12 4月, 2015 1 次提交
  21. 02 12月, 2014 1 次提交
    • D
      KEYS: Fix the size of the key description passed to/from userspace · aa9d4437
      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: NChristian Kastner <debian@kvr.at>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NChristian Kastner <debian@kvr.at>
      aa9d4437
  22. 17 9月, 2014 1 次提交
    • D
      KEYS: Reinstate EPERM for a key type name beginning with a '.' · 54e2c2c1
      David Howells 提交于
      Reinstate the generation of EPERM for a key type name beginning with a '.' in
      a userspace call.  Types whose name begins with a '.' are internal only.
      
      The test was removed by:
      
      	commit a4e3b8d7
      	Author: Mimi Zohar <zohar@linux.vnet.ibm.com>
      	Date:   Thu May 22 14:02:23 2014 -0400
      	Subject: KEYS: special dot prefixed keyring name bug fix
      
      I think we want to keep the restriction on type name so that userspace can't
      add keys of a special internal type.
      
      Note that removal of the test causes several of the tests in the keyutils
      testsuite to fail.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NVivek Goyal <vgoyal@redhat.com>
      cc: Mimi Zohar <zohar@linux.vnet.ibm.com>
      54e2c2c1
  23. 18 7月, 2014 1 次提交
    • D
      KEYS: Allow special keys (eg. DNS results) to be invalidated by CAP_SYS_ADMIN · 0c7774ab
      David Howells 提交于
      Special kernel keys, such as those used to hold DNS results for AFS, CIFS and
      NFS and those used to hold idmapper results for NFS, used to be
      'invalidateable' with key_revoke().  However, since the default permissions for
      keys were reduced:
      
      	Commit: 96b5c8fe
      	KEYS: Reduce initial permissions on keys
      
      it has become impossible to do this.
      
      Add a key flag (KEY_FLAG_ROOT_CAN_INVAL) that will permit a key to be
      invalidated by root.  This should not be used for system keyrings as the
      garbage collector will try and remove any invalidate key.  For system keyrings,
      KEY_FLAG_ROOT_CAN_CLEAR can be used instead.
      
      After this, from userspace, keyctl_invalidate() and "keyctl invalidate" can be
      used by any possessor of CAP_SYS_ADMIN (typically root) to invalidate DNS and
      idmapper keys.  Invalidated keys are immediately garbage collected and will be
      immediately rerequested if needed again.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NSteve Dickson <steved@redhat.com>
      0c7774ab
  24. 17 7月, 2014 1 次提交
  25. 15 3月, 2014 1 次提交
  26. 24 9月, 2013 1 次提交
    • D
      KEYS: Add per-user_namespace registers for persistent per-UID kerberos caches · f36f8c75
      David Howells 提交于
      Add support for per-user_namespace registers of persistent per-UID kerberos
      caches held within the kernel.
      
      This allows the kerberos cache to be retained beyond the life of all a user's
      processes so that the user's cron jobs can work.
      
      The kerberos cache is envisioned as a keyring/key tree looking something like:
      
      	struct user_namespace
      	  \___ .krb_cache keyring		- The register
      		\___ _krb.0 keyring		- Root's Kerberos cache
      		\___ _krb.5000 keyring		- User 5000's Kerberos cache
      		\___ _krb.5001 keyring		- User 5001's Kerberos cache
      			\___ tkt785 big_key	- A ccache blob
      			\___ tkt12345 big_key	- Another ccache blob
      
      Or possibly:
      
      	struct user_namespace
      	  \___ .krb_cache keyring		- The register
      		\___ _krb.0 keyring		- Root's Kerberos cache
      		\___ _krb.5000 keyring		- User 5000's Kerberos cache
      		\___ _krb.5001 keyring		- User 5001's Kerberos cache
      			\___ tkt785 keyring	- A ccache
      				\___ krbtgt/REDHAT.COM@REDHAT.COM big_key
      				\___ http/REDHAT.COM@REDHAT.COM user
      				\___ afs/REDHAT.COM@REDHAT.COM user
      				\___ nfs/REDHAT.COM@REDHAT.COM user
      				\___ krbtgt/KERNEL.ORG@KERNEL.ORG big_key
      				\___ http/KERNEL.ORG@KERNEL.ORG big_key
      
      What goes into a particular Kerberos cache is entirely up to userspace.  Kernel
      support is limited to giving you the Kerberos cache keyring that you want.
      
      The user asks for their Kerberos cache by:
      
      	krb_cache = keyctl_get_krbcache(uid, dest_keyring);
      
      The uid is -1 or the user's own UID for the user's own cache or the uid of some
      other user's cache (requires CAP_SETUID).  This permits rpc.gssd or whatever to
      mess with the cache.
      
      The cache returned is a keyring named "_krb.<uid>" that the possessor can read,
      search, clear, invalidate, unlink from and add links to.  Active LSMs get a
      chance to rule on whether the caller is permitted to make a link.
      
      Each uid's cache keyring is created when it first accessed and is given a
      timeout that is extended each time this function is called so that the keyring
      goes away after a while.  The timeout is configurable by sysctl but defaults to
      three days.
      
      Each user_namespace struct gets a lazily-created keyring that serves as the
      register.  The cache keyrings are added to it.  This means that standard key
      search and garbage collection facilities are available.
      
      The user_namespace struct's register goes away when it does and anything left
      in it is then automatically gc'd.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NSimo Sorce <simo@redhat.com>
      cc: Serge E. Hallyn <serge.hallyn@ubuntu.com>
      cc: Eric W. Biederman <ebiederm@xmission.com>
      f36f8c75
  27. 08 5月, 2013 1 次提交
  28. 08 10月, 2012 1 次提交
    • D
      KEYS: Add payload preparsing opportunity prior to key instantiate or update · cf7f601c
      David Howells 提交于
      Give the key type the opportunity to preparse the payload prior to the
      instantiation and update routines being called.  This is done with the
      provision of two new key type operations:
      
      	int (*preparse)(struct key_preparsed_payload *prep);
      	void (*free_preparse)(struct key_preparsed_payload *prep);
      
      If the first operation is present, then it is called before key creation (in
      the add/update case) or before the key semaphore is taken (in the update and
      instantiate cases).  The second operation is called to clean up if the first
      was called.
      
      preparse() is given the opportunity to fill in the following structure:
      
      	struct key_preparsed_payload {
      		char		*description;
      		void		*type_data[2];
      		void		*payload;
      		const void	*data;
      		size_t		datalen;
      		size_t		quotalen;
      	};
      
      Before the preparser is called, the first three fields will have been cleared,
      the payload pointer and size will be stored in data and datalen and the default
      quota size from the key_type struct will be stored into quotalen.
      
      The preparser may parse the payload in any way it likes and may store data in
      the type_data[] and payload fields for use by the instantiate() and update()
      ops.
      
      The preparser may also propose a description for the key by attaching it as a
      string to the description field.  This can be used by passing a NULL or ""
      description to the add_key() system call or the key_create_or_update()
      function.  This cannot work with request_key() as that required the description
      to tell the upcall about the key to be created.
      
      This, for example permits keys that store PGP public keys to generate their own
      name from the user ID and public key fingerprint in the key.
      
      The instantiate() and update() operations are then modified to look like this:
      
      	int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
      	int (*update)(struct key *key, struct key_preparsed_payload *prep);
      
      and the new payload data is passed in *prep, whether or not it was preparsed.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NRusty Russell <rusty@rustcorp.com.au>
      cf7f601c
  29. 03 10月, 2012 1 次提交
    • D
      KEYS: Make the session and process keyrings per-thread · 3a50597d
      David Howells 提交于
      Make the session keyring per-thread rather than per-process, but still
      inherited from the parent thread to solve a problem with PAM and gdm.
      
      The problem is that join_session_keyring() will reject attempts to change the
      session keyring of a multithreaded program but gdm is now multithreaded before
      it gets to the point of starting PAM and running pam_keyinit to create the
      session keyring.  See:
      
      	https://bugs.freedesktop.org/show_bug.cgi?id=49211
      
      The reason that join_session_keyring() will only change the session keyring
      under a single-threaded environment is that it's hard to alter the other
      thread's credentials to effect the change in a multi-threaded program.  The
      problems are such as:
      
       (1) How to prevent two threads both running join_session_keyring() from
           racing.
      
       (2) Another thread's credentials may not be modified directly by this process.
      
       (3) The number of threads is uncertain whilst we're not holding the
           appropriate spinlock, making preallocation slightly tricky.
      
       (4) We could use TIF_NOTIFY_RESUME and key_replace_session_keyring() to get
           another thread to replace its keyring, but that means preallocating for
           each thread.
      
      A reasonable way around this is to make the session keyring per-thread rather
      than per-process and just document that if you want a common session keyring,
      you must get it before you spawn any threads - which is the current situation
      anyway.
      
      Whilst we're at it, we can the process keyring behave in the same way.  This
      means we can clean up some of the ickyness in the creds code.
      
      Basically, after this patch, the session, process and thread keyrings are about
      inheritance rules only and not about sharing changes of keyring.
      Reported-by: NMantas M. <grawity@gmail.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NRay Strode <rstrode@redhat.com>
      3a50597d
  30. 28 9月, 2012 1 次提交
  31. 14 9月, 2012 1 次提交
    • E
      userns: Convert security/keys to the new userns infrastructure · 9a56c2db
      Eric W. Biederman 提交于
      - Replace key_user ->user_ns equality checks with kuid_has_mapping checks.
      - Use from_kuid to generate key descriptions
      - Use kuid_t and kgid_t and the associated helpers instead of uid_t and gid_t
      - Avoid potential problems with file descriptor passing by displaying
        keys in the user namespace of the opener of key status proc files.
      
      Cc: linux-security-module@vger.kernel.org
      Cc: keyrings@linux-nfs.org
      Cc: David Howells <dhowells@redhat.com>
      Signed-off-by: NEric W. Biederman <ebiederm@xmission.com>
      9a56c2db
  32. 13 9月, 2012 2 次提交
    • O
      task_work: Revert "hold task_lock around checks in keyctl" · b3f68f16
      Oleg Nesterov 提交于
      This reverts commit d35abdb2.
      
      task_lock() was added to ensure exit_mm() and thus exit_task_work() is
      not possible before task_work_add().
      
      This is wrong, task_lock() must not be nested with write_lock(tasklist).
      And this is no longer needed, task_work_add() now fails if it is called
      after exit_task_work().
      Reported-by: NDave Jones <davej@redhat.com>
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Signed-off-by: NPeter Zijlstra <a.p.zijlstra@chello.nl>
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Link: http://lkml.kernel.org/r/20120826191214.GA4231@redhat.comSigned-off-by: NIngo Molnar <mingo@kernel.org>
      b3f68f16
    • D
      KEYS: Add payload preparsing opportunity prior to key instantiate or update · d4f65b5d
      David Howells 提交于
      Give the key type the opportunity to preparse the payload prior to the
      instantiation and update routines being called.  This is done with the
      provision of two new key type operations:
      
      	int (*preparse)(struct key_preparsed_payload *prep);
      	void (*free_preparse)(struct key_preparsed_payload *prep);
      
      If the first operation is present, then it is called before key creation (in
      the add/update case) or before the key semaphore is taken (in the update and
      instantiate cases).  The second operation is called to clean up if the first
      was called.
      
      preparse() is given the opportunity to fill in the following structure:
      
      	struct key_preparsed_payload {
      		char		*description;
      		void		*type_data[2];
      		void		*payload;
      		const void	*data;
      		size_t		datalen;
      		size_t		quotalen;
      	};
      
      Before the preparser is called, the first three fields will have been cleared,
      the payload pointer and size will be stored in data and datalen and the default
      quota size from the key_type struct will be stored into quotalen.
      
      The preparser may parse the payload in any way it likes and may store data in
      the type_data[] and payload fields for use by the instantiate() and update()
      ops.
      
      The preparser may also propose a description for the key by attaching it as a
      string to the description field.  This can be used by passing a NULL or ""
      description to the add_key() system call or the key_create_or_update()
      function.  This cannot work with request_key() as that required the description
      to tell the upcall about the key to be created.
      
      This, for example permits keys that store PGP public keys to generate their own
      name from the user ID and public key fingerprint in the key.
      
      The instantiate() and update() operations are then modified to look like this:
      
      	int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
      	int (*update)(struct key *key, struct key_preparsed_payload *prep);
      
      and the new payload data is passed in *prep, whether or not it was preparsed.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      d4f65b5d