diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/Kconfig.locks | 2 | ||||
-rw-r--r-- | kernel/auditsc.c | 27 | ||||
-rw-r--r-- | kernel/pm_qos_params.c | 2 |
3 files changed, 19 insertions, 12 deletions
diff --git a/kernel/Kconfig.locks b/kernel/Kconfig.locks index 88c92fb44618..5068e2a4e75f 100644 --- a/kernel/Kconfig.locks +++ b/kernel/Kconfig.locks | |||
@@ -199,4 +199,4 @@ config INLINE_WRITE_UNLOCK_IRQRESTORE | |||
199 | def_bool !DEBUG_SPINLOCK && ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE | 199 | def_bool !DEBUG_SPINLOCK && ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE |
200 | 200 | ||
201 | config MUTEX_SPIN_ON_OWNER | 201 | config MUTEX_SPIN_ON_OWNER |
202 | def_bool SMP && !DEBUG_MUTEXES && !HAVE_DEFAULT_NO_SPIN_MUTEXES | 202 | def_bool SMP && !DEBUG_MUTEXES |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index b33513a08beb..00d79df03e76 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -443,17 +443,25 @@ static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree) | |||
443 | 443 | ||
444 | /* Determine if any context name data matches a rule's watch data */ | 444 | /* Determine if any context name data matches a rule's watch data */ |
445 | /* Compare a task_struct with an audit_rule. Return 1 on match, 0 | 445 | /* Compare a task_struct with an audit_rule. Return 1 on match, 0 |
446 | * otherwise. */ | 446 | * otherwise. |
447 | * | ||
448 | * If task_creation is true, this is an explicit indication that we are | ||
449 | * filtering a task rule at task creation time. This and tsk == current are | ||
450 | * the only situations where tsk->cred may be accessed without an rcu read lock. | ||
451 | */ | ||
447 | static int audit_filter_rules(struct task_struct *tsk, | 452 | static int audit_filter_rules(struct task_struct *tsk, |
448 | struct audit_krule *rule, | 453 | struct audit_krule *rule, |
449 | struct audit_context *ctx, | 454 | struct audit_context *ctx, |
450 | struct audit_names *name, | 455 | struct audit_names *name, |
451 | enum audit_state *state) | 456 | enum audit_state *state, |
457 | bool task_creation) | ||
452 | { | 458 | { |
453 | const struct cred *cred = get_task_cred(tsk); | 459 | const struct cred *cred; |
454 | int i, j, need_sid = 1; | 460 | int i, j, need_sid = 1; |
455 | u32 sid; | 461 | u32 sid; |
456 | 462 | ||
463 | cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation); | ||
464 | |||
457 | for (i = 0; i < rule->field_count; i++) { | 465 | for (i = 0; i < rule->field_count; i++) { |
458 | struct audit_field *f = &rule->fields[i]; | 466 | struct audit_field *f = &rule->fields[i]; |
459 | int result = 0; | 467 | int result = 0; |
@@ -637,10 +645,8 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
637 | break; | 645 | break; |
638 | } | 646 | } |
639 | 647 | ||
640 | if (!result) { | 648 | if (!result) |
641 | put_cred(cred); | ||
642 | return 0; | 649 | return 0; |
643 | } | ||
644 | } | 650 | } |
645 | 651 | ||
646 | if (ctx) { | 652 | if (ctx) { |
@@ -656,7 +662,6 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
656 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; | 662 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; |
657 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; | 663 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; |
658 | } | 664 | } |
659 | put_cred(cred); | ||
660 | return 1; | 665 | return 1; |
661 | } | 666 | } |
662 | 667 | ||
@@ -671,7 +676,8 @@ static enum audit_state audit_filter_task(struct task_struct *tsk, char **key) | |||
671 | 676 | ||
672 | rcu_read_lock(); | 677 | rcu_read_lock(); |
673 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) { | 678 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) { |
674 | if (audit_filter_rules(tsk, &e->rule, NULL, NULL, &state)) { | 679 | if (audit_filter_rules(tsk, &e->rule, NULL, NULL, |
680 | &state, true)) { | ||
675 | if (state == AUDIT_RECORD_CONTEXT) | 681 | if (state == AUDIT_RECORD_CONTEXT) |
676 | *key = kstrdup(e->rule.filterkey, GFP_ATOMIC); | 682 | *key = kstrdup(e->rule.filterkey, GFP_ATOMIC); |
677 | rcu_read_unlock(); | 683 | rcu_read_unlock(); |
@@ -705,7 +711,7 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, | |||
705 | list_for_each_entry_rcu(e, list, list) { | 711 | list_for_each_entry_rcu(e, list, list) { |
706 | if ((e->rule.mask[word] & bit) == bit && | 712 | if ((e->rule.mask[word] & bit) == bit && |
707 | audit_filter_rules(tsk, &e->rule, ctx, NULL, | 713 | audit_filter_rules(tsk, &e->rule, ctx, NULL, |
708 | &state)) { | 714 | &state, false)) { |
709 | rcu_read_unlock(); | 715 | rcu_read_unlock(); |
710 | ctx->current_state = state; | 716 | ctx->current_state = state; |
711 | return state; | 717 | return state; |
@@ -743,7 +749,8 @@ void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx) | |||
743 | 749 | ||
744 | list_for_each_entry_rcu(e, list, list) { | 750 | list_for_each_entry_rcu(e, list, list) { |
745 | if ((e->rule.mask[word] & bit) == bit && | 751 | if ((e->rule.mask[word] & bit) == bit && |
746 | audit_filter_rules(tsk, &e->rule, ctx, n, &state)) { | 752 | audit_filter_rules(tsk, &e->rule, ctx, n, |
753 | &state, false)) { | ||
747 | rcu_read_unlock(); | 754 | rcu_read_unlock(); |
748 | ctx->current_state = state; | 755 | ctx->current_state = state; |
749 | return; | 756 | return; |
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index 0da058bff8eb..beb184689af9 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c | |||
@@ -385,7 +385,7 @@ static ssize_t pm_qos_power_read(struct file *filp, char __user *buf, | |||
385 | s32 value; | 385 | s32 value; |
386 | unsigned long flags; | 386 | unsigned long flags; |
387 | struct pm_qos_object *o; | 387 | struct pm_qos_object *o; |
388 | struct pm_qos_request_list *pm_qos_req = filp->private_data;; | 388 | struct pm_qos_request_list *pm_qos_req = filp->private_data; |
389 | 389 | ||
390 | if (!pm_qos_req) | 390 | if (!pm_qos_req) |
391 | return -EINVAL; | 391 | return -EINVAL; |