Commit Graph

220 Commits

Author SHA1 Message Date
David Howells
b404aef72f KEYS: Don't check for NULL key pointer in key_validate()
Don't bother checking for NULL key pointer in key_validate() as all of the
places that call it will crash anyway if the relevant key pointer is NULL by
the time they call key_validate().  Therefore, the checking must be done prior
to calling here.

Whilst we're at it, simplify the key_validate() function a bit and mark its
argument const.

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: James Morris <james.l.morris@oracle.com>
2012-05-16 00:54:33 +10:00
David Howells
fd75815f72 KEYS: Add invalidation support
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: David Howells <dhowells@redhat.com>
2012-05-11 10:56:56 +01:00
David Howells
31d5a79d7f KEYS: Do LRU discard in full keyrings
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: David Howells <dhowells@redhat.com>
2012-05-11 10:56:56 +01:00
David Howells
233e4735f2 KEYS: Permit in-place link replacement in keyring list
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: David Howells <dhowells@redhat.com>
2012-05-11 10:56:56 +01:00
David Howells
65d87fe68a KEYS: Perform RCU synchronisation on keys prior to key destruction
Make the keys garbage collector invoke synchronize_rcu() prior to destroying
keys with a zero usage count.  This means that a key can be examined under the
RCU read lock in the safe knowledge that it won't get deallocated until after
the lock is released - even if its usage count becomes zero whilst we're
looking at it.

This is useful in keyring search vs key link.  Consider a keyring containing a
link to a key.  That link can be replaced in-place in the keyring without
requiring an RCU copy-and-replace on the keyring contents without breaking a
search underway on that keyring when the displaced key is released, provided
the key is actually destroyed only after the RCU read lock held by the search
algorithm is released.

This permits __key_link() to replace a key without having to reallocate the key
payload.  A key gets replaced if a new key being linked into a keyring has the
same type and description.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Jeff Layton <jlayton@redhat.com>
2012-05-11 10:56:56 +01:00
David Howells
1eb1bcf5bf KEYS: Announce key type (un)registration
Announce the (un)registration of a key type in the core key code rather than
in the callers.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Mimi Zohar <zohar@us.ibm.com>
2012-05-11 10:56:56 +01:00
David Howells
9f7ce8e249 KEYS: Reorganise keys Makefile
Reorganise the keys directory Makefile to put all the core bits together and
the type-specific bits after.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Mimi Zohar <zohar@us.ibm.com>
2012-05-11 10:56:56 +01:00
David Howells
f0894940ae KEYS: Move the key config into security/keys/Kconfig
Move the key config into security/keys/Kconfig as there are going to be a lot
of key-related options.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Mimi Zohar <zohar@us.ibm.com>
2012-05-11 10:56:56 +01:00
Oleg Nesterov
9d944ef32e usermodehelper: kill umh_wait, renumber UMH_* constants
No functional changes.  It is not sane to use UMH_KILLABLE with enum
umh_wait, but obviously we do not want another argument in
call_usermodehelper_* helpers.  Kill this enum, use the plain int.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Tejun Heo <tj@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-03-23 16:58:41 -07:00
Linus Torvalds
f63d395d47 NFS client updates for Linux 3.4
New features include:
 - Add NFS client support for containers.
   This should enable most of the necessary functionality, including
   lockd support, and support for rpc.statd, NFSv4 idmapper and
   RPCSEC_GSS upcalls into the correct network namespace from
   which the mount system call was issued.
 - NFSv4 idmapper scalability improvements
   Base the idmapper cache on the keyring interface to allow concurrent
   access to idmapper entries. Start the process of migrating users from
   the single-threaded daemon-based approach to the multi-threaded
   request-key based approach.
 - NFSv4.1 implementation id.
   Allows the NFSv4.1 client and server to mutually identify each other
   for logging and debugging purposes.
 - Support the 'vers=4.1' mount option for mounting NFSv4.1 instead of
   having to use the more counterintuitive 'vers=4,minorversion=1'.
 - SUNRPC tracepoints.
   Start the process of adding tracepoints in order to improve debugging
   of the RPC layer.
 - pNFS object layout support for autologin.
 
 Important bugfixes include:
 - Fix a bug in rpc_wake_up/rpc_wake_up_status that caused them to fail
   to wake up all tasks when applied to priority waitqueues.
 - Ensure that we handle read delegations correctly, when we try to
   truncate a file.
 - A number of fixes for NFSv4 state manager loops (mostly to do with
   delegation recovery).
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iQIcBAABAgAGBQJPalZbAAoJEGcL54qWCgDyCi4P+QHcmzQhJO7HWx3Pzjs67bFT
 xMSYaKHGWS4AJKUBVl5OKBxUExfrMHBNbElV3IKUIwBlDx8RVtnwfptKSe146iki
 dn4TrRO5es8nmI4hRDcGMlzJDZq4y0Qg//qiUFmojiNW/Avw0ljfMoVUejJJ09FV
 oeDk4EGtcxkEyH+g48ZjYbyspRnG8qtD3atf70Z3lYE0ELdG/B5Dyzw1RDrA5p73
 xJX3lqy8p/4ROzw/dmNoxdAXOrr3Q4/T58Bvp/lUglPy/EHyPmWzFoH0MU0C/PFu
 5VnAl6QDbNCTcIw9FvJlX/mIyErpNG9eKzUskUc9L9SA+B+J/i4rIap4KATRN3nH
 7QhE5qUacPuJnvxml7MPmlQTuft3fkAQ7NhKIWrbRi1QS9FmJC5NxctIb8loqlFn
 yIXdKeLfMshB+NyuFS9uzStX7SmV3eMgVd+5ZxRjYxm+PKJLw2KXeudArL6M5mHK
 3QeKZpqwaYQ3RfaTNpvAp0doiXHCO5UbWfI0Pe8xQs/QcMCNReffqV2G4IJKFAu6
 WpoN2UDQC9LCBifLw2nS7kku8+ZVXLQU8OC1NVl3TG15xD9cNLXuk3/y5llPGq4O
 odo52uLFpJohbDaHMj5RTKOfchTQCm2iyuVmxZEeAySypMSiAXmW7COSKHs/HxI1
 VBm+EI00Pvmm5+fUjIlp
 =LuHE
 -----END PGP SIGNATURE-----

