1. 23 8月, 2011 1 次提交
    • D
      KEYS: If install_session_keyring() is given a keyring, it should install it · 99599537
      David Howells 提交于
      If install_session_keyring() is given a keyring, it should install it rather
      than just creating a new one anyway.  This was accidentally broken in:
      
      	commit d84f4f99
      	Author: David Howells <dhowells@redhat.com>
      	Date:   Fri Nov 14 10:39:23 2008 +1100
      	Subject: CRED: Inaugurate COW credentials
      
      The impact of that commit is that pam_keyinit no longer works correctly if
      'force' isn't specified against a login process. This is because:
      
      	keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0)
      
      now always creates a new session keyring and thus the check whether the session
      keyring and the user-session keyring are the same is always false.  This leads
      pam_keyinit to conclude that a session keyring is installed and it shouldn't be
      revoked by pam_keyinit here if 'revoke' is specified.
      
      Any system that specifies 'force' against pam_keyinit in the PAM configuration
      files for login methods (login, ssh, su -l, kdm, etc.) is not affected since
      that bypasses the broken check and forces the creation of a new session keyring
      anyway (for which the revoke flag is not cleared) - and any subsequent call to
      pam_keyinit really does have a session keyring already installed, and so the
      check works correctly there.
      
      Reverting to the previous behaviour will cause the kernel to subscribe the
      process to the user-session keyring as its session keyring if it doesn't have a
      session keyring of its own.  pam_keyinit will detect this and install a new
      session keyring anyway (and won't clear the revert flag).
      
      This can be tested by commenting out pam_keyinit in the /etc/pam.d files and
      running the following program a couple of times in a row:
      
      	#include <stdio.h>
      	#include <stdlib.h>
      	#include <keyutils.h>
      	int main(int argc, char *argv[])
      	{
      		key_serial_t uk, usk, sk;
      		uk = keyctl_get_keyring_ID(KEY_SPEC_USER_KEYRING, 0);
      		usk = keyctl_get_keyring_ID(KEY_SPEC_USER_SESSION_KEYRING, 0);
      		sk = keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0);
      		printf("keys: %08x %08x %08x\n", uk, usk, sk);
      		return 0;
      	}
      
      Without the patch, I see:
      
      	keys: 3884e281 24c4dfcf 22825f8e
      	keys: 3884e281 24c4dfcf 068772be
      
      With the patch, I see:
      
      	keys: 26be9c83 0e755ce0 0e755ce0
      	keys: 26be9c83 0e755ce0 0e755ce0
      
      As can be seen, with the patch, the session keyring is the same as the
      user-session keyring each time; without the patch a new session keyring is
      generated each time.
      Reported-by: NGreg Wettstein <greg@enjellic.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NGreg Wettstein <greg@enjellic.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      99599537
  2. 09 7月, 2011 1 次提交
  3. 27 6月, 2011 5 次提交
  4. 22 6月, 2011 1 次提交
    • D
      KEYS: Fix error handling in construct_key_and_link() · b1d7dd80
      David Howells 提交于
      Fix error handling in construct_key_and_link().
      
      If construct_alloc_key() returns an error, it shouldn't pass out through
      the normal path as the key_serial() called by the kleave() statement
      will oops when it gets an error code in the pointer:
      
        BUG: unable to handle kernel paging request at ffffffffffffff84
        IP: [<ffffffff8120b401>] request_key_and_link+0x4d7/0x52f
        ..
        Call Trace:
         [<ffffffff8120b52c>] request_key+0x41/0x75
         [<ffffffffa00ed6e8>] cifs_get_spnego_key+0x206/0x226 [cifs]
         [<ffffffffa00eb0c9>] CIFS_SessSetup+0x511/0x1234 [cifs]
         [<ffffffffa00d9799>] cifs_setup_session+0x90/0x1ae [cifs]
         [<ffffffffa00d9c02>] cifs_get_smb_ses+0x34b/0x40f [cifs]
         [<ffffffffa00d9e05>] cifs_mount+0x13f/0x504 [cifs]
         [<ffffffffa00caabb>] cifs_do_mount+0xc4/0x672 [cifs]
         [<ffffffff8113ae8c>] mount_fs+0x69/0x155
         [<ffffffff8114ff0e>] vfs_kern_mount+0x63/0xa0
         [<ffffffff81150be2>] do_kern_mount+0x4d/0xdf
         [<ffffffff81152278>] do_mount+0x63c/0x69f
         [<ffffffff8115255c>] sys_mount+0x88/0xc2
         [<ffffffff814fbdc2>] system_call_fastpath+0x16/0x1b
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NJeff Layton <jlayton@redhat.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      b1d7dd80
  5. 18 6月, 2011 1 次提交
    • D
      KEYS/DNS: Fix ____call_usermodehelper() to not lose the session keyring · 87966996
      David Howells 提交于
      ____call_usermodehelper() now erases any credentials set by the
      subprocess_inf::init() function.  The problem is that commit
      17f60a7d ("capabilites: allow the application of capability limits
      to usermode helpers") creates and commits new credentials with
      prepare_kernel_cred() after the call to the init() function.  This wipes
      all keyrings after umh_keys_init() is called.
      
      The best way to deal with this is to put the init() call just prior to
      the commit_creds() call, and pass the cred pointer to init().  That
      means that umh_keys_init() and suchlike can modify the credentials
      _before_ they are published and potentially in use by the rest of the
      system.
      
      This prevents request_key() from working as it is prevented from passing
      the session keyring it set up with the authorisation token to
      /sbin/request-key, and so the latter can't assume the authority to
      instantiate the key.  This causes the in-kernel DNS resolver to fail
      with ENOKEY unconditionally.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NEric Paris <eparis@redhat.com>
      Tested-by: NJeff Layton <jlayton@redhat.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      87966996
  6. 14 6月, 2011 1 次提交
  7. 27 5月, 2011 1 次提交
  8. 20 5月, 2011 1 次提交
    • R
      Create Documentation/security/, · d410fa4e
      Randy Dunlap 提交于
      move LSM-, credentials-, and keys-related files from Documentation/
        to Documentation/security/,
      add Documentation/security/00-INDEX, and
      update all occurrences of Documentation/<moved_file>
        to Documentation/security/<moved_file>.
      d410fa4e
  9. 08 5月, 2011 1 次提交
  10. 17 3月, 2011 2 次提交
    • D
      KEYS: Make request_key() and co. return an error for a negative key · 4aab1e89
      David Howells 提交于
      Make request_key() and co. return an error for a negative or rejected key.  If
      the key was simply negated, then return ENOKEY, otherwise return the error
      with which it was rejected.
      
      Without this patch, the following command returns a key number (with the latest
      keyutils):
      
      	[root@andromeda ~]# keyctl request2 user debug:foo rejected @s
      	586569904
      
      Trying to print the key merely gets you a permission denied error:
      
      	[root@andromeda ~]# keyctl print 586569904
      	keyctl_read_alloc: Permission denied
      
      Doing another request_key() call does get you the error, as long as it hasn't
      expired yet:
      
      	[root@andromeda ~]# keyctl request user debug:foo
      	request_key: Key was rejected by service
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      4aab1e89
    • D
      KEYS: Improve /proc/keys · 78b7280c
      David Howells 提交于
      Improve /proc/keys by:
      
       (1) Don't attempt to summarise the payload of a negated key.  It won't have
           one.  To this end, a helper function - key_is_instantiated() has been
           added that allows the caller to find out whether the key is positively
           instantiated (as opposed to being uninstantiated or negatively
           instantiated).
      
       (2) Do show keys that are negative, expired or revoked rather than hiding
           them.  This requires an override flag (no_state_check) to be passed to
           search_my_process_keyrings() and keyring_search_aux() to suppress this
           check.
      
           Without this, keys that are possessed by the caller, but only grant
           permissions to the caller if possessed are skipped as the possession check
           fails.
      
           Keys that are visible due to user, group or other checks are visible with
           or without this patch.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      78b7280c
  11. 08 3月, 2011 4 次提交
  12. 26 1月, 2011 1 次提交
    • D
      KEYS: Fix __key_link_end() quota fixup on error · ceb73c12
      David Howells 提交于
      Fix __key_link_end()'s attempt to fix up the quota if an error occurs.
      
      There are two erroneous cases: Firstly, we always decrease the quota if
      the preallocated replacement keyring needs cleaning up, irrespective of
      whether or not we should (we may have replaced a pointer rather than
      adding another pointer).
      
      Secondly, we never clean up the quota if we added a pointer without the
      keyring storage being extended (we allocate multiple pointers at a time,
      even if we're not going to use them all immediately).
      
      We handle this by setting the bottom bit of the preallocation pointer in
      __key_link_begin() to indicate that the quota needs fixing up, which is
      then passed to __key_link() (which clears the whole thing) and
      __key_link_end().
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      ceb73c12
  13. 24 1月, 2011 3 次提交
  14. 22 1月, 2011 2 次提交
  15. 19 1月, 2011 3 次提交
  16. 14 1月, 2011 1 次提交
  17. 24 12月, 2010 1 次提交
    • D
      KEYS: Don't call up_write() if __key_link_begin() returns an error · 3fc5e98d
      David Howells 提交于
      In construct_alloc_key(), up_write() is called in the error path if
      __key_link_begin() fails, but this is incorrect as __key_link_begin() only
      returns with the nominated keyring locked if it returns successfully.
      
      Without this patch, you might see the following in dmesg:
      
      	=====================================
      	[ BUG: bad unlock balance detected! ]
      	-------------------------------------
      	mount.cifs/5769 is trying to release lock (&key->sem) at:
      	[<ffffffff81201159>] request_key_and_link+0x263/0x3fc
      	but there are no more locks to release!
      
      	other info that might help us debug this:
      	3 locks held by mount.cifs/5769:
      	 #0:  (&type->s_umount_key#41/1){+.+.+.}, at: [<ffffffff81131321>] sget+0x278/0x3e7
      	 #1:  (&ret_buf->session_mutex){+.+.+.}, at: [<ffffffffa0258e59>] cifs_get_smb_ses+0x35a/0x443 [cifs]
      	 #2:  (root_key_user.cons_lock){+.+.+.}, at: [<ffffffff81201000>] request_key_and_link+0x10a/0x3fc
      
      	stack backtrace:
      	Pid: 5769, comm: mount.cifs Not tainted 2.6.37-rc6+ #1
      	Call Trace:
      	 [<ffffffff81201159>] ? request_key_and_link+0x263/0x3fc
      	 [<ffffffff81081601>] print_unlock_inbalance_bug+0xca/0xd5
      	 [<ffffffff81083248>] lock_release_non_nested+0xc1/0x263
      	 [<ffffffff81201159>] ? request_key_and_link+0x263/0x3fc
      	 [<ffffffff81201159>] ? request_key_and_link+0x263/0x3fc
      	 [<ffffffff81083567>] lock_release+0x17d/0x1a4
      	 [<ffffffff81073f45>] up_write+0x23/0x3b
      	 [<ffffffff81201159>] request_key_and_link+0x263/0x3fc
      	 [<ffffffffa026fe9e>] ? cifs_get_spnego_key+0x61/0x21f [cifs]
      	 [<ffffffff812013c5>] request_key+0x41/0x74
      	 [<ffffffffa027003d>] cifs_get_spnego_key+0x200/0x21f [cifs]
      	 [<ffffffffa026e296>] CIFS_SessSetup+0x55d/0x1273 [cifs]
      	 [<ffffffffa02589e1>] cifs_setup_session+0x90/0x1ae [cifs]
      	 [<ffffffffa0258e7e>] cifs_get_smb_ses+0x37f/0x443 [cifs]
      	 [<ffffffffa025a9e3>] cifs_mount+0x1aa1/0x23f3 [cifs]
      	 [<ffffffff8111fd94>] ? alloc_debug_processing+0xdb/0x120
      	 [<ffffffffa027002c>] ? cifs_get_spnego_key+0x1ef/0x21f [cifs]
      	 [<ffffffffa024cc71>] cifs_do_mount+0x165/0x2b3 [cifs]
      	 [<ffffffff81130e72>] vfs_kern_mount+0xaf/0x1dc
      	 [<ffffffff81131007>] do_kern_mount+0x4d/0xef
      	 [<ffffffff811483b9>] do_mount+0x6f4/0x733
      	 [<ffffffff8114861f>] sys_mount+0x88/0xc2
      	 [<ffffffff8100ac42>] system_call_fastpath+0x16/0x1b
      Reported-by: NJeff Layton <jlayton@redhat.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-and-Tested-by: NJeff Layton <jlayton@redhat.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      3fc5e98d
  18. 15 12月, 2010 4 次提交
  19. 30 11月, 2010 1 次提交
  20. 29 11月, 2010 2 次提交
    • M
      keys: add new key-type encrypted · 7e70cb49
      Mimi Zohar 提交于
      Define a new kernel key-type called 'encrypted'. Encrypted keys are kernel
      generated random numbers, which are encrypted/decrypted with a 'trusted'
      symmetric key. Encrypted keys are created/encrypted/decrypted in the kernel.
      Userspace only ever sees/stores encrypted blobs.
      
      Changelog:
      - bug fix: replaced master-key rcu based locking with semaphore
        (reported by David Howells)
      - Removed memset of crypto_shash_digest() digest output
      - Replaced verification of 'key-type:key-desc' using strcspn(), with
        one based on string constants.
      - Moved documentation to Documentation/keys-trusted-encrypted.txt
      - Replace hash with shash (based on comments by David Howells)
      - Make lengths/counts size_t where possible (based on comments by David Howells)
        Could not convert most lengths, as crypto expects 'unsigned int'
        (size_t: on 32 bit is defined as unsigned int, but on 64 bit is unsigned long)
      - Add 'const' where possible (based on comments by David Howells)
      - allocate derived_buf dynamically to support arbitrary length master key
        (fixed by Roberto Sassu)
      - wait until late_initcall for crypto libraries to be registered
      - cleanup security/Kconfig
      - Add missing 'update' keyword (reported/fixed by Roberto Sassu)
      - Free epayload on failure to create key (reported/fixed by Roberto Sassu)
      - Increase the data size limit (requested by Roberto Sassu)
      - Crypto return codes are always 0 on success and negative on failure,
        remove unnecessary tests.
      - Replaced kzalloc() with kmalloc()
      Signed-off-by: NMimi Zohar <zohar@us.ibm.com>
      Signed-off-by: NDavid Safford <safford@watson.ibm.com>
      Reviewed-by: NRoberto Sassu <roberto.sassu@polito.it>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      7e70cb49
    • M
      keys: add new trusted key-type · d00a1c72
      Mimi Zohar 提交于
      Define a new kernel key-type called 'trusted'.  Trusted keys are random
      number symmetric keys, generated and RSA-sealed by the TPM.  The TPM
      only unseals the keys, if the boot PCRs and other criteria match.
      Userspace can only ever see encrypted blobs.
      
      Based on suggestions by Jason Gunthorpe, several new options have been
      added to support additional usages.
      
      The new options are:
      migratable=  designates that the key may/may not ever be updated
                   (resealed under a new key, new pcrinfo or new auth.)
      
      pcrlock=n    extends the designated PCR 'n' with a random value,
                   so that a key sealed to that PCR may not be unsealed
                   again until after a reboot.
      
      keyhandle=   specifies the sealing/unsealing key handle.
      
      keyauth=     specifies the sealing/unsealing key auth.
      
      blobauth=    specifies the sealed data auth.
      
      Implementation of a kernel reserved locality for trusted keys will be
      investigated for a possible future extension.
      
      Changelog:
      - Updated and added examples to Documentation/keys-trusted-encrypted.txt
      - Moved generic TPM constants to include/linux/tpm_command.h
        (David Howell's suggestion.)
      - trusted_defined.c: replaced kzalloc with kmalloc, added pcrlock failure
        error handling, added const qualifiers where appropriate.
      - moved to late_initcall
      - updated from hash to shash (suggestion by David Howells)
      - reduced worst stack usage (tpm_seal) from 530 to 312 bytes
      - moved documentation to Documentation directory (suggestion by David Howells)
      - all the other code cleanups suggested by David Howells
      - Add pcrlock CAP_SYS_ADMIN dependency (based on comment by Jason Gunthorpe)
      - New options: migratable, pcrlock, keyhandle, keyauth, blobauth (based on
        discussions with Jason Gunthorpe)
      - Free payload on failure to create key(reported/fixed by Roberto Sassu)
      - Updated Kconfig and other descriptions (based on Serge Hallyn's suggestion)
      - Replaced kzalloc() with kmalloc() (reported by Serge Hallyn)
      Signed-off-by: NDavid Safford <safford@watson.ibm.com>
      Signed-off-by: NMimi Zohar <zohar@us.ibm.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      d00a1c72
  21. 29 10月, 2010 1 次提交
  22. 10 9月, 2010 2 次提交
    • D
      KEYS: Fix bug in keyctl_session_to_parent() if parent has no session keyring · 3d96406c
      David Howells 提交于
      Fix a bug in keyctl_session_to_parent() whereby it tries to check the ownership
      of the parent process's session keyring whether or not the parent has a session
      keyring [CVE-2010-2960].
      
      This results in the following oops:
      
        BUG: unable to handle kernel NULL pointer dereference at 00000000000000a0
        IP: [<ffffffff811ae4dd>] keyctl_session_to_parent+0x251/0x443
        ...
        Call Trace:
         [<ffffffff811ae2f3>] ? keyctl_session_to_parent+0x67/0x443
         [<ffffffff8109d286>] ? __do_fault+0x24b/0x3d0
         [<ffffffff811af98c>] sys_keyctl+0xb4/0xb8
         [<ffffffff81001eab>] system_call_fastpath+0x16/0x1b
      
      if the parent process has no session keyring.
      
      If the system is using pam_keyinit then it mostly protected against this as all
      processes derived from a login will have inherited the session keyring created
      by pam_keyinit during the log in procedure.
      
      To test this, pam_keyinit calls need to be commented out in /etc/pam.d/.
      Reported-by: NTavis Ormandy <taviso@cmpxchg8b.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NTavis Ormandy <taviso@cmpxchg8b.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      3d96406c
    • D
      KEYS: Fix RCU no-lock warning in keyctl_session_to_parent() · 9d1ac65a
      David Howells 提交于
      There's an protected access to the parent process's credentials in the middle
      of keyctl_session_to_parent().  This results in the following RCU warning:
      
        ===================================================
        [ INFO: suspicious rcu_dereference_check() usage. ]
        ---------------------------------------------------
        security/keys/keyctl.c:1291 invoked rcu_dereference_check() without protection!
      
        other info that might help us debug this:
      
        rcu_scheduler_active = 1, debug_locks = 0
        1 lock held by keyctl-session-/2137:
         #0:  (tasklist_lock){.+.+..}, at: [<ffffffff811ae2ec>] keyctl_session_to_parent+0x60/0x236
      
        stack backtrace:
        Pid: 2137, comm: keyctl-session- Not tainted 2.6.36-rc2-cachefs+ #1
        Call Trace:
         [<ffffffff8105606a>] lockdep_rcu_dereference+0xaa/0xb3
         [<ffffffff811ae379>] keyctl_session_to_parent+0xed/0x236
         [<ffffffff811af77e>] sys_keyctl+0xb4/0xb6
         [<ffffffff81001eab>] system_call_fastpath+0x16/0x1b
      
      The code should take the RCU read lock to make sure the parents credentials
      don't go away, even though it's holding a spinlock and has IRQ disabled.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      9d1ac65a