diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/audit.h | 1 | ||||
-rw-r--r-- | kernel/auditfilter.c | 209 | ||||
-rw-r--r-- | kernel/auditsc.c | 65 | ||||
-rw-r--r-- | kernel/futex.c | 8 | ||||
-rw-r--r-- | kernel/irq/handle.c | 4 | ||||
-rw-r--r-- | kernel/irq/manage.c | 48 | ||||
-rw-r--r-- | kernel/irq/spurious.c | 4 |
7 files changed, 243 insertions, 96 deletions
diff --git a/kernel/audit.h b/kernel/audit.h index 8323e4132a33..6aa33b848cf2 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
@@ -81,6 +81,7 @@ struct audit_krule { | |||
81 | u32 mask[AUDIT_BITMASK_SIZE]; | 81 | u32 mask[AUDIT_BITMASK_SIZE]; |
82 | u32 buflen; /* for data alloc on list rules */ | 82 | u32 buflen; /* for data alloc on list rules */ |
83 | u32 field_count; | 83 | u32 field_count; |
84 | char *filterkey; /* ties events to rules */ | ||
84 | struct audit_field *fields; | 85 | struct audit_field *fields; |
85 | struct audit_field *inode_f; /* quick access to an inode field */ | 86 | struct audit_field *inode_f; /* quick access to an inode field */ |
86 | struct audit_watch *watch; /* associated watch */ | 87 | struct audit_watch *watch; /* associated watch */ |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 4c99d2c586ed..5b4e16276ca0 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -141,6 +141,7 @@ static inline void audit_free_rule(struct audit_entry *e) | |||
141 | selinux_audit_rule_free(f->se_rule); | 141 | selinux_audit_rule_free(f->se_rule); |
142 | } | 142 | } |
143 | kfree(e->rule.fields); | 143 | kfree(e->rule.fields); |
144 | kfree(e->rule.filterkey); | ||
144 | kfree(e); | 145 | kfree(e); |
145 | } | 146 | } |
146 | 147 | ||
@@ -278,6 +279,29 @@ static int audit_to_watch(struct audit_krule *krule, char *path, int len, | |||
278 | return 0; | 279 | return 0; |
279 | } | 280 | } |
280 | 281 | ||
282 | static __u32 *classes[AUDIT_SYSCALL_CLASSES]; | ||
283 | |||
284 | int __init audit_register_class(int class, unsigned *list) | ||
285 | { | ||
286 | __u32 *p = kzalloc(AUDIT_BITMASK_SIZE * sizeof(__u32), GFP_KERNEL); | ||
287 | if (!p) | ||
288 | return -ENOMEM; | ||
289 | while (*list != ~0U) { | ||
290 | unsigned n = *list++; | ||
291 | if (n >= AUDIT_BITMASK_SIZE * 32 - AUDIT_SYSCALL_CLASSES) { | ||
292 | kfree(p); | ||
293 | return -EINVAL; | ||
294 | } | ||
295 | p[AUDIT_WORD(n)] |= AUDIT_BIT(n); | ||
296 | } | ||
297 | if (class >= AUDIT_SYSCALL_CLASSES || classes[class]) { | ||
298 | kfree(p); | ||
299 | return -EINVAL; | ||
300 | } | ||
301 | classes[class] = p; | ||
302 | return 0; | ||
303 | } | ||
304 | |||
281 | /* Common user-space to kernel rule translation. */ | 305 | /* Common user-space to kernel rule translation. */ |
282 | static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) | 306 | static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) |
283 | { | 307 | { |
@@ -321,6 +345,22 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) | |||
321 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) | 345 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) |
322 | entry->rule.mask[i] = rule->mask[i]; | 346 | entry->rule.mask[i] = rule->mask[i]; |
323 | 347 | ||
348 | for (i = 0; i < AUDIT_SYSCALL_CLASSES; i++) { | ||
349 | int bit = AUDIT_BITMASK_SIZE * 32 - i - 1; | ||
350 | __u32 *p = &entry->rule.mask[AUDIT_WORD(bit)]; | ||
351 | __u32 *class; | ||
352 | |||
353 | if (!(*p & AUDIT_BIT(bit))) | ||
354 | continue; | ||
355 | *p &= ~AUDIT_BIT(bit); | ||
356 | class = classes[i]; | ||
357 | if (class) { | ||
358 | int j; | ||
359 | for (j = 0; j < AUDIT_BITMASK_SIZE; j++) | ||
360 | entry->rule.mask[j] |= class[j]; | ||
361 | } | ||
362 | } | ||
363 | |||
324 | return entry; | 364 | return entry; |
325 | 365 | ||
326 | exit_err: | 366 | exit_err: |
@@ -469,11 +509,16 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
469 | case AUDIT_ARG2: | 509 | case AUDIT_ARG2: |
470 | case AUDIT_ARG3: | 510 | case AUDIT_ARG3: |
471 | break; | 511 | break; |
472 | case AUDIT_SE_USER: | 512 | case AUDIT_SUBJ_USER: |
473 | case AUDIT_SE_ROLE: | 513 | case AUDIT_SUBJ_ROLE: |
474 | case AUDIT_SE_TYPE: | 514 | case AUDIT_SUBJ_TYPE: |
475 | case AUDIT_SE_SEN: | 515 | case AUDIT_SUBJ_SEN: |
476 | case AUDIT_SE_CLR: | 516 | case AUDIT_SUBJ_CLR: |
517 | case AUDIT_OBJ_USER: | ||
518 | case AUDIT_OBJ_ROLE: | ||
519 | case AUDIT_OBJ_TYPE: | ||
520 | case AUDIT_OBJ_LEV_LOW: | ||
521 | case AUDIT_OBJ_LEV_HIGH: | ||
477 | str = audit_unpack_string(&bufp, &remain, f->val); | 522 | str = audit_unpack_string(&bufp, &remain, f->val); |
478 | if (IS_ERR(str)) | 523 | if (IS_ERR(str)) |
479 | goto exit_free; | 524 | goto exit_free; |
@@ -511,6 +556,16 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
511 | if (err) | 556 | if (err) |
512 | goto exit_free; | 557 | goto exit_free; |
513 | break; | 558 | break; |
559 | case AUDIT_FILTERKEY: | ||
560 | err = -EINVAL; | ||
561 | if (entry->rule.filterkey || f->val > AUDIT_MAX_KEY_LEN) | ||
562 | goto exit_free; | ||
563 | str = audit_unpack_string(&bufp, &remain, f->val); | ||
564 | if (IS_ERR(str)) | ||
565 | goto exit_free; | ||
566 | entry->rule.buflen += f->val; | ||
567 | entry->rule.filterkey = str; | ||
568 | break; | ||
514 | default: | 569 | default: |
515 | goto exit_free; | 570 | goto exit_free; |
516 | } | 571 | } |
@@ -600,11 +655,16 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) | |||
600 | data->fields[i] = f->type; | 655 | data->fields[i] = f->type; |
601 | data->fieldflags[i] = f->op; | 656 | data->fieldflags[i] = f->op; |
602 | switch(f->type) { | 657 | switch(f->type) { |
603 | case AUDIT_SE_USER: | 658 | case AUDIT_SUBJ_USER: |
604 | case AUDIT_SE_ROLE: | 659 | case AUDIT_SUBJ_ROLE: |
605 | case AUDIT_SE_TYPE: | 660 | case AUDIT_SUBJ_TYPE: |
606 | case AUDIT_SE_SEN: | 661 | case AUDIT_SUBJ_SEN: |
607 | case AUDIT_SE_CLR: | 662 | case AUDIT_SUBJ_CLR: |
663 | case AUDIT_OBJ_USER: | ||
664 | case AUDIT_OBJ_ROLE: | ||
665 | case AUDIT_OBJ_TYPE: | ||
666 | case AUDIT_OBJ_LEV_LOW: | ||
667 | case AUDIT_OBJ_LEV_HIGH: | ||
608 | data->buflen += data->values[i] = | 668 | data->buflen += data->values[i] = |
609 | audit_pack_string(&bufp, f->se_str); | 669 | audit_pack_string(&bufp, f->se_str); |
610 | break; | 670 | break; |
@@ -612,6 +672,10 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) | |||
612 | data->buflen += data->values[i] = | 672 | data->buflen += data->values[i] = |
613 | audit_pack_string(&bufp, krule->watch->path); | 673 | audit_pack_string(&bufp, krule->watch->path); |
614 | break; | 674 | break; |
675 | case AUDIT_FILTERKEY: | ||
676 | data->buflen += data->values[i] = | ||
677 | audit_pack_string(&bufp, krule->filterkey); | ||
678 | break; | ||
615 | default: | 679 | default: |
616 | data->values[i] = f->val; | 680 | data->values[i] = f->val; |
617 | } | 681 | } |
@@ -639,11 +703,16 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b) | |||
639 | return 1; | 703 | return 1; |
640 | 704 | ||
641 | switch(a->fields[i].type) { | 705 | switch(a->fields[i].type) { |
642 | case AUDIT_SE_USER: | 706 | case AUDIT_SUBJ_USER: |
643 | case AUDIT_SE_ROLE: | 707 | case AUDIT_SUBJ_ROLE: |
644 | case AUDIT_SE_TYPE: | 708 | case AUDIT_SUBJ_TYPE: |
645 | case AUDIT_SE_SEN: | 709 | case AUDIT_SUBJ_SEN: |
646 | case AUDIT_SE_CLR: | 710 | case AUDIT_SUBJ_CLR: |
711 | case AUDIT_OBJ_USER: | ||
712 | case AUDIT_OBJ_ROLE: | ||
713 | case AUDIT_OBJ_TYPE: | ||
714 | case AUDIT_OBJ_LEV_LOW: | ||
715 | case AUDIT_OBJ_LEV_HIGH: | ||
647 | if (strcmp(a->fields[i].se_str, b->fields[i].se_str)) | 716 | if (strcmp(a->fields[i].se_str, b->fields[i].se_str)) |
648 | return 1; | 717 | return 1; |
649 | break; | 718 | break; |
@@ -651,6 +720,11 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b) | |||
651 | if (strcmp(a->watch->path, b->watch->path)) | 720 | if (strcmp(a->watch->path, b->watch->path)) |
652 | return 1; | 721 | return 1; |
653 | break; | 722 | break; |
723 | case AUDIT_FILTERKEY: | ||
724 | /* both filterkeys exist based on above type compare */ | ||
725 | if (strcmp(a->filterkey, b->filterkey)) | ||
726 | return 1; | ||
727 | break; | ||
654 | default: | 728 | default: |
655 | if (a->fields[i].val != b->fields[i].val) | 729 | if (a->fields[i].val != b->fields[i].val) |
656 | return 1; | 730 | return 1; |
@@ -730,6 +804,7 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old, | |||
730 | u32 fcount = old->field_count; | 804 | u32 fcount = old->field_count; |
731 | struct audit_entry *entry; | 805 | struct audit_entry *entry; |
732 | struct audit_krule *new; | 806 | struct audit_krule *new; |
807 | char *fk; | ||
733 | int i, err = 0; | 808 | int i, err = 0; |
734 | 809 | ||
735 | entry = audit_init_entry(fcount); | 810 | entry = audit_init_entry(fcount); |
@@ -753,13 +828,25 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old, | |||
753 | * the originals will all be freed when the old rule is freed. */ | 828 | * the originals will all be freed when the old rule is freed. */ |
754 | for (i = 0; i < fcount; i++) { | 829 | for (i = 0; i < fcount; i++) { |
755 | switch (new->fields[i].type) { | 830 | switch (new->fields[i].type) { |
756 | case AUDIT_SE_USER: | 831 | case AUDIT_SUBJ_USER: |
757 | case AUDIT_SE_ROLE: | 832 | case AUDIT_SUBJ_ROLE: |
758 | case AUDIT_SE_TYPE: | 833 | case AUDIT_SUBJ_TYPE: |
759 | case AUDIT_SE_SEN: | 834 | case AUDIT_SUBJ_SEN: |
760 | case AUDIT_SE_CLR: | 835 | case AUDIT_SUBJ_CLR: |
836 | case AUDIT_OBJ_USER: | ||
837 | case AUDIT_OBJ_ROLE: | ||
838 | case AUDIT_OBJ_TYPE: | ||
839 | case AUDIT_OBJ_LEV_LOW: | ||
840 | case AUDIT_OBJ_LEV_HIGH: | ||
761 | err = audit_dupe_selinux_field(&new->fields[i], | 841 | err = audit_dupe_selinux_field(&new->fields[i], |
762 | &old->fields[i]); | 842 | &old->fields[i]); |
843 | break; | ||
844 | case AUDIT_FILTERKEY: | ||
845 | fk = kstrdup(old->filterkey, GFP_KERNEL); | ||
846 | if (unlikely(!fk)) | ||
847 | err = -ENOMEM; | ||
848 | else | ||
849 | new->filterkey = fk; | ||
763 | } | 850 | } |
764 | if (err) { | 851 | if (err) { |
765 | audit_free_rule(entry); | 852 | audit_free_rule(entry); |
@@ -1245,6 +1332,34 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q) | |||
1245 | skb_queue_tail(q, skb); | 1332 | skb_queue_tail(q, skb); |
1246 | } | 1333 | } |
1247 | 1334 | ||
1335 | /* Log rule additions and removals */ | ||
1336 | static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action, | ||
1337 | struct audit_krule *rule, int res) | ||
1338 | { | ||
1339 | struct audit_buffer *ab; | ||
1340 | |||
1341 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | ||
1342 | if (!ab) | ||
1343 | return; | ||
1344 | audit_log_format(ab, "auid=%u", loginuid); | ||
1345 | if (sid) { | ||
1346 | char *ctx = NULL; | ||
1347 | u32 len; | ||
1348 | if (selinux_ctxid_to_string(sid, &ctx, &len)) | ||
1349 | audit_log_format(ab, " ssid=%u", sid); | ||
1350 | else | ||
1351 | audit_log_format(ab, " subj=%s", ctx); | ||
1352 | kfree(ctx); | ||
1353 | } | ||
1354 | audit_log_format(ab, " %s rule key=", action); | ||
1355 | if (rule->filterkey) | ||
1356 | audit_log_untrustedstring(ab, rule->filterkey); | ||
1357 | else | ||
1358 | audit_log_format(ab, "(null)"); | ||
1359 | audit_log_format(ab, " list=%d res=%d", rule->listnr, res); | ||
1360 | audit_log_end(ab); | ||
1361 | } | ||
1362 | |||
1248 | /** | 1363 | /** |
1249 | * audit_receive_filter - apply all rules to the specified message type | 1364 | * audit_receive_filter - apply all rules to the specified message type |
1250 | * @type: audit message type | 1365 | * @type: audit message type |
@@ -1304,24 +1419,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
1304 | 1419 | ||
1305 | err = audit_add_rule(entry, | 1420 | err = audit_add_rule(entry, |
1306 | &audit_filter_list[entry->rule.listnr]); | 1421 | &audit_filter_list[entry->rule.listnr]); |
1307 | 1422 | audit_log_rule_change(loginuid, sid, "add", &entry->rule, !err); | |
1308 | if (sid) { | ||
1309 | char *ctx = NULL; | ||
1310 | u32 len; | ||
1311 | if (selinux_ctxid_to_string(sid, &ctx, &len)) { | ||
1312 | /* Maybe call audit_panic? */ | ||
1313 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
1314 | "auid=%u ssid=%u add rule to list=%d res=%d", | ||
1315 | loginuid, sid, entry->rule.listnr, !err); | ||
1316 | } else | ||
1317 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
1318 | "auid=%u subj=%s add rule to list=%d res=%d", | ||
1319 | loginuid, ctx, entry->rule.listnr, !err); | ||
1320 | kfree(ctx); | ||
1321 | } else | ||
1322 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
1323 | "auid=%u add rule to list=%d res=%d", | ||
1324 | loginuid, entry->rule.listnr, !err); | ||
1325 | 1423 | ||
1326 | if (err) | 1424 | if (err) |
1327 | audit_free_rule(entry); | 1425 | audit_free_rule(entry); |
@@ -1337,24 +1435,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
1337 | 1435 | ||
1338 | err = audit_del_rule(entry, | 1436 | err = audit_del_rule(entry, |
1339 | &audit_filter_list[entry->rule.listnr]); | 1437 | &audit_filter_list[entry->rule.listnr]); |
1340 | 1438 | audit_log_rule_change(loginuid, sid, "remove", &entry->rule, | |
1341 | if (sid) { | 1439 | !err); |
1342 | char *ctx = NULL; | ||
1343 | u32 len; | ||
1344 | if (selinux_ctxid_to_string(sid, &ctx, &len)) { | ||
1345 | /* Maybe call audit_panic? */ | ||
1346 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
1347 | "auid=%u ssid=%u remove rule from list=%d res=%d", | ||
1348 | loginuid, sid, entry->rule.listnr, !err); | ||
1349 | } else | ||
1350 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
1351 | "auid=%u subj=%s remove rule from list=%d res=%d", | ||
1352 | loginuid, ctx, entry->rule.listnr, !err); | ||
1353 | kfree(ctx); | ||
1354 | } else | ||
1355 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
1356 | "auid=%u remove rule from list=%d res=%d", | ||
1357 | loginuid, entry->rule.listnr, !err); | ||
1358 | 1440 | ||
1359 | audit_free_rule(entry); | 1441 | audit_free_rule(entry); |
1360 | break; | 1442 | break; |
@@ -1514,11 +1596,16 @@ static inline int audit_rule_has_selinux(struct audit_krule *rule) | |||
1514 | for (i = 0; i < rule->field_count; i++) { | 1596 | for (i = 0; i < rule->field_count; i++) { |
1515 | struct audit_field *f = &rule->fields[i]; | 1597 | struct audit_field *f = &rule->fields[i]; |
1516 | switch (f->type) { | 1598 | switch (f->type) { |
1517 | case AUDIT_SE_USER: | 1599 | case AUDIT_SUBJ_USER: |
1518 | case AUDIT_SE_ROLE: | 1600 | case AUDIT_SUBJ_ROLE: |
1519 | case AUDIT_SE_TYPE: | 1601 | case AUDIT_SUBJ_TYPE: |
1520 | case AUDIT_SE_SEN: | 1602 | case AUDIT_SUBJ_SEN: |
1521 | case AUDIT_SE_CLR: | 1603 | case AUDIT_SUBJ_CLR: |
1604 | case AUDIT_OBJ_USER: | ||
1605 | case AUDIT_OBJ_ROLE: | ||
1606 | case AUDIT_OBJ_TYPE: | ||
1607 | case AUDIT_OBJ_LEV_LOW: | ||
1608 | case AUDIT_OBJ_LEV_HIGH: | ||
1522 | return 1; | 1609 | return 1; |
1523 | } | 1610 | } |
1524 | } | 1611 | } |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index dc5e3f01efe7..ae40ac8c39e7 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -186,6 +186,7 @@ struct audit_context { | |||
186 | int auditable; /* 1 if record should be written */ | 186 | int auditable; /* 1 if record should be written */ |
187 | int name_count; | 187 | int name_count; |
188 | struct audit_names names[AUDIT_NAMES]; | 188 | struct audit_names names[AUDIT_NAMES]; |
189 | char * filterkey; /* key for rule that triggered record */ | ||
189 | struct dentry * pwd; | 190 | struct dentry * pwd; |
190 | struct vfsmount * pwdmnt; | 191 | struct vfsmount * pwdmnt; |
191 | struct audit_context *previous; /* For nested syscalls */ | 192 | struct audit_context *previous; /* For nested syscalls */ |
@@ -320,11 +321,11 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
320 | if (ctx) | 321 | if (ctx) |
321 | result = audit_comparator(ctx->loginuid, f->op, f->val); | 322 | result = audit_comparator(ctx->loginuid, f->op, f->val); |
322 | break; | 323 | break; |
323 | case AUDIT_SE_USER: | 324 | case AUDIT_SUBJ_USER: |
324 | case AUDIT_SE_ROLE: | 325 | case AUDIT_SUBJ_ROLE: |
325 | case AUDIT_SE_TYPE: | 326 | case AUDIT_SUBJ_TYPE: |
326 | case AUDIT_SE_SEN: | 327 | case AUDIT_SUBJ_SEN: |
327 | case AUDIT_SE_CLR: | 328 | case AUDIT_SUBJ_CLR: |
328 | /* NOTE: this may return negative values indicating | 329 | /* NOTE: this may return negative values indicating |
329 | a temporary error. We simply treat this as a | 330 | a temporary error. We simply treat this as a |
330 | match for now to avoid losing information that | 331 | match for now to avoid losing information that |
@@ -341,6 +342,46 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
341 | ctx); | 342 | ctx); |
342 | } | 343 | } |
343 | break; | 344 | break; |
345 | case AUDIT_OBJ_USER: | ||
346 | case AUDIT_OBJ_ROLE: | ||
347 | case AUDIT_OBJ_TYPE: | ||
348 | case AUDIT_OBJ_LEV_LOW: | ||
349 | case AUDIT_OBJ_LEV_HIGH: | ||
350 | /* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR | ||
351 | also applies here */ | ||
352 | if (f->se_rule) { | ||
353 | /* Find files that match */ | ||
354 | if (name) { | ||
355 | result = selinux_audit_rule_match( | ||
356 | name->osid, f->type, f->op, | ||
357 | f->se_rule, ctx); | ||
358 | } else if (ctx) { | ||
359 | for (j = 0; j < ctx->name_count; j++) { | ||
360 | if (selinux_audit_rule_match( | ||
361 | ctx->names[j].osid, | ||
362 | f->type, f->op, | ||
363 | f->se_rule, ctx)) { | ||
364 | ++result; | ||
365 | break; | ||
366 | } | ||
367 | } | ||
368 | } | ||
369 | /* Find ipc objects that match */ | ||
370 | if (ctx) { | ||
371 | struct audit_aux_data *aux; | ||
372 | for (aux = ctx->aux; aux; | ||
373 | aux = aux->next) { | ||
374 | if (aux->type == AUDIT_IPC) { | ||
375 | struct audit_aux_data_ipcctl *axi = (void *)aux; | ||
376 | if (selinux_audit_rule_match(axi->osid, f->type, f->op, f->se_rule, ctx)) { | ||
377 | ++result; | ||
378 | break; | ||
379 | } | ||
380 | } | ||
381 | } | ||
382 | } | ||
383 | } | ||
384 | break; | ||
344 | case AUDIT_ARG0: | 385 | case AUDIT_ARG0: |
345 | case AUDIT_ARG1: | 386 | case AUDIT_ARG1: |
346 | case AUDIT_ARG2: | 387 | case AUDIT_ARG2: |
@@ -348,11 +389,17 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
348 | if (ctx) | 389 | if (ctx) |
349 | result = audit_comparator(ctx->argv[f->type-AUDIT_ARG0], f->op, f->val); | 390 | result = audit_comparator(ctx->argv[f->type-AUDIT_ARG0], f->op, f->val); |
350 | break; | 391 | break; |
392 | case AUDIT_FILTERKEY: | ||
393 | /* ignore this field for filtering */ | ||
394 | result = 1; | ||
395 | break; | ||
351 | } | 396 | } |
352 | 397 | ||
353 | if (!result) | 398 | if (!result) |
354 | return 0; | 399 | return 0; |
355 | } | 400 | } |
401 | if (rule->filterkey) | ||
402 | ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC); | ||
356 | switch (rule->action) { | 403 | switch (rule->action) { |
357 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; | 404 | case AUDIT_NEVER: *state = AUDIT_DISABLED; break; |
358 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; | 405 | case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break; |
@@ -627,6 +674,7 @@ static inline void audit_free_context(struct audit_context *context) | |||
627 | } | 674 | } |
628 | audit_free_names(context); | 675 | audit_free_names(context); |
629 | audit_free_aux(context); | 676 | audit_free_aux(context); |
677 | kfree(context->filterkey); | ||
630 | kfree(context); | 678 | kfree(context); |
631 | context = previous; | 679 | context = previous; |
632 | } while (context); | 680 | } while (context); |
@@ -735,6 +783,11 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
735 | context->euid, context->suid, context->fsuid, | 783 | context->euid, context->suid, context->fsuid, |
736 | context->egid, context->sgid, context->fsgid, tty); | 784 | context->egid, context->sgid, context->fsgid, tty); |
737 | audit_log_task_info(ab, tsk); | 785 | audit_log_task_info(ab, tsk); |
786 | if (context->filterkey) { | ||
787 | audit_log_format(ab, " key="); | ||
788 | audit_log_untrustedstring(ab, context->filterkey); | ||
789 | } else | ||
790 | audit_log_format(ab, " key=(null)"); | ||
738 | audit_log_end(ab); | 791 | audit_log_end(ab); |
739 | 792 | ||
740 | for (aux = context->aux; aux; aux = aux->next) { | 793 | for (aux = context->aux; aux; aux = aux->next) { |
@@ -1060,6 +1113,8 @@ void audit_syscall_exit(int valid, long return_code) | |||
1060 | } else { | 1113 | } else { |
1061 | audit_free_names(context); | 1114 | audit_free_names(context); |
1062 | audit_free_aux(context); | 1115 | audit_free_aux(context); |
1116 | kfree(context->filterkey); | ||
1117 | context->filterkey = NULL; | ||
1063 | tsk->audit_context = context; | 1118 | tsk->audit_context = context; |
1064 | } | 1119 | } |
1065 | } | 1120 | } |
diff --git a/kernel/futex.c b/kernel/futex.c index 6c91f938005d..15caf93e4a43 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -630,8 +630,10 @@ static int futex_wake(u32 __user *uaddr, int nr_wake) | |||
630 | 630 | ||
631 | list_for_each_entry_safe(this, next, head, list) { | 631 | list_for_each_entry_safe(this, next, head, list) { |
632 | if (match_futex (&this->key, &key)) { | 632 | if (match_futex (&this->key, &key)) { |
633 | if (this->pi_state) | 633 | if (this->pi_state) { |
634 | return -EINVAL; | 634 | ret = -EINVAL; |
635 | break; | ||
636 | } | ||
635 | wake_futex(this); | 637 | wake_futex(this); |
636 | if (++ret >= nr_wake) | 638 | if (++ret >= nr_wake) |
637 | break; | 639 | break; |
@@ -1208,7 +1210,7 @@ static int do_futex_lock_pi(u32 __user *uaddr, int detect, int trylock, | |||
1208 | } | 1210 | } |
1209 | 1211 | ||
1210 | down_read(&curr->mm->mmap_sem); | 1212 | down_read(&curr->mm->mmap_sem); |
1211 | hb = queue_lock(&q, -1, NULL); | 1213 | spin_lock(q.lock_ptr); |
1212 | 1214 | ||
1213 | /* | 1215 | /* |
1214 | * Got the lock. We might not be the anticipated owner if we | 1216 | * Got the lock. We might not be the anticipated owner if we |
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index e71266c3803e..6d8b30114961 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -142,7 +142,7 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, | |||
142 | } | 142 | } |
143 | #endif | 143 | #endif |
144 | 144 | ||
145 | if (!(action->flags & SA_INTERRUPT)) | 145 | if (!(action->flags & IRQF_DISABLED)) |
146 | local_irq_enable(); | 146 | local_irq_enable(); |
147 | 147 | ||
148 | do { | 148 | do { |
@@ -153,7 +153,7 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, | |||
153 | action = action->next; | 153 | action = action->next; |
154 | } while (action); | 154 | } while (action); |
155 | 155 | ||
156 | if (status & SA_SAMPLE_RANDOM) | 156 | if (status & IRQF_SAMPLE_RANDOM) |
157 | add_interrupt_randomness(irq); | 157 | add_interrupt_randomness(irq); |
158 | local_irq_disable(); | 158 | local_irq_disable(); |
159 | 159 | ||
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index b7117e81ac56..fede5fa351df 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -114,7 +114,7 @@ void enable_irq(unsigned int irq) | |||
114 | spin_lock_irqsave(&desc->lock, flags); | 114 | spin_lock_irqsave(&desc->lock, flags); |
115 | switch (desc->depth) { | 115 | switch (desc->depth) { |
116 | case 0: | 116 | case 0: |
117 | printk(KERN_WARNING "Unablanced enable_irq(%d)\n", irq); | 117 | printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq); |
118 | WARN_ON(1); | 118 | WARN_ON(1); |
119 | break; | 119 | break; |
120 | case 1: { | 120 | case 1: { |
@@ -167,7 +167,7 @@ int can_request_irq(unsigned int irq, unsigned long irqflags) | |||
167 | 167 | ||
168 | action = irq_desc[irq].action; | 168 | action = irq_desc[irq].action; |
169 | if (action) | 169 | if (action) |
170 | if (irqflags & action->flags & SA_SHIRQ) | 170 | if (irqflags & action->flags & IRQF_SHARED) |
171 | action = NULL; | 171 | action = NULL; |
172 | 172 | ||
173 | return !action; | 173 | return !action; |
@@ -205,7 +205,7 @@ int setup_irq(unsigned int irq, struct irqaction *new) | |||
205 | * so we have to be careful not to interfere with a | 205 | * so we have to be careful not to interfere with a |
206 | * running system. | 206 | * running system. |
207 | */ | 207 | */ |
208 | if (new->flags & SA_SAMPLE_RANDOM) { | 208 | if (new->flags & IRQF_SAMPLE_RANDOM) { |
209 | /* | 209 | /* |
210 | * This function might sleep, we want to call it first, | 210 | * This function might sleep, we want to call it first, |
211 | * outside of the atomic block. | 211 | * outside of the atomic block. |
@@ -227,16 +227,17 @@ int setup_irq(unsigned int irq, struct irqaction *new) | |||
227 | /* | 227 | /* |
228 | * Can't share interrupts unless both agree to and are | 228 | * Can't share interrupts unless both agree to and are |
229 | * the same type (level, edge, polarity). So both flag | 229 | * the same type (level, edge, polarity). So both flag |
230 | * fields must have SA_SHIRQ set and the bits which | 230 | * fields must have IRQF_SHARED set and the bits which |
231 | * set the trigger type must match. | 231 | * set the trigger type must match. |
232 | */ | 232 | */ |
233 | if (!((old->flags & new->flags) & SA_SHIRQ) || | 233 | if (!((old->flags & new->flags) & IRQF_SHARED) || |
234 | ((old->flags ^ new->flags) & SA_TRIGGER_MASK)) | 234 | ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK)) |
235 | goto mismatch; | 235 | goto mismatch; |
236 | 236 | ||
237 | #if defined(CONFIG_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) | 237 | #if defined(CONFIG_IRQ_PER_CPU) && defined(IRQF_PERCPU) |
238 | /* All handlers must agree on per-cpuness */ | 238 | /* All handlers must agree on per-cpuness */ |
239 | if ((old->flags & IRQ_PER_CPU) != (new->flags & IRQ_PER_CPU)) | 239 | if ((old->flags & IRQF_PERCPU) != |
240 | (new->flags & IRQF_PERCPU)) | ||
240 | goto mismatch; | 241 | goto mismatch; |
241 | #endif | 242 | #endif |
242 | 243 | ||
@@ -249,26 +250,27 @@ int setup_irq(unsigned int irq, struct irqaction *new) | |||
249 | } | 250 | } |
250 | 251 | ||
251 | *p = new; | 252 | *p = new; |
252 | #if defined(CONFIG_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) | 253 | #if defined(CONFIG_IRQ_PER_CPU) && defined(IRQF_PERCPU) |
253 | if (new->flags & SA_PERCPU_IRQ) | 254 | if (new->flags & IRQF_PERCPU) |
254 | desc->status |= IRQ_PER_CPU; | 255 | desc->status |= IRQ_PER_CPU; |
255 | #endif | 256 | #endif |
256 | if (!shared) { | 257 | if (!shared) { |
257 | irq_chip_set_defaults(desc->chip); | 258 | irq_chip_set_defaults(desc->chip); |
258 | 259 | ||
259 | /* Setup the type (level, edge polarity) if configured: */ | 260 | /* Setup the type (level, edge polarity) if configured: */ |
260 | if (new->flags & SA_TRIGGER_MASK) { | 261 | if (new->flags & IRQF_TRIGGER_MASK) { |
261 | if (desc->chip && desc->chip->set_type) | 262 | if (desc->chip && desc->chip->set_type) |
262 | desc->chip->set_type(irq, | 263 | desc->chip->set_type(irq, |
263 | new->flags & SA_TRIGGER_MASK); | 264 | new->flags & IRQF_TRIGGER_MASK); |
264 | else | 265 | else |
265 | /* | 266 | /* |
266 | * SA_TRIGGER_* but the PIC does not support | 267 | * IRQF_TRIGGER_* but the PIC does not support |
267 | * multiple flow-types? | 268 | * multiple flow-types? |
268 | */ | 269 | */ |
269 | printk(KERN_WARNING "setup_irq(%d) SA_TRIGGER" | 270 | printk(KERN_WARNING "No IRQF_TRIGGER set_type " |
270 | "set. No set_type function available\n", | 271 | "function for IRQ %d (%s)\n", irq, |
271 | irq); | 272 | desc->chip ? desc->chip->name : |
273 | "unknown"); | ||
272 | } else | 274 | } else |
273 | compat_irq_chip_set_default_handler(desc); | 275 | compat_irq_chip_set_default_handler(desc); |
274 | 276 | ||
@@ -297,8 +299,8 @@ int setup_irq(unsigned int irq, struct irqaction *new) | |||
297 | 299 | ||
298 | mismatch: | 300 | mismatch: |
299 | spin_unlock_irqrestore(&desc->lock, flags); | 301 | spin_unlock_irqrestore(&desc->lock, flags); |
300 | if (!(new->flags & SA_PROBEIRQ)) { | 302 | if (!(new->flags & IRQF_PROBE_SHARED)) { |
301 | printk(KERN_ERR "%s: irq handler mismatch\n", __FUNCTION__); | 303 | printk(KERN_ERR "IRQ handler type mismatch for IRQ %d\n", irq); |
302 | dump_stack(); | 304 | dump_stack(); |
303 | } | 305 | } |
304 | return -EBUSY; | 306 | return -EBUSY; |
@@ -365,7 +367,7 @@ void free_irq(unsigned int irq, void *dev_id) | |||
365 | kfree(action); | 367 | kfree(action); |
366 | return; | 368 | return; |
367 | } | 369 | } |
368 | printk(KERN_ERR "Trying to free free IRQ%d\n", irq); | 370 | printk(KERN_ERR "Trying to free already-free IRQ %d\n", irq); |
369 | spin_unlock_irqrestore(&desc->lock, flags); | 371 | spin_unlock_irqrestore(&desc->lock, flags); |
370 | return; | 372 | return; |
371 | } | 373 | } |
@@ -396,9 +398,9 @@ EXPORT_SYMBOL(free_irq); | |||
396 | * | 398 | * |
397 | * Flags: | 399 | * Flags: |
398 | * | 400 | * |
399 | * SA_SHIRQ Interrupt is shared | 401 | * IRQF_SHARED Interrupt is shared |
400 | * SA_INTERRUPT Disable local interrupts while processing | 402 | * IRQF_DISABLED Disable local interrupts while processing |
401 | * SA_SAMPLE_RANDOM The interrupt can be used for entropy | 403 | * IRQF_SAMPLE_RANDOM The interrupt can be used for entropy |
402 | * | 404 | * |
403 | */ | 405 | */ |
404 | int request_irq(unsigned int irq, | 406 | int request_irq(unsigned int irq, |
@@ -414,7 +416,7 @@ int request_irq(unsigned int irq, | |||
414 | * which interrupt is which (messes up the interrupt freeing | 416 | * which interrupt is which (messes up the interrupt freeing |
415 | * logic etc). | 417 | * logic etc). |
416 | */ | 418 | */ |
417 | if ((irqflags & SA_SHIRQ) && !dev_id) | 419 | if ((irqflags & IRQF_SHARED) && !dev_id) |
418 | return -EINVAL; | 420 | return -EINVAL; |
419 | if (irq >= NR_IRQS) | 421 | if (irq >= NR_IRQS) |
420 | return -EINVAL; | 422 | return -EINVAL; |
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index b483deed311c..417e98092cf2 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c | |||
@@ -36,7 +36,7 @@ static int misrouted_irq(int irq, struct pt_regs *regs) | |||
36 | * Already running: If it is shared get the other | 36 | * Already running: If it is shared get the other |
37 | * CPU to go looking for our mystery interrupt too | 37 | * CPU to go looking for our mystery interrupt too |
38 | */ | 38 | */ |
39 | if (desc->action && (desc->action->flags & SA_SHIRQ)) | 39 | if (desc->action && (desc->action->flags & IRQF_SHARED)) |
40 | desc->status |= IRQ_PENDING; | 40 | desc->status |= IRQ_PENDING; |
41 | spin_unlock(&desc->lock); | 41 | spin_unlock(&desc->lock); |
42 | continue; | 42 | continue; |
@@ -48,7 +48,7 @@ static int misrouted_irq(int irq, struct pt_regs *regs) | |||
48 | 48 | ||
49 | while (action) { | 49 | while (action) { |
50 | /* Only shared IRQ handlers are safe to call */ | 50 | /* Only shared IRQ handlers are safe to call */ |
51 | if (action->flags & SA_SHIRQ) { | 51 | if (action->flags & IRQF_SHARED) { |
52 | if (action->handler(i, action->dev_id, regs) == | 52 | if (action->handler(i, action->dev_id, regs) == |
53 | IRQ_HANDLED) | 53 | IRQ_HANDLED) |
54 | ok = 1; | 54 | ok = 1; |