Merge tag 'nfs-for-3.4-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client updates for Linux 3.4 from Trond Myklebust:
 "New features include:
   - Add NFS client support for containers.

     This should enable most of the necessary functionality, including
     lockd support, and support for rpc.statd, NFSv4 idmapper and
     RPCSEC_GSS upcalls into the correct network namespace from which
     the mount system call was issued.

   - NFSv4 idmapper scalability improvements

     Base the idmapper cache on the keyring interface to allow
     concurrent access to idmapper entries.  Start the process of
     migrating users from the single-threaded daemon-based approach to
     the multi-threaded request-key based approach.

   - NFSv4.1 implementation id.

     Allows the NFSv4.1 client and server to mutually identify each
     other for logging and debugging purposes.

   - Support the 'vers=4.1' mount option for mounting NFSv4.1 instead of
     having to use the more counterintuitive 'vers=4,minorversion=1'.

   - SUNRPC tracepoints.

     Start the process of adding tracepoints in order to improve
     debugging of the RPC layer.

   - pNFS object layout support for autologin.

  Important bugfixes include:

   - Fix a bug in rpc_wake_up/rpc_wake_up_status that caused them to
     fail to wake up all tasks when applied to priority waitqueues.

   - Ensure that we handle read delegations correctly, when we try to
     truncate a file.

   - A number of fixes for NFSv4 state manager loops (mostly to do with
     delegation recovery)."

* tag 'nfs-for-3.4-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (224 commits)
  NFS: fix sb->s_id in nfs debug prints
  xprtrdma: Remove assumption that each segment is <= PAGE_SIZE
  xprtrdma: The transport should not bug-check when a dup reply is received
  pnfs-obj: autologin: Add support for protocol autologin
  NFS: Remove nfs4_setup_sequence from generic rename code
  NFS: Remove nfs4_setup_sequence from generic unlink code
  NFS: Remove nfs4_setup_sequence from generic read code
  NFS: Remove nfs4_setup_sequence from generic write code
  NFS: Fix more NFS debug related build warnings
  SUNRPC/LOCKD: Fix build warnings when CONFIG_SUNRPC_DEBUG is undefined
  nfs: non void functions must return a value
  SUNRPC: Kill compiler warning when RPC_DEBUG is unset
  SUNRPC/NFS: Add Kbuild dependencies for NFS_DEBUG/RPC_DEBUG
  NFS: Use cond_resched_lock() to reduce latencies in the commit scans
  NFSv4: It is not safe to dereference lsp->ls_state in release_lockowner
  NFS: ncommit count is being double decremented
  SUNRPC: We must not use list_for_each_entry_safe() in rpc_wake_up()
  Try using machine credentials for RENEW calls
  NFSv4.1: Fix a few issues in filelayout_commit_pagelist
  NFSv4.1: Clean ups and bugfixes for the pNFS read/writeback/commit code
  ...
