diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-11 17:55:15 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-11 17:55:15 -0500 |
commit | c727b4c63c9bf33c65351bbcc738161edb444b24 (patch) | |
tree | 2e9f3d6cfa17f2fc62a64dbb41fff9e6baabfd24 /kernel | |
parent | 93ccb3910ae3dbff6d224aecd22d8eece3d70ce9 (diff) | |
parent | 3cb7a56344ca45ee56d71c5f8fe9f922306bff1f (diff) |
Merge branch 'akpm' (incoming fixes from Andrew)
Merge misc fixes from Andrew Morton:
"The audit fixes have been floating around for a while - Al and Eric
aren't responding to either myself or Kees so I asked Kees to
re-review them and here they are."
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (22 commits)
lib/rbtree.c: avoid the use of non-static __always_inline
MAINTAINERS: Omar had moved
mm: compaction: partially revert capture of suitable high-order page
linux/audit.h: move ptrace.h include to kernel header
kernel/audit.c: avoid negative sleep durations
audit: catch possible NULL audit buffers
audit: create explicit AUDIT_SECCOMP event type
MAINTAINERS: fix a status pattern
MAINTAINERS: fix arch/arm/plat-omap/include/plat/omap_hwmod.h
mm: thp: acquire the anon_vma rwsem for write during split
mm: mmap: annotate vm_lock_anon_vma locking properly for lockdep
lockdep, rwsem: provide down_write_nest_lock()
arch/mn10300/Kconfig: select CONFIG_GENERIC_ATOMIC64
mm: bootmem: fix free_all_bootmem_core() with odd bitmap alignment
mm: use aligned zone start for pfn_to_bitidx calculation
fs/exec.c: work around icc miscompilation
mm: compaction: fix echo 1 > compact_memory return error issue
mm: memblock: fix wrong memmove size in memblock_merge_regions()
drivers/video/ssd1307fb.c: fix bit order bug in the byte translation function
mm: migrate: check page_count of THP before migrating
...
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/audit.c | 40 | ||||
-rw-r--r-- | kernel/audit_tree.c | 26 | ||||
-rw-r--r-- | kernel/audit_watch.c | 2 | ||||
-rw-r--r-- | kernel/auditsc.c | 20 | ||||
-rw-r--r-- | kernel/rwsem.c | 10 |
5 files changed, 71 insertions, 27 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 40414e9143db..d596e5355f15 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -272,6 +272,8 @@ static int audit_log_config_change(char *function_name, int new, int old, | |||
272 | int rc = 0; | 272 | int rc = 0; |
273 | 273 | ||
274 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 274 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
275 | if (unlikely(!ab)) | ||
276 | return rc; | ||
275 | audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new, | 277 | audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new, |
276 | old, from_kuid(&init_user_ns, loginuid), sessionid); | 278 | old, from_kuid(&init_user_ns, loginuid), sessionid); |
277 | if (sid) { | 279 | if (sid) { |
@@ -619,6 +621,8 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | |||
619 | } | 621 | } |
620 | 622 | ||
621 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); | 623 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); |
624 | if (unlikely(!*ab)) | ||
625 | return rc; | ||
622 | audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u", | 626 | audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u", |
623 | task_tgid_vnr(current), | 627 | task_tgid_vnr(current), |
624 | from_kuid(&init_user_ns, current_uid()), | 628 | from_kuid(&init_user_ns, current_uid()), |
@@ -1097,6 +1101,23 @@ static inline void audit_get_stamp(struct audit_context *ctx, | |||
1097 | } | 1101 | } |
1098 | } | 1102 | } |
1099 | 1103 | ||
1104 | /* | ||
1105 | * Wait for auditd to drain the queue a little | ||
1106 | */ | ||
1107 | static void wait_for_auditd(unsigned long sleep_time) | ||
1108 | { | ||
1109 | DECLARE_WAITQUEUE(wait, current); | ||
1110 | set_current_state(TASK_INTERRUPTIBLE); | ||
1111 | add_wait_queue(&audit_backlog_wait, &wait); | ||
1112 | |||
1113 | if (audit_backlog_limit && | ||
1114 | skb_queue_len(&audit_skb_queue) > audit_backlog_limit) | ||
1115 | schedule_timeout(sleep_time); | ||
1116 | |||
1117 | __set_current_state(TASK_RUNNING); | ||
1118 | remove_wait_queue(&audit_backlog_wait, &wait); | ||
1119 | } | ||
1120 | |||
1100 | /* Obtain an audit buffer. This routine does locking to obtain the | 1121 | /* Obtain an audit buffer. This routine does locking to obtain the |
1101 | * audit buffer, but then no locking is required for calls to | 1122 | * audit buffer, but then no locking is required for calls to |
1102 | * audit_log_*format. If the tsk is a task that is currently in a | 1123 | * audit_log_*format. If the tsk is a task that is currently in a |
@@ -1142,20 +1163,13 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, | |||
1142 | 1163 | ||
1143 | while (audit_backlog_limit | 1164 | while (audit_backlog_limit |
1144 | && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { | 1165 | && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { |
1145 | if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time | 1166 | if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time) { |
1146 | && time_before(jiffies, timeout_start + audit_backlog_wait_time)) { | 1167 | unsigned long sleep_time; |
1147 | 1168 | ||
1148 | /* Wait for auditd to drain the queue a little */ | 1169 | sleep_time = timeout_start + audit_backlog_wait_time - |
1149 | DECLARE_WAITQUEUE(wait, current); | 1170 | jiffies; |
1150 | set_current_state(TASK_INTERRUPTIBLE); | 1171 | if ((long)sleep_time > 0) |
1151 | add_wait_queue(&audit_backlog_wait, &wait); | 1172 | wait_for_auditd(sleep_time); |
1152 | |||
1153 | if (audit_backlog_limit && | ||
1154 | skb_queue_len(&audit_skb_queue) > audit_backlog_limit) | ||
1155 | schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies); | ||
1156 | |||
1157 | __set_current_state(TASK_RUNNING); | ||
1158 | remove_wait_queue(&audit_backlog_wait, &wait); | ||
1159 | continue; | 1173 | continue; |
1160 | } | 1174 | } |
1161 | if (audit_rate_check() && printk_ratelimit()) | 1175 | if (audit_rate_check() && printk_ratelimit()) |
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index e81175ef25f8..642a89c4f3d6 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c | |||
@@ -449,11 +449,26 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) | |||
449 | return 0; | 449 | return 0; |
450 | } | 450 | } |
451 | 451 | ||
452 | static void audit_log_remove_rule(struct audit_krule *rule) | ||
453 | { | ||
454 | struct audit_buffer *ab; | ||
455 | |||
456 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | ||
457 | if (unlikely(!ab)) | ||
458 | return; | ||
459 | audit_log_format(ab, "op="); | ||
460 | audit_log_string(ab, "remove rule"); | ||
461 | audit_log_format(ab, " dir="); | ||
462 | audit_log_untrustedstring(ab, rule->tree->pathname); | ||
463 | audit_log_key(ab, rule->filterkey); | ||
464 | audit_log_format(ab, " list=%d res=1", rule->listnr); | ||
465 | audit_log_end(ab); | ||
466 | } | ||
467 | |||
452 | static void kill_rules(struct audit_tree *tree) | 468 | static void kill_rules(struct audit_tree *tree) |
453 | { | 469 | { |
454 | struct audit_krule *rule, *next; | 470 | struct audit_krule *rule, *next; |
455 | struct audit_entry *entry; | 471 | struct audit_entry *entry; |
456 | struct audit_buffer *ab; | ||
457 | 472 | ||
458 | list_for_each_entry_safe(rule, next, &tree->rules, rlist) { | 473 | list_for_each_entry_safe(rule, next, &tree->rules, rlist) { |
459 | entry = container_of(rule, struct audit_entry, rule); | 474 | entry = container_of(rule, struct audit_entry, rule); |
@@ -461,14 +476,7 @@ static void kill_rules(struct audit_tree *tree) | |||
461 | list_del_init(&rule->rlist); | 476 | list_del_init(&rule->rlist); |
462 | if (rule->tree) { | 477 | if (rule->tree) { |
463 | /* not a half-baked one */ | 478 | /* not a half-baked one */ |
464 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 479 | audit_log_remove_rule(rule); |
465 | audit_log_format(ab, "op="); | ||
466 | audit_log_string(ab, "remove rule"); | ||
467 | audit_log_format(ab, " dir="); | ||
468 | audit_log_untrustedstring(ab, rule->tree->pathname); | ||
469 | audit_log_key(ab, rule->filterkey); | ||
470 | audit_log_format(ab, " list=%d res=1", rule->listnr); | ||
471 | audit_log_end(ab); | ||
472 | rule->tree = NULL; | 480 | rule->tree = NULL; |
473 | list_del_rcu(&entry->list); | 481 | list_del_rcu(&entry->list); |
474 | list_del(&entry->rule.list); | 482 | list_del(&entry->rule.list); |
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 4a599f699adc..22831c4d369c 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c | |||
@@ -240,6 +240,8 @@ static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watc | |||
240 | if (audit_enabled) { | 240 | if (audit_enabled) { |
241 | struct audit_buffer *ab; | 241 | struct audit_buffer *ab; |
242 | ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE); | 242 | ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE); |
243 | if (unlikely(!ab)) | ||
244 | return; | ||
243 | audit_log_format(ab, "auid=%u ses=%u op=", | 245 | audit_log_format(ab, "auid=%u ses=%u op=", |
244 | from_kuid(&init_user_ns, audit_get_loginuid(current)), | 246 | from_kuid(&init_user_ns, audit_get_loginuid(current)), |
245 | audit_get_sessionid(current)); | 247 | audit_get_sessionid(current)); |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index e37e6a12c5e3..a371f857a0a9 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -1464,14 +1464,14 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
1464 | audit_log_end(ab); | 1464 | audit_log_end(ab); |
1465 | ab = audit_log_start(context, GFP_KERNEL, | 1465 | ab = audit_log_start(context, GFP_KERNEL, |
1466 | AUDIT_IPC_SET_PERM); | 1466 | AUDIT_IPC_SET_PERM); |
1467 | if (unlikely(!ab)) | ||
1468 | return; | ||
1467 | audit_log_format(ab, | 1469 | audit_log_format(ab, |
1468 | "qbytes=%lx ouid=%u ogid=%u mode=%#ho", | 1470 | "qbytes=%lx ouid=%u ogid=%u mode=%#ho", |
1469 | context->ipc.qbytes, | 1471 | context->ipc.qbytes, |
1470 | context->ipc.perm_uid, | 1472 | context->ipc.perm_uid, |
1471 | context->ipc.perm_gid, | 1473 | context->ipc.perm_gid, |
1472 | context->ipc.perm_mode); | 1474 | context->ipc.perm_mode); |
1473 | if (!ab) | ||
1474 | return; | ||
1475 | } | 1475 | } |
1476 | break; } | 1476 | break; } |
1477 | case AUDIT_MQ_OPEN: { | 1477 | case AUDIT_MQ_OPEN: { |
@@ -2675,7 +2675,7 @@ void __audit_mmap_fd(int fd, int flags) | |||
2675 | context->type = AUDIT_MMAP; | 2675 | context->type = AUDIT_MMAP; |
2676 | } | 2676 | } |
2677 | 2677 | ||
2678 | static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) | 2678 | static void audit_log_task(struct audit_buffer *ab) |
2679 | { | 2679 | { |
2680 | kuid_t auid, uid; | 2680 | kuid_t auid, uid; |
2681 | kgid_t gid; | 2681 | kgid_t gid; |
@@ -2693,6 +2693,11 @@ static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) | |||
2693 | audit_log_task_context(ab); | 2693 | audit_log_task_context(ab); |
2694 | audit_log_format(ab, " pid=%d comm=", current->pid); | 2694 | audit_log_format(ab, " pid=%d comm=", current->pid); |
2695 | audit_log_untrustedstring(ab, current->comm); | 2695 | audit_log_untrustedstring(ab, current->comm); |
2696 | } | ||
2697 | |||
2698 | static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) | ||
2699 | { | ||
2700 | audit_log_task(ab); | ||
2696 | audit_log_format(ab, " reason="); | 2701 | audit_log_format(ab, " reason="); |
2697 | audit_log_string(ab, reason); | 2702 | audit_log_string(ab, reason); |
2698 | audit_log_format(ab, " sig=%ld", signr); | 2703 | audit_log_format(ab, " sig=%ld", signr); |
@@ -2715,6 +2720,8 @@ void audit_core_dumps(long signr) | |||
2715 | return; | 2720 | return; |
2716 | 2721 | ||
2717 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); | 2722 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); |
2723 | if (unlikely(!ab)) | ||
2724 | return; | ||
2718 | audit_log_abend(ab, "memory violation", signr); | 2725 | audit_log_abend(ab, "memory violation", signr); |
2719 | audit_log_end(ab); | 2726 | audit_log_end(ab); |
2720 | } | 2727 | } |
@@ -2723,8 +2730,11 @@ void __audit_seccomp(unsigned long syscall, long signr, int code) | |||
2723 | { | 2730 | { |
2724 | struct audit_buffer *ab; | 2731 | struct audit_buffer *ab; |
2725 | 2732 | ||
2726 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); | 2733 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_SECCOMP); |
2727 | audit_log_abend(ab, "seccomp", signr); | 2734 | if (unlikely(!ab)) |
2735 | return; | ||
2736 | audit_log_task(ab); | ||
2737 | audit_log_format(ab, " sig=%ld", signr); | ||
2728 | audit_log_format(ab, " syscall=%ld", syscall); | 2738 | audit_log_format(ab, " syscall=%ld", syscall); |
2729 | audit_log_format(ab, " compat=%d", is_compat_task()); | 2739 | audit_log_format(ab, " compat=%d", is_compat_task()); |
2730 | audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current)); | 2740 | audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current)); |
diff --git a/kernel/rwsem.c b/kernel/rwsem.c index 6850f53e02d8..b3c6c3fcd847 100644 --- a/kernel/rwsem.c +++ b/kernel/rwsem.c | |||
@@ -116,6 +116,16 @@ void down_read_nested(struct rw_semaphore *sem, int subclass) | |||
116 | 116 | ||
117 | EXPORT_SYMBOL(down_read_nested); | 117 | EXPORT_SYMBOL(down_read_nested); |
118 | 118 | ||
119 | void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest) | ||
120 | { | ||
121 | might_sleep(); | ||
122 | rwsem_acquire_nest(&sem->dep_map, 0, 0, nest, _RET_IP_); | ||
123 | |||
124 | LOCK_CONTENDED(sem, __down_write_trylock, __down_write); | ||
125 | } | ||
126 | |||
127 | EXPORT_SYMBOL(_down_write_nest_lock); | ||
128 | |||
119 | void down_write_nested(struct rw_semaphore *sem, int subclass) | 129 | void down_write_nested(struct rw_semaphore *sem, int subclass) |
120 | { | 130 | { |
121 | might_sleep(); | 131 | might_sleep(); |