1. 25 5月, 2012 1 次提交
    • D
      KEYS: Fix some sparse warnings · 423b9788
      David Howells 提交于
      Fix some sparse warnings in the keyrings code:
      
       (1) compat_keyctl_instantiate_key_iov() should be static.
      
       (2) There were a couple of places where a pointer was being compared against
           integer 0 rather than NULL.
      
       (3) keyctl_instantiate_key_common() should not take a __user-labelled iovec
           pointer as the caller must have copied the iovec to kernel space.
      
       (4) __key_link_begin() takes and __key_link_end() releases
           keyring_serialise_link_sem under some circumstances and so this should be
           declared.
      
           Note that adding __acquires() and __releases() for this doesn't help cure
           the warnings messages - something only commenting out both helps.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <james.l.morris@oracle.com>
      423b9788
  2. 11 5月, 2012 3 次提交
    • D
      KEYS: Add invalidation support · fd75815f
      David Howells 提交于
      Add support for invalidating a key - which renders it immediately invisible to
      further searches and causes the garbage collector to immediately wake up,
      remove it from keyrings and then destroy it when it's no longer referenced.
      
      It's better not to do this with keyctl_revoke() as that marks the key to start
      returning -EKEYREVOKED to searches when what is actually desired is to have the
      key refetched.
      
      To invalidate a key the caller must be granted SEARCH permission by the key.
      This may be too strict.  It may be better to also permit invalidation if the
      caller has any of READ, WRITE or SETATTR permission.
      
      The primary use for this is to evict keys that are cached in special keyrings,
      such as the DNS resolver or an ID mapper.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      fd75815f
    • D
      KEYS: Do LRU discard in full keyrings · 31d5a79d
      David Howells 提交于
      Do an LRU discard in keyrings that are full rather than returning ENFILE.  To
      perform this, a time_t is added to the key struct and updated by the creation
      of a link to a key and by a key being found as the result of a search.  At the
      completion of a successful search, the keyrings in the path between the root of
      the search and the first found link to it also have their last-used times
      updated.
      
      Note that discarding a link to a key from a keyring does not necessarily
      destroy the key as there may be references held by other places.
      
      An alternate discard method that might suffice is to perform FIFO discard from
      the keyring, using the spare 2-byte hole in the keylist header as the index of
      the next link to be discarded.
      
      This is useful when using a keyring as a cache for DNS results or foreign
      filesystem IDs.
      
      
      This can be tested by the following.  As root do:
      
      	echo 1000 >/proc/sys/kernel/keys/root_maxkeys
      
      	kr=`keyctl newring foo @s`
      	for ((i=0; i<2000; i++)); do keyctl add user a$i a $kr; done
      
      Without this patch ENFILE should be reported when the keyring fills up.  With
      this patch, the keyring discards keys in an LRU fashion.  Note that the stored
      LRU time has a granularity of 1s.
      
      After doing this, /proc/key-users can be observed and should show that most of
      the 2000 keys have been discarded:
      
      	[root@andromeda ~]# cat /proc/key-users
      	    0:   517 516/516 513/1000 5249/20000
      
      The "513/1000" here is the number of quota-accounted keys present for this user
      out of the maximum permitted.
      
      In /proc/keys, the keyring shows the number of keys it has and the number of
      slots it has allocated:
      
      	[root@andromeda ~]# grep foo /proc/keys
      	200c64c4 I--Q--     1 perm 3b3f0000     0     0 keyring   foo: 509/509
      
      The maximum is (PAGE_SIZE - header) / key pointer size.  That's typically 509
      on a 64-bit system and 1020 on a 32-bit system.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      31d5a79d
    • D
      KEYS: Permit in-place link replacement in keyring list · 233e4735
      David Howells 提交于
      Make use of the previous patch that makes the garbage collector perform RCU
      synchronisation before destroying defunct keys.  Key pointers can now be
      replaced in-place without creating a new keyring payload and replacing the
      whole thing as the discarded keys will not be destroyed until all currently
      held RCU read locks are released.
      
      If the keyring payload space needs to be expanded or contracted, then a
      replacement will still need allocating, and the original will still have to be
      freed by RCU.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      233e4735
  3. 18 1月, 2012 1 次提交
  4. 23 8月, 2011 1 次提交
  5. 09 7月, 2011 1 次提交
  6. 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
  7. 08 3月, 2011 1 次提交
  8. 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
  9. 22 1月, 2011 2 次提交
  10. 25 5月, 2010 1 次提交
  11. 06 5月, 2010 2 次提交
  12. 05 5月, 2010 2 次提交
    • D
      KEYS: Use RCU dereference wrappers in keyring key type code · f0641cba
      David Howells 提交于
      The keyring key type code should use RCU dereference wrappers, even when it
      holds the keyring's key semaphore.
      Reported-by: NVegard Nossum <vegard.nossum@gmail.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NSerge Hallyn <serue@us.ibm.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      f0641cba
    • T
      KEYS: find_keyring_by_name() can gain access to a freed keyring · cea7daa3
      Toshiyuki Okajima 提交于
      find_keyring_by_name() can gain access to a keyring that has had its reference
      count reduced to zero, and is thus ready to be freed.  This then allows the
      dead keyring to be brought back into use whilst it is being destroyed.
      
      The following timeline illustrates the process:
      
      |(cleaner)                           (user)
      |
      | free_user(user)                    sys_keyctl()
      |  |                                  |
      |  key_put(user->session_keyring)     keyctl_get_keyring_ID()
      |  ||	//=> keyring->usage = 0        |
      |  |schedule_work(&key_cleanup_task)   lookup_user_key()
      |  ||                                   |
      |  kmem_cache_free(,user)               |
      |  .                                    |[KEY_SPEC_USER_KEYRING]
      |  .                                    install_user_keyrings()
      |  .                                    ||
      | key_cleanup() [<= worker_thread()]    ||
      |  |                                    ||
      |  [spin_lock(&key_serial_lock)]        |[mutex_lock(&key_user_keyr..mutex)]
      |  |                                    ||
      |  atomic_read() == 0                   ||
      |  |{ rb_ease(&key->serial_node,) }     ||
      |  |                                    ||
      |  [spin_unlock(&key_serial_lock)]      |find_keyring_by_name()
      |  |                                    |||
      |  keyring_destroy(keyring)             ||[read_lock(&keyring_name_lock)]
      |  ||                                   |||
      |  |[write_lock(&keyring_name_lock)]    ||atomic_inc(&keyring->usage)
      |  |.                                   ||| *** GET freeing keyring ***
      |  |.                                   ||[read_unlock(&keyring_name_lock)]
      |  ||                                   ||
      |  |list_del()                          |[mutex_unlock(&key_user_k..mutex)]
      |  ||                                   |
      |  |[write_unlock(&keyring_name_lock)]  ** INVALID keyring is returned **
      |  |                                    .
      |  kmem_cache_free(,keyring)            .
      |                                       .
      |                                       atomic_dec(&keyring->usage)
      v                                         *** DESTROYED ***
      TIME
      
      If CONFIG_SLUB_DEBUG=y then we may see the following message generated:
      
      	=============================================================================
      	BUG key_jar: Poison overwritten
      	-----------------------------------------------------------------------------
      
      	INFO: 0xffff880197a7e200-0xffff880197a7e200. First byte 0x6a instead of 0x6b
      	INFO: Allocated in key_alloc+0x10b/0x35f age=25 cpu=1 pid=5086
      	INFO: Freed in key_cleanup+0xd0/0xd5 age=12 cpu=1 pid=10
      	INFO: Slab 0xffffea000592cb90 objects=16 used=2 fp=0xffff880197a7e200 flags=0x200000000000c3
      	INFO: Object 0xffff880197a7e200 @offset=512 fp=0xffff880197a7e300
      
      	Bytes b4 0xffff880197a7e1f0:  5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
      	  Object 0xffff880197a7e200:  6a 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b jkkkkkkkkkkkkkkk
      
      Alternatively, we may see a system panic happen, such as:
      
      	BUG: unable to handle kernel NULL pointer dereference at 0000000000000001
      	IP: [<ffffffff810e61a3>] kmem_cache_alloc+0x5b/0xe9
      	PGD 6b2b4067 PUD 6a80d067 PMD 0
      	Oops: 0000 [#1] SMP
      	last sysfs file: /sys/kernel/kexec_crash_loaded
      	CPU 1
      	...
      	Pid: 31245, comm: su Not tainted 2.6.34-rc5-nofixed-nodebug #2 D2089/PRIMERGY
      	RIP: 0010:[<ffffffff810e61a3>]  [<ffffffff810e61a3>] kmem_cache_alloc+0x5b/0xe9
      	RSP: 0018:ffff88006af3bd98  EFLAGS: 00010002
      	RAX: 0000000000000000 RBX: 0000000000000001 RCX: ffff88007d19900b
      	RDX: 0000000100000000 RSI: 00000000000080d0 RDI: ffffffff81828430
      	RBP: ffffffff81828430 R08: ffff88000a293750 R09: 0000000000000000
      	R10: 0000000000000001 R11: 0000000000100000 R12: 00000000000080d0
      	R13: 00000000000080d0 R14: 0000000000000296 R15: ffffffff810f20ce
      	FS:  00007f97116bc700(0000) GS:ffff88000a280000(0000) knlGS:0000000000000000
      	CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      	CR2: 0000000000000001 CR3: 000000006a91c000 CR4: 00000000000006e0
      	DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      	DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
      	Process su (pid: 31245, threadinfo ffff88006af3a000, task ffff8800374414c0)
      	Stack:
      	 0000000512e0958e 0000000000008000 ffff880037f8d180 0000000000000001
      	 0000000000000000 0000000000008001 ffff88007d199000 ffffffff810f20ce
      	 0000000000008000 ffff88006af3be48 0000000000000024 ffffffff810face3
      	Call Trace:
      	 [<ffffffff810f20ce>] ? get_empty_filp+0x70/0x12f
      	 [<ffffffff810face3>] ? do_filp_open+0x145/0x590
      	 [<ffffffff810ce208>] ? tlb_finish_mmu+0x2a/0x33
      	 [<ffffffff810ce43c>] ? unmap_region+0xd3/0xe2
      	 [<ffffffff810e4393>] ? virt_to_head_page+0x9/0x2d
      	 [<ffffffff81103916>] ? alloc_fd+0x69/0x10e
      	 [<ffffffff810ef4ed>] ? do_sys_open+0x56/0xfc
      	 [<ffffffff81008a02>] ? system_call_fastpath+0x16/0x1b
      	Code: 0f 1f 44 00 00 49 89 c6 fa 66 0f 1f 44 00 00 65 4c 8b 04 25 60 e8 00 00 48 8b 45 00 49 01 c0 49 8b 18 48 85 db 74 0d 48 63 45 18 <48> 8b 04 03 49 89 00 eb 14 4c 89 f9 83 ca ff 44 89 e6 48 89 ef
      	RIP  [<ffffffff810e61a3>] kmem_cache_alloc+0x5b/0xe9
      
      This problem is that find_keyring_by_name does not confirm that the keyring is
      valid before accepting it.
      
      Skipping keyrings that have been reduced to a zero count seems the way to go.
      To this end, use atomic_inc_not_zero() to increment the usage count and skip
      the candidate keyring if that returns false.
      
      The following script _may_ cause the bug to happen, but there's no guarantee
      as the window of opportunity is small:
      
      	#!/bin/sh
      	LOOP=100000
      	USER=dummy_user
      	/bin/su -c "exit;" $USER || { /usr/sbin/adduser -m $USER; add=1; }
      	for ((i=0; i<LOOP; i++))
      	do
      		/bin/su -c "echo '$i' > /dev/null" $USER
      	done
      	(( add == 1 )) && /usr/sbin/userdel -r $USER
      	exit
      
      Note that the nominated user must not be in use.
      
      An alternative way of testing this may be:
      
      	for ((i=0; i<100000; i++))
      	do
      		keyctl session foo /bin/true || break
      	done >&/dev/null
      
      as that uses a keyring named "foo" rather than relying on the user and
      user-session named keyrings.
      Reported-by: NToshiyuki Okajima <toshi.okajima@jp.fujitsu.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NToshiyuki Okajima <toshi.okajima@jp.fujitsu.com>
      Acked-by: NSerge Hallyn <serue@us.ibm.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      cea7daa3
  13. 28 4月, 2010 1 次提交
    • D
      keys: don't need to use RCU in keyring_read() as semaphore is held · b59ec78c
      David Howells 提交于
      keyring_read() doesn't need to use rcu_dereference() to access the keyring
      payload as the caller holds the key semaphore to prevent modifications
      from happening whilst the data is read out.
      
      This should solve the following warning:
      
      ===================================================
      [ INFO: suspicious rcu_dereference_check() usage. ]
      ---------------------------------------------------
      security/keys/keyring.c:204 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/2144:
       #0:  (&key->sem){+++++.}, at: [<ffffffff81177f7c>] keyctl_read_key+0x9c/0xcf
      
      stack backtrace:
      Pid: 2144, comm: keyctl Not tainted 2.6.34-rc2-cachefs #113
      Call Trace:
       [<ffffffff8105121f>] lockdep_rcu_dereference+0xaa/0xb2
       [<ffffffff811762d5>] keyring_read+0x4d/0xe7
       [<ffffffff81177f8c>] keyctl_read_key+0xac/0xcf
       [<ffffffff811788d4>] sys_keyctl+0x75/0xb9
       [<ffffffff81001eeb>] system_call_fastpath+0x16/0x1b
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Cc: Herbert Xu <herbert@gondor.apana.org.au>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      b59ec78c
  14. 23 4月, 2010 1 次提交
  15. 10 3月, 2010 1 次提交
  16. 05 3月, 2010 1 次提交
  17. 25 2月, 2010 1 次提交
  18. 15 9月, 2009 1 次提交
    • D
      KEYS: Fix garbage collector · c08ef808
      David Howells 提交于
      Fix a number of problems with the new key garbage collector:
      
       (1) A rogue semicolon in keyring_gc() was causing the initial count of dead
           keys to be miscalculated.
      
       (2) A missing return in keyring_gc() meant that under certain circumstances,
           the keyring semaphore would be unlocked twice.
      
       (3) The key serial tree iterator (key_garbage_collector()) part of the garbage
           collector has been modified to:
      
           (a) Complete each scan of the keyrings before setting the new timer.
      
           (b) Only set the new timer for keys that have yet to expire.  This means
               that the new timer is now calculated correctly, and the gc doesn't
               get into a loop continually scanning for keys that have expired, and
               preventing other things from happening, like RCU cleaning up the old
               keyring contents.
      
           (c) Perform an extra scan if any keys were garbage collected in this one
           	 as a key might become garbage during a scan, and (b) could mean we
           	 don't set the timer again.
      
       (4) Made key_schedule_gc() take the time at which to do a collection run,
           rather than the time at which the key expires.  This means the collection
           of dead keys (key type unregistered) can happen immediately.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      c08ef808
  19. 02 9月, 2009 1 次提交
    • D
      KEYS: Add garbage collection for dead, revoked and expired keys. [try #6] · 5d135440
      David Howells 提交于
      Add garbage collection for dead, revoked and expired keys.  This involved
      erasing all links to such keys from keyrings that point to them.  At that
      point, the key will be deleted in the normal manner.
      
      Keyrings from which garbage collection occurs are shrunk and their quota
      consumption reduced as appropriate.
      
      Dead keys (for which the key type has been removed) will be garbage collected
      immediately.
      
      Revoked and expired keys will hang around for a number of seconds, as set in
      /proc/sys/kernel/keys/gc_delay before being automatically removed.  The default
      is 5 minutes.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      5d135440
  20. 27 2月, 2009 1 次提交
  21. 14 11月, 2008 2 次提交
    • 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
      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
  22. 29 4月, 2008 2 次提交
    • D
      keys: don't generate user and user session keyrings unless they're accessed · 69664cf1
      David Howells 提交于
      Don't generate the per-UID user and user session keyrings unless they're
      explicitly accessed.  This solves a problem during a login process whereby
      set*uid() is called before the SELinux PAM module, resulting in the per-UID
      keyrings having the wrong security labels.
      
      This also cures the problem of multiple per-UID keyrings sometimes appearing
      due to PAM modules (including pam_keyinit) setuiding and causing user_structs
      to come into and go out of existence whilst the session keyring pins the user
      keyring.  This is achieved by first searching for extant per-UID keyrings
      before inventing new ones.
      
      The serial bound argument is also dropped from find_keyring_by_name() as it's
      not currently made use of (setting it to 0 disables the feature).
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Cc: <kwc@citi.umich.edu>
      Cc: <arunsr@cse.iitk.ac.in>
      Cc: <dwalsh@redhat.com>
      Cc: Stephen Smalley <sds@tycho.nsa.gov>
      Cc: James Morris <jmorris@namei.org>
      Cc: Chris Wright <chrisw@sous-sol.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      69664cf1
    • K
      keys: check starting keyring as part of search · dceba994
      Kevin Coffman 提交于
      Check the starting keyring as part of the search to (a) see if that is what
      we're searching for, and (b) to check it is still valid for searching.
      
      The scenario: User in process A does things that cause things to be created in
      its process session keyring.  The user then does an su to another user and
      starts a new process, B.  The two processes now share the same process session
      keyring.
      
      Process B does an NFS access which results in an upcall to gssd.  When gssd
      attempts to instantiate the context key (to be linked into the process session
      keyring), it is denied access even though it has an authorization key.
      
      The order of calls is:
      
         keyctl_instantiate_key()
            lookup_user_key()				    (the default: case)
               search_process_keyrings(current)
      	    search_process_keyrings(rka->context)   (recursive call)
      	       keyring_search_aux()
      
      keyring_search_aux() verifies the keys and keyrings underneath the top-level
      keyring it is given, but that top-level keyring is neither fully validated nor
      checked to see if it is the thing being searched for.
      
      This patch changes keyring_search_aux() to:
      1) do more validation on the top keyring it is given and
      2) check whether that top-level keyring is the thing being searched for
      Signed-off-by: NKevin Coffman <kwc@citi.umich.edu>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Cc: Paul Moore <paul.moore@hp.com>
      Cc: Chris Wright <chrisw@sous-sol.org>
      Cc: Stephen Smalley <sds@tycho.nsa.gov>
      Cc: James Morris <jmorris@namei.org>
      Cc: Kevin Coffman <kwc@citi.umich.edu>
      Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
      Cc: "J. Bruce Fields" <bfields@fieldses.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      dceba994
  23. 27 4月, 2007 1 次提交
  24. 08 12月, 2006 1 次提交
  25. 27 6月, 2006 2 次提交
  26. 23 6月, 2006 1 次提交
  27. 11 4月, 2006 1 次提交
    • D
      [Security] Keys: Fix oops when adding key to non-keyring · c3a9d654
      David Howells 提交于
      This fixes the problem of an oops occuring when a user attempts to add a
      key to a non-keyring key [CVE-2006-1522].
      
      The problem is that __keyring_search_one() doesn't check that the
      keyring it's been given is actually a keyring.
      
      I've fixed this problem by:
      
       (1) declaring that caller of __keyring_search_one() must guarantee that
           the keyring is a keyring; and
      
       (2) making key_create_or_update() check that the keyring is a keyring,
           and return -ENOTDIR if it isn't.
      
      This can be tested by:
      
      	keyctl add user b b `keyctl add user a a @s`
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      c3a9d654
  28. 09 1月, 2006 2 次提交
    • D
      [PATCH] keys: Permit running process to instantiate keys · b5f545c8
      David Howells 提交于
      Make it possible for a running process (such as gssapid) to be able to
      instantiate a key, as was requested by Trond Myklebust for NFS4.
      
      The patch makes the following changes:
      
       (1) A new, optional key type method has been added. This permits a key type
           to intercept requests at the point /sbin/request-key is about to be
           spawned and do something else with them - passing them over the
           rpc_pipefs files or netlink sockets for instance.
      
           The uninstantiated key, the authorisation key and the intended operation
           name are passed to the method.
      
       (2) The callout_info is no longer passed as an argument to /sbin/request-key
           to prevent unauthorised viewing of this data using ps or by looking in
           /proc/pid/cmdline.
      
           This means that the old /sbin/request-key program will not work with the
           patched kernel as it will expect to see an extra argument that is no
           longer there.
      
           A revised keyutils package will be made available tomorrow.
      
       (3) The callout_info is now attached to the authorisation key. Reading this
           key will retrieve the information.
      
       (4) A new field has been added to the task_struct. This holds the
           authorisation key currently active for a thread. Searches now look here
           for the caller's set of keys rather than looking for an auth key in the
           lowest level of the session keyring.
      
           This permits a thread to be servicing multiple requests at once and to
           switch between them. Note that this is per-thread, not per-process, and
           so is usable in multithreaded programs.
      
           The setting of this field is inherited across fork and exec.
      
       (5) A new keyctl function (KEYCTL_ASSUME_AUTHORITY) has been added that
           permits a thread to assume the authority to deal with an uninstantiated
           key. Assumption is only permitted if the authorisation key associated
           with the uninstantiated key is somewhere in the thread's keyrings.
      
           This function can also clear the assumption.
      
       (6) A new magic key specifier has been added to refer to the currently
           assumed authorisation key (KEY_SPEC_REQKEY_AUTH_KEY).
      
       (7) Instantiation will only proceed if the appropriate authorisation key is
           assumed first. The assumed authorisation key is discarded if
           instantiation is successful.
      
       (8) key_validate() is moved from the file of request_key functions to the
           file of permissions functions.
      
       (9) The documentation is updated.
      
      From: <Valdis.Kletnieks@vt.edu>
      
          Build fix.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
      Cc: Alexander Zangerl <az@bond.edu.au>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      b5f545c8
    • D
      [PATCH] keys: Discard duplicate keys from a keyring on link · cab8eb59
      David Howells 提交于
      Cause any links within a keyring to keys that match a key to be linked into
      that keyring to be discarded as a link to the new key is added.  The match is
      contingent on the type and description strings being the same.
      
      This permits requests, adds and searches to displace negative, expired,
      revoked and dead keys easily.  After some discussion it was concluded that
      duplicate valid keys should probably be discarded also as they would otherwise
      hide the new key.
      
      Since request_key() is intended to be the primary method by which keys are
      added to a keyring, duplicate valid keys wouldn't be an issue there as that
      function would return an existing match in preference to creating a new key.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
      Cc: Alexander Zangerl <az@bond.edu.au>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      cab8eb59
  29. 07 1月, 2006 2 次提交
  30. 02 12月, 2005 1 次提交