2012-03-23 08:53:47 -07:00
Dan Carpenter
f67dabbdde KEYS: testing wrong bit for KEY_FLAG_REVOKED
The test for "if (cred->request_key_auth->flags & KEY_FLAG_REVOKED) {"
should actually testing that the (1 << KEY_FLAG_REVOKED) bit is set.
The current code actually checks for KEY_FLAG_DEAD.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <james.l.morris@oracle.com>
2012-03-07 11:12:06 +11:00
Bryan Schumaker
59e6b9c113 Created a function for setting timeouts on keys
The keyctl_set_timeout function isn't exported to other parts of the
kernel, but I want to use it for the NFS idmapper.  I already have the
key, but I wanted a generic way to set the timeout.

Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2012-03-01 16:50:31 -05:00
James Morris
9e3ff38647 Merge branch 'next-queue' into next 2012-02-09 17:02:34 +11:00
Linus Torvalds
7908b3ef68 Merge git://git.samba.org/sfrench/cifs-2.6
* git://git.samba.org/sfrench/cifs-2.6:
  CIFS: Rename *UCS* functions to *UTF16*
  [CIFS] ACL and FSCACHE support no longer EXPERIMENTAL
  [CIFS] Fix build break with multiuser patch when LANMAN disabled
  cifs: warn about impending deprecation of legacy MultiuserMount code
  cifs: fetch credentials out of keyring for non-krb5 auth multiuser mounts
  cifs: sanitize username handling
  keys: add a "logon" key type
  cifs: lower default wsize when unix extensions are not used
  cifs: better instrumentation for coalesce_t2
  cifs: integer overflow in parse_dacl()
  cifs: Fix sparse warning when calling cifs_strtoUCS
  CIFS: Add descriptions to the brlock cache functions
2012-01-23 08:59:49 -08:00
Mimi Zohar
f6b24579d0 keys: fix user_defined key sparse messages
Replace the rcu_assign_pointer() calls with rcu_assign_keypointer().

Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>
2012-01-19 16:16:29 +11:00
David Howells
700920eb5b KEYS: Allow special keyrings to be cleared
The kernel contains some special internal keyrings, for instance the DNS
resolver keyring :

2a93faf1 I-----     1 perm 1f030000     0     0 keyring   .dns_resolver: empty

It would occasionally be useful to allow the contents of such keyrings to be
flushed by root (cache invalidation).

Allow a flag to be set on a keyring to mark that someone possessing the
sysadmin capability can clear the keyring, even without normal write access to
the keyring.

Set this flag on the special keyrings created by the DNS resolver, the NFS
identity mapper and the CIFS identity mapper.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Jeff Layton <jlayton@redhat.com>
Acked-by: Steve Dickson <steved@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>
2012-01-19 14:38:51 +11:00
Jeff Layton
9f6ed2ca25 keys: add a "logon" key type
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: David Howells <dhowells@redhat.com>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <smfrench@gmail.com>
2012-01-17 22:39:40 -06:00
Mimi Zohar
6ac6172a93 encrypted-keys: fix rcu and sparse messages
Enabling CONFIG_PROVE_RCU and CONFIG_SPARSE_RCU_POINTER resulted in
"suspicious rcu_dereference_check() usage!" and "incompatible types
in comparison expression (different address spaces)" messages.

Access the masterkey directly when holding the rwsem.

Changelog v1:
- Use either rcu_read_lock()/rcu_derefence_key()/rcu_read_unlock()
or remove the unnecessary rcu_derefence() - David Howells

Reported-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>
2012-01-18 10:41:30 +11:00
Mimi Zohar
ee0b31a25a keys: fix trusted/encrypted keys sparse rcu_assign_pointer messages
Define rcu_assign_keypointer(), which uses the key payload.rcudata instead
of payload.data, to resolve the CONFIG_SPARSE_RCU_POINTER message:
"incompatible types in comparison expression (different address spaces)"

Replace the rcu_assign_pointer() calls in encrypted/trusted keys with
rcu_assign_keypointer().

Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>
2012-01-18 10:41:29 +11:00
David Howells
efde8b6e16 KEYS: Add missing smp_rmb() primitives to the keyring search code
Add missing smp_rmb() primitives to the keyring search code.

