17 Nov, 2011

1 commit


23 Aug, 2011

3 commits

  • 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
    Signed-off-by: David Howells
    Signed-off-by: James Morris

    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: David Howells
    Signed-off-by: James Morris

    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: David Howells
    Signed-off-by: James Morris

    David Howells
     

08 Mar, 2011

2 commits

  • Add a new keyctl op to reject a key with a specified error code. This works
    much the same as negating a key, and so keyctl_negate_key() is made a special
    case of keyctl_reject_key(). The difference is that keyctl_negate_key()
    selects ENOKEY as the error to be reported.

    Typically the key would be rejected with EKEYEXPIRED, EKEYREVOKED or
    EKEYREJECTED, but this is not mandatory.

    Signed-off-by: David Howells
    Signed-off-by: James Morris

    David Howells
     
  • Add a key type operation to permit the key type to vet the description of a new
    key that key_alloc() is about to allocate. The operation may reject the
    description if it wishes with an error of its choosing. If it does this, the
    key will not be allocated.

    Signed-off-by: David Howells
    Reviewed-by: Mimi Zohar
    Signed-off-by: James Morris

    David Howells
     

26 Jan, 2011

1 commit

  • Fix __key_link_end()'s attempt to fix up the quota if an error occurs.

    There are two erroneous cases: Firstly, we always decrease the quota if
    the preallocated replacement keyring needs cleaning up, irrespective of
    whether or not we should (we may have replaced a pointer rather than
    adding another pointer).

    Secondly, we never clean up the quota if we added a pointer without the
    keyring storage being extended (we allocate multiple pointers at a time,
    even if we're not going to use them all immediately).

    We handle this by setting the bottom bit of the preallocation pointer in
    __key_link_begin() to indicate that the quota needs fixing up, which is
    then passed to __key_link() (which clears the whole thing) and
    __key_link_end().

    Signed-off-by: David Howells
    Signed-off-by: Linus Torvalds

    David Howells
     

22 Jan, 2011

2 commits

  • Fix up comments in the key management code. No functional changes.

    Signed-off-by: David Howells
    Signed-off-by: Linus Torvalds

    David Howells
     
  • Do a bit of a style clean up in the key management code. No functional
    changes.

    Done using:

    perl -p -i -e 's!^/[*]*/\n!!' security/keys/*.c
    perl -p -i -e 's!} /[*] end [a-z0-9_]*[(][)] [*]/\n!}\n!' security/keys/*.c
    sed -i -s -e ": next" -e N -e 's/^\n[}]$/}/' -e t -e P -e 's/^.*\n//' -e "b next" security/keys/*.c

    To remove /*****/ lines, remove comments on the closing brace of a
    function to name the function and remove blank lines before the closing
    brace of a function.

    Signed-off-by: David Howells
    Signed-off-by: Linus Torvalds

    David Howells
     

06 May, 2010

1 commit

  • Do preallocation for __key_link() so that the various callers in request_key.c
    can deal with any errors from this source before attempting to construct a key.
    This allows them to assume that the actual linkage step is guaranteed to be
    successful.

    Signed-off-by: David Howells
    Signed-off-by: James Morris

    David Howells
     

23 Apr, 2010

1 commit


15 Sep, 2009

1 commit

  • Fix a number of problems with the new key garbage collector:

    (1) A rogue semicolon in keyring_gc() was causing the initial count of dead
    keys to be miscalculated.

    (2) A missing return in keyring_gc() meant that under certain circumstances,
    the keyring semaphore would be unlocked twice.

    (3) The key serial tree iterator (key_garbage_collector()) part of the garbage
    collector has been modified to:

    (a) Complete each scan of the keyrings before setting the new timer.

    (b) Only set the new timer for keys that have yet to expire. This means
    that the new timer is now calculated correctly, and the gc doesn't
    get into a loop continually scanning for keys that have expired, and
    preventing other things from happening, like RCU cleaning up the old
    keyring contents.

    (c) Perform an extra scan if any keys were garbage collected in this one
    as a key might become garbage during a scan, and (b) could mean we
    don't set the timer again.

    (4) Made key_schedule_gc() take the time at which to do a collection run,
    rather than the time at which the key expires. This means the collection
    of dead keys (key type unregistered) can happen immediately.

    Signed-off-by: David Howells
    Signed-off-by: James Morris

    David Howells
     

02 Sep, 2009

3 commits

  • Add garbage collection for dead, revoked and expired keys. This involved
    erasing all links to such keys from keyrings that point to them. At that
    point, the key will be deleted in the normal manner.

    Keyrings from which garbage collection occurs are shrunk and their quota
    consumption reduced as appropriate.

    Dead keys (for which the key type has been removed) will be garbage collected
    immediately.

    Revoked and expired keys will hang around for a number of seconds, as set in
    /proc/sys/kernel/keys/gc_delay before being automatically removed. The default
    is 5 minutes.

    Signed-off-by: David Howells
    Signed-off-by: James Morris

    David Howells
     
  • Set the KEY_FLAG_DEAD flag on keys for which the type has been removed. This
    causes the key_permission() function to return EKEYREVOKED in response to
    various commands. It does not, however, prevent unlinking or clearing of
    keyrings from detaching the key.

    Signed-off-by: David Howells
    Acked-by: Serge Hallyn
    Signed-off-by: James Morris

    David Howells
     
  • Allow keys for which the key type has been removed to be unlinked. Currently
    dead-type keys can only be disposed of by completely clearing the keyrings
    that point to them.

    Signed-off-by: David Howells
    Acked-by: Serge Hallyn
    Signed-off-by: James Morris

    David Howells
     

27 Feb, 2009

1 commit

  • per-uid keys were looked by uid only. Use the user namespace
    to distinguish the same uid in different namespaces.

    This does not address key_permission. So a task can for instance
    try to join a keyring owned by the same uid in another namespace.
    That will be handled by a separate patch.

    Signed-off-by: Serge E. Hallyn
    Acked-by: David Howells
    Signed-off-by: James Morris

    Serge E. Hallyn
     

14 Nov, 2008

2 commits

  • 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: David Howells
    Acked-by: James Morris
    Signed-off-by: James Morris

    David Howells
     
  • Wrap access to task credentials so that they can be separated more easily from
    the task_struct during the introduction of COW creds.

    Change most current->(|e|s|fs)[ug]id to current_(|e|s|fs)[ug]id().

    Change some task->e?[ug]id to task_e?[ug]id(). In some places it makes more
    sense to use RCU directly rather than a convenient wrapper; these will be
    addressed by later patches.

    Signed-off-by: David Howells
    Reviewed-by: James Morris
    Acked-by: Serge Hallyn
    Signed-off-by: James Morris

    David Howells
     

29 Apr, 2008

3 commits

  • Make the keyring quotas controllable through /proc/sys files:

    (*) /proc/sys/kernel/keys/root_maxkeys
    /proc/sys/kernel/keys/root_maxbytes

    Maximum number of keys that root may have and the maximum total number of
    bytes of data that root may have stored in those keys.

    (*) /proc/sys/kernel/keys/maxkeys
    /proc/sys/kernel/keys/maxbytes

    Maximum number of keys that each non-root user may have and the maximum
    total number of bytes of data that each of those users may have stored in
    their keys.

    Also increase the quotas as a number of people have been complaining that it's
    not big enough. I'm not sure that it's big enough now either, but on the
    other hand, it can now be set in /etc/sysctl.conf.

    Signed-off-by: David Howells
    Cc:
    Cc:
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    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: David Howells
    Cc:
    Cc:
    Cc:
    Cc: Stephen Smalley
    Cc: James Morris
    Cc: Chris Wright
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     
  • The key_create_or_update() function provided by the keyring code has a default
    set of permissions that are always applied to the key when created. This
    might not be desirable to all clients.

    Here's a patch that adds a "perm" parameter to the function to address this,
    which can be set to KEY_PERM_UNDEF to revert to the current behaviour.

    Signed-off-by: Arun Raghavan
    Signed-off-by: David Howells
    Cc: Satyam Sharma
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Arun Raghavan
     

08 Feb, 2008

1 commit


17 Oct, 2007

1 commit

  • 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: David Howells
    Signed-off-by: Alan Cox
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     

20 Jul, 2007

1 commit

  • Slab destructors were no longer supported after Christoph's
    c59def9f222d44bb7e2f0a559f2906191a0862d7 change. They've been
    BUGs for both slab and slub, and slob never supported them
    either.

    This rips out support for the dtor pointer from kmem_cache_create()
    completely and fixes up every single callsite in the kernel (there were
    about 224, not including the slab allocator definitions themselves,
    or the documentation references).

    Signed-off-by: Paul Mundt

    Paul Mundt
     

07 Feb, 2007

1 commit

  • Fix the key serial number collision avoidance code in key_alloc_serial().

    This didn't use to be so much of a problem as the key serial numbers were
    allocated from a simple incremental counter, and it would have to go through
    two billion keys before it could possibly encounter a collision. However, now
    that random numbers are used instead, collisions are much more likely.

    This is fixed by finding a hole in the rbtree where the next unused serial
    number ought to be and using that by going almost back to the top of the
    insertion routine and redoing the insertion with the new serial number rather
    than trying to be clever and attempting to work out the insertion point
    pointer directly.

    This fixes kernel BZ #7727.

    Signed-off-by: David Howells
    Signed-off-by: Linus Torvalds

    David Howells
     

08 Dec, 2006

3 commits

  • Signed-off-by: Eric Sesterhenn
    Signed-off-by: Alexey Dobriyan
    Acked-By: David Howells
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Eric Sesterhenn
     
  • Replace all uses of kmem_cache_t with struct kmem_cache.

    The patch was generated using the following script:

    #!/bin/sh
    #
    # Replace one string by another in all the kernel sources.
    #

    set -e

    for file in `find * -name "*.c" -o -name "*.h"|xargs grep -l $1`; do
    quilt add $file
    sed -e "1,\$s/$1/$2/g" $file >/tmp/$$
    mv /tmp/$$ $file
    quilt refresh
    done

    The script was run like this

    sh replace kmem_cache_t "struct kmem_cache"

    Signed-off-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     
  • SLAB_KERNEL is an alias of GFP_KERNEL.

    Signed-off-by: Christoph Lameter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christoph Lameter
     

22 Nov, 2006

1 commit

  • Pass the work_struct pointer to the work function rather than context data.
    The work function can use container_of() to work out the data.

    For the cases where the container of the work_struct may go away the moment the
    pending bit is cleared, it is made possible to defer the release of the
    structure by deferring the clearing of the pending bit.

    To make this work, an extra flag is introduced into the management side of the
    work_struct. This governs auto-release of the structure upon execution.

    Ordinarily, the work queue executor would release the work_struct for further
    scheduling or deallocation by clearing the pending bit prior to jumping to the
    work function. This means that, unless the driver makes some guarantee itself
    that the work_struct won't go away, the work function may not access anything
    else in the work_struct or its container lest they be deallocated.. This is a
    problem if the auxiliary data is taken away (as done by the last patch).

    However, if the pending bit is *not* cleared before jumping to the work
    function, then the work function *may* access the work_struct and its container
    with no problems. But then the work function must itself release the
    work_struct by calling work_release().

    In most cases, automatic release is fine, so this is the default. Special
    initiators exist for the non-auto-release case (ending in _NAR).

    Signed-Off-By: David Howells

    David Howells
     

28 Jun, 2006

1 commit

  • Add more poison values to include/linux/poison.h. It's not clear to me
    whether some others should be added or not, so I haven't added any of
    these:

    ./include/linux/libata.h:#define ATA_TAG_POISON 0xfafbfcfdU
    ./arch/ppc/8260_io/fcc_enet.c:1918: memset((char *)(&(immap->im_dprambase[(mem_addr+64)])), 0x88, 32);
    ./drivers/usb/mon/mon_text.c:429: memset(mem, 0xe5, sizeof(struct mon_event_text));
    ./drivers/char/ftape/lowlevel/ftape-ctl.c:738: memset(ft_buffer[i]->address, 0xAA, FT_BUFF_SIZE);
    ./drivers/block/sx8.c:/* 0xf is just arbitrary, non-zero noise; this is sorta like poisoning */

    Signed-off-by: Randy Dunlap
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Randy Dunlap
     

27 Jun, 2006

2 commits

  • Cause key_alloc_serial() to generate key serial numbers randomly rather than
    in linear sequence.

    Using an linear sequence permits a covert communication channel to be
    established, in which one process can communicate with another by creating or
    not creating new keys within a certain timeframe. The second process can
    probe for the expected next key serial number and judge its existence by the
    error returned.

    This is a problem as the serial number namespace is globally shared between
    all tasks, regardless of their context.

    For more information on this topic, this old TCSEC guide is recommended:

    http://www.radium.ncsc.mil/tpep/library/rainbow/NCSC-TG-030.html

    Signed-off-by: Michael LeMay
    Signed-off-by: James Morris
    Signed-off-by: David Howells
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michael LeMay
     
  • Add the ability for key creation to overrun the user's quota in some
    circumstances - notably when a session keyring is created and assigned to a
    process that didn't previously have one.

    This means it's still possible to log in, should PAM require the creation of a
    new session keyring, and fix an overburdened key quota.

    Signed-off-by: David Howells
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     

23 Jun, 2006

2 commits

  • 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: David Howells
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     
  • 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: Michael LeMay
    Signed-off-by: David Howells
    Signed-off-by: James Morris
    Acked-by: Chris Wright
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Michael LeMay
     

21 Apr, 2006

1 commit


11 Apr, 2006

1 commit

  • This fixes the problem of an oops occuring when a user attempts to add a
    key to a non-keyring key [CVE-2006-1522].

    The problem is that __keyring_search_one() doesn't check that the
    keyring it's been given is actually a keyring.

    I've fixed this problem by:

    (1) declaring that caller of __keyring_search_one() must guarantee that
    the keyring is a keyring; and

    (2) making key_create_or_update() check that the keyring is a keyring,
    and return -ENOTDIR if it isn't.

    This can be tested by:

    keyctl add user b b `keyctl add user a a @s`

    Signed-off-by: David Howells
    Signed-off-by: Linus Torvalds

    David Howells
     

26 Mar, 2006

2 commits

  • Cause an attempt to add a duplicate non-updateable key (such as a keyring) to
    a keyring to discard the extant copy in favour of the new one rather than
    failing with EEXIST:

    # do the test in an empty session
    keyctl session
    # create a new keyring called "a" and attach to session
    keyctl newring a @s
    # create another new keyring called "a" and attach to session,
    # displacing the keyring added by the second command:
    keyctl newring a @s

    Without this patch, the third command will fail.

    For updateable keys (such as those of "user" type), the update method will
    still be called rather than a new key being created.

    Signed-off-by: David Howells
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     
  • Make key quota detection generate an error if either quota is exceeded rather
    than only if both quotas are exceeded.

    Signed-off-by: David Howells
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     

07 Jan, 2006

2 commits