From 3162534069597e34dd0ac9eb711be8dc23835ae7 Mon Sep 17 00:00:00 2001 From: Joseph Cihula Date: Tue, 30 Jun 2009 19:30:59 -0700 Subject: x86, intel_txt: Intel TXT boot support This patch adds kernel configuration and boot support for Intel Trusted Execution Technology (Intel TXT). Intel's technology for safer computing, Intel Trusted Execution Technology (Intel TXT), defines platform-level enhancements that provide the building blocks for creating trusted platforms. Intel TXT was formerly known by the code name LaGrande Technology (LT). Intel TXT in Brief: o Provides dynamic root of trust for measurement (DRTM) o Data protection in case of improper shutdown o Measurement and verification of launched environment Intel TXT is part of the vPro(TM) brand and is also available some non-vPro systems. It is currently available on desktop systems based on the Q35, X38, Q45, and Q43 Express chipsets (e.g. Dell Optiplex 755, HP dc7800, etc.) and mobile systems based on the GM45, PM45, and GS45 Express chipsets. For more information, see http://www.intel.com/technology/security/. This site also has a link to the Intel TXT MLE Developers Manual, which has been updated for the new released platforms. A much more complete description of how these patches support TXT, how to configure a system for it, etc. is in the Documentation/intel_txt.txt file in this patch. This patch provides the TXT support routines for complete functionality, documentation for TXT support and for the changes to the boot_params structure, and boot detection of a TXT launch. Attempts to shutdown (reboot, Sx) the system will result in platform resets; subsequent patches will support these shutdown modes properly. Documentation/intel_txt.txt | 210 +++++++++++++++++++++ Documentation/x86/zero-page.txt | 1 arch/x86/include/asm/bootparam.h | 3 arch/x86/include/asm/fixmap.h | 3 arch/x86/include/asm/tboot.h | 197 ++++++++++++++++++++ arch/x86/kernel/Makefile | 1 arch/x86/kernel/setup.c | 4 arch/x86/kernel/tboot.c | 379 +++++++++++++++++++++++++++++++++++++++ security/Kconfig | 30 +++ 9 files changed, 827 insertions(+), 1 deletion(-) Signed-off-by: Joseph Cihula Signed-off-by: Shane Wang Signed-off-by: Gang Wei Signed-off-by: H. Peter Anvin --- security/Kconfig | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'security') diff --git a/security/Kconfig b/security/Kconfig index d23c839038f..edc7cbdc012 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -113,6 +113,36 @@ config SECURITY_ROOTPLUG If you are unsure how to answer this question, answer N. +config INTEL_TXT + bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)" + depends on EXPERIMENTAL && X86 && DMAR && ACPI + help + This option enables support for booting the kernel with the + Trusted Boot (tboot) module. This will utilize + Intel(R) Trusted Execution Technology to perform a measured launch + of the kernel. If the system does not support Intel(R) TXT, this + will have no effect. + + Intel TXT will provide higher assurance of sysem configuration and + initial state as well as data reset protection. This is used to + create a robust initial kernel measurement and verification, which + helps to ensure that kernel security mechanisms are functioning + correctly. This level of protection requires a root of trust outside + of the kernel itself. + + Intel TXT also helps solve real end user concerns about having + confidence that their hardware is running the VMM or kernel that + it was conigured with, especially since they may be responsible for + providing such assurances to VMs and services running on it. + + See for more information + about Intel(R) TXT. + See for more information about tboot. + See Documentation/intel_txt.txt for a description of how to enable + Intel TXT support in a kernel boot. + + If you are unsure as to whether this is required, answer N. + source security/selinux/Kconfig source security/smack/Kconfig source security/tomoyo/Kconfig -- cgit v1.2.3 From 3c556e4198926b284ff5ff6756111a64e1e98cb0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 12 Aug 2009 12:00:40 -0300 Subject: x86, intel_txt: Fix typos in Kconfig help Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: H. Peter Anvin --- security/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'security') diff --git a/security/Kconfig b/security/Kconfig index edc7cbdc012..6631774672c 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -123,7 +123,7 @@ config INTEL_TXT of the kernel. If the system does not support Intel(R) TXT, this will have no effect. - Intel TXT will provide higher assurance of sysem configuration and + Intel TXT will provide higher assurance of system configuration and initial state as well as data reset protection. This is used to create a robust initial kernel measurement and verification, which helps to ensure that kernel security mechanisms are functioning @@ -132,7 +132,7 @@ config INTEL_TXT Intel TXT also helps solve real end user concerns about having confidence that their hardware is running the VMM or kernel that - it was conigured with, especially since they may be responsible for + it was configured with, especially since they may be responsible for providing such assurances to VMs and services running on it. See for more information -- cgit v1.2.3 From 69575d388603365f2afbf4166df93152df59b165 Mon Sep 17 00:00:00 2001 From: Shane Wang Date: Tue, 1 Sep 2009 18:25:07 -0700 Subject: x86, intel_txt: clean up the impact on generic code, unbreak non-x86 Move tboot.h from asm to linux to fix the build errors of intel_txt patch on non-X86 platforms. Remove the tboot code from generic code init/main.c and kernel/cpu.c. Signed-off-by: Shane Wang Signed-off-by: H. Peter Anvin --- security/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'security') diff --git a/security/Kconfig b/security/Kconfig index 6631774672c..5721847a7a6 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -115,7 +115,7 @@ config SECURITY_ROOTPLUG config INTEL_TXT bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)" - depends on EXPERIMENTAL && X86 && DMAR && ACPI + depends on HAVE_INTEL_TXT help This option enables support for booting the kernel with the Trusted Boot (tboot) module. This will utilize -- cgit v1.2.3 From ed868a56988464cd31de0302426a5e94d3127f10 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Sat, 12 Sep 2009 22:54:10 -0400 Subject: Creds: creds->security can be NULL is selinux is disabled __validate_process_creds should check if selinux is actually enabled before running tests on the selinux portion of the credentials struct. Signed-off-by: Eric Paris Signed-off-by: James Morris --- security/selinux/exports.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'security') diff --git a/security/selinux/exports.c b/security/selinux/exports.c index c73aeaa008e..c0a454aee1e 100644 --- a/security/selinux/exports.c +++ b/security/selinux/exports.c @@ -63,3 +63,9 @@ void selinux_secmark_refcount_dec(void) atomic_dec(&selinux_secmark_refcount); } EXPORT_SYMBOL_GPL(selinux_secmark_refcount_dec); + +bool selinux_is_enabled(void) +{ + return selinux_enabled; +} +EXPORT_SYMBOL_GPL(selinux_is_enabled); -- cgit v1.2.3 From 008574b11171a1ee9583a00188e27ff9e0432061 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Sat, 12 Sep 2009 22:54:17 -0400 Subject: SELinux: seperate avc_cache flushing Move the avc_cache flushing into it's own function so it can be reused when disabling SELinux. Signed-off-by: Eric Paris Signed-off-by: James Morris --- security/selinux/avc.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'security') diff --git a/security/selinux/avc.c b/security/selinux/avc.c index e3d19014259..f6012462364 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -709,18 +709,16 @@ out: } /** - * avc_ss_reset - Flush the cache and revalidate migrated permissions. - * @seqno: policy sequence number + * avc_flush - Flush the cache */ -int avc_ss_reset(u32 seqno) +static void avc_flush(void) { - struct avc_callback_node *c; - int i, rc = 0, tmprc; - unsigned long flag; - struct avc_node *node; struct hlist_head *head; struct hlist_node *next; + struct avc_node *node; spinlock_t *lock; + unsigned long flag; + int i; for (i = 0; i < AVC_CACHE_SLOTS; i++) { head = &avc_cache.slots[i]; @@ -737,6 +735,18 @@ int avc_ss_reset(u32 seqno) rcu_read_unlock(); spin_unlock_irqrestore(lock, flag); } +} + +/** + * avc_ss_reset - Flush the cache and revalidate migrated permissions. + * @seqno: policy sequence number + */ +int avc_ss_reset(u32 seqno) +{ + struct avc_callback_node *c; + int rc = 0, tmprc; + + avc_flush(); for (c = avc_callbacks; c; c = c->next) { if (c->events & AVC_CALLBACK_RESET) { -- cgit v1.2.3 From 4e6d0bffd3d72a32b620525c9007d2482c731775 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Sat, 12 Sep 2009 22:54:23 -0400 Subject: SELinux: flush the avc before disabling SELinux Before SELinux is disabled at boot it can create AVC entries. This patch will flush those entries before disabling SELinux. Signed-off-by: Eric Paris Signed-off-by: James Morris --- security/selinux/avc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'security') diff --git a/security/selinux/avc.c b/security/selinux/avc.c index f6012462364..1ed0f076aad 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -868,6 +868,8 @@ u32 avc_policy_seqno(void) void avc_disable(void) { + avc_flush(); + synchronize_rcu(); if (avc_node_cachep) kmem_cache_destroy(avc_node_cachep); } -- cgit v1.2.3 From 5c84342a3e147a23752276650340801c237d0e56 Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Mon, 14 Sep 2009 12:46:23 +0100 Subject: KEYS: Unlock tasklist when exiting early from keyctl_session_to_parent When we exit early from keyctl_session_to_parent because of permissions or because the session keyring is the same as the parent, we need to unlock the tasklist. The missing unlock causes the system to hang completely when using keyctl(KEYCTL_SESSION_TO_PARENT) with a keyring shared with the parent. Signed-off-by: Marc Dionne Signed-off-by: David Howells Signed-off-by: James Morris --- security/keys/keyctl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'security') diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 74c96852459..60983f38852 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1319,6 +1319,7 @@ long keyctl_session_to_parent(void) already_same: ret = 0; not_permitted: + write_unlock_irq(&tasklist_lock); put_cred(cred); return ret; -- cgit v1.2.3 From c08ef808ef24df32e25fbd949fe5310172f3c408 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 14 Sep 2009 17:26:13 +0100 Subject: KEYS: Fix garbage collector 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 --- security/keys/gc.c | 78 ++++++++++++++++++++++++++++++++----------------- security/keys/key.c | 4 +-- security/keys/keyctl.c | 2 +- security/keys/keyring.c | 24 +++++++++++---- 4 files changed, 73 insertions(+), 35 deletions(-) (limited to 'security') diff --git a/security/keys/gc.c b/security/keys/gc.c index 1e616aef55f..485fc6233c3 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c @@ -26,8 +26,10 @@ static void key_garbage_collector(struct work_struct *); static DEFINE_TIMER(key_gc_timer, key_gc_timer_func, 0, 0); static DECLARE_WORK(key_gc_work, key_garbage_collector); static key_serial_t key_gc_cursor; /* the last key the gc considered */ +static bool key_gc_again; static unsigned long key_gc_executing; static time_t key_gc_next_run = LONG_MAX; +static time_t key_gc_new_timer; /* * Schedule a garbage collection run @@ -40,9 +42,7 @@ void key_schedule_gc(time_t gc_at) kenter("%ld", gc_at - now); - gc_at += key_gc_delay; - - if (now >= gc_at) { + if (gc_at <= now) { schedule_work(&key_gc_work); } else if (gc_at < key_gc_next_run) { expires = jiffies + (gc_at - now) * HZ; @@ -112,16 +112,18 @@ static void key_garbage_collector(struct work_struct *work) struct rb_node *rb; key_serial_t cursor; struct key *key, *xkey; - time_t new_timer = LONG_MAX, limit; + time_t new_timer = LONG_MAX, limit, now; - kenter(""); + now = current_kernel_time().tv_sec; + kenter("[%x,%ld]", key_gc_cursor, key_gc_new_timer - now); if (test_and_set_bit(0, &key_gc_executing)) { - key_schedule_gc(current_kernel_time().tv_sec); + key_schedule_gc(current_kernel_time().tv_sec + 1); + kleave(" [busy; deferring]"); return; } - limit = current_kernel_time().tv_sec; + limit = now; if (limit > key_gc_delay) limit -= key_gc_delay; else @@ -129,12 +131,19 @@ static void key_garbage_collector(struct work_struct *work) spin_lock(&key_serial_lock); - if (RB_EMPTY_ROOT(&key_serial_tree)) - goto reached_the_end; + if (unlikely(RB_EMPTY_ROOT(&key_serial_tree))) { + spin_unlock(&key_serial_lock); + clear_bit(0, &key_gc_executing); + return; + } cursor = key_gc_cursor; if (cursor < 0) cursor = 0; + if (cursor > 0) + new_timer = key_gc_new_timer; + else + key_gc_again = false; /* find the first key above the cursor */ key = NULL; @@ -160,35 +169,50 @@ static void key_garbage_collector(struct work_struct *work) /* trawl through the keys looking for keyrings */ for (;;) { - if (key->expiry > 0 && key->expiry < new_timer) + if (key->expiry > now && key->expiry < new_timer) { + kdebug("will expire %x in %ld", + key_serial(key), key->expiry - now); new_timer = key->expiry; + } if (key->type == &key_type_keyring && - key_gc_keyring(key, limit)) { - /* the gc ate our lock */ - schedule_work(&key_gc_work); - goto no_unlock; - } + key_gc_keyring(key, limit)) + /* the gc had to release our lock so that the keyring + * could be modified, so we have to get it again */ + goto gc_released_our_lock; rb = rb_next(&key->serial_node); - if (!rb) { - key_gc_cursor = 0; - break; - } + if (!rb) + goto reached_the_end; key = rb_entry(rb, struct key, serial_node); } -out: - spin_unlock(&key_serial_lock); -no_unlock: +gc_released_our_lock: + kdebug("gc_released_our_lock"); + key_gc_new_timer = new_timer; + key_gc_again = true; clear_bit(0, &key_gc_executing); - if (new_timer < LONG_MAX) - key_schedule_gc(new_timer); - - kleave(""); + schedule_work(&key_gc_work); + kleave(" [continue]"); return; + /* when we reach the end of the run, we set the timer for the next one */ reached_the_end: + kdebug("reached_the_end"); + spin_unlock(&key_serial_lock); + key_gc_new_timer = new_timer; key_gc_cursor = 0; - goto out; + clear_bit(0, &key_gc_executing); + + if (key_gc_again) { + /* there may have been a key that expired whilst we were + * scanning, so if we discarded any links we should do another + * scan */ + new_timer = now + 1; + key_schedule_gc(new_timer); + } else if (new_timer < LONG_MAX) { + new_timer += key_gc_delay; + key_schedule_gc(new_timer); + } + kleave(" [end]"); } diff --git a/security/keys/key.c b/security/keys/key.c index 08531ad0f25..e50d264c9ad 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -500,7 +500,7 @@ int key_negate_and_link(struct key *key, set_bit(KEY_FLAG_INSTANTIATED, &key->flags); now = current_kernel_time(); key->expiry = now.tv_sec + timeout; - key_schedule_gc(key->expiry); + key_schedule_gc(key->expiry + key_gc_delay); if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) awaken = 1; @@ -909,7 +909,7 @@ void key_revoke(struct key *key) time = now.tv_sec; if (key->revoked_at == 0 || key->revoked_at > time) { key->revoked_at = time; - key_schedule_gc(key->revoked_at); + key_schedule_gc(key->revoked_at + key_gc_delay); } up_write(&key->sem); diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 60983f38852..2fb28efc532 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1115,7 +1115,7 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout) } key->expiry = expiry; - key_schedule_gc(key->expiry); + key_schedule_gc(key->expiry + key_gc_delay); up_write(&key->sem); key_put(key); diff --git a/security/keys/keyring.c b/security/keys/keyring.c index ac977f661a7..8ec02746ca9 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -1019,18 +1019,18 @@ void keyring_gc(struct key *keyring, time_t limit) struct key *key; int loop, keep, max; - kenter("%x", key_serial(keyring)); + kenter("{%x,%s}", key_serial(keyring), keyring->description); down_write(&keyring->sem); klist = keyring->payload.subscriptions; if (!klist) - goto just_return; + goto no_klist; /* work out how many subscriptions we're keeping */ keep = 0; for (loop = klist->nkeys - 1; loop >= 0; loop--) - if (!key_is_dead(klist->keys[loop], limit)); + if (!key_is_dead(klist->keys[loop], limit)) keep++; if (keep == klist->nkeys) @@ -1041,7 +1041,7 @@ void keyring_gc(struct key *keyring, time_t limit) new = kmalloc(sizeof(struct keyring_list) + max * sizeof(struct key *), GFP_KERNEL); if (!new) - goto just_return; + goto nomem; new->maxkeys = max; new->nkeys = 0; new->delkey = 0; @@ -1081,7 +1081,21 @@ void keyring_gc(struct key *keyring, time_t limit) discard_new: new->nkeys = keep; keyring_clear_rcu_disposal(&new->rcu); + up_write(&keyring->sem); + kleave(" [discard]"); + return; + just_return: up_write(&keyring->sem); - kleave(" [no]"); + kleave(" [no dead]"); + return; + +no_klist: + up_write(&keyring->sem); + kleave(" [no_klist]"); + return; + +nomem: + up_write(&keyring->sem); + kleave(" [oom]"); } -- cgit v1.2.3 From 1fd7317d02ec03c6fdf072317841287933d06d24 Mon Sep 17 00:00:00 2001 From: Nick Black Date: Tue, 22 Sep 2009 16:43:33 -0700 Subject: Move magic numbers into magic.h Move various magic-number definitions into magic.h. Signed-off-by: Nick Black Acked-by: Pekka Enberg Cc: Al Viro Cc: "David S. Miller" Cc: Casey Schaufler Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/smack/smack_lsm.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'security') diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index acae7ef4092..c33b6bb9b6d 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -30,17 +30,11 @@ #include #include #include +#include #include "smack.h" #define task_security(task) (task_cred_xxx((task), security)) -/* - * I hope these are the hokeyist lines of code in the module. Casey. - */ -#define DEVPTS_SUPER_MAGIC 0x1cd1 -#define SOCKFS_MAGIC 0x534F434B -#define TMPFS_MAGIC 0x01021994 - /** * smk_fetch - Fetch the smack label from a file. * @ip: a pointer to the inode -- cgit v1.2.3 From 88e9d34c727883d7d6f02cf1475b3ec98b8480c7 Mon Sep 17 00:00:00 2001 From: James Morris Date: Tue, 22 Sep 2009 16:43:43 -0700 Subject: seq_file: constify seq_operations Make all seq_operations structs const, to help mitigate against revectoring user-triggerable function pointers. This is derived from the grsecurity patch, although generated from scratch because it's simpler than extracting the changes from there. Signed-off-by: James Morris Acked-by: Serge Hallyn Acked-by: Casey Schaufler Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/integrity/ima/ima_fs.c | 4 ++-- security/smack/smackfs.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'security') diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 6bfc7eaebfd..8e9777b7640 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -146,7 +146,7 @@ static int ima_measurements_show(struct seq_file *m, void *v) return 0; } -static struct seq_operations ima_measurments_seqops = { +static const struct seq_operations ima_measurments_seqops = { .start = ima_measurements_start, .next = ima_measurements_next, .stop = ima_measurements_stop, @@ -221,7 +221,7 @@ static int ima_ascii_measurements_show(struct seq_file *m, void *v) return 0; } -static struct seq_operations ima_ascii_measurements_seqops = { +static const struct seq_operations ima_ascii_measurements_seqops = { .start = ima_measurements_start, .next = ima_measurements_next, .stop = ima_measurements_stop, diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index f83a8098072..aeead758509 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -187,7 +187,7 @@ static void load_seq_stop(struct seq_file *s, void *v) /* No-op */ } -static struct seq_operations load_seq_ops = { +static const struct seq_operations load_seq_ops = { .start = load_seq_start, .next = load_seq_next, .show = load_seq_show, @@ -503,7 +503,7 @@ static void cipso_seq_stop(struct seq_file *s, void *v) /* No-op */ } -static struct seq_operations cipso_seq_ops = { +static const struct seq_operations cipso_seq_ops = { .start = cipso_seq_start, .stop = cipso_seq_stop, .next = cipso_seq_next, @@ -697,7 +697,7 @@ static void netlbladdr_seq_stop(struct seq_file *s, void *v) /* No-op */ } -static struct seq_operations netlbladdr_seq_ops = { +static const struct seq_operations netlbladdr_seq_ops = { .start = netlbladdr_seq_start, .stop = netlbladdr_seq_stop, .next = netlbladdr_seq_next, -- cgit v1.2.3 From 606531c316d30e9639473a6da09ee917125ab467 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 16 Sep 2009 15:54:14 +0100 Subject: KEYS: Have the garbage collector set its timer for live expired keys The key garbage collector sets a timer to start a new collection cycle at the point the earliest key to expire should be considered garbage. However, it currently only does this if the key it is considering hasn't yet expired. If the key being considering has expired, but hasn't yet reached the collection time then it is ignored, and won't be collected until some other key provokes a round of collection. Make the garbage collector set the timer for the earliest key that hasn't yet passed its collection time, rather than the earliest key that hasn't yet expired. Signed-off-by: David Howells Signed-off-by: James Morris --- security/keys/gc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'security') diff --git a/security/keys/gc.c b/security/keys/gc.c index 485fc6233c3..4770be375ff 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c @@ -169,9 +169,9 @@ static void key_garbage_collector(struct work_struct *work) /* trawl through the keys looking for keyrings */ for (;;) { - if (key->expiry > now && key->expiry < new_timer) { + if (key->expiry > limit && key->expiry < new_timer) { kdebug("will expire %x in %ld", - key_serial(key), key->expiry - now); + key_serial(key), key->expiry - limit); new_timer = key->expiry; } -- cgit v1.2.3 From 5224ee086321fec78970e2f2805892d2b34e8957 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Sun, 20 Sep 2009 21:21:10 -0400 Subject: SELinux: do not destroy the avc_cache_nodep The security_ops reset done when SELinux is disabled at run time is done after the avc cache is freed and after the kmem_cache for the avc is also freed. This means that between the time the selinux disable code destroys the avc_node_cachep another process could make a security request and could try to allocate from the cache. We are just going to leave the cachep around, like we always have. SELinux: Disabled at runtime. BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] kmem_cache_alloc+0x9a/0x185 PGD 0 Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC last sysfs file: CPU 1 Modules linked in: Pid: 12, comm: khelper Not tainted 2.6.31-tip-05525-g0eeacc6-dirty #14819 System Product Name RIP: 0010:[] [] kmem_cache_alloc+0x9a/0x185 RSP: 0018:ffff88003f9258b0 EFLAGS: 00010086 RAX: 0000000000000001 RBX: 0000000000000000 RCX: 0000000078c0129e RDX: 0000000000000000 RSI: ffffffff8130b626 RDI: ffffffff81122528 RBP: ffff88003f925900 R08: 0000000078c0129e R09: 0000000000000001 R10: 0000000000000000 R11: 0000000078c0129e R12: 0000000000000246 R13: 0000000000008020 R14: ffff88003f8586d8 R15: 0000000000000001 FS: 0000000000000000(0000) GS:ffff880002b00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b CR2: 0000000000000000 CR3: 0000000001001000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: ffffffff827bd420 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process khelper (pid: 12, threadinfo ffff88003f924000, task ffff88003f928000) Stack: 0000000000000246 0000802000000246 ffffffff8130b626 0000000000000001 <0> 0000000078c0129e 0000000000000000 ffff88003f925a70 0000000000000002 <0> 0000000000000001 0000000000000001 ffff88003f925960 ffffffff8130b626 Call Trace: [] ? avc_alloc_node+0x36/0x273 [] avc_alloc_node+0x36/0x273 [] ? avc_latest_notif_update+0x7d/0x9e [] avc_insert+0x51/0x18d [] avc_has_perm_noaudit+0x9d/0x128 [] avc_has_perm+0x45/0x88 [] current_has_perm+0x52/0x6d [] selinux_task_create+0x2f/0x45 [] security_task_create+0x29/0x3f [] copy_process+0x82/0xdf0 [] ? register_lock_class+0x2f/0x36c [] ? mark_lock+0x2e/0x1e1 [] do_fork+0x16e/0x382 [] ? register_lock_class+0x2f/0x36c [] ? probe_workqueue_execution+0x57/0xf9 [] ? mark_lock+0x2e/0x1e1 [] ? probe_workqueue_execution+0x57/0xf9 [] kernel_thread+0x82/0xe0 [] ? ____call_usermodehelper+0x0/0x139 [] ? child_rip+0x0/0x20 [] ? __call_usermodehelper+0x65/0x9a [] run_workqueue+0x171/0x27e [] ? run_workqueue+0x11d/0x27e [] ? __call_usermodehelper+0x0/0x9a [] worker_thread+0xe8/0x10f [] ? autoremove_wake_function+0x0/0x63 [] ? worker_thread+0x0/0x10f [] kthread+0x91/0x99 [] child_rip+0xa/0x20 [] ? restore_args+0x0/0x30 [] ? kthread+0x0/0x99 [] ? child_rip+0x0/0x20 Code: 0f 85 99 00 00 00 9c 58 66 66 90 66 90 49 89 c4 fa 66 66 90 66 66 90 e8 83 34 fb ff e8 d7 e9 26 00 48 98 49 8b 94 c6 10 01 00 00 <48> 8b 1a 44 8b 7a 18 48 85 db 74 0f 8b 42 14 48 8b 04 c3 ff 42 RIP [] kmem_cache_alloc+0x9a/0x185 RSP CR2: 0000000000000000 ---[ end trace 42f41a982344e606 ]--- Reported-by: Ingo Molnar Signed-off-by: Eric Paris Signed-off-by: James Morris --- security/selinux/avc.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'security') diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 1ed0f076aad..b4b5da1c0a4 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -868,8 +868,19 @@ u32 avc_policy_seqno(void) void avc_disable(void) { - avc_flush(); - synchronize_rcu(); - if (avc_node_cachep) - kmem_cache_destroy(avc_node_cachep); + /* + * If you are looking at this because you have realized that we are + * not destroying the avc_node_cachep it might be easy to fix, but + * I don't know the memory barrier semantics well enough to know. It's + * possible that some other task dereferenced security_ops when + * it still pointed to selinux operations. If that is the case it's + * possible that it is about to use the avc and is about to need the + * avc_node_cachep. I know I could wrap the security.c security_ops call + * in an rcu_lock, but seriously, it's not worth it. Instead I just flush + * the cache and get that memory back. + */ + if (avc_node_cachep) { + avc_flush(); + /* kmem_cache_destroy(avc_node_cachep); */ + } } -- cgit v1.2.3 From d81165919ebf6e1cb9eeb612150f9287ad414659 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Wed, 23 Sep 2009 13:46:00 -0400 Subject: lsm: Use a compressed IPv6 string format in audit events Currently the audit subsystem prints uncompressed IPv6 addresses which not only differs from common usage but also results in ridiculously large audit strings which is not a good thing. This patch fixes this by simply converting audit to always print compressed IPv6 addresses. Old message example: audit(1253576792.161:30): avc: denied { ingress } for saddr=0000:0000:0000:0000:0000:0000:0000:0001 src=5000 daddr=0000:0000:0000:0000:0000:0000:0000:0001 dest=35502 netif=lo scontext=system_u:object_r:unlabeled_t:s15:c0.c1023 tcontext=system_u:object_r:lo_netif_t:s0-s15:c0.c1023 tclass=netif New message example: audit(1253576792.161:30): avc: denied { ingress } for saddr=::1 src=5000 daddr=::1 dest=35502 netif=lo scontext=system_u:object_r:unlabeled_t:s15:c0.c1023 tcontext=system_u:object_r:lo_netif_t:s0-s15:c0.c1023 tclass=netif Signed-off-by: Paul Moore Signed-off-by: Eric Paris Signed-off-by: Al Viro --- security/lsm_audit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'security') diff --git a/security/lsm_audit.c b/security/lsm_audit.c index 500aad0ebd6..3bb90b6f1dd 100644 --- a/security/lsm_audit.c +++ b/security/lsm_audit.c @@ -187,7 +187,7 @@ static inline void print_ipv6_addr(struct audit_buffer *ab, char *name1, char *name2) { if (!ipv6_addr_any(addr)) - audit_log_format(ab, " %s=%pI6", name1, addr); + audit_log_format(ab, " %s=%pI6c", name1, addr); if (port) audit_log_format(ab, " %s=%d", name2, ntohs(port)); } -- cgit v1.2.3 From be367d09927023d081f9199665c8500f69f14d22 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Wed, 23 Sep 2009 15:56:31 -0700 Subject: cgroups: let ss->can_attach and ss->attach do whole threadgroups at a time Alter the ss->can_attach and ss->attach functions to be able to deal with a whole threadgroup at a time, for use in cgroup_attach_proc. (This is a pre-patch to cgroup-procs-writable.patch.) Currently, new mode of the attach function can only tell the subsystem about the old cgroup of the threadgroup leader. No subsystem currently needs that information for each thread that's being moved, but if one were to be added (for example, one that counts tasks within a group) this bit would need to be reworked a bit to tell the subsystem the right information. [hidave.darkstar@gmail.com: fix build] Signed-off-by: Ben Blum Signed-off-by: Paul Menage Acked-by: Li Zefan Reviewed-by: Matt Helsley Cc: "Eric W. Biederman" Cc: Oleg Nesterov Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Dave Young Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/device_cgroup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'security') diff --git a/security/device_cgroup.c b/security/device_cgroup.c index b8186bac8b7..6cf8fd2b79e 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -61,7 +61,8 @@ static inline struct dev_cgroup *task_devcgroup(struct task_struct *task) struct cgroup_subsys devices_subsys; static int devcgroup_can_attach(struct cgroup_subsys *ss, - struct cgroup *new_cgroup, struct task_struct *task) + struct cgroup *new_cgroup, struct task_struct *task, + bool threadgroup) { if (current != task && !capable(CAP_SYS_ADMIN)) return -EPERM; -- cgit v1.2.3 From 0b7570e77f7c3abd43107dabc47ea89daf9a1cba Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 23 Sep 2009 15:56:46 -0700 Subject: do_wait() wakeup optimization: change __wake_up_parent() to use filtered wakeup Ratan Nalumasu reported that in a process with many threads doing unnecessary wakeups. Every waiting thread in the process wakes up to loop through the children and see that the only ones it cares about are still not ready. Now that we have struct wait_opts we can change do_wait/__wake_up_parent to use filtered wakeups. We can make child_wait_callback() more clever later, right now it only checks eligible_child(). Signed-off-by: Oleg Nesterov Acked-by: Roland McGrath Cc: Ingo Molnar Cc: Ratan Nalumasu Cc: Vitaly Mayatskikh Acked-by: James Morris Tested-by: Valdis Kletnieks Acked-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'security') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 417f7c99452..bb230d5d708 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2411,7 +2411,7 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm) /* Wake up the parent if it is waiting so that it can recheck * wait permission to the new task SID. */ read_lock(&tasklist_lock); - wake_up_interruptible(¤t->real_parent->signal->wait_chldexit); + __wake_up_parent(current, current->real_parent); read_unlock(&tasklist_lock); } -- cgit v1.2.3 From 8d65af789f3e2cf4cfbdbf71a0f7a61ebcd41d38 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 23 Sep 2009 15:57:19 -0700 Subject: sysctl: remove "struct file *" argument of ->proc_handler It's unused. It isn't needed -- read or write flag is already passed and sysctl shouldn't care about the rest. It _was_ used in two places at arch/frv for some reason. Signed-off-by: Alexey Dobriyan Cc: David Howells Cc: "Eric W. Biederman" Cc: Al Viro Cc: Ralf Baechle Cc: Martin Schwidefsky Cc: Ingo Molnar Cc: "David S. Miller" Cc: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/min_addr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'security') diff --git a/security/min_addr.c b/security/min_addr.c index 14cc7b3b8d0..c844eed7915 100644 --- a/security/min_addr.c +++ b/security/min_addr.c @@ -28,12 +28,12 @@ static void update_mmap_min_addr(void) * sysctl handler which just sets dac_mmap_min_addr = the new value and then * calls update_mmap_min_addr() so non MAP_FIXED hints get rounded properly */ -int mmap_min_addr_handler(struct ctl_table *table, int write, struct file *filp, +int mmap_min_addr_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { int ret; - ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos); + ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); update_mmap_min_addr(); -- cgit v1.2.3