When keyring payloads are appended to without replacement (thus using up spare
slots in the key pointer array), an smp_wmb() is issued between the pointer
assignment and the increment of the key count (nkeys).

There should be corresponding read barriers between the read of nkeys and
dereferences of keys[n] when n is dependent on the value of nkeys.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
2012-01-18 10:41:27 +11:00
James Morris
8fcc995495 Merge branch 'next' into for-linus
Conflicts:
	security/integrity/evm/evm_crypto.c

Resolved upstream fix vs. next conflict manually.

Signed-off-by: James Morris <jmorris@namei.org>
2012-01-09 12:16:48 +11:00
David Howells
7845bc3964 KEYS: Give key types their own lockdep class for key->sem
Give keys their own lockdep class to differentiate them from each other in case
a key of one type has to refer to a key of another type.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Mimi Zohar <zohar@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
2011-11-17 09:35:32 +11:00
Mimi Zohar
9c69898783 encrypted-keys: module build fixes
Encrypted keys are encrypted/decrypted using either a trusted or
user-defined key type, which is referred to as the 'master' key.
The master key may be of type trusted iff the trusted key is
builtin or both the trusted key and encrypted keys are built as
modules.  This patch resolves the build dependency problem.

- Use "masterkey-$(CONFIG_TRUSTED_KEYS)-$(CONFIG_ENCRYPTED_KEYS)" construct
to encapsulate the above logic. (Suggested by Dimtry Kasatkin.)
- Fixing the encrypted-keys Makefile, results in a module name change
from encrypted.ko to encrypted-keys.ko.
- Add module dependency for request_trusted_key() definition

Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
2011-11-16 14:23:14 -05:00
Mimi Zohar
f4a0d5abef encrypted-keys: fix error return code
Fix request_master_key() error return code.

Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
2011-11-16 14:23:13 -05:00
David Howells
9f35a33b8d KEYS: Fix a NULL pointer deref in the user-defined key type
Fix a NULL pointer deref in the user-defined key type whereby updating a
negative key into a fully instantiated key will cause an oops to occur
when the code attempts to free the non-existent old payload.

