1. 14 11月, 2008 7 次提交
    • D
      CRED: Make execve() take advantage of copy-on-write credentials · a6f76f23
      David Howells 提交于
      Make execve() take advantage of copy-on-write credentials, allowing it to set
      up the credentials in advance, and then commit the whole lot after the point
      of no return.
      
      This patch and the preceding patches have been tested with the LTP SELinux
      testsuite.
      
      This patch makes several logical sets of alteration:
      
       (1) execve().
      
           The credential bits from struct linux_binprm are, for the most part,
           replaced with a single credentials pointer (bprm->cred).  This means that
           all the creds can be calculated in advance and then applied at the point
           of no return with no possibility of failure.
      
           I would like to replace bprm->cap_effective with:
      
      	cap_isclear(bprm->cap_effective)
      
           but this seems impossible due to special behaviour for processes of pid 1
           (they always retain their parent's capability masks where normally they'd
           be changed - see cap_bprm_set_creds()).
      
           The following sequence of events now happens:
      
           (a) At the start of do_execve, the current task's cred_exec_mutex is
           	 locked to prevent PTRACE_ATTACH from obsoleting the calculation of
           	 creds that we make.
      
           (a) prepare_exec_creds() is then called to make a copy of the current
           	 task's credentials and prepare it.  This copy is then assigned to
           	 bprm->cred.
      
        	 This renders security_bprm_alloc() and security_bprm_free()
           	 unnecessary, and so they've been removed.
      
           (b) The determination of unsafe execution is now performed immediately
           	 after (a) rather than later on in the code.  The result is stored in
           	 bprm->unsafe for future reference.
      
           (c) prepare_binprm() is called, possibly multiple times.
      
           	 (i) This applies the result of set[ug]id binaries to the new creds
           	     attached to bprm->cred.  Personality bit clearance is recorded,
           	     but now deferred on the basis that the exec procedure may yet
           	     fail.
      
               (ii) This then calls the new security_bprm_set_creds().  This should
      	     calculate the new LSM and capability credentials into *bprm->cred.
      
      	     This folds together security_bprm_set() and parts of
      	     security_bprm_apply_creds() (these two have been removed).
      	     Anything that might fail must be done at this point.
      
               (iii) bprm->cred_prepared is set to 1.
      
      	     bprm->cred_prepared is 0 on the first pass of the security
      	     calculations, and 1 on all subsequent passes.  This allows SELinux
      	     in (ii) to base its calculations only on the initial script and
      	     not on the interpreter.
      
           (d) flush_old_exec() is called to commit the task to execution.  This
           	 performs the following steps with regard to credentials:
      
      	 (i) Clear pdeath_signal and set dumpable on certain circumstances that
      	     may not be covered by commit_creds().
      
               (ii) Clear any bits in current->personality that were deferred from
                   (c.i).
      
           (e) install_exec_creds() [compute_creds() as was] is called to install the
           	 new credentials.  This performs the following steps with regard to
           	 credentials:
      
               (i) Calls security_bprm_committing_creds() to apply any security
                   requirements, such as flushing unauthorised files in SELinux, that
                   must be done before the credentials are changed.
      
      	     This is made up of bits of security_bprm_apply_creds() and
      	     security_bprm_post_apply_creds(), both of which have been removed.
      	     This function is not allowed to fail; anything that might fail
      	     must have been done in (c.ii).
      
               (ii) Calls commit_creds() to apply the new credentials in a single
                   assignment (more or less).  Possibly pdeath_signal and dumpable
                   should be part of struct creds.
      
      	 (iii) Unlocks the task's cred_replace_mutex, thus allowing
      	     PTRACE_ATTACH to take place.
      
               (iv) Clears The bprm->cred pointer as the credentials it was holding
                   are now immutable.
      
               (v) Calls security_bprm_committed_creds() to apply any security
                   alterations that must be done after the creds have been changed.
                   SELinux uses this to flush signals and signal handlers.
      
           (f) If an error occurs before (d.i), bprm_free() will call abort_creds()
           	 to destroy the proposed new credentials and will then unlock
           	 cred_replace_mutex.  No changes to the credentials will have been
           	 made.
      
       (2) LSM interface.
      
           A number of functions have been changed, added or removed:
      
           (*) security_bprm_alloc(), ->bprm_alloc_security()
           (*) security_bprm_free(), ->bprm_free_security()
      
           	 Removed in favour of preparing new credentials and modifying those.
      
           (*) security_bprm_apply_creds(), ->bprm_apply_creds()
           (*) security_bprm_post_apply_creds(), ->bprm_post_apply_creds()
      
           	 Removed; split between security_bprm_set_creds(),
           	 security_bprm_committing_creds() and security_bprm_committed_creds().
      
           (*) security_bprm_set(), ->bprm_set_security()
      
           	 Removed; folded into security_bprm_set_creds().
      
           (*) security_bprm_set_creds(), ->bprm_set_creds()
      
           	 New.  The new credentials in bprm->creds should be checked and set up
           	 as appropriate.  bprm->cred_prepared is 0 on the first call, 1 on the
           	 second and subsequent calls.
      
           (*) security_bprm_committing_creds(), ->bprm_committing_creds()
           (*) security_bprm_committed_creds(), ->bprm_committed_creds()
      
           	 New.  Apply the security effects of the new credentials.  This
           	 includes closing unauthorised files in SELinux.  This function may not
           	 fail.  When the former is called, the creds haven't yet been applied
           	 to the process; when the latter is called, they have.
      
       	 The former may access bprm->cred, the latter may not.
      
       (3) SELinux.
      
           SELinux has a number of changes, in addition to those to support the LSM
           interface changes mentioned above:
      
           (a) The bprm_security_struct struct has been removed in favour of using
           	 the credentials-under-construction approach.
      
           (c) flush_unauthorized_files() now takes a cred pointer and passes it on
           	 to inode_has_perm(), file_has_perm() and dentry_open().
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NJames Morris <jmorris@namei.org>
      Acked-by: NSerge Hallyn <serue@us.ibm.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      a6f76f23
    • D
      CRED: Inaugurate COW credentials · d84f4f99
      David Howells 提交于
      Inaugurate copy-on-write credentials management.  This uses RCU to manage the
      credentials pointer in the task_struct with respect to accesses by other tasks.
      A process may only modify its own credentials, and so does not need locking to
      access or modify its own credentials.
      
      A mutex (cred_replace_mutex) is added to the task_struct to control the effect
      of PTRACE_ATTACHED on credential calculations, particularly with respect to
      execve().
      
      With this patch, the contents of an active credentials struct may not be
      changed directly; rather a new set of credentials must be prepared, modified
      and committed using something like the following sequence of events:
      
      	struct cred *new = prepare_creds();
      	int ret = blah(new);
      	if (ret < 0) {
      		abort_creds(new);
      		return ret;
      	}
      	return commit_creds(new);
      
      There are some exceptions to this rule: the keyrings pointed to by the active
      credentials may be instantiated - keyrings violate the COW rule as managing
      COW keyrings is tricky, given that it is possible for a task to directly alter
      the keys in a keyring in use by another task.
      
      To help enforce this, various pointers to sets of credentials, such as those in
      the task_struct, are declared const.  The purpose of this is compile-time
      discouragement of altering credentials through those pointers.  Once a set of
      credentials has been made public through one of these pointers, it may not be
      modified, except under special circumstances:
      
        (1) Its reference count may incremented and decremented.
      
        (2) The keyrings to which it points may be modified, but not replaced.
      
      The only safe way to modify anything else is to create a replacement and commit
      using the functions described in Documentation/credentials.txt (which will be
      added by a later patch).
      
      This patch and the preceding patches have been tested with the LTP SELinux
      testsuite.
      
      This patch makes several logical sets of alteration:
      
       (1) execve().
      
           This now prepares and commits credentials in various places in the
           security code rather than altering the current creds directly.
      
       (2) Temporary credential overrides.
      
           do_coredump() and sys_faccessat() now prepare their own credentials and
           temporarily override the ones currently on the acting thread, whilst
           preventing interference from other threads by holding cred_replace_mutex
           on the thread being dumped.
      
           This will be replaced in a future patch by something that hands down the
           credentials directly to the functions being called, rather than altering
           the task's objective credentials.
      
       (3) LSM interface.
      
           A number of functions have been changed, added or removed:
      
           (*) security_capset_check(), ->capset_check()
           (*) security_capset_set(), ->capset_set()
      
           	 Removed in favour of security_capset().
      
           (*) security_capset(), ->capset()
      
           	 New.  This is passed a pointer to the new creds, a pointer to the old
           	 creds and the proposed capability sets.  It should fill in the new
           	 creds or return an error.  All pointers, barring the pointer to the
           	 new creds, are now const.
      
           (*) security_bprm_apply_creds(), ->bprm_apply_creds()
      
           	 Changed; now returns a value, which will cause the process to be
           	 killed if it's an error.
      
           (*) security_task_alloc(), ->task_alloc_security()
      
           	 Removed in favour of security_prepare_creds().
      
           (*) security_cred_free(), ->cred_free()
      
           	 New.  Free security data attached to cred->security.
      
           (*) security_prepare_creds(), ->cred_prepare()
      
           	 New. Duplicate any security data attached to cred->security.
      
           (*) security_commit_creds(), ->cred_commit()
      
           	 New. Apply any security effects for the upcoming installation of new
           	 security by commit_creds().
      
           (*) security_task_post_setuid(), ->task_post_setuid()
      
           	 Removed in favour of security_task_fix_setuid().
      
           (*) security_task_fix_setuid(), ->task_fix_setuid()
      
           	 Fix up the proposed new credentials for setuid().  This is used by
           	 cap_set_fix_setuid() to implicitly adjust capabilities in line with
           	 setuid() changes.  Changes are made to the new credentials, rather
           	 than the task itself as in security_task_post_setuid().
      
           (*) security_task_reparent_to_init(), ->task_reparent_to_init()
      
           	 Removed.  Instead the task being reparented to init is referred
           	 directly to init's credentials.
      
      	 NOTE!  This results in the loss of some state: SELinux's osid no
      	 longer records the sid of the thread that forked it.
      
           (*) security_key_alloc(), ->key_alloc()
           (*) security_key_permission(), ->key_permission()
      
           	 Changed.  These now take cred pointers rather than task pointers to
           	 refer to the security context.
      
       (4) sys_capset().
      
           This has been simplified and uses less locking.  The LSM functions it
           calls have been merged.
      
       (5) reparent_to_kthreadd().
      
           This gives the current thread the same credentials as init by simply using
           commit_thread() to point that way.
      
       (6) __sigqueue_alloc() and switch_uid()
      
           __sigqueue_alloc() can't stop the target task from changing its creds
           beneath it, so this function gets a reference to the currently applicable
           user_struct which it then passes into the sigqueue struct it returns if
           successful.
      
           switch_uid() is now called from commit_creds(), and possibly should be
           folded into that.  commit_creds() should take care of protecting
           __sigqueue_alloc().
      
       (7) [sg]et[ug]id() and co and [sg]et_current_groups.
      
           The set functions now all use prepare_creds(), commit_creds() and
           abort_creds() to build and check a new set of credentials before applying
           it.
      
           security_task_set[ug]id() is called inside the prepared section.  This
           guarantees that nothing else will affect the creds until we've finished.
      
           The calling of set_dumpable() has been moved into commit_creds().
      
           Much of the functionality of set_user() has been moved into
           commit_creds().
      
           The get functions all simply access the data directly.
      
       (8) security_task_prctl() and cap_task_prctl().
      
           security_task_prctl() has been modified to return -ENOSYS if it doesn't
           want to handle a function, or otherwise return the return value directly
           rather than through an argument.
      
           Additionally, cap_task_prctl() now prepares a new set of credentials, even
           if it doesn't end up using it.
      
       (9) Keyrings.
      
           A number of changes have been made to the keyrings code:
      
           (a) switch_uid_keyring(), copy_keys(), exit_keys() and suid_keys() have
           	 all been dropped and built in to the credentials functions directly.
           	 They may want separating out again later.
      
           (b) key_alloc() and search_process_keyrings() now take a cred pointer
           	 rather than a task pointer to specify the security context.
      
           (c) copy_creds() gives a new thread within the same thread group a new
           	 thread keyring if its parent had one, otherwise it discards the thread
           	 keyring.
      
           (d) The authorisation key now points directly to the credentials to extend
           	 the search into rather pointing to the task that carries them.
      
           (e) Installing thread, process or session keyrings causes a new set of
           	 credentials to be created, even though it's not strictly necessary for
           	 process or session keyrings (they're shared).
      
      (10) Usermode helper.
      
           The usermode helper code now carries a cred struct pointer in its
           subprocess_info struct instead of a new session keyring pointer.  This set
           of credentials is derived from init_cred and installed on the new process
           after it has been cloned.
      
           call_usermodehelper_setup() allocates the new credentials and
           call_usermodehelper_freeinfo() discards them if they haven't been used.  A
           special cred function (prepare_usermodeinfo_creds()) is provided
           specifically for call_usermodehelper_setup() to call.
      
           call_usermodehelper_setkeys() adjusts the credentials to sport the
           supplied keyring as the new session keyring.
      
      (11) SELinux.
      
           SELinux has a number of changes, in addition to those to support the LSM
           interface changes mentioned above:
      
           (a) selinux_setprocattr() no longer does its check for whether the
           	 current ptracer can access processes with the new SID inside the lock
           	 that covers getting the ptracer's SID.  Whilst this lock ensures that
           	 the check is done with the ptracer pinned, the result is only valid
           	 until the lock is released, so there's no point doing it inside the
           	 lock.
      
      (12) is_single_threaded().
      
           This function has been extracted from selinux_setprocattr() and put into
           a file of its own in the lib/ directory as join_session_keyring() now
           wants to use it too.
      
           The code in SELinux just checked to see whether a task shared mm_structs
           with other tasks (CLONE_VM), but that isn't good enough.  We really want
           to know if they're part of the same thread group (CLONE_THREAD).
      
      (13) nfsd.
      
           The NFS server daemon now has to use the COW credentials to set the
           credentials it is going to use.  It really needs to pass the credentials
           down to the functions it calls, but it can't do that until other patches
           in this series have been applied.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NJames Morris <jmorris@namei.org>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      d84f4f99
    • D
      CRED: Separate per-task-group keyrings from signal_struct · bb952bb9
      David Howells 提交于
      Separate per-task-group keyrings from signal_struct and dangle their anchor
      from the cred struct rather than the signal_struct.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-by: NJames Morris <jmorris@namei.org>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      bb952bb9
    • D
      CRED: Use RCU to access another task's creds and to release a task's own creds · c69e8d9c
      David Howells 提交于
      Use RCU to access another task's creds and to release a task's own creds.
      This means that it will be possible for the credentials of a task to be
      replaced without another task (a) requiring a full lock to read them, and (b)
      seeing deallocated memory.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NJames Morris <jmorris@namei.org>
      Acked-by: NSerge Hallyn <serue@us.ibm.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      c69e8d9c
    • D
      CRED: Wrap current->cred and a few other accessors · 86a264ab
      David Howells 提交于
      Wrap current->cred and a few other accessors to hide their actual
      implementation.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NJames Morris <jmorris@namei.org>
      Acked-by: NSerge Hallyn <serue@us.ibm.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      86a264ab
    • D
      CRED: Separate task security context from task_struct · b6dff3ec
      David Howells 提交于
      Separate the task security context from task_struct.  At this point, the
      security data is temporarily embedded in the task_struct with two pointers
      pointing to it.
      
      Note that the Alpha arch is altered as it refers to (E)UID and (E)GID in
      entry.S via asm-offsets.
      
      With comment fixes Signed-off-by: Marc Dionne <marc.c.dionne@gmail.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Acked-by: NJames Morris <jmorris@namei.org>
      Acked-by: NSerge Hallyn <serue@us.ibm.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      b6dff3ec
    • D
      KEYS: Alter use of key instantiation link-to-keyring argument · 8bbf4976
      David Howells 提交于
      Alter the use of the key instantiation and negation functions' link-to-keyring
      arguments.  Currently this specifies a keyring in the target process to link
      the key into, creating the keyring if it doesn't exist.  This, however, can be
      a problem for copy-on-write credentials as it means that the instantiating
      process can alter the credentials of the requesting process.
      
      This patch alters the behaviour such that:
      
       (1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
           keyring by ID (ringid >= 0), then that keyring will be used.
      
       (2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
           special constants that refer to the requesting process's keyrings
           (KEY_SPEC_*_KEYRING, all <= 0), then:
      
           (a) If sys_request_key() was given a keyring to use (destringid) then the
           	 key will be attached to that keyring.
      
           (b) If sys_request_key() was given a NULL keyring, then the key being
           	 instantiated will be attached to the default keyring as set by
           	 keyctl_set_reqkey_keyring().
      
       (3) No extra link will be made.
      
      Decision point (1) follows current behaviour, and allows those instantiators
      who've searched for a specifically named keyring in the requestor's keyring so
      as to partition the keys by type to still have their named keyrings.
      
      Decision point (2) allows the requestor to make sure that the key or keys that
      get produced by request_key() go where they want, whilst allowing the
      instantiator to request that the key is retained.  This is mainly useful for
      situations where the instantiator makes a secondary request, the key for which
      should be retained by the initial requestor:
      
      	+-----------+        +--------------+        +--------------+
      	|           |        |              |        |              |
      	| Requestor |------->| Instantiator |------->| Instantiator |
      	|           |        |              |        |              |
      	+-----------+        +--------------+        +--------------+
      	           request_key()           request_key()
      
      This might be useful, for example, in Kerberos, where the requestor requests a
      ticket, and then the ticket instantiator requests the TGT, which someone else
      then has to go and fetch.  The TGT, however, should be retained in the
      keyrings of the requestor, not the first instantiator.  To make this explict
      an extra special keyring constant is also added.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-by: NJames Morris <jmorris@namei.org>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      8bbf4976
  2. 29 4月, 2008 1 次提交
    • D
      keys: don't generate user and user session keyrings unless they're accessed · 69664cf1
      David Howells 提交于
      Don't generate the per-UID user and user session keyrings unless they're
      explicitly accessed.  This solves a problem during a login process whereby
      set*uid() is called before the SELinux PAM module, resulting in the per-UID
      keyrings having the wrong security labels.
      
      This also cures the problem of multiple per-UID keyrings sometimes appearing
      due to PAM modules (including pam_keyinit) setuiding and causing user_structs
      to come into and go out of existence whilst the session keyring pins the user
      keyring.  This is achieved by first searching for extant per-UID keyrings
      before inventing new ones.
      
      The serial bound argument is also dropped from find_keyring_by_name() as it's
      not currently made use of (setting it to 0 disables the feature).
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Cc: <kwc@citi.umich.edu>
      Cc: <arunsr@cse.iitk.ac.in>
      Cc: <dwalsh@redhat.com>
      Cc: Stephen Smalley <sds@tycho.nsa.gov>
      Cc: James Morris <jmorris@namei.org>
      Cc: Chris Wright <chrisw@sous-sol.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      69664cf1
  3. 08 2月, 2008 1 次提交
  4. 17 10月, 2007 1 次提交
    • D
      KEYS: Make request_key() and co fundamentally asynchronous · 76181c13
      David Howells 提交于
      Make request_key() and co fundamentally asynchronous to make it easier for
      NFS to make use of them.  There are now accessor functions that do
      asynchronous constructions, a wait function to wait for construction to
      complete, and a completion function for the key type to indicate completion
      of construction.
      
      Note that the construction queue is now gone.  Instead, keys under
      construction are linked in to the appropriate keyring in advance, and that
      anyone encountering one must wait for it to be complete before they can use
      it.  This is done automatically for userspace.
      
      The following auxiliary changes are also made:
      
       (1) Key type implementation stuff is split from linux/key.h into
           linux/key-type.h.
      
       (2) AF_RXRPC provides a way to allocate null rxrpc-type keys so that AFS does
           not need to call key_instantiate_and_link() directly.
      
       (3) Adjust the debugging macros so that they're -Wformat checked even if
           they are disabled, and make it so they can be enabled simply by defining
           __KDEBUG to be consistent with other code of mine.
      
       (3) Documentation.
      
      [alan@lxorguk.ukuu.org.uk: keys: missing word in documentation]
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NAlan Cox <alan@redhat.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      76181c13
  5. 08 12月, 2006 1 次提交
  6. 27 6月, 2006 1 次提交
  7. 23 6月, 2006 2 次提交
    • D
      [PATCH] Keys: Fix race between two instantiators of a key · 04c567d9
      David Howells 提交于
      Add a revocation notification method to the key type and calls it whilst
      the key's semaphore is still write-locked after setting the revocation
      flag.
      
      The patch then uses this to maintain a reference on the task_struct of the
      process that calls request_key() for as long as the authorisation key
      remains unrevoked.
      
      This fixes a potential race between two processes both of which have
      assumed the authority to instantiate a key (one may have forked the other
      for example).  The problem is that there's no locking around the check for
      revocation of the auth key and the use of the task_struct it points to, nor
      does the auth key keep a reference on the task_struct.
      
      Access to the "context" pointer in the auth key must thenceforth be done
      with the auth key semaphore held.  The revocation method is called with the
      target key semaphore held write-locked and the search of the context
      process's keyrings is done with the auth key semaphore read-locked.
      
      The check for the revocation state of the auth key just prior to searching
      it is done after the auth key is read-locked for the search.  This ensures
      that the auth key can't be revoked between the check and the search.
      
      The revocation notification method is added so that the context task_struct
      can be released as soon as instantiation happens rather than waiting for
      the auth key to be destroyed, thus avoiding the unnecessary pinning of the
      requesting process.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      04c567d9
    • M
      [PATCH] selinux: add hooks for key subsystem · d720024e
      Michael LeMay 提交于
      Introduce SELinux hooks to support the access key retention subsystem
      within the kernel.  Incorporate new flask headers from a modified version
      of the SELinux reference policy, with support for the new security class
      representing retained keys.  Extend the "key_alloc" security hook with a
      task parameter representing the intended ownership context for the key
      being allocated.  Attach security information to root's default keyrings
      within the SELinux initialization routine.
      
      Has passed David's testsuite.
      Signed-off-by: NMichael LeMay <mdlemay@epoch.ncsc.mil>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NJames Morris <jmorris@namei.org>
      Acked-by: NChris Wright <chrisw@sous-sol.org>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      d720024e
  8. 11 4月, 2006 1 次提交
  9. 22 3月, 2006 1 次提交
  10. 09 1月, 2006 1 次提交
    • D
      [PATCH] keys: Permit running process to instantiate keys · b5f545c8
      David Howells 提交于
      Make it possible for a running process (such as gssapid) to be able to
      instantiate a key, as was requested by Trond Myklebust for NFS4.
      
      The patch makes the following changes:
      
       (1) A new, optional key type method has been added. This permits a key type
           to intercept requests at the point /sbin/request-key is about to be
           spawned and do something else with them - passing them over the
           rpc_pipefs files or netlink sockets for instance.
      
           The uninstantiated key, the authorisation key and the intended operation
           name are passed to the method.
      
       (2) The callout_info is no longer passed as an argument to /sbin/request-key
           to prevent unauthorised viewing of this data using ps or by looking in
           /proc/pid/cmdline.
      
           This means that the old /sbin/request-key program will not work with the
           patched kernel as it will expect to see an extra argument that is no
           longer there.
      
           A revised keyutils package will be made available tomorrow.
      
       (3) The callout_info is now attached to the authorisation key. Reading this
           key will retrieve the information.
      
       (4) A new field has been added to the task_struct. This holds the
           authorisation key currently active for a thread. Searches now look here
           for the caller's set of keys rather than looking for an auth key in the
           lowest level of the session keyring.
      
           This permits a thread to be servicing multiple requests at once and to
           switch between them. Note that this is per-thread, not per-process, and
           so is usable in multithreaded programs.
      
           The setting of this field is inherited across fork and exec.
      
       (5) A new keyctl function (KEYCTL_ASSUME_AUTHORITY) has been added that
           permits a thread to assume the authority to deal with an uninstantiated
           key. Assumption is only permitted if the authorisation key associated
           with the uninstantiated key is somewhere in the thread's keyrings.
      
           This function can also clear the assumption.
      
       (6) A new magic key specifier has been added to refer to the currently
           assumed authorisation key (KEY_SPEC_REQKEY_AUTH_KEY).
      
       (7) Instantiation will only proceed if the appropriate authorisation key is
           assumed first. The assumed authorisation key is discarded if
           instantiation is successful.
      
       (8) key_validate() is moved from the file of request_key functions to the
           file of permissions functions.
      
       (9) The documentation is updated.
      
      From: <Valdis.Kletnieks@vt.edu>
      
          Build fix.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
      Cc: Alexander Zangerl <az@bond.edu.au>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      b5f545c8
  11. 31 10月, 2005 1 次提交
    • D
      [PATCH] Keys: Add LSM hooks for key management [try #3] · 29db9190
      David Howells 提交于
      The attached patch adds LSM hooks for key management facilities. The notable
      changes are:
      
       (1) The key struct now supports a security pointer for the use of security
           modules. This will permit key labelling and restrictions on which
           programs may access a key.
      
       (2) Security modules get a chance to note (or abort) the allocation of a key.
      
       (3) The key permission checking can now be enhanced by the security modules;
           the permissions check consults LSM if all other checks bear out.
      
       (4) The key permissions checking functions now return an error code rather
           than a boolean value.
      
       (5) An extra permission has been added to govern the modification of
           attributes (UID, GID, permissions).
      
      Note that there isn't an LSM hook specifically for each keyctl() operation,
      but rather the permissions hook allows control of individual operations based
      on the permission request bits.
      
      Key management access control through LSM is enabled by automatically if both
      CONFIG_KEYS and CONFIG_SECURITY are enabled.
      
      This should be applied on top of the patch ensubjected:
      
      	[PATCH] Keys: Possessor permissions should be additive
      Signed-Off-By: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NChris Wright <chrisw@osdl.org>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      29db9190
  12. 29 9月, 2005 1 次提交
    • D
      [PATCH] Keys: Add possessor permissions to keys [try #3] · 664cceb0
      David Howells 提交于
      The attached patch adds extra permission grants to keys for the possessor of a
      key in addition to the owner, group and other permissions bits. This makes
      SUID binaries easier to support without going as far as labelling keys and key
      targets using the LSM facilities.
      
      This patch adds a second "pointer type" to key structures (struct key_ref *)
      that can have the bottom bit of the address set to indicate the possession of
      a key. This is propagated through searches from the keyring to the discovered
      key. It has been made a separate type so that the compiler can spot attempts
      to dereference a potentially incorrect pointer.
      
      The "possession" attribute can't be attached to a key structure directly as
      it's not an intrinsic property of a key.
      
      Pointers to keys have been replaced with struct key_ref *'s wherever
      possession information needs to be passed through.
      
      This does assume that the bottom bit of the pointer will always be zero on
      return from kmem_cache_alloc().
      
      The key reference type has been made into a typedef so that at least it can be
      located in the sources, even though it's basically a pointer to an undefined
      type. I've also renamed the accessor functions to be more useful, and all
      reference variables should now end in "_ref".
      Signed-Off-By: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      664cceb0
  13. 05 8月, 2005 1 次提交
    • D
      [PATCH] Error during attempt to join key management session can leave semaphore pinned · bcf945d3
      David Howells 提交于
      The attached patch prevents an error during the key session joining operation
      from hanging future joins in the D state [CAN-2005-2098].
      
      The problem is that the error handling path for the KEYCTL_JOIN_SESSION_KEYRING
      operation has one error path that doesn't release the session management
      semaphore. Further attempts to get the semaphore will then sleep for ever in
      the D state.
      
      This can happen in four situations, all involving an attempt to allocate a new
      session keyring:
      
       (1) ENOMEM.
      
       (2) The users key quota being reached.
      
       (3) A keyring name that is an empty string.
      
       (4) A keyring name that is too long.
      
      Any user may attempt this operation, and so any user can cause the problem to
      occur.
      Signed-Off-By: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      bcf945d3
  14. 26 6月, 2005 1 次提交
    • P
      [PATCH] RCU: clean up a few remaining synchronize_kernel() calls · b2b18660
      Paul E. McKenney 提交于
      2.6.12-rc6-mm1 has a few remaining synchronize_kernel()s, some (but not
      all) in comments.  This patch changes these synchronize_kernel() calls (and
      comments) to synchronize_rcu() or synchronize_sched() as follows:
      
      - arch/x86_64/kernel/mce.c mce_read(): change to synchronize_sched() to
        handle races with machine-check exceptions (synchronize_rcu() would not cut
        it given RCU implementations intended for hardcore realtime use.
      
      - drivers/input/serio/i8042.c i8042_stop(): change to synchronize_sched() to
        handle races with i8042_interrupt() interrupt handler.  Again,
        synchronize_rcu() would not cut it given RCU implementations intended for
        hardcore realtime use.
      
      - include/*/kdebug.h comments: change to synchronize_sched() to handle races
        with NMIs.  As before, synchronize_rcu() would not cut it...
      
      - include/linux/list.h comment: change to synchronize_rcu(), since this
        comment is for list_del_rcu().
      
      - security/keys/key.c unregister_key_type(): change to synchronize_rcu(),
        since this is interacting with RCU read side.
      
      - security/keys/process_keys.c install_session_keyring(): change to
        synchronize_rcu(), since this is interacting with RCU read side.
      Signed-off-by: N"Paul E. McKenney" <paulmck@us.ibm.com>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      b2b18660
  15. 24 6月, 2005 3 次提交
    • D
      [PATCH] Keys: Make request-key create an authorisation key · 3e30148c
      David Howells 提交于
      The attached patch makes the following changes:
      
       (1) There's a new special key type called ".request_key_auth".
      
           This is an authorisation key for when one process requests a key and
           another process is started to construct it. This type of key cannot be
           created by the user; nor can it be requested by kernel services.
      
           Authorisation keys hold two references:
      
           (a) Each refers to a key being constructed. When the key being
           	 constructed is instantiated the authorisation key is revoked,
           	 rendering it of no further use.
      
           (b) The "authorising process". This is either:
      
           	 (i) the process that called request_key(), or:
      
           	 (ii) if the process that called request_key() itself had an
           	      authorisation key in its session keyring, then the authorising
           	      process referred to by that authorisation key will also be
           	      referred to by the new authorisation key.
      
      	 This means that the process that initiated a chain of key requests
      	 will authorise the lot of them, and will, by default, wind up with
      	 the keys obtained from them in its keyrings.
      
       (2) request_key() creates an authorisation key which is then passed to
           /sbin/request-key in as part of a new session keyring.
      
       (3) When request_key() is searching for a key to hand back to the caller, if
           it comes across an authorisation key in the session keyring of the
           calling process, it will also search the keyrings of the process
           specified therein and it will use the specified process's credentials
           (fsuid, fsgid, groups) to do that rather than the calling process's
           credentials.
      
           This allows a process started by /sbin/request-key to find keys belonging
           to the authorising process.
      
       (4) A key can be read, even if the process executing KEYCTL_READ doesn't have
           direct read or search permission if that key is contained within the
           keyrings of a process specified by an authorisation key found within the
           calling process's session keyring, and is searchable using the
           credentials of the authorising process.
      
           This allows a process started by /sbin/request-key to read keys belonging
           to the authorising process.
      
       (5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
           KEYCTL_NEGATE will specify a keyring of the authorising process, rather
           than the process doing the instantiation.
      
       (6) One of the process keyrings can be nominated as the default to which
           request_key() should attach new keys if not otherwise specified. This is
           done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
           constants. The current setting can also be read using this call.
      
       (7) request_key() is partially interruptible. If it is waiting for another
           process to finish constructing a key, it can be interrupted. This permits
           a request-key cycle to be broken without recourse to rebooting.
      Signed-Off-By: NDavid Howells <dhowells@redhat.com>
      Signed-Off-By: NBenoit Boissinot <benoit.boissinot@ens-lyon.org>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      3e30148c
    • D
      [PATCH] Keys: Use RCU to manage session keyring pointer · 8589b4e0
      David Howells 提交于
      The attached patch uses RCU to manage the session keyring pointer in struct
      signal_struct.  This means that searching need not disable interrupts and get
      a the sighand spinlock to access this pointer.  Furthermore, by judicious use
      of rcu_read_(un)lock(), this patch also avoids the need to take and put
      refcounts on the session keyring itself, thus saving on even more atomic ops.
      Signed-Off-By: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      8589b4e0
    • D
      [PATCH] keys: Discard key spinlock and use RCU for key payload · 76d8aeab
      David Howells 提交于
      The attached patch changes the key implementation in a number of ways:
      
       (1) It removes the spinlock from the key structure.
      
       (2) The key flags are now accessed using atomic bitops instead of
           write-locking the key spinlock and using C bitwise operators.
      
           The three instantiation flags are dealt with with the construction
           semaphore held during the request_key/instantiate/negate sequence, thus
           rendering the spinlock superfluous.
      
           The key flags are also now bit numbers not bit masks.
      
       (3) The key payload is now accessed using RCU. This permits the recursive
           keyring search algorithm to be simplified greatly since no locks need be
           taken other than the usual RCU preemption disablement. Searching now does
           not require any locks or semaphores to be held; merely that the starting
           keyring be pinned.
      
       (4) The keyring payload now includes an RCU head so that it can be disposed
           of by call_rcu(). This requires that the payload be copied on unlink to
           prevent introducing races in copy-down vs search-up.
      
       (5) The user key payload is now a structure with the data following it. It
           includes an RCU head like the keyring payload and for the same reason. It
           also contains a data length because the data length in the key may be
           changed on another CPU whilst an RCU protected read is in progress on the
           payload. This would then see the supposed RCU payload and the on-key data
           length getting out of sync.
      
           I'm tempted to drop the key's datalen entirely, except that it's used in
           conjunction with quota management and so is a little tricky to get rid
           of.
      
       (6) Update the keys documentation.
      Signed-Off-By: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NAndrew Morton <akpm@osdl.org>
      Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
      76d8aeab
  16. 17 4月, 2005 1 次提交
    • L
      Linux-2.6.12-rc2 · 1da177e4
      Linus Torvalds 提交于
      Initial git repository build. I'm not bothering with the full history,
      even though we have it. We can create a separate "historical" git
      archive of that later if we want to, and in the meantime it's about
      3.2GB when imported into git - space that would just make the early
      git days unnecessarily complicated, when we don't have a lot of good
      infrastructure for it.
      
      Let it rip!
      1da177e4