1. 03 9月, 2014 1 次提交
  2. 23 7月, 2014 3 次提交
  3. 19 7月, 2014 1 次提交
  4. 15 3月, 2014 1 次提交
  5. 02 12月, 2013 1 次提交
    • D
      KEYS: Pre-clear struct key on allocation · 2480f57f
      David Howells 提交于
      The second word of key->payload does not get initialised in key_alloc(), but
      the big_key type is relying on it having been cleared.  The problem comes when
      big_key fails to instantiate a large key and doesn't then set the payload.  The
      big_key_destroy() op is called from the garbage collector and this assumes that
      the dentry pointer stored in the second word will be NULL if instantiation did
      not complete.
      
      Therefore just pre-clear the entire struct key on allocation rather than trying
      to be clever and only initialising to 0 only those bits that aren't otherwise
      initialised.
      
      The lack of initialisation can lead to a bug report like the following if
      big_key failed to initialise its file:
      
      	general protection fault: 0000 [#1] SMP
      	Modules linked in: ...
      	CPU: 0 PID: 51 Comm: kworker/0:1 Not tainted 3.10.0-53.el7.x86_64 #1
      	Hardware name: Dell Inc. PowerEdge 1955/0HC513, BIOS 1.4.4 12/09/2008
      	Workqueue: events key_garbage_collector
      	task: ffff8801294f5680 ti: ffff8801296e2000 task.ti: ffff8801296e2000
      	RIP: 0010:[<ffffffff811b4a51>] dput+0x21/0x2d0
      	...
      	Call Trace:
      	 [<ffffffff811a7b06>] path_put+0x16/0x30
      	 [<ffffffff81235604>] big_key_destroy+0x44/0x60
      	 [<ffffffff8122dc4b>] key_gc_unused_keys.constprop.2+0x5b/0xe0
      	 [<ffffffff8122df2f>] key_garbage_collector+0x1df/0x3c0
      	 [<ffffffff8107759b>] process_one_work+0x17b/0x460
      	 [<ffffffff8107834b>] worker_thread+0x11b/0x400
      	 [<ffffffff81078230>] ? rescuer_thread+0x3e0/0x3e0
      	 [<ffffffff8107eb00>] kthread+0xc0/0xd0
      	 [<ffffffff8107ea40>] ? kthread_create_on_node+0x110/0x110
      	 [<ffffffff815c4bec>] ret_from_fork+0x7c/0xb0
      	 [<ffffffff8107ea40>] ? kthread_create_on_node+0x110/0x110
      Reported-by: NPatrik Kis <pkis@redhat.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-by: NStephen Gallagher <sgallagh@redhat.com>
      2480f57f
  6. 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
  7. 26 9月, 2013 1 次提交
  8. 24 9月, 2013 4 次提交
  9. 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
  10. 03 10月, 2012 1 次提交
    • 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
  11. 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
  12. 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
  13. 21 8月, 2012 1 次提交
    • T
      workqueue: deprecate system_nrt[_freezable]_wq · 3b07e9ca
      Tejun Heo 提交于
      system_nrt[_freezable]_wq are now spurious.  Mark them deprecated and
      convert all users to system[_freezable]_wq.
      
      If you're cc'd and wondering what's going on: Now all workqueues are
      non-reentrant, so there's no reason to use system_nrt[_freezable]_wq.
      Please use system[_freezable]_wq instead.
      
      This patch doesn't make any functional difference.
      Signed-off-by: NTejun Heo <tj@kernel.org>
      Acked-By: NLai Jiangshan <laijs@cn.fujitsu.com>
      
      Cc: Jens Axboe <axboe@kernel.dk>
      Cc: David Airlie <airlied@linux.ie>
      Cc: Jiri Kosina <jkosina@suse.cz>
      Cc: "David S. Miller" <davem@davemloft.net>
      Cc: Rusty Russell <rusty@rustcorp.com.au>
      Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
      Cc: David Howells <dhowells@redhat.com>
      3b07e9ca
  14. 11 5月, 2012 2 次提交
    • 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: Announce key type (un)registration · 1eb1bcf5
      David Howells 提交于
      Announce the (un)registration of a key type in the core key code rather than
      in the callers.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NMimi Zohar <zohar@us.ibm.com>
      1eb1bcf5
  15. 08 4月, 2012 1 次提交
  16. 02 3月, 2012 1 次提交
  17. 18 1月, 2012 1 次提交
    • J
      keys: add a "logon" key type · 9f6ed2ca
      Jeff Layton 提交于
      For CIFS, we want to be able to store NTLM credentials (aka username
      and password) in the keyring. We do not, however want to allow users
      to fetch those keys back out of the keyring since that would be a
      security risk.
      
      Unfortunately, due to the nuances of key permission bits, it's not
      possible to do this. We need to grant search permissions so the kernel
      can find these keys, but that also implies permissions to read the
      payload.
      
      Resolve this by adding a new key_type. This key type is essentially
      the same as key_type_user, but does not define a .read op. This
      prevents the payload from ever being visible from userspace. This
      key type also vets the description to ensure that it's "qualified"
      by checking to ensure that it has a ':' in it that is preceded by
      other characters.
      Acked-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJeff Layton <jlayton@redhat.com>
      Signed-off-by: NSteve French <smfrench@gmail.com>
      9f6ed2ca
  18. 17 11月, 2011 1 次提交
  19. 23 8月, 2011 3 次提交
    • D
      KEYS: Correctly destroy key payloads when their keytype is removed · 0c061b57
      David Howells 提交于
      unregister_key_type() has code to mark a key as dead and make it unavailable in
      one loop and then destroy all those unavailable key payloads in the next loop.
      However, the loop to mark keys dead renders the key undetectable to the second
      loop by changing the key type pointer also.
      
      Fix this by the following means:
      
       (1) The key code has two garbage collectors: one deletes unreferenced keys and
           the other alters keyrings to delete links to old dead, revoked and expired
           keys.  They can end up holding each other up as both want to scan the key
           serial tree under spinlock.  Combine these into a single routine.
      
       (2) Move the dead key marking, dead link removal and dead key removal into the
           garbage collector as a three phase process running over the three cycles
           of the normal garbage collection procedure.  This is tracked by the
           KEY_GC_REAPING_DEAD_1, _2 and _3 state flags.
      
           unregister_key_type() then just unlinks the key type from the list, wakes
           up the garbage collector and waits for the third phase to complete.
      
       (3) Downgrade the key types sem in unregister_key_type() once it has deleted
           the key type from the list so that it doesn't block the keyctl() syscall.
      
       (4) Dead keys that cannot be simply removed in the third phase have their
           payloads destroyed with the key's semaphore write-locked to prevent
           interference by the keyctl() syscall.  There should be no in-kernel users
           of dead keys of that type by the point of unregistration, though keyctl()
           may be holding a reference.
      
       (5) Only perform timer recalculation in the GC if the timer actually expired.
           If it didn't, we'll get another cycle when it goes off - and if the key
           that actually triggered it has been removed, it's not a problem.
      
       (6) Only garbage collect link if the timer expired or if we're doing dead key
           clean up phase 2.
      
       (7) As only key_garbage_collector() is permitted to use rb_erase() on the key
           serial tree, it doesn't need to revalidate its cursor after dropping the
           spinlock as the node the cursor points to must still exist in the tree.
      
       (8) Drop the spinlock in the GC if there is contention on it or if we need to
           reschedule.  After dealing with that, get the spinlock again and resume
           scanning.
      
      This has been tested in the following ways:
      
       (1) Run the keyutils testsuite against it.
      
       (2) Using the AF_RXRPC and RxKAD modules to test keytype removal:
      
           Load the rxrpc_s key type:
      
      	# insmod /tmp/af-rxrpc.ko
      	# insmod /tmp/rxkad.ko
      
           Create a key (http://people.redhat.com/~dhowells/rxrpc/listen.c):
      
      	# /tmp/listen &
      	[1] 8173
      
           Find the key:
      
      	# grep rxrpc_s /proc/keys
      	091086e1 I--Q--     1 perm 39390000     0     0 rxrpc_s   52:2
      
           Link it to a session keyring, preferably one with a higher serial number:
      
      	# keyctl link 0x20e36251 @s
      
           Kill the process (the key should remain as it's linked to another place):
      
      	# fg
      	/tmp/listen
      	^C
      
           Remove the key type:
      
      	rmmod rxkad
      	rmmod af-rxrpc
      
           This can be made a more effective test by altering the following part of
           the patch:
      
      	if (unlikely(gc_state & KEY_GC_REAPING_DEAD_2)) {
      		/* Make sure everyone revalidates their keys if we marked a
      		 * bunch as being dead and make sure all keyring ex-payloads
      		 * are destroyed.
      		 */
      		kdebug("dead sync");
      		synchronize_rcu();
      
           To call synchronize_rcu() in GC phase 1 instead.  That causes that the
           keyring's old payload content to hang around longer until it's RCU
           destroyed - which usually happens after GC phase 3 is complete.  This
           allows the destroy_dead_key branch to be tested.
      Reported-by: NBenjamin Coddington <bcodding@gmail.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      0c061b57
    • D
      KEYS: Make the key reaper non-reentrant · b072e9bc
      David Howells 提交于
      Make the key reaper non-reentrant by sticking it on the appropriate system work
      queue when we queue it.  This will allow it to have global state and drop
      locks.  It should probably be non-reentrant already as it may spend a long time
      holding the key serial spinlock, and so multiple entrants can spend long
      periods of time just sitting there spinning, waiting to get the lock.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      b072e9bc
    • D
      KEYS: Move the unreferenced key reaper to the keys garbage collector file · 8bc16dea
      David Howells 提交于
      Move the unreferenced key reaper function to the keys garbage collector file
      as that's a more appropriate place with the dead key link reaper.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      8bc16dea
  20. 08 3月, 2011 2 次提交
  21. 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
  22. 22 1月, 2011 2 次提交
  23. 06 5月, 2010 1 次提交
  24. 23 4月, 2010 1 次提交
  25. 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
  26. 02 9月, 2009 3 次提交
  27. 27 2月, 2009 1 次提交
  28. 14 11月, 2008 1 次提交
    • 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