This results in an oops that looks something like the following:

  BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
  IP: [<ffffffff81085fa1>] __call_rcu+0x11/0x13e
  PGD 3391d067 PUD 3894a067 PMD 0
  Oops: 0002 [#1] SMP
  CPU 1
  Pid: 4354, comm: keyctl Not tainted 3.1.0-fsdevel+ #1140                  /DG965RY
  RIP: 0010:[<ffffffff81085fa1>]  [<ffffffff81085fa1>] __call_rcu+0x11/0x13e
  RSP: 0018:ffff88003d591df8  EFLAGS: 00010246
  RAX: 0000000000000000 RBX: 0000000000000000 RCX: 000000000000006e
  RDX: ffffffff8161d0c0 RSI: 0000000000000000 RDI: 0000000000000000
  RBP: ffff88003d591e18 R08: 0000000000000000 R09: ffffffff8152fa6c
  R10: 0000000000000000 R11: 0000000000000300 R12: ffff88003b8f9538
  R13: ffffffff8161d0c0 R14: ffff88003b8f9d50 R15: ffff88003c69f908
  FS:  00007f97eb18c720(0000) GS:ffff88003bd00000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 0000000000000008 CR3: 000000003d47a000 CR4: 00000000000006e0
  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
  DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
  Process keyctl (pid: 4354, threadinfo ffff88003d590000, task ffff88003c78a040)
  Stack:
   ffff88003e0ffde0 ffff88003b8f9538 0000000000000001 ffff88003b8f9d50
   ffff88003d591e28 ffffffff810860f0 ffff88003d591e68 ffffffff8117bfea
   ffff88003d591e68 ffffffff00000000 ffff88003e0ffde1 ffff88003e0ffde0
  Call Trace:
   [<ffffffff810860f0>] call_rcu_sched+0x10/0x12
   [<ffffffff8117bfea>] user_update+0x8d/0xa2
   [<ffffffff8117723a>] key_create_or_update+0x236/0x270
   [<ffffffff811789b1>] sys_add_key+0x123/0x17e
   [<ffffffff813b84bb>] system_call_fastpath+0x16/0x1b

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Jeff Layton <jlayton@redhat.com>
Acked-by: Neil Horman <nhorman@redhat.com>
Acked-by: Steve Dickson <steved@redhat.com>
Acked-by: James Morris <jmorris@namei.org>
Cc: stable@kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2011-11-15 22:32:38 -02:00
Andy Shevchenko
02473119bc security: follow rename pack_hex_byte() to hex_byte_pack()
There is no functional change.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Mimi Zohar <zohar@us.ibm.com>
Cc: James Morris <jmorris@namei.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2011-10-31 17:30:56 -07:00
Christopher Yeoh
fcf634098c Cross Memory Attach
The basic idea behind cross memory attach is to allow MPI programs doing
intra-node communication to do a single copy of the message rather than a
double copy of the message via shared memory.

The following patch attempts to achieve this by allowing a destination
process, given an address and size from a source process, to copy memory
directly from the source process into its own address space via a system
call.  There is also a symmetrical ability to copy from the current
process's address space into a destination process's address space.

- Use of /proc/pid/mem has been considered, but there are issues with
  using it:
  - Does not allow for specifying iovecs for both src and dest, assuming
    preadv or pwritev was implemented either the area read from or
  written to would need to be contiguous.
  - Currently mem_read allows only processes who are currently
  ptrace'ing the target and are still able to ptrace the target to read
  from the target. This check could possibly be moved to the open call,
  but its not clear exactly what race this restriction is stopping
  (reason  appears to have been lost)
  - Having to send the fd of /proc/self/mem via SCM_RIGHTS on unix
  domain socket is a bit ugly from a userspace point of view,
  especially when you may have hundreds if not (eventually) thousands
  of processes  that all need to do this with each other
  - Doesn't allow for some future use of the interface we would like to
  consider adding in the future (see below)
  - Interestingly reading from /proc/pid/mem currently actually
  involves two copies! (But this could be fixed pretty easily)

As mentioned previously use of vmsplice instead was considered, but has
problems.  Since you need the reader and writer working co-operatively if
the pipe is not drained then you block.  Which requires some wrapping to
do non blocking on the send side or polling on the receive.  In all to all
communication it requires ordering otherwise you can deadlock.  And in the
example of many MPI tasks writing to one MPI task vmsplice serialises the
copying.

There are some cases of MPI collectives where even a single copy interface
does not get us the performance gain we could.  For example in an
MPI_Reduce rather than copy the data from the source we would like to
instead use it directly in a mathops (say the reduce is doing a sum) as
this would save us doing a copy.  We don't need to keep a copy of the data
from the source.  I haven't implemented this, but I think this interface
could in the future do all this through the use of the flags - eg could
specify the math operation and type and the kernel rather than just
copying the data would apply the specified operation between the source
and destination and store it in the destination.

Although we don't have a "second user" of the interface (though I've had
some nibbles from people who may be interested in using it for intra
process messaging which is not MPI).  This interface is something which
hardware vendors are already doing for their custom drivers to implement
fast local communication.  And so in addition to this being useful for
OpenMPI it would mean the driver maintainers don't have to fix things up
when the mm changes.

There was some discussion about how much faster a true zero copy would
go. Here's a link back to the email with some testing I did on that:

http://marc.info/?l=linux-mm&m=130105930902915&w=2

There is a basic man page for the proposed interface here:

http://ozlabs.org/~cyeoh/cma/process_vm_readv.txt

This has been implemented for x86 and powerpc, other architecture should
mainly (I think) just need to add syscall numbers for the process_vm_readv
and process_vm_writev. There are 32 bit compatibility versions for
64-bit kernels.

For arch maintainers there are some simple tests to be able to quickly
verify that the syscalls are working correctly here:

http://ozlabs.org/~cyeoh/cma/cma-test-20110718.tgz

Signed-off-by: Chris Yeoh <yeohc@au1.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: James Morris <jmorris@namei.org>
Cc: <linux-man@vger.kernel.org>
Cc: <linux-arch@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2011-10-31 17:30:44 -07:00
Mimi Zohar
2b3ff6319e encrypted-keys: check hex2bin result
For each hex2bin call in encrypted keys, check that the ascii hex string
is valid.  On failure, return -EINVAL.

Changelog v1:
- hex2bin now returns an int

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
2011-09-20 23:26:44 -04:00
Mimi Zohar
2684bf7f29 trusted-keys: check hex2bin result
For each hex2bin call in trusted keys, check that the ascii hex string is
valid.  On failure, return -EINVAL.

