aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/audit.c62
-rw-r--r--kernel/audit.h11
-rw-r--r--kernel/auditfilter.c60
3 files changed, 81 insertions, 52 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index df57b493e1cb..bf74bf02aa4b 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -366,6 +366,50 @@ static int kauditd_thread(void *dummy)
366 return 0; 366 return 0;
367} 367}
368 368
369int audit_send_list(void *_dest)
370{
371 struct audit_netlink_list *dest = _dest;
372 int pid = dest->pid;
373 struct sk_buff *skb;
374
375 /* wait for parent to finish and send an ACK */
376 mutex_lock(&audit_netlink_mutex);
377 mutex_unlock(&audit_netlink_mutex);
378
379 while ((skb = __skb_dequeue(&dest->q)) != NULL)
380 netlink_unicast(audit_sock, skb, pid, 0);
381
382 kfree(dest);
383
384 return 0;
385}
386
387struct sk_buff *audit_make_reply(int pid, int seq, int type, int done,
388 int multi, void *payload, int size)
389{
390 struct sk_buff *skb;
391 struct nlmsghdr *nlh;
392 int len = NLMSG_SPACE(size);
393 void *data;
394 int flags = multi ? NLM_F_MULTI : 0;
395 int t = done ? NLMSG_DONE : type;
396
397 skb = alloc_skb(len, GFP_KERNEL);
398 if (!skb)
399 return NULL;
400
401 nlh = NLMSG_PUT(skb, pid, seq, t, size);
402 nlh->nlmsg_flags = flags;
403 data = NLMSG_DATA(nlh);
404 memcpy(data, payload, size);
405 return skb;
406
407nlmsg_failure: /* Used by NLMSG_PUT */
408 if (skb)
409 kfree_skb(skb);
410 return NULL;
411}
412
369/** 413/**
370 * audit_send_reply - send an audit reply message via netlink 414 * audit_send_reply - send an audit reply message via netlink
371 * @pid: process id to send reply to 415 * @pid: process id to send reply to
@@ -383,29 +427,13 @@ void audit_send_reply(int pid, int seq, int type, int done, int multi,
383 void *payload, int size) 427 void *payload, int size)
384{ 428{
385 struct sk_buff *skb; 429 struct sk_buff *skb;
386 struct nlmsghdr *nlh; 430 skb = audit_make_reply(pid, seq, type, done, multi, payload, size);
387 int len = NLMSG_SPACE(size);
388 void *data;
389 int flags = multi ? NLM_F_MULTI : 0;
390 int t = done ? NLMSG_DONE : type;
391
392 skb = alloc_skb(len, GFP_KERNEL);
393 if (!skb) 431 if (!skb)
394 return; 432 return;
395
396 nlh = NLMSG_PUT(skb, pid, seq, t, size);
397 nlh->nlmsg_flags = flags;
398 data = NLMSG_DATA(nlh);
399 memcpy(data, payload, size);
400
401 /* Ignore failure. It'll only happen if the sender goes away, 433 /* Ignore failure. It'll only happen if the sender goes away,
402 because our timeout is set to infinite. */ 434 because our timeout is set to infinite. */
403 netlink_unicast(audit_sock, skb, pid, 0); 435 netlink_unicast(audit_sock, skb, pid, 0);
404 return; 436 return;
405
406nlmsg_failure: /* Used by NLMSG_PUT */
407 if (skb)
408 kfree_skb(skb);
409} 437}
410 438
411/* 439/*
diff --git a/kernel/audit.h b/kernel/audit.h
index 6f733920fd32..8948fc1e9e54 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -22,6 +22,7 @@
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/fs.h> 23#include <linux/fs.h>
24#include <linux/audit.h> 24#include <linux/audit.h>
25#include <linux/skbuff.h>
25 26
26/* 0 = no checking 27/* 0 = no checking
27 1 = put_count checking 28 1 = put_count checking
@@ -82,6 +83,9 @@ struct audit_entry {
82extern int audit_pid; 83extern int audit_pid;
83extern int audit_comparator(const u32 left, const u32 op, const u32 right); 84extern int audit_comparator(const u32 left, const u32 op, const u32 right);
84 85
86extern struct sk_buff * audit_make_reply(int pid, int seq, int type,
87 int done, int multi,
88 void *payload, int size);
85extern void audit_send_reply(int pid, int seq, int type, 89extern void audit_send_reply(int pid, int seq, int type,
86 int done, int multi, 90 int done, int multi,
87 void *payload, int size); 91 void *payload, int size);
@@ -89,4 +93,11 @@ extern void audit_log_lost(const char *message);
89extern void audit_panic(const char *message); 93extern void audit_panic(const char *message);
90extern struct mutex audit_netlink_mutex; 94extern struct mutex audit_netlink_mutex;
91 95
96struct audit_netlink_list {
97 int pid;
98 struct sk_buff_head q;
99};
100
101int audit_send_list(void *);
102
92extern int selinux_audit_rule_update(void); 103extern int selinux_audit_rule_update(void);
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 7c134906d689..ccfea6d82cc3 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -510,19 +510,12 @@ static inline int audit_del_rule(struct audit_entry *entry,
510 510
511/* List rules using struct audit_rule. Exists for backward 511/* List rules using struct audit_rule. Exists for backward
512 * compatibility with userspace. */ 512 * compatibility with userspace. */
513static int audit_list(void *_dest) 513static void audit_list(int pid, int seq, struct sk_buff_head *q)
514{ 514{
515 int pid, seq; 515 struct sk_buff *skb;
516 int *dest = _dest;
517 struct audit_entry *entry; 516 struct audit_entry *entry;
518 int i; 517 int i;
519 518
520 pid = dest[0];
521 seq = dest[1];
522 kfree(dest);
523
524 mutex_lock(&audit_netlink_mutex);
525
526 /* The *_rcu iterators not needed here because we are 519 /* The *_rcu iterators not needed here because we are
527 always called with audit_netlink_mutex held. */ 520 always called with audit_netlink_mutex held. */
528 for (i=0; i<AUDIT_NR_FILTERS; i++) { 521 for (i=0; i<AUDIT_NR_FILTERS; i++) {
@@ -532,31 +525,25 @@ static int audit_list(void *_dest)
532 rule = audit_krule_to_rule(&entry->rule); 525 rule = audit_krule_to_rule(&entry->rule);
533 if (unlikely(!rule)) 526 if (unlikely(!rule))
534 break; 527 break;
535 audit_send_reply(pid, seq, AUDIT_LIST, 0, 1, 528 skb = audit_make_reply(pid, seq, AUDIT_LIST, 0, 1,
536 rule, sizeof(*rule)); 529 rule, sizeof(*rule));
530 if (skb)
531 skb_queue_tail(q, skb);
537 kfree(rule); 532 kfree(rule);
538 } 533 }
539 } 534 }
540 audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0); 535 skb = audit_make_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
541 536 if (skb)
542 mutex_unlock(&audit_netlink_mutex); 537 skb_queue_tail(q, skb);
543 return 0;
544} 538}
545 539
546/* List rules using struct audit_rule_data. */ 540/* List rules using struct audit_rule_data. */
547static int audit_list_rules(void *_dest) 541static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
548{ 542{
549 int pid, seq; 543 struct sk_buff *skb;
550 int *dest = _dest;
551 struct audit_entry *e; 544 struct audit_entry *e;
552 int i; 545 int i;
553 546
554 pid = dest[0];
555 seq = dest[1];
556 kfree(dest);
557
558 mutex_lock(&audit_netlink_mutex);
559
560 /* The *_rcu iterators not needed here because we are 547 /* The *_rcu iterators not needed here because we are
561 always called with audit_netlink_mutex held. */ 548 always called with audit_netlink_mutex held. */
562 for (i=0; i<AUDIT_NR_FILTERS; i++) { 549 for (i=0; i<AUDIT_NR_FILTERS; i++) {
@@ -566,15 +553,16 @@ static int audit_list_rules(void *_dest)
566 data = audit_krule_to_data(&e->rule); 553 data = audit_krule_to_data(&e->rule);
567 if (unlikely(!data)) 554 if (unlikely(!data))
568 break; 555 break;
569 audit_send_reply(pid, seq, AUDIT_LIST_RULES, 0, 1, 556 skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 0, 1,
570 data, sizeof(*data)); 557 data, sizeof(*data));
558 if (skb)
559 skb_queue_tail(q, skb);
571 kfree(data); 560 kfree(data);
572 } 561 }
573 } 562 }
574 audit_send_reply(pid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0); 563 skb = audit_make_reply(pid, seq, AUDIT_LIST_RULES, 1, 1, NULL, 0);
575 564 if (skb)
576 mutex_unlock(&audit_netlink_mutex); 565 skb_queue_tail(q, skb);
577 return 0;
578} 566}
579 567
580/** 568/**
@@ -592,7 +580,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
592 size_t datasz, uid_t loginuid, u32 sid) 580 size_t datasz, uid_t loginuid, u32 sid)
593{ 581{
594 struct task_struct *tsk; 582 struct task_struct *tsk;
595 int *dest; 583 struct audit_netlink_list *dest;
596 int err = 0; 584 int err = 0;
597 struct audit_entry *entry; 585 struct audit_entry *entry;
598 586
@@ -605,18 +593,20 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
605 * happen if we're actually running in the context of auditctl 593 * happen if we're actually running in the context of auditctl
606 * trying to _send_ the stuff */ 594 * trying to _send_ the stuff */
607 595
608 dest = kmalloc(2 * sizeof(int), GFP_KERNEL); 596 dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
609 if (!dest) 597 if (!dest)
610 return -ENOMEM; 598 return -ENOMEM;
611 dest[0] = pid; 599 dest->pid = pid;
612 dest[1] = seq; 600 skb_queue_head_init(&dest->q);
613 601
614 if (type == AUDIT_LIST) 602 if (type == AUDIT_LIST)
615 tsk = kthread_run(audit_list, dest, "audit_list"); 603 audit_list(pid, seq, &dest->q);
616 else 604 else
617 tsk = kthread_run(audit_list_rules, dest, 605 audit_list_rules(pid, seq, &dest->q);
618 "audit_list_rules"); 606
607 tsk = kthread_run(audit_send_list, dest, "audit_send_list");
619 if (IS_ERR(tsk)) { 608 if (IS_ERR(tsk)) {
609 skb_queue_purge(&dest->q);
620 kfree(dest); 610 kfree(dest);
621 err = PTR_ERR(tsk); 611 err = PTR_ERR(tsk);
622 } 612 }