1. 02 12月, 2014 1 次提交
    • D
      KEYS: Simplify KEYRING_SEARCH_{NO,DO}_STATE_CHECK flags · 054f6180
      David Howells 提交于
      Simplify KEYRING_SEARCH_{NO,DO}_STATE_CHECK flags to be two variations of the
      same flag.  They are effectively mutually exclusive and one or the other
      should be provided, but not both.
      
      Keyring cycle detection and key possession determination are the only things
      that set NO_STATE_CHECK, except that neither flag really does anything there
      because neither purpose makes use of the keyring_search_iterator() function,
      but rather provides their own.
      
      For cycle detection we definitely want to check inside of expired keyrings,
      just so that we don't create a cycle we can't get rid of.  Revoked keyrings
      are cleared at revocation time and can't then be reused, so shouldn't be a
      problem either way.
      
      For possession determination, we *might* want to validate each keyring before
      searching it: do you possess a key that's hidden behind an expired or just
      plain inaccessible keyring?  Currently, the answer is yes.  Note that you
      cannot, however, possess a key behind a revoked keyring because they are
      cleared on revocation.
      
      keyring_search() sets DO_STATE_CHECK, which is correct.
      
      request_key_and_link() currently doesn't specify whether to check the key
      state or not - but it should set DO_STATE_CHECK.
      
      key_get_instantiation_authkey() also currently doesn't specify whether to
      check the key state or not - but it probably should also set DO_STATE_CHECK.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NChuck Lever <chuck.lever@oracle.com>
      054f6180
  2. 17 9月, 2014 2 次提交
    • D
      KEYS: Remove key_type::match in favour of overriding default by match_preparse · c06cfb08
      David Howells 提交于
      A previous patch added a ->match_preparse() method to the key type.  This is
      allowed to override the function called by the iteration algorithm.
      Therefore, we can just set a default that simply checks for an exact match of
      the key description with the original criterion data and allow match_preparse
      to override it as needed.
      
      The key_type::match op is then redundant and can be removed, as can the
      user_match() function.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NVivek Goyal <vgoyal@redhat.com>
      c06cfb08
    • D
      KEYS: Preparse match data · 46291959
      David Howells 提交于
      Preparse the match data.  This provides several advantages:
      
       (1) The preparser can reject invalid criteria up front.
      
       (2) The preparser can convert the criteria to binary data if necessary (the
           asymmetric key type really wants to do binary comparison of the key IDs).
      
       (3) The preparser can set the type of search to be performed.  This means
           that it's not then a one-off setting in the key type.
      
       (4) The preparser can set an appropriate comparator function.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NVivek Goyal <vgoyal@redhat.com>
      46291959
  3. 16 7月, 2014 1 次提交
    • N
      sched: Remove proliferation of wait_on_bit() action functions · 74316201
      NeilBrown 提交于
      The current "wait_on_bit" interface requires an 'action'
      function to be provided which does the actual waiting.
      There are over 20 such functions, many of them identical.
      Most cases can be satisfied by one of just two functions, one
      which uses io_schedule() and one which just uses schedule().
      
      So:
       Rename wait_on_bit and        wait_on_bit_lock to
              wait_on_bit_action and wait_on_bit_lock_action
       to make it explicit that they need an action function.
      
       Introduce new wait_on_bit{,_lock} and wait_on_bit{,_lock}_io
       which are *not* given an action function but implicitly use
       a standard one.
       The decision to error-out if a signal is pending is now made
       based on the 'mode' argument rather than being encoded in the action
       function.
      
       All instances of the old wait_on_bit and wait_on_bit_lock which
       can use the new version have been changed accordingly and their
       action functions have been discarded.
       wait_on_bit{_lock} does not return any specific error code in the
       event of a signal so the caller must check for non-zero and
       interpolate their own error code as appropriate.
      
      The wait_on_bit() call in __fscache_wait_on_invalidate() was
      ambiguous as it specified TASK_UNINTERRUPTIBLE but used
      fscache_wait_bit_interruptible as an action function.
      David Howells confirms this should be uniformly
      "uninterruptible"
      
      The main remaining user of wait_on_bit{,_lock}_action is NFS
      which needs to use a freezer-aware schedule() call.
      
      A comment in fs/gfs2/glock.c notes that having multiple 'action'
      functions is useful as they display differently in the 'wchan'
      field of 'ps'. (and /proc/$PID/wchan).
      As the new bit_wait{,_io} functions are tagged "__sched", they
      will not show up at all, but something higher in the stack.  So
      the distinction will still be visible, only with different
      function names (gds2_glock_wait versus gfs2_glock_dq_wait in the
      gfs2/glock.c case).
      
      Since first version of this patch (against 3.15) two new action
      functions appeared, on in NFS and one in CIFS.  CIFS also now
      uses an action function that makes the same freezer aware
      schedule call as NFS.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      Acked-by: David Howells <dhowells@redhat.com> (fscache, keys)
      Acked-by: Steven Whitehouse <swhiteho@redhat.com> (gfs2)
      Acked-by: NPeter Zijlstra <peterz@infradead.org>
      Cc: Oleg Nesterov <oleg@redhat.com>
      Cc: Steve French <sfrench@samba.org>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Link: http://lkml.kernel.org/r/20140707051603.28027.72349.stgit@notabene.brownSigned-off-by: NIngo Molnar <mingo@kernel.org>
      74316201
  4. 30 10月, 2013 1 次提交
    • D
      KEYS: Fix a race between negating a key and reading the error set · 74792b00
      David Howells 提交于
      key_reject_and_link() marking a key as negative and setting the error with
      which it was negated races with keyring searches and other things that read
      that error.
      
      The fix is to switch the order in which the assignments are done in
      key_reject_and_link() and to use memory barriers.
      
      Kudos to Dave Wysochanski <dwysocha@redhat.com> and Scott Mayhew
      <smayhew@redhat.com> for tracking this down.
      
      This may be the cause of:
      
      BUG: unable to handle kernel NULL pointer dereference at 0000000000000070
      IP: [<ffffffff81219011>] wait_for_key_construction+0x31/0x80
      PGD c6b2c3067 PUD c59879067 PMD 0
      Oops: 0000 [#1] SMP
      last sysfs file: /sys/devices/system/cpu/cpu3/cache/index2/shared_cpu_map
      CPU 0
      Modules linked in: ...
      
      Pid: 13359, comm: amqzxma0 Not tainted 2.6.32-358.20.1.el6.x86_64 #1 IBM System x3650 M3 -[7945PSJ]-/00J6159
      RIP: 0010:[<ffffffff81219011>] wait_for_key_construction+0x31/0x80
      RSP: 0018:ffff880c6ab33758  EFLAGS: 00010246
      RAX: ffffffff81219080 RBX: 0000000000000000 RCX: 0000000000000002
      RDX: ffffffff81219060 RSI: 0000000000000000 RDI: 0000000000000000
      RBP: ffff880c6ab33768 R08: 0000000000000000 R09: 0000000000000000
      R10: 0000000000000001 R11: 0000000000000000 R12: ffff880adfcbce40
      R13: ffffffffa03afb84 R14: ffff880adfcbce40 R15: ffff880adfcbce43
      FS:  00007f29b8042700(0000) GS:ffff880028200000(0000) knlGS:0000000000000000
      CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      CR2: 0000000000000070 CR3: 0000000c613dc000 CR4: 00000000000007f0
      DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
      Process amqzxma0 (pid: 13359, threadinfo ffff880c6ab32000, task ffff880c610deae0)
      Stack:
       ffff880adfcbce40 0000000000000000 ffff880c6ab337b8 ffffffff81219695
      <d> 0000000000000000 ffff880a000000d0 ffff880c6ab337a8 000000000000000f
      <d> ffffffffa03afb93 000000000000000f ffff88186c7882c0 0000000000000014
      Call Trace:
       [<ffffffff81219695>] request_key+0x65/0xa0
       [<ffffffffa03a0885>] nfs_idmap_request_key+0xc5/0x170 [nfs]
       [<ffffffffa03a0eb4>] nfs_idmap_lookup_id+0x34/0x80 [nfs]
       [<ffffffffa03a1255>] nfs_map_group_to_gid+0x75/0xa0 [nfs]
       [<ffffffffa039a9ad>] decode_getfattr_attrs+0xbdd/0xfb0 [nfs]
       [<ffffffff81057310>] ? __dequeue_entity+0x30/0x50
       [<ffffffff8100988e>] ? __switch_to+0x26e/0x320
       [<ffffffffa039ae03>] decode_getfattr+0x83/0xe0 [nfs]
       [<ffffffffa039b610>] ? nfs4_xdr_dec_getattr+0x0/0xa0 [nfs]
       [<ffffffffa039b69f>] nfs4_xdr_dec_getattr+0x8f/0xa0 [nfs]
       [<ffffffffa02dada4>] rpcauth_unwrap_resp+0x84/0xb0 [sunrpc]
       [<ffffffffa039b610>] ? nfs4_xdr_dec_getattr+0x0/0xa0 [nfs]
       [<ffffffffa02cf923>] call_decode+0x1b3/0x800 [sunrpc]
       [<ffffffff81096de0>] ? wake_bit_function+0x0/0x50
       [<ffffffffa02cf770>] ? call_decode+0x0/0x800 [sunrpc]
       [<ffffffffa02d99a7>] __rpc_execute+0x77/0x350 [sunrpc]
       [<ffffffff81096c67>] ? bit_waitqueue+0x17/0xd0
       [<ffffffffa02d9ce1>] rpc_execute+0x61/0xa0 [sunrpc]
       [<ffffffffa02d03a5>] rpc_run_task+0x75/0x90 [sunrpc]
       [<ffffffffa02d04c2>] rpc_call_sync+0x42/0x70 [sunrpc]
       [<ffffffffa038ff80>] _nfs4_call_sync+0x30/0x40 [nfs]
       [<ffffffffa038836c>] _nfs4_proc_getattr+0xac/0xc0 [nfs]
       [<ffffffff810aac87>] ? futex_wait+0x227/0x380
       [<ffffffffa038b856>] nfs4_proc_getattr+0x56/0x80 [nfs]
       [<ffffffffa0371403>] __nfs_revalidate_inode+0xe3/0x220 [nfs]
       [<ffffffffa037158e>] nfs_revalidate_mapping+0x4e/0x170 [nfs]
       [<ffffffffa036f147>] nfs_file_read+0x77/0x130 [nfs]
       [<ffffffff811811aa>] do_sync_read+0xfa/0x140
       [<ffffffff81096da0>] ? autoremove_wake_function+0x0/0x40
       [<ffffffff8100bb8e>] ? apic_timer_interrupt+0xe/0x20
       [<ffffffff8100b9ce>] ? common_interrupt+0xe/0x13
       [<ffffffff81228ffb>] ? selinux_file_permission+0xfb/0x150
       [<ffffffff8121bed6>] ? security_file_permission+0x16/0x20
       [<ffffffff81181a95>] vfs_read+0xb5/0x1a0
       [<ffffffff81181bd1>] sys_read+0x51/0x90
       [<ffffffff810dc685>] ? __audit_syscall_exit+0x265/0x290
       [<ffffffff8100b072>] system_call_fastpath+0x16/0x1b
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      cc: Dave Wysochanski <dwysocha@redhat.com>
      cc: Scott Mayhew <smayhew@redhat.com>
      74792b00
  5. 24 9月, 2013 4 次提交
    • D
      KEYS: Expand the capacity of a keyring · b2a4df20
      David Howells 提交于
      Expand the capacity of a keyring to be able to hold a lot more keys by using
      the previously added associative array implementation.  Currently the maximum
      capacity is:
      
      	(PAGE_SIZE - sizeof(header)) / sizeof(struct key *)
      
      which, on a 64-bit system, is a little more 500.  However, since this is being
      used for the NFS uid mapper, we need more than that.  The new implementation
      gives us effectively unlimited capacity.
      
      With some alterations, the keyutils testsuite runs successfully to completion
      after this patch is applied.  The alterations are because (a) keyrings that
      are simply added to no longer appear ordered and (b) some of the errors have
      changed a bit.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      b2a4df20
    • D
      KEYS: Introduce a search context structure · 4bdf0bc3
      David Howells 提交于
      Search functions pass around a bunch of arguments, each of which gets copied
      with each call.  Introduce a search context structure to hold these.
      
      Whilst we're at it, create a search flag that indicates whether the search
      should be directly to the description or whether it should iterate through all
      keys looking for a non-description match.
      
      This will be useful when keyrings use a generic data struct with generic
      routines to manage their content as the search terms can just be passed
      through to the iterator callback function.
      
      Also, for future use, the data to be supplied to the match function is
      separated from the description pointer in the search context.  This makes it
      clear which is being supplied.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      4bdf0bc3
    • D
      KEYS: Consolidate the concept of an 'index key' for key access · 16feef43
      David Howells 提交于
      Consolidate the concept of an 'index key' for accessing keys.  The index key
      is the search term needed to find a key directly - basically the key type and
      the key description.  We can add to that the description length.
      
      This will be useful when turning a keyring into an associative array rather
      than just a pointer block.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      16feef43
    • D
      KEYS: Skip key state checks when checking for possession · 61ea0c0b
      David Howells 提交于
      Skip key state checks (invalidation, revocation and expiration) when checking
      for possession.  Without this, keys that have been marked invalid, revoked
      keys and expired keys are not given a possession attribute - which means the
      possessor is not granted any possession permits and cannot do anything with
      them unless they also have one a user, group or other permit.
      
      This causes failures in the keyutils test suite's revocation and expiration
      tests now that commit 96b5c8fe reduced the
      initial permissions granted to a key.
      
      The failures are due to accesses to revoked and expired keys being given
      EACCES instead of EKEYREVOKED or EKEYEXPIRED.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      61ea0c0b
  6. 01 5月, 2013 1 次提交
  7. 03 10月, 2012 2 次提交
    • D
      KEYS: Reduce initial permissions on keys · 96b5c8fe
      David Howells 提交于
      Reduce the initial permissions on new keys to grant the possessor everything,
      view permission only to the user (so the keys can be seen in /proc/keys) and
      nothing else.
      
      This gives the creator a chance to adjust the permissions mask before other
      processes can access the new key or create a link to it.
      
      To aid with this, keyring_alloc() now takes a permission argument rather than
      setting the permissions itself.
      
      The following permissions are now set:
      
       (1) The user and user-session keyrings grant the user that owns them full
           permissions and grant a possessor everything bar SETATTR.
      
       (2) The process and thread keyrings grant the possessor full permissions but
           only grant the user VIEW.  This permits the user to see them in
           /proc/keys, but not to do anything with them.
      
       (3) Anonymous session keyrings grant the possessor full permissions, but only
           grant the user VIEW and READ.  This means that the user can see them in
           /proc/keys and can list them, but nothing else.  Possibly READ shouldn't
           be provided either.
      
       (4) Named session keyrings grant everything an anonymous session keyring does,
           plus they grant the user LINK permission.  The whole point of named
           session keyrings is that others can also subscribe to them.  Possibly this
           should be a separate permission to LINK.
      
       (5) The temporary session keyring created by call_sbin_request_key() gets the
           same permissions as an anonymous session keyring.
      
       (6) Keys created by add_key() get VIEW, SEARCH, LINK and SETATTR for the
           possessor, plus READ and/or WRITE if the key type supports them.  The used
           only gets VIEW now.
      
       (7) Keys created by request_key() now get the same as those created by
           add_key().
      Reported-by: NLennart Poettering <lennart@poettering.net>
      Reported-by: NStef Walter <stefw@redhat.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      96b5c8fe
    • 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
  8. 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
  9. 01 6月, 2012 1 次提交
  10. 24 3月, 2012 1 次提交
  11. 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
  12. 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
  13. 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
  14. 17 3月, 2011 1 次提交
    • 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
  15. 08 3月, 2011 1 次提交
  16. 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
  17. 22 1月, 2011 1 次提交
  18. 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
  19. 07 8月, 2010 1 次提交
  20. 02 8月, 2010 1 次提交
  21. 28 5月, 2010 1 次提交
  22. 06 5月, 2010 2 次提交
  23. 05 5月, 2010 2 次提交
    • D
      KEYS: call_sbin_request_key() must write lock keyrings before modifying them · 896903c2
      David Howells 提交于
      call_sbin_request_key() creates a keyring and then attempts to insert a link to
      the authorisation key into that keyring, but does so without holding a write
      lock on the keyring semaphore.
      
      It will normally get away with this because it hasn't told anyone that the
      keyring exists yet.  The new keyring, however, has had its serial number
      published, which means it can be accessed directly by that handle.
      
      This was found by a previous patch that adds RCU lockdep checks to the code
      that reads the keyring payload pointer, which includes a check that the keyring
      semaphore is actually locked.
      
      Without this patch, the following command:
      
      	keyctl request2 user b a @s
      
      will provoke the following lockdep warning is displayed in dmesg:
      
      	===================================================
      	[ INFO: suspicious rcu_dereference_check() usage. ]
      	---------------------------------------------------
      	security/keys/keyring.c:727 invoked rcu_dereference_check() without protection!
      
      	other info that might help us debug this:
      
      	rcu_scheduler_active = 1, debug_locks = 0
      	2 locks held by keyctl/2076:
      	 #0:  (key_types_sem){.+.+.+}, at: [<ffffffff811a5b29>] key_type_lookup+0x1c/0x71
      	 #1:  (keyring_serialise_link_sem){+.+.+.}, at: [<ffffffff811a6d1e>] __key_link+0x4d/0x3c5
      
      	stack backtrace:
      	Pid: 2076, comm: keyctl Not tainted 2.6.34-rc6-cachefs #54
      	Call Trace:
      	 [<ffffffff81051fdc>] lockdep_rcu_dereference+0xaa/0xb2
      	 [<ffffffff811a6d1e>] ? __key_link+0x4d/0x3c5
      	 [<ffffffff811a6e6f>] __key_link+0x19e/0x3c5
      	 [<ffffffff811a5952>] ? __key_instantiate_and_link+0xb1/0xdc
      	 [<ffffffff811a59bf>] ? key_instantiate_and_link+0x42/0x5f
      	 [<ffffffff811aa0dc>] call_sbin_request_key+0xe7/0x33b
      	 [<ffffffff8139376a>] ? mutex_unlock+0x9/0xb
      	 [<ffffffff811a5952>] ? __key_instantiate_and_link+0xb1/0xdc
      	 [<ffffffff811a59bf>] ? key_instantiate_and_link+0x42/0x5f
      	 [<ffffffff811aa6fa>] ? request_key_auth_new+0x1c2/0x23c
      	 [<ffffffff810aaf15>] ? cache_alloc_debugcheck_after+0x108/0x173
      	 [<ffffffff811a9d00>] ? request_key_and_link+0x146/0x300
      	 [<ffffffff810ac568>] ? kmem_cache_alloc+0xe1/0x118
      	 [<ffffffff811a9e45>] request_key_and_link+0x28b/0x300
      	 [<ffffffff811a89ac>] sys_request_key+0xf7/0x14a
      	 [<ffffffff81052c0b>] ? trace_hardirqs_on_caller+0x10c/0x130
      	 [<ffffffff81394fb9>] ? trace_hardirqs_on_thunk+0x3a/0x3f
      	 [<ffffffff81001eeb>] system_call_fastpath+0x16/0x1b
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      896903c2
    • D
      KEYS: Fix an RCU warning · bfeb0360
      David Howells 提交于
      Fix the following RCU warning:
      
      ===================================================
      [ INFO: suspicious rcu_dereference_check() usage. ]
      ---------------------------------------------------
      security/keys/request_key.c:116 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/5372:
       #0:  (key_types_sem){.+.+.+}, at: [<ffffffff811a4e3d>] key_type_lookup+0x1c/0x70
      
      stack backtrace:
      Pid: 5372, comm: keyctl Not tainted 2.6.34-rc3-cachefs #150
      Call Trace:
       [<ffffffff810515f8>] lockdep_rcu_dereference+0xaa/0xb2
       [<ffffffff811a9220>] call_sbin_request_key+0x156/0x2b6
       [<ffffffff811a4c66>] ? __key_instantiate_and_link+0xb1/0xdc
       [<ffffffff811a4cd3>] ? key_instantiate_and_link+0x42/0x5f
       [<ffffffff811a96b8>] ? request_key_auth_new+0x17b/0x1f3
       [<ffffffff811a8e00>] ? request_key_and_link+0x271/0x400
       [<ffffffff810aba6f>] ? kmem_cache_alloc+0xe1/0x118
       [<ffffffff811a8f1a>] request_key_and_link+0x38b/0x400
       [<ffffffff811a7b72>] sys_request_key+0xf7/0x14a
       [<ffffffff81052227>] ? trace_hardirqs_on_caller+0x10c/0x130
       [<ffffffff81393f5c>] ? trace_hardirqs_on_thunk+0x3a/0x3f
       [<ffffffff81001eeb>] system_call_fastpath+0x16/0x1b
      
      This was caused by doing:
      
      	[root@andromeda ~]# keyctl newring fred @s
      	539196288
      	[root@andromeda ~]# keyctl request2 user a a 539196288
      	request_key: Required key not available
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NEric Dumazet <eric.dumazet@gmail.com>
      Signed-off-by: NPaul E. McKenney <paulmck@linux.vnet.ibm.com>
      bfeb0360
  24. 28 4月, 2010 1 次提交
    • D
      keys: the request_key() syscall should link an existing key to the dest keyring · 03449cd9
      David Howells 提交于
      The request_key() system call and request_key_and_link() should make a
      link from an existing key to the destination keyring (if supplied), not
      just from a new key to the destination keyring.
      
      This can be tested by:
      
      	ring=`keyctl newring fred @s`
      	keyctl request2 user debug:a a
      	keyctl request user debug:a $ring
      	keyctl list $ring
      
      If it says:
      
      	keyring is empty
      
      then it didn't work.  If it shows something like:
      
      	1 key in keyring:
      	1070462727: --alswrv     0     0 user: debug:a
      
      then it did.
      
      request_key() system call is meant to recursively search all your keyrings for
      the key you desire, and, optionally, if it doesn't exist, call out to userspace
      to create one for you.
      
      If request_key() finds or creates a key, it should, optionally, create a link
      to that key from the destination keyring specified.
      
      Therefore, if, after a successful call to request_key() with a desination
      keyring specified, you see the destination keyring empty, the code didn't work
      correctly.
      
      If you see the found key in the keyring, then it did - which is what the patch
      is required for.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Cc: James Morris <jmorris@namei.org>
      Cc: <stable@kernel.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      03449cd9
  25. 25 4月, 2010 1 次提交
  26. 10 4月, 2009 1 次提交
    • D
      keys: Handle there being no fallback destination keyring for request_key() · 34574dd1
      David Howells 提交于
      When request_key() is called, without there being any standard process
      keyrings on which to fall back if a destination keyring is not specified, an
      oops is liable to occur when construct_alloc_key() calls down_write() on
      dest_keyring's semaphore.
      
      Due to function inlining this may be seen as an oops in down_write() as called
      from request_key_and_link().
      
      This situation crops up during boot, where request_key() is called from within
      the kernel (such as in CIFS mounts) where nobody is actually logged in, and so
      PAM has not had a chance to create a session keyring and user keyrings to act
      as the fallback.
      
      To fix this, make construct_alloc_key() not attempt to cache a key if there is
      no fallback key if no destination keyring is given specifically.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NJeff Layton <jlayton@redhat.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      34574dd1
  27. 27 2月, 2009 1 次提交
  28. 14 11月, 2008 6 次提交
    • D
      CRED: Inaugurate COW credentials · d84f4f99
      David Howells 提交于
      Inaugurate copy-on-write credentials management.  This uses RCU to manage the
      credentials pointer in the task_struct with respect to accesses by other tasks.
      A process may only modify its own credentials, and so does not need locking to
      access or modify its own credentials.
      
      A mutex (cred_replace_mutex) is added to the task_struct to control the effect
      of PTRACE_ATTACHED on credential calculations, particularly with respect to
      execve().
      
      With this patch, the contents of an active credentials struct may not be
      changed directly; rather a new set of credentials must be prepared, modified
      and committed using something like the following sequence of events:
      
      	struct cred *new = prepare_creds();
      	int ret = blah(new);
      	if (ret < 0) {
      		abort_creds(new);
      		return ret;
      	}
      	return commit_creds(new);
      
      There are some exceptions to this rule: the keyrings pointed to by the active
      credentials may be instantiated - keyrings violate the COW rule as managing
      COW keyrings is tricky, given that it is possible for a task to directly alter
      the keys in a keyring in use by another task.
      
      To help enforce this, various pointers to sets of credentials, such as those in
      the task_struct, are declared const.  The purpose of this is compile-time
      discouragement of altering credentials through those pointers.  Once a set of
      credentials has been made public through one of these pointers, it may not be
      modified, except under special circumstances:
      
        (1) Its reference count may incremented and decremented.
      
        (2) The keyrings to which it points may be modified, but not replaced.
      
      The only safe way to modify anything else is to create a replacement and commit
      using the functions described in Documentation/credentials.txt (which will be
      added by a later patch).
      
      This patch and the preceding patches have been tested with the LTP SELinux
      testsuite.
      
      This patch makes several logical sets of alteration:
      
       (1) execve().
      
           This now prepares and commits credentials in various places in the
           security code rather than altering the current creds directly.
      
       (2) Temporary credential overrides.
      
           do_coredump() and sys_faccessat() now prepare their own credentials and
           temporarily override the ones currently on the acting thread, whilst
           preventing interference from other threads by holding cred_replace_mutex
           on the thread being dumped.
      
           This will be replaced in a future patch by something that hands down the
           credentials directly to the functions being called, rather than altering
           the task's objective credentials.
      
       (3) LSM interface.
      
           A number of functions have been changed, added or removed:
      
           (*) security_capset_check(), ->capset_check()
           (*) security_capset_set(), ->capset_set()
      
           	 Removed in favour of security_capset().
      
           (*) security_capset(), ->capset()
      
           	 New.  This is passed a pointer to the new creds, a pointer to the old
           	 creds and the proposed capability sets.  It should fill in the new
           	 creds or return an error.  All pointers, barring the pointer to the
           	 new creds, are now const.
      
           (*) security_bprm_apply_creds(), ->bprm_apply_creds()
      
           	 Changed; now returns a value, which will cause the process to be
           	 killed if it's an error.
      
           (*) security_task_alloc(), ->task_alloc_security()
      
           	 Removed in favour of security_prepare_creds().
      
           (*) security_cred_free(), ->cred_free()
      
           	 New.  Free security data attached to cred->security.
      
           (*) security_prepare_creds(), ->cred_prepare()
      
           	 New. Duplicate any security data attached to cred->security.
      
           (*) security_commit_creds(), ->cred_commit()
      
           	 New. Apply any security effects for the upcoming installation of new
           	 security by commit_creds().
      
           (*) security_task_post_setuid(), ->task_post_setuid()
      
           	 Removed in favour of security_task_fix_setuid().
      
           (*) security_task_fix_setuid(), ->task_fix_setuid()
      
           	 Fix up the proposed new credentials for setuid().  This is used by
           	 cap_set_fix_setuid() to implicitly adjust capabilities in line with
           	 setuid() changes.  Changes are made to the new credentials, rather
           	 than the task itself as in security_task_post_setuid().
      
           (*) security_task_reparent_to_init(), ->task_reparent_to_init()
      
           	 Removed.  Instead the task being reparented to init is referred
           	 directly to init's credentials.
      
      	 NOTE!  This results in the loss of some state: SELinux's osid no
      	 longer records the sid of the thread that forked it.
      
           (*) security_key_alloc(), ->key_alloc()
           (*) security_key_permission(), ->key_permission()
      
           	 Changed.  These now take cred pointers rather than task pointers to
           	 refer to the security context.
      
       (4) sys_capset().
      
           This has been simplified and uses less locking.  The LSM functions it
           calls have been merged.
      
       (5) reparent_to_kthreadd().
      
           This gives the current thread the same credentials as init by simply using
           commit_thread() to point that way.
      
       (6) __sigqueue_alloc() and switch_uid()
      
           __sigqueue_alloc() can't stop the target task from changing its creds
           beneath it, so this function gets a reference to the currently applicable
           user_struct which it then passes into the sigqueue struct it returns if
           successful.
      
           switch_uid() is now called from commit_creds(), and possibly should be
           folded into that.  commit_creds() should take care of protecting
           __sigqueue_alloc().
      
       (7) [sg]et[ug]id() and co and [sg]et_current_groups.
      
           The set functions now all use prepare_creds(), commit_creds() and
           abort_creds() to build and check a new set of credentials before applying
           it.
      
           security_task_set[ug]id() is called inside the prepared section.  This
           guarantees that nothing else will affect the creds until we've finished.
      
           The calling of set_dumpable() has been moved into commit_creds().
      
           Much of the functionality of set_user() has been moved into
           commit_creds().
      
           The get functions all simply access the data directly.
      
       (8) security_task_prctl() and cap_task_prctl().
      
           security_task_prctl() has been modified to return -ENOSYS if it doesn't
           want to handle a function, or otherwise return the return value directly
           rather than through an argument.
      
           Additionally, cap_task_prctl() now prepares a new set of credentials, even
           if it doesn't end up using it.
      
       (9) Keyrings.
      
           A number of changes have been made to the keyrings code:
      
           (a) switch_uid_keyring(), copy_keys(), exit_keys() and suid_keys() have
           	 all been dropped and built in to the credentials functions directly.
           	 They may want separating out again later.
      
           (b) key_alloc() and search_process_keyrings() now take a cred pointer
           	 rather than a task pointer to specify the security context.
      
           (c) copy_creds() gives a new thread within the same thread group a new
           	 thread keyring if its parent had one, otherwise it discards the thread
           	 keyring.
      
           (d) The authorisation key now points directly to the credentials to extend
           	 the search into rather pointing to the task that carries them.
      
           (e) Installing thread, process or session keyrings causes a new set of
           	 credentials to be created, even though it's not strictly necessary for
           	 process or session keyrings (they're shared).
      
      (10) Usermode helper.
      
           The usermode helper code now carries a cred struct pointer in its
           subprocess_info struct instead of a new session keyring pointer.  This set
           of credentials is derived from init_cred and installed on the new process
           after it has been cloned.
      
           call_usermodehelper_setup() allocates the new credentials and
           call_usermodehelper_freeinfo() discards them if they haven't been used.  A
           special cred function (prepare_usermodeinfo_creds()) is provided
           specifically for call_usermodehelper_setup() to call.
      
           call_usermodehelper_setkeys() adjusts the credentials to sport the
           supplied keyring as the new session keyring.
      
      (11) SELinux.
      
           SELinux has a number of changes, in addition to those to support the LSM
           interface changes mentioned above:
      
           (a) selinux_setprocattr() no longer does its check for whether the
           	 current ptracer can access processes with the new SID inside the lock
           	 that covers getting the ptracer's SID.  Whilst this lock ensures that
           	 the check is done with the ptracer pinned, the result is only valid
           	 until the lock is released, so there's no point doing it inside the
           	 lock.
      
      (12) is_single_threaded().
      
           This function has been extracted from selinux_setprocattr() and put into
           a file of its own in the lib/ directory as join_session_keyring() now
           wants to use it too.
      
           The code in SELinux just checked to see whether a task shared mm_structs
           with other tasks (CLONE_VM), but that isn't good enough.  We really want
           to know if they're part of the same thread group (CLONE_THREAD).
      
      (13) nfsd.
      
           The NFS server daemon now has to use the COW credentials to set the
           credentials it is going to use.  It really needs to pass the credentials
           down to the functions it calls, but it can't do that until other patches
           in this series have been applied.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NJames Morris <jmorris@namei.org>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      d84f4f99
    • D
      CRED: Separate per-task-group keyrings from signal_struct · bb952bb9
      David Howells 提交于
      Separate per-task-group keyrings from signal_struct and dangle their anchor
      from the cred struct rather than the signal_struct.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-by: NJames Morris <jmorris@namei.org>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      bb952bb9
    • D
      CRED: Wrap current->cred and a few other accessors · 86a264ab
      David Howells 提交于
      Wrap current->cred and a few other accessors to hide their actual
      implementation.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NJames Morris <jmorris@namei.org>
      Acked-by: NSerge Hallyn <serue@us.ibm.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      86a264ab
    • D
      CRED: Separate task security context from task_struct · b6dff3ec
      David Howells 提交于
      Separate the task security context from task_struct.  At this point, the
      security data is temporarily embedded in the task_struct with two pointers
      pointing to it.
      
      Note that the Alpha arch is altered as it refers to (E)UID and (E)GID in
      entry.S via asm-offsets.
      
      With comment fixes Signed-off-by: Marc Dionne <marc.c.dionne@gmail.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NJames Morris <jmorris@namei.org>
      Acked-by: NSerge Hallyn <serue@us.ibm.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      b6dff3ec
    • D
      KEYS: Alter use of key instantiation link-to-keyring argument · 8bbf4976
      David Howells 提交于
      Alter the use of the key instantiation and negation functions' link-to-keyring
      arguments.  Currently this specifies a keyring in the target process to link
      the key into, creating the keyring if it doesn't exist.  This, however, can be
      a problem for copy-on-write credentials as it means that the instantiating
      process can alter the credentials of the requesting process.
      
      This patch alters the behaviour such that:
      
       (1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
           keyring by ID (ringid >= 0), then that keyring will be used.
      
       (2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
           special constants that refer to the requesting process's keyrings
           (KEY_SPEC_*_KEYRING, all <= 0), then:
      
           (a) If sys_request_key() was given a keyring to use (destringid) then the
           	 key will be attached to that keyring.
      
           (b) If sys_request_key() was given a NULL keyring, then the key being
           	 instantiated will be attached to the default keyring as set by
           	 keyctl_set_reqkey_keyring().
      
       (3) No extra link will be made.
      
      Decision point (1) follows current behaviour, and allows those instantiators
      who've searched for a specifically named keyring in the requestor's keyring so
      as to partition the keys by type to still have their named keyrings.
      
      Decision point (2) allows the requestor to make sure that the key or keys that
      get produced by request_key() go where they want, whilst allowing the
      instantiator to request that the key is retained.  This is mainly useful for
      situations where the instantiator makes a secondary request, the key for which
      should be retained by the initial requestor:
      
      	+-----------+        +--------------+        +--------------+
      	|           |        |              |        |              |
      	| Requestor |------->| Instantiator |------->| Instantiator |
      	|           |        |              |        |              |
      	+-----------+        +--------------+        +--------------+
      	           request_key()           request_key()
      
      This might be useful, for example, in Kerberos, where the requestor requests a
      ticket, and then the ticket instantiator requests the TGT, which someone else
      then has to go and fetch.  The TGT, however, should be retained in the
      keyrings of the requestor, not the first instantiator.  To make this explict
      an extra special keyring constant is also added.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-by: NJames Morris <jmorris@namei.org>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      8bbf4976
    • D
      KEYS: Disperse linux/key_ui.h · e9e349b0
      David Howells 提交于
      Disperse the bits of linux/key_ui.h as the reason they were put here (keyfs)
      didn't get in.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-by: NJames Morris <jmorris@namei.org>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      e9e349b0