1. 26 9月, 2013 1 次提交
  2. 24 9月, 2013 6 次提交
    • 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: Drop the permissions argument from __keyring_search_one() · e57e8669
      David Howells 提交于
      Drop the permissions argument from __keyring_search_one() as the only caller
      passes 0 here - which causes all checks to be skipped.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      e57e8669
    • D
      KEYS: Define a __key_get() wrapper to use rather than atomic_inc() · ccc3e6d9
      David Howells 提交于
      Define a __key_get() wrapper to use rather than atomic_inc() on the key usage
      count as this makes it easier to hook in refcount error debugging.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      ccc3e6d9
    • 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: Use bool in make_key_ref() and is_key_possessed() · a5b4bd28
      David Howells 提交于
      Make make_key_ref() take a bool possession parameter and make
      is_key_possessed() return a bool.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      a5b4bd28
  3. 08 10月, 2012 1 次提交
    • D
      KEYS: Add payload preparsing opportunity prior to key instantiate or update · cf7f601c
      David Howells 提交于
      Give the key type the opportunity to preparse the payload prior to the
      instantiation and update routines being called.  This is done with the
      provision of two new key type operations:
      
      	int (*preparse)(struct key_preparsed_payload *prep);
      	void (*free_preparse)(struct key_preparsed_payload *prep);
      
      If the first operation is present, then it is called before key creation (in
      the add/update case) or before the key semaphore is taken (in the update and
      instantiate cases).  The second operation is called to clean up if the first
      was called.
      
      preparse() is given the opportunity to fill in the following structure:
      
      	struct key_preparsed_payload {
      		char		*description;
      		void		*type_data[2];
      		void		*payload;
      		const void	*data;
      		size_t		datalen;
      		size_t		quotalen;
      	};
      
      Before the preparser is called, the first three fields will have been cleared,
      the payload pointer and size will be stored in data and datalen and the default
      quota size from the key_type struct will be stored into quotalen.
      
      The preparser may parse the payload in any way it likes and may store data in
      the type_data[] and payload fields for use by the instantiate() and update()
      ops.
      
      The preparser may also propose a description for the key by attaching it as a
      string to the description field.  This can be used by passing a NULL or ""
      description to the add_key() system call or the key_create_or_update()
      function.  This cannot work with request_key() as that required the description
      to tell the upcall about the key to be created.
      
      This, for example permits keys that store PGP public keys to generate their own
      name from the user ID and public key fingerprint in the key.
      
      The instantiate() and update() operations are then modified to look like this:
      
      	int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
      	int (*update)(struct key *key, struct key_preparsed_payload *prep);
      
      and the new payload data is passed in *prep, whether or not it was preparsed.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NRusty Russell <rusty@rustcorp.com.au>
      cf7f601c
  4. 03 10月, 2012 2 次提交
    • D
      KEYS: Use keyring_alloc() to create special keyrings · f8aa23a5
      David Howells 提交于
      Use keyring_alloc() to create special keyrings now that it has a permissions
      parameter rather than using key_alloc() + key_instantiate_and_link().
      
      Also document and export keyring_alloc() so that modules can use it too.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      f8aa23a5
    • 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
  5. 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
  6. 13 9月, 2012 1 次提交
    • D
      KEYS: Add payload preparsing opportunity prior to key instantiate or update · d4f65b5d
      David Howells 提交于
      Give the key type the opportunity to preparse the payload prior to the
      instantiation and update routines being called.  This is done with the
      provision of two new key type operations:
      
      	int (*preparse)(struct key_preparsed_payload *prep);
      	void (*free_preparse)(struct key_preparsed_payload *prep);
      
      If the first operation is present, then it is called before key creation (in
      the add/update case) or before the key semaphore is taken (in the update and
      instantiate cases).  The second operation is called to clean up if the first
      was called.
      
      preparse() is given the opportunity to fill in the following structure:
      
      	struct key_preparsed_payload {
      		char		*description;
      		void		*type_data[2];
      		void		*payload;
      		const void	*data;
      		size_t		datalen;
      		size_t		quotalen;
      	};
      
      Before the preparser is called, the first three fields will have been cleared,
      the payload pointer and size will be stored in data and datalen and the default
      quota size from the key_type struct will be stored into quotalen.
      
      The preparser may parse the payload in any way it likes and may store data in
      the type_data[] and payload fields for use by the instantiate() and update()
      ops.
      
      The preparser may also propose a description for the key by attaching it as a
      string to the description field.  This can be used by passing a NULL or ""
      description to the add_key() system call or the key_create_or_update()
      function.  This cannot work with request_key() as that required the description
      to tell the upcall about the key to be created.
      
      This, for example permits keys that store PGP public keys to generate their own
      name from the user ID and public key fingerprint in the key.
      
      The instantiate() and update() operations are then modified to look like this:
      
      	int (*instantiate)(struct key *key, struct key_preparsed_payload *prep);
      	int (*update)(struct key *key, struct key_preparsed_payload *prep);
      
      and the new payload data is passed in *prep, whether or not it was preparsed.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      d4f65b5d
  7. 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
  8. 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
  9. 18 1月, 2012 1 次提交
  10. 23 8月, 2011 1 次提交
  11. 09 7月, 2011 1 次提交
  12. 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
  13. 08 3月, 2011 1 次提交
  14. 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
  15. 22 1月, 2011 2 次提交
  16. 25 5月, 2010 1 次提交
  17. 06 5月, 2010 2 次提交
  18. 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
  19. 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
  20. 23 4月, 2010 1 次提交
  21. 10 3月, 2010 1 次提交
  22. 05 3月, 2010 1 次提交
  23. 25 2月, 2010 1 次提交
  24. 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
  25. 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
  26. 27 2月, 2009 1 次提交
  27. 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
  28. 29 4月, 2008 1 次提交
    • 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