Changelog v1:
- hex2bin now returns an int

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
2011-09-20 23:26:05 -04:00
Stephen Rothwell
cc100551b4 encrypted-keys: IS_ERR need include/err.h
Fixes this build error:

security/keys/encrypted-keys/masterkey_trusted.c: In function 'request_trusted_key':
security/keys/encrypted-keys/masterkey_trusted.c:35:2: error: implicit declaration of function 'IS_ERR'

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
2011-09-15 17:37:24 -04:00
Mimi Zohar
982e617a31 encrypted-keys: remove trusted-keys dependency
Encrypted keys are decrypted/encrypted using either a trusted-key or,
for those systems without a TPM, a user-defined key.  This patch
removes the trusted-keys and TCG_TPM dependencies.

Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
2011-09-14 15:23:49 -04:00
Mimi Zohar
61cf45d019 encrypted-keys: create encrypted-keys directory
Move all files associated with encrypted keys to keys/encrypted-keys.

Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
2011-09-14 15:22:26 -04:00
David Howells
0c061b5707 KEYS: Correctly destroy key payloads when their keytype is removed
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: Benjamin Coddington <bcodding@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>
2011-08-23 09:57:37 +10:00
David Howells
d199798bdf KEYS: The dead key link reaper should be non-reentrant
The dead key link reaper should be non-reentrant as it relies on global state
to keep track of where it's got to when it returns to the work queue manager to
give it some air.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>
2011-08-23 09:57:36 +10:00
David Howells
b072e9bc2f KEYS: Make the key reaper non-reentrant
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: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>
2011-08-23 09:57:36 +10:00
David Howells
8bc16deabc KEYS: Move the unreferenced key reaper to the keys garbage collector file
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: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>
2011-08-23 09:57:36 +10:00
David Howells
6d528b0822 KEYS: __key_link() should use the RCU deref wrapper for keyring payloads
__key_link() should use the RCU deref wrapper rcu_dereference_locked_keyring()
for accessing keyring payloads rather than calling rcu_dereference_protected()
directly.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>
2011-08-23 09:57:34 +10:00
David Howells
3ecf1b4f34 KEYS: keyctl_get_keyring_ID() should create a session keyring if create flag set
The keyctl call:

	keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1)

should create a session keyring if the process doesn't have one of its own
because the create flag argument is set - rather than subscribing to and
returning the user-session keyring as:

	keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0)

will do.

This can be tested by commenting out pam_keyinit in the /etc/pam.d files and
running the following program a couple of times in a row:

	#include <stdio.h>
	#include <stdlib.h>
	#include <keyutils.h>
	int main(int argc, char *argv[])
	{
		key_serial_t uk, usk, sk, nsk;
		uk  = keyctl_get_keyring_ID(KEY_SPEC_USER_KEYRING, 0);
		usk = keyctl_get_keyring_ID(KEY_SPEC_USER_SESSION_KEYRING, 0);
		sk  = keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0);
		nsk = keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1);
		printf("keys: %08x %08x %08x %08x\n", uk, usk, sk, nsk);
		return 0;
	}

Without this patch, I see:

	keys: 3975ddc7 119c0c66 119c0c66 119c0c66
	keys: 3975ddc7 119c0c66 119c0c66 119c0c66

With this patch, I see:

	keys: 2cb4997b 34112878 34112878 17db2ce3
	keys: 2cb4997b 34112878 34112878 39f3c73e

As can be seen, the session keyring starts off the same as the user-session
keyring each time, but with the patch a new session keyring is created when
the create flag is set.

Reported-by: Greg Wettstein <greg@enjellic.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Greg Wettstein <greg@enjellic.com>
Signed-off-by: James Morris <jmorris@namei.org>
2011-08-23 09:57:34 +10:00
David Howells
995995378f KEYS: If install_session_keyring() is given a keyring, it should install it
If install_session_keyring() is given a keyring, it should install it rather
than just creating a new one anyway.  This was accidentally broken in:

	commit d84f4f992c
	Author: David Howells <dhowells@redhat.com>
	Date:   Fri Nov 14 10:39:23 2008 +1100
	Subject: CRED: Inaugurate COW credentials

The impact of that commit is that pam_keyinit no longer works correctly if
'force' isn't specified against a login process. This is because:

	keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0)

now always creates a new session keyring and thus the check whether the session
keyring and the user-session keyring are the same is always false.  This leads
pam_keyinit to conclude that a session keyring is installed and it shouldn't be
revoked by pam_keyinit here if 'revoke' is specified.

