1. 19 1月, 2012 1 次提交
  2. 18 1月, 2012 3 次提交
  3. 17 11月, 2011 3 次提交
  4. 16 11月, 2011 1 次提交
    • D
      KEYS: Fix a NULL pointer deref in the user-defined key type · 9f35a33b
      David Howells 提交于
      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: NDavid Howells <dhowells@redhat.com>
      Acked-by: NJeff Layton <jlayton@redhat.com>
      Acked-by: NNeil Horman <nhorman@redhat.com>
      Acked-by: NSteve Dickson <steved@redhat.com>
      Acked-by: NJames Morris <jmorris@namei.org>
      Cc: stable@kernel.org
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      9f35a33b
  5. 01 11月, 2011 2 次提交
    • A
      security: follow rename pack_hex_byte() to hex_byte_pack() · 02473119
      Andy Shevchenko 提交于
      There is no functional change.
      Signed-off-by: NAndy Shevchenko <andriy.shevchenko@linux.intel.com>
      Cc: Mimi Zohar <zohar@us.ibm.com>
      Cc: James Morris <jmorris@namei.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      02473119
    • C
      Cross Memory Attach · fcf63409
      Christopher Yeoh 提交于
      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.tgzSigned-off-by: NChris 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: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      fcf63409
  6. 21 9月, 2011 2 次提交
  7. 16 9月, 2011 1 次提交
  8. 15 9月, 2011 2 次提交
  9. 23 8月, 2011 7 次提交
    • 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: The dead key link reaper should be non-reentrant · d199798b
      David Howells 提交于
      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: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      d199798b
    • 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
    • D
      KEYS: __key_link() should use the RCU deref wrapper for keyring payloads · 6d528b08
      David Howells 提交于
      __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: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      6d528b08
    • D
      KEYS: keyctl_get_keyring_ID() should create a session keyring if create flag set · 3ecf1b4f
      David Howells 提交于
      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: NGreg Wettstein <greg@enjellic.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NGreg Wettstein <greg@enjellic.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      3ecf1b4f
    • D
      KEYS: If install_session_keyring() is given a keyring, it should install it · 99599537
      David Howells 提交于
      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 d84f4f99
      	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: NGreg Wettstein <greg@enjellic.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Tested-by: NGreg Wettstein <greg@enjellic.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      99599537
  10. 09 7月, 2011 1 次提交
  11. 27 6月, 2011 5 次提交
  12. 22 6月, 2011 1 次提交
    • D
      KEYS: Fix error handling in construct_key_and_link() · b1d7dd80
      David Howells 提交于
      Fix error handling in construct_key_and_link().
      
      If construct_alloc_key() returns an error, it shouldn't pass out through
      the normal path as the key_serial() called by the kleave() statement
      will oops when it gets an error code in the pointer:
      
        BUG: unable to handle kernel paging request at ffffffffffffff84
        IP: [<ffffffff8120b401>] request_key_and_link+0x4d7/0x52f
        ..
        Call Trace:
         [<ffffffff8120b52c>] request_key+0x41/0x75
         [<ffffffffa00ed6e8>] cifs_get_spnego_key+0x206/0x226 [cifs]
         [<ffffffffa00eb0c9>] CIFS_SessSetup+0x511/0x1234 [cifs]
         [<ffffffffa00d9799>] cifs_setup_session+0x90/0x1ae [cifs]
         [<ffffffffa00d9c02>] cifs_get_smb_ses+0x34b/0x40f [cifs]
         [<ffffffffa00d9e05>] cifs_mount+0x13f/0x504 [cifs]
         [<ffffffffa00caabb>] cifs_do_mount+0xc4/0x672 [cifs]
         [<ffffffff8113ae8c>] mount_fs+0x69/0x155
         [<ffffffff8114ff0e>] vfs_kern_mount+0x63/0xa0
         [<ffffffff81150be2>] do_kern_mount+0x4d/0xdf
         [<ffffffff81152278>] do_mount+0x63c/0x69f
         [<ffffffff8115255c>] sys_mount+0x88/0xc2
         [<ffffffff814fbdc2>] system_call_fastpath+0x16/0x1b
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NJeff Layton <jlayton@redhat.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      b1d7dd80
  13. 18 6月, 2011 1 次提交
    • D
      KEYS/DNS: Fix ____call_usermodehelper() to not lose the session keyring · 87966996
      David Howells 提交于
      ____call_usermodehelper() now erases any credentials set by the
      subprocess_inf::init() function.  The problem is that commit
      17f60a7d ("capabilites: allow the application of capability limits
      to usermode helpers") creates and commits new credentials with
      prepare_kernel_cred() after the call to the init() function.  This wipes
      all keyrings after umh_keys_init() is called.
      
      The best way to deal with this is to put the init() call just prior to
      the commit_creds() call, and pass the cred pointer to init().  That
      means that umh_keys_init() and suchlike can modify the credentials
      _before_ they are published and potentially in use by the rest of the
      system.
      
      This prevents request_key() from working as it is prevented from passing
      the session keyring it set up with the authorisation token to
      /sbin/request-key, and so the latter can't assume the authority to
      instantiate the key.  This causes the in-kernel DNS resolver to fail
      with ENOKEY unconditionally.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NEric Paris <eparis@redhat.com>
      Tested-by: NJeff Layton <jlayton@redhat.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      87966996
  14. 14 6月, 2011 1 次提交
  15. 27 5月, 2011 1 次提交
  16. 20 5月, 2011 1 次提交
    • R
      Create Documentation/security/, · d410fa4e
      Randy Dunlap 提交于
      move LSM-, credentials-, and keys-related files from Documentation/
        to Documentation/security/,
      add Documentation/security/00-INDEX, and
      update all occurrences of Documentation/<moved_file>
        to Documentation/security/<moved_file>.
      d410fa4e
  17. 08 5月, 2011 1 次提交
  18. 17 3月, 2011 2 次提交
    • D
      KEYS: Make request_key() and co. return an error for a negative key · 4aab1e89
      David Howells 提交于
      Make request_key() and co. return an error for a negative or rejected key.  If
      the key was simply negated, then return ENOKEY, otherwise return the error
      with which it was rejected.
      
      Without this patch, the following command returns a key number (with the latest
      keyutils):
      
      	[root@andromeda ~]# keyctl request2 user debug:foo rejected @s
      	586569904
      
      Trying to print the key merely gets you a permission denied error:
      
      	[root@andromeda ~]# keyctl print 586569904
      	keyctl_read_alloc: Permission denied
      
      Doing another request_key() call does get you the error, as long as it hasn't
      expired yet:
      
      	[root@andromeda ~]# keyctl request user debug:foo
      	request_key: Key was rejected by service
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      4aab1e89
    • 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
  19. 08 3月, 2011 4 次提交