aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-06-22 10:04:33 -0400
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-06-22 10:04:33 -0400
commit9ad9ad385be27fcc7c16d290d972c6173e780a61 (patch)
treebbca700c2d88ba421a6c9c348de367eaf4de0e2c /kernel
parent177bbc733a1d9c935bc3d6efd776a6699b29b1ca (diff)
AUDIT: Wait for backlog to clear when generating messages.
Add a gfp_mask to audit_log_start() and audit_log(), to reduce the amount of GFP_ATOMIC allocation -- most of it doesn't need to be GFP_ATOMIC. Also if the mask includes __GFP_WAIT, then wait up to 60 seconds for the auditd backlog to clear instead of immediately abandoning the message. The timeout should probably be made configurable, but for now it'll suffice that it only happens if auditd is actually running. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c60
-rw-r--r--kernel/auditsc.c14
2 files changed, 52 insertions, 22 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 09a37581213b..644ab825118b 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -106,6 +106,7 @@ static LIST_HEAD(audit_freelist);
106static struct sk_buff_head audit_skb_queue; 106static struct sk_buff_head audit_skb_queue;
107static struct task_struct *kauditd_task; 107static struct task_struct *kauditd_task;
108static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); 108static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
109static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
109 110
110/* The netlink socket is only to be read by 1 CPU, which lets us assume 111/* The netlink socket is only to be read by 1 CPU, which lets us assume
111 * that list additions and deletions never happen simultaneously in 112 * that list additions and deletions never happen simultaneously in
@@ -130,6 +131,7 @@ struct audit_buffer {
130 struct list_head list; 131 struct list_head list;
131 struct sk_buff *skb; /* formatted skb ready to send */ 132 struct sk_buff *skb; /* formatted skb ready to send */
132 struct audit_context *ctx; /* NULL or associated context */ 133 struct audit_context *ctx; /* NULL or associated context */
134 int gfp_mask;
133}; 135};
134 136
135static void audit_set_pid(struct audit_buffer *ab, pid_t pid) 137static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
@@ -226,7 +228,7 @@ static int audit_set_rate_limit(int limit, uid_t loginuid)
226{ 228{
227 int old = audit_rate_limit; 229 int old = audit_rate_limit;
228 audit_rate_limit = limit; 230 audit_rate_limit = limit;
229 audit_log(NULL, AUDIT_CONFIG_CHANGE, 231 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
230 "audit_rate_limit=%d old=%d by auid=%u", 232 "audit_rate_limit=%d old=%d by auid=%u",
231 audit_rate_limit, old, loginuid); 233 audit_rate_limit, old, loginuid);
232 return old; 234 return old;
@@ -236,7 +238,7 @@ static int audit_set_backlog_limit(int limit, uid_t loginuid)
236{ 238{
237 int old = audit_backlog_limit; 239 int old = audit_backlog_limit;
238 audit_backlog_limit = limit; 240 audit_backlog_limit = limit;
239 audit_log(NULL, AUDIT_CONFIG_CHANGE, 241 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
240 "audit_backlog_limit=%d old=%d by auid=%u", 242 "audit_backlog_limit=%d old=%d by auid=%u",
241 audit_backlog_limit, old, loginuid); 243 audit_backlog_limit, old, loginuid);
242 return old; 244 return old;
@@ -248,7 +250,7 @@ static int audit_set_enabled(int state, uid_t loginuid)
248 if (state != 0 && state != 1) 250 if (state != 0 && state != 1)
249 return -EINVAL; 251 return -EINVAL;
250 audit_enabled = state; 252 audit_enabled = state;
251 audit_log(NULL, AUDIT_CONFIG_CHANGE, 253 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
252 "audit_enabled=%d old=%d by auid=%u", 254 "audit_enabled=%d old=%d by auid=%u",
253 audit_enabled, old, loginuid); 255 audit_enabled, old, loginuid);
254 return old; 256 return old;
@@ -262,7 +264,7 @@ static int audit_set_failure(int state, uid_t loginuid)
262 && state != AUDIT_FAIL_PANIC) 264 && state != AUDIT_FAIL_PANIC)
263 return -EINVAL; 265 return -EINVAL;
264 audit_failure = state; 266 audit_failure = state;
265 audit_log(NULL, AUDIT_CONFIG_CHANGE, 267 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
266 "audit_failure=%d old=%d by auid=%u", 268 "audit_failure=%d old=%d by auid=%u",
267 audit_failure, old, loginuid); 269 audit_failure, old, loginuid);
268 return old; 270 return old;
@@ -274,6 +276,7 @@ int kauditd_thread(void *dummy)
274 276
275 while (1) { 277 while (1) {
276 skb = skb_dequeue(&audit_skb_queue); 278 skb = skb_dequeue(&audit_skb_queue);
279 wake_up(&audit_backlog_wait);
277 if (skb) { 280 if (skb) {
278 if (audit_pid) { 281 if (audit_pid) {
279 int err = netlink_unicast(audit_sock, skb, audit_pid, 0); 282 int err = netlink_unicast(audit_sock, skb, audit_pid, 0);
@@ -417,7 +420,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
417 if (status_get->mask & AUDIT_STATUS_PID) { 420 if (status_get->mask & AUDIT_STATUS_PID) {
418 int old = audit_pid; 421 int old = audit_pid;
419 audit_pid = status_get->pid; 422 audit_pid = status_get->pid;
420 audit_log(NULL, AUDIT_CONFIG_CHANGE, 423 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
421 "audit_pid=%d old=%d by auid=%u", 424 "audit_pid=%d old=%d by auid=%u",
422 audit_pid, old, loginuid); 425 audit_pid, old, loginuid);
423 } 426 }
@@ -435,7 +438,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
435 err = audit_filter_user(pid, msg_type); 438 err = audit_filter_user(pid, msg_type);
436 if (err == 1) { 439 if (err == 1) {
437 err = 0; 440 err = 0;
438 ab = audit_log_start(NULL, msg_type); 441 ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
439 if (ab) { 442 if (ab) {
440 audit_log_format(ab, 443 audit_log_format(ab,
441 "user pid=%d uid=%u auid=%u msg='%.1024s'", 444 "user pid=%d uid=%u auid=%u msg='%.1024s'",
@@ -522,7 +525,7 @@ static int __init audit_init(void)
522 skb_queue_head_init(&audit_skb_queue); 525 skb_queue_head_init(&audit_skb_queue);
523 audit_initialized = 1; 526 audit_initialized = 1;
524 audit_enabled = audit_default; 527 audit_enabled = audit_default;
525 audit_log(NULL, AUDIT_KERNEL, "initialized"); 528 audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
526 return 0; 529 return 0;
527} 530}
528__initcall(audit_init); 531__initcall(audit_init);
@@ -586,6 +589,7 @@ static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
586 goto err; 589 goto err;
587 590
588 ab->ctx = ctx; 591 ab->ctx = ctx;
592 ab->gfp_mask = gfp_mask;
589 nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0)); 593 nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
590 nlh->nlmsg_type = type; 594 nlh->nlmsg_type = type;
591 nlh->nlmsg_flags = 0; 595 nlh->nlmsg_flags = 0;
@@ -644,17 +648,42 @@ static inline void audit_get_stamp(struct audit_context *ctx,
644 * syscall, then the syscall is marked as auditable and an audit record 648 * syscall, then the syscall is marked as auditable and an audit record
645 * will be written at syscall exit. If there is no associated task, tsk 649 * will be written at syscall exit. If there is no associated task, tsk
646 * should be NULL. */ 650 * should be NULL. */
647struct audit_buffer *audit_log_start(struct audit_context *ctx, int type) 651
652struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask,
653 int type)
648{ 654{
649 struct audit_buffer *ab = NULL; 655 struct audit_buffer *ab = NULL;
650 struct timespec t; 656 struct timespec t;
651 unsigned int serial; 657 unsigned int serial;
658 int reserve;
652 659
653 if (!audit_initialized) 660 if (!audit_initialized)
654 return NULL; 661 return NULL;
655 662
656 if (audit_backlog_limit 663 if (gfp_mask & __GFP_WAIT)
657 && skb_queue_len(&audit_skb_queue) > audit_backlog_limit) { 664 reserve = 0;
665 else
666 reserve = 5; /* Allow atomic callers to go up to five
667 entries over the normal backlog limit */
668
669 while (audit_backlog_limit
670 && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) {
671 if (gfp_mask & __GFP_WAIT) {
672 int ret = 1;
673 /* Wait for auditd to drain the queue a little */
674 DECLARE_WAITQUEUE(wait, current);
675 set_current_state(TASK_INTERRUPTIBLE);
676 add_wait_queue(&audit_backlog_wait, &wait);
677
678 if (audit_backlog_limit &&
679 skb_queue_len(&audit_skb_queue) > audit_backlog_limit)
680 ret = schedule_timeout(HZ * 60);
681
682 __set_current_state(TASK_RUNNING);
683 remove_wait_queue(&audit_backlog_wait, &wait);
684 if (ret)
685 continue;
686 }
658 if (audit_rate_check()) 687 if (audit_rate_check())
659 printk(KERN_WARNING 688 printk(KERN_WARNING
660 "audit: audit_backlog=%d > " 689 "audit: audit_backlog=%d > "
@@ -665,7 +694,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int type)
665 return NULL; 694 return NULL;
666 } 695 }
667 696
668 ab = audit_buffer_alloc(ctx, GFP_ATOMIC, type); 697 ab = audit_buffer_alloc(ctx, gfp_mask, type);
669 if (!ab) { 698 if (!ab) {
670 audit_log_lost("out of memory in audit_log_start"); 699 audit_log_lost("out of memory in audit_log_start");
671 return NULL; 700 return NULL;
@@ -689,7 +718,7 @@ static inline int audit_expand(struct audit_buffer *ab, int extra)
689{ 718{
690 struct sk_buff *skb = ab->skb; 719 struct sk_buff *skb = ab->skb;
691 int ret = pskb_expand_head(skb, skb_headroom(skb), extra, 720 int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
692 GFP_ATOMIC); 721 ab->gfp_mask);
693 if (ret < 0) { 722 if (ret < 0) {
694 audit_log_lost("out of memory in audit_expand"); 723 audit_log_lost("out of memory in audit_expand");
695 return 0; 724 return 0;
@@ -808,7 +837,7 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
808 audit_log_format(ab, " %s", prefix); 837 audit_log_format(ab, " %s", prefix);
809 838
810 /* We will allow 11 spaces for ' (deleted)' to be appended */ 839 /* We will allow 11 spaces for ' (deleted)' to be appended */
811 path = kmalloc(PATH_MAX+11, GFP_KERNEL); 840 path = kmalloc(PATH_MAX+11, ab->gfp_mask);
812 if (!path) { 841 if (!path) {
813 audit_log_format(ab, "<no memory>"); 842 audit_log_format(ab, "<no memory>");
814 return; 843 return;
@@ -849,12 +878,13 @@ void audit_log_end(struct audit_buffer *ab)
849/* Log an audit record. This is a convenience function that calls 878/* Log an audit record. This is a convenience function that calls
850 * audit_log_start, audit_log_vformat, and audit_log_end. It may be 879 * audit_log_start, audit_log_vformat, and audit_log_end. It may be
851 * called in any context. */ 880 * called in any context. */
852void audit_log(struct audit_context *ctx, int type, const char *fmt, ...) 881void audit_log(struct audit_context *ctx, int gfp_mask, int type,
882 const char *fmt, ...)
853{ 883{
854 struct audit_buffer *ab; 884 struct audit_buffer *ab;
855 va_list args; 885 va_list args;
856 886
857 ab = audit_log_start(ctx, type); 887 ab = audit_log_start(ctx, gfp_mask, type);
858 if (ab) { 888 if (ab) {
859 va_start(args, fmt); 889 va_start(args, fmt);
860 audit_log_vformat(ab, fmt, args); 890 audit_log_vformat(ab, fmt, args);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index fc858b0c044a..f463fd230846 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -346,7 +346,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
346 } 346 }
347 listnr = entry->rule.flags & ~AUDIT_FILTER_PREPEND; 347 listnr = entry->rule.flags & ~AUDIT_FILTER_PREPEND;
348 audit_add_rule(entry, &audit_filter_list[listnr]); 348 audit_add_rule(entry, &audit_filter_list[listnr]);
349 audit_log(NULL, AUDIT_CONFIG_CHANGE, 349 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
350 "auid=%u added an audit rule\n", loginuid); 350 "auid=%u added an audit rule\n", loginuid);
351 break; 351 break;
352 case AUDIT_DEL: 352 case AUDIT_DEL:
@@ -356,7 +356,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
356 356
357 err = audit_del_rule(data, &audit_filter_list[listnr]); 357 err = audit_del_rule(data, &audit_filter_list[listnr]);
358 if (!err) 358 if (!err)
359 audit_log(NULL, AUDIT_CONFIG_CHANGE, 359 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
360 "auid=%u removed an audit rule\n", loginuid); 360 "auid=%u removed an audit rule\n", loginuid);
361 break; 361 break;
362 default: 362 default:
@@ -756,7 +756,7 @@ static void audit_log_exit(struct audit_context *context)
756 struct audit_buffer *ab; 756 struct audit_buffer *ab;
757 struct audit_aux_data *aux; 757 struct audit_aux_data *aux;
758 758
759 ab = audit_log_start(context, AUDIT_SYSCALL); 759 ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
760 if (!ab) 760 if (!ab)
761 return; /* audit_panic has been called */ 761 return; /* audit_panic has been called */
762 audit_log_format(ab, "arch=%x syscall=%d", 762 audit_log_format(ab, "arch=%x syscall=%d",
@@ -788,7 +788,7 @@ static void audit_log_exit(struct audit_context *context)
788 788
789 for (aux = context->aux; aux; aux = aux->next) { 789 for (aux = context->aux; aux; aux = aux->next) {
790 790
791 ab = audit_log_start(context, aux->type); 791 ab = audit_log_start(context, GFP_KERNEL, aux->type);
792 if (!ab) 792 if (!ab)
793 continue; /* audit_panic has been called */ 793 continue; /* audit_panic has been called */
794 794
@@ -825,14 +825,14 @@ static void audit_log_exit(struct audit_context *context)
825 } 825 }
826 826
827 if (context->pwd && context->pwdmnt) { 827 if (context->pwd && context->pwdmnt) {
828 ab = audit_log_start(context, AUDIT_CWD); 828 ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
829 if (ab) { 829 if (ab) {
830 audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt); 830 audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt);
831 audit_log_end(ab); 831 audit_log_end(ab);
832 } 832 }
833 } 833 }
834 for (i = 0; i < context->name_count; i++) { 834 for (i = 0; i < context->name_count; i++) {
835 ab = audit_log_start(context, AUDIT_PATH); 835 ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
836 if (!ab) 836 if (!ab)
837 continue; /* audit_panic has been called */ 837 continue; /* audit_panic has been called */
838 838
@@ -1118,7 +1118,7 @@ int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
1118 if (task->audit_context) { 1118 if (task->audit_context) {
1119 struct audit_buffer *ab; 1119 struct audit_buffer *ab;
1120 1120
1121 ab = audit_log_start(NULL, AUDIT_LOGIN); 1121 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
1122 if (ab) { 1122 if (ab) {
1123 audit_log_format(ab, "login pid=%d uid=%u " 1123 audit_log_format(ab, "login pid=%d uid=%u "
1124 "old auid=%u new auid=%u", 1124 "old auid=%u new auid=%u",