Any system that specifies 'force' against pam_keyinit in the PAM configuration
files for login methods (login, ssh, su -l, kdm, etc.) is not affected since
that bypasses the broken check and forces the creation of a new session keyring
anyway (for which the revoke flag is not cleared) - and any subsequent call to
pam_keyinit really does have a session keyring already installed, and so the
check works correctly there.

Reverting to the previous behaviour will cause the kernel to subscribe the
process to the user-session keyring as its session keyring if it doesn't have a
session keyring of its own.  pam_keyinit will detect this and install a new
session keyring anyway (and won't clear the revert flag).

This can be tested by commenting out pam_keyinit in the /etc/pam.d files and
running the following program a couple of times in a row:

	#include <stdio.h>
	#include <stdlib.h>
	#include <keyutils.h>
	int main(int argc, char *argv[])
	{
		key_serial_t uk, usk, sk;
		uk = keyctl_get_keyring_ID(KEY_SPEC_USER_KEYRING, 0);
		usk = keyctl_get_keyring_ID(KEY_SPEC_USER_SESSION_KEYRING, 0);
		sk = keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0);
		printf("keys: %08x %08x %08x\n", uk, usk, sk);
		return 0;
	}

Without the patch, I see:

	keys: 3884e281 24c4dfcf 22825f8e
	keys: 3884e281 24c4dfcf 068772be

With the patch, I see:

	keys: 26be9c83 0e755ce0 0e755ce0
	keys: 26be9c83 0e755ce0 0e755ce0

As can be seen, with the patch, the session keyring is the same as the
user-session keyring each time; without the patch a new session keyring is
generated each time.

Reported-by: Greg Wettstein <greg@enjellic.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Greg Wettstein <greg@enjellic.com>
Signed-off-by: James Morris <jmorris@namei.org>
2011-08-23 09:57:33 +10:00
Linus Torvalds
95b6886526 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6: (54 commits)
  tpm_nsc: Fix bug when loading multiple TPM drivers
  tpm: Move tpm_tis_reenable_interrupts out of CONFIG_PNP block
  tpm: Fix compilation warning when CONFIG_PNP is not defined
  TOMOYO: Update kernel-doc.
  tpm: Fix a typo
  tpm_tis: Probing function for Intel iTPM bug
  tpm_tis: Fix the probing for interrupts
  tpm_tis: Delay ACPI S3 suspend while the TPM is busy
  tpm_tis: Re-enable interrupts upon (S3) resume
  tpm: Fix display of data in pubek sysfs entry
  tpm_tis: Add timeouts sysfs entry
  tpm: Adjust interface timeouts if they are too small
  tpm: Use interface timeouts returned from the TPM
  tpm_tis: Introduce durations sysfs entry
  tpm: Adjust the durations if they are too small
  tpm: Use durations returned from TPM
  TOMOYO: Enable conditional ACL.
  TOMOYO: Allow using argv[]/envp[] of execve() as conditions.
  TOMOYO: Allow using executable's realpath and symlink's target as conditions.
  TOMOYO: Allow using owner/group etc. of file objects as conditions.
  ...

Fix up trivial conflict in security/tomoyo/realpath.c
2011-07-27 19:26:38 -07:00
Jiri Kosina
b7e9c223be Merge branch 'master' into for-next
Sync with Linus' tree to be able to apply pending patches that
are based on newer code already present upstream.
2011-07-11 14:15:55 +02:00
Michal Hocko
d8bf4ca9ca rcu: treewide: Do not use rcu_read_lock_held when calling rcu_dereference_check
Since ca5ecddf (rcu: define __rcu address space modifier for sparse)
rcu_dereference_check use rcu_read_lock_held as a part of condition
automatically so callers do not have to do that as well.

Signed-off-by: Michal Hocko <mhocko@suse.cz>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2011-07-08 22:21:58 +02:00
James Morris
5b944a71a1 Merge branch 'linus' into next 2011-06-30 18:43:56 +10:00
Roberto Sassu
79a73d1887 encrypted-keys: add ecryptfs format support
The 'encrypted' key type defines its own payload format which contains a
symmetric key randomly generated that cannot be used directly to mount
an eCryptfs filesystem, because it expects an authentication token
structure.

This patch introduces the new format 'ecryptfs' that allows to store an
authentication token structure inside the encrypted key payload containing
a randomly generated symmetric key, as the same for the format 'default'.

More details about the usage of encrypted keys with the eCryptfs
filesystem can be found in the file 'Documentation/keys-ecryptfs.txt'.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Acked-by: Gianluca Ramunno <ramunno@polito.it>
Acked-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2011-06-27 09:11:17 -04:00
Roberto Sassu
4e561d388f encrypted-keys: add key format support
This patch introduces a new parameter, called 'format', that defines the
format of data stored by encrypted keys. The 'default' format identifies
encrypted keys containing only the symmetric key, while other formats can
be defined to support additional information. The 'format' parameter is
written in the datablob produced by commands 'keyctl print' or
'keyctl pipe' and is integrity protected by the HMAC.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Acked-by: Gianluca Ramunno <ramunno@polito.it>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2011-06-27 09:10:45 -04:00
Roberto Sassu
7103dff0e5 encrypted-keys: added additional debug messages
Some debug messages have been added in the function datablob_parse() in
order to better identify errors returned when dealing with 'encrypted'
keys.

Changelog from version v4:
- made the debug messages more understandable 

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Acked-by: Gianluca Ramunno <ramunno@polito.it>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2011-06-27 09:10:34 -04:00
Roberto Sassu
08fa2aa54e encrypted-keys: fixed valid_master_desc() function description
Valid key type prefixes for the parameter 'key-type' are: 'trusted' and
'user'.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Acked-by: Gianluca Ramunno <ramunno@polito.it>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2011-06-27 09:08:52 -04:00
Roberto Sassu
f91c2c5cfa encrypted_keys: avoid dumping the master key if the request fails
Do not dump the master key if an error is encountered during the request.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Acked-by: Gianluca Ramunno <ramunno@polito.it>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2011-06-27 09:08:39 -04:00
David Howells
b1d7dd80aa KEYS: Fix error handling in construct_key_and_link()
Fix error handling in construct_key_and_link().

If construct_alloc_key() returns an error, it shouldn't pass out through
the normal path as the key_serial() called by the kleave() statement
will oops when it gets an error code in the pointer:

  BUG: unable to handle kernel paging request at ffffffffffffff84
  IP: [<ffffffff8120b401>] request_key_and_link+0x4d7/0x52f
  ..
  Call Trace:
   [<ffffffff8120b52c>] request_key+0x41/0x75
   [<ffffffffa00ed6e8>] cifs_get_spnego_key+0x206/0x226 [cifs]
   [<ffffffffa00eb0c9>] CIFS_SessSetup+0x511/0x1234 [cifs]
   [<ffffffffa00d9799>] cifs_setup_session+0x90/0x1ae [cifs]
   [<ffffffffa00d9c02>] cifs_get_smb_ses+0x34b/0x40f [cifs]
   [<ffffffffa00d9e05>] cifs_mount+0x13f/0x504 [cifs]
   [<ffffffffa00caabb>] cifs_do_mount+0xc4/0x672 [cifs]
   [<ffffffff8113ae8c>] mount_fs+0x69/0x155
   [<ffffffff8114ff0e>] vfs_kern_mount+0x63/0xa0
   [<ffffffff81150be2>] do_kern_mount+0x4d/0xdf
   [<ffffffff81152278>] do_mount+0x63c/0x69f
   [<ffffffff8115255c>] sys_mount+0x88/0xc2
   [<ffffffff814fbdc2>] system_call_fastpath+0x16/0x1b

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2011-06-21 18:31:45 -07:00
David Howells
879669961b KEYS/DNS: Fix ____call_usermodehelper() to not lose the session keyring
____call_usermodehelper() now erases any credentials set by the
subprocess_inf::init() function.  The problem is that commit
17f60a7da1 ("capabilites: allow the application of capability limits
to usermode helpers") creates and commits new credentials with
prepare_kernel_cred() after the call to the init() function.  This wipes
all keyrings after umh_keys_init() is called.

The best way to deal with this is to put the init() call just prior to
the commit_creds() call, and pass the cred pointer to init().  That
means that umh_keys_init() and suchlike can modify the credentials
_before_ they are published and potentially in use by the rest of the
system.

This prevents request_key() from working as it is prevented from passing
the session keyring it set up with the authorisation token to
/sbin/request-key, and so the latter can't assume the authority to
instantiate the key.  This causes the in-kernel DNS resolver to fail
with ENOKEY unconditionally.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Eric Paris <eparis@redhat.com>
Tested-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2011-06-17 09:40:48 -07:00