diff options
-rw-r--r-- | include/linux/audit.h | 16 | ||||
-rw-r--r-- | kernel/audit.c | 48 | ||||
-rw-r--r-- | kernel/auditsc.c | 23 | ||||
-rw-r--r-- | security/selinux/avc.c | 2 |
4 files changed, 33 insertions, 56 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 58c5589b531f..405332ebf3c6 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -216,11 +216,14 @@ extern void audit_signal_info(int sig, struct task_struct *t); | |||
216 | #ifdef CONFIG_AUDIT | 216 | #ifdef CONFIG_AUDIT |
217 | /* These are defined in audit.c */ | 217 | /* These are defined in audit.c */ |
218 | /* Public API */ | 218 | /* Public API */ |
219 | extern void audit_log(struct audit_context *ctx, | 219 | #define audit_log(ctx, fmt, args...) \ |
220 | const char *fmt, ...) | 220 | audit_log_type(ctx, AUDIT_KERNEL, 0, fmt, ##args) |
221 | __attribute__((format(printf,2,3))); | 221 | extern void audit_log_type(struct audit_context *ctx, int type, |
222 | int pid, const char *fmt, ...) | ||
223 | __attribute__((format(printf,4,5))); | ||
222 | 224 | ||
223 | extern struct audit_buffer *audit_log_start(struct audit_context *ctx); | 225 | extern struct audit_buffer *audit_log_start(struct audit_context *ctx, int type, |
226 | int pid); | ||
224 | extern void audit_log_format(struct audit_buffer *ab, | 227 | extern void audit_log_format(struct audit_buffer *ab, |
225 | const char *fmt, ...) | 228 | const char *fmt, ...) |
226 | __attribute__((format(printf,2,3))); | 229 | __attribute__((format(printf,2,3))); |
@@ -240,8 +243,9 @@ extern void audit_send_reply(int pid, int seq, int type, | |||
240 | void *payload, int size); | 243 | void *payload, int size); |
241 | extern void audit_log_lost(const char *message); | 244 | extern void audit_log_lost(const char *message); |
242 | #else | 245 | #else |
243 | #define audit_log(t,f,...) do { ; } while (0) | 246 | #define audit_log(c,f,...) do { ; } while (0) |
244 | #define audit_log_start(t) ({ NULL; }) | 247 | #define audit_log_type(c,t,p,f,...) do { ; } while (0) |
248 | #define audit_log_start(c,t,p) ({ NULL; }) | ||
245 | #define audit_log_vformat(b,f,a) do { ; } while (0) | 249 | #define audit_log_vformat(b,f,a) do { ; } while (0) |
246 | #define audit_log_format(b,f,...) do { ; } while (0) | 250 | #define audit_log_format(b,f,...) do { ; } while (0) |
247 | #define audit_log_end(b) do { ; } while (0) | 251 | #define audit_log_end(b) do { ; } while (0) |
diff --git a/kernel/audit.c b/kernel/audit.c index c18b769e23a2..060b554f481e 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -140,18 +140,6 @@ struct audit_buffer { | |||
140 | struct audit_context *ctx; /* NULL or associated context */ | 140 | struct audit_context *ctx; /* NULL or associated context */ |
141 | }; | 141 | }; |
142 | 142 | ||
143 | void audit_set_type(struct audit_buffer *ab, int type) | ||
144 | { | ||
145 | struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data; | ||
146 | nlh->nlmsg_type = type; | ||
147 | } | ||
148 | |||
149 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) | ||
150 | { | ||
151 | struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data; | ||
152 | nlh->nlmsg_pid = pid; | ||
153 | } | ||
154 | |||
155 | struct audit_entry { | 143 | struct audit_entry { |
156 | struct list_head list; | 144 | struct list_head list; |
157 | struct audit_rule rule; | 145 | struct audit_rule rule; |
@@ -344,7 +332,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
344 | void *data; | 332 | void *data; |
345 | struct audit_status *status_get, status_set; | 333 | struct audit_status *status_get, status_set; |
346 | int err; | 334 | int err; |
347 | struct audit_buffer *ab; | ||
348 | u16 msg_type = nlh->nlmsg_type; | 335 | u16 msg_type = nlh->nlmsg_type; |
349 | uid_t loginuid; /* loginuid of sender */ | 336 | uid_t loginuid; /* loginuid of sender */ |
350 | struct audit_sig_info sig_data; | 337 | struct audit_sig_info sig_data; |
@@ -396,19 +383,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
396 | loginuid); | 383 | loginuid); |
397 | break; | 384 | break; |
398 | case AUDIT_USER: | 385 | case AUDIT_USER: |
399 | ab = audit_log_start(NULL); | 386 | audit_log_type(NULL, AUDIT_USER, pid, |
400 | if (!ab) | ||
401 | break; /* audit_panic has been called */ | ||
402 | audit_log_format(ab, | ||
403 | "user pid=%d uid=%d length=%d loginuid=%u" | 387 | "user pid=%d uid=%d length=%d loginuid=%u" |
404 | " msg='%.1024s'", | 388 | " msg='%.1024s'", |
405 | pid, uid, | 389 | pid, uid, |
406 | (int)(nlh->nlmsg_len | 390 | (int)(nlh->nlmsg_len |
407 | - ((char *)data - (char *)nlh)), | 391 | - ((char *)data - (char *)nlh)), |
408 | loginuid, (char *)data); | 392 | loginuid, (char *)data); |
409 | audit_set_type(ab, AUDIT_USER); | ||
410 | audit_set_pid(ab, pid); | ||
411 | audit_log_end(ab); | ||
412 | break; | 393 | break; |
413 | case AUDIT_ADD: | 394 | case AUDIT_ADD: |
414 | case AUDIT_DEL: | 395 | case AUDIT_DEL: |
@@ -560,12 +541,10 @@ static void audit_buffer_free(struct audit_buffer *ab) | |||
560 | spin_unlock_irqrestore(&audit_freelist_lock, flags); | 541 | spin_unlock_irqrestore(&audit_freelist_lock, flags); |
561 | } | 542 | } |
562 | 543 | ||
563 | static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, | 544 | static struct audit_buffer * audit_buffer_alloc(int gfp_mask) |
564 | int gfp_mask) | ||
565 | { | 545 | { |
566 | unsigned long flags; | 546 | unsigned long flags; |
567 | struct audit_buffer *ab = NULL; | 547 | struct audit_buffer *ab = NULL; |
568 | struct nlmsghdr *nlh; | ||
569 | 548 | ||
570 | spin_lock_irqsave(&audit_freelist_lock, flags); | 549 | spin_lock_irqsave(&audit_freelist_lock, flags); |
571 | if (!list_empty(&audit_freelist)) { | 550 | if (!list_empty(&audit_freelist)) { |
@@ -587,12 +566,6 @@ static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, | |||
587 | if (!ab->skb) | 566 | if (!ab->skb) |
588 | goto err; | 567 | goto err; |
589 | 568 | ||
590 | ab->ctx = ctx; | ||
591 | nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0)); | ||
592 | nlh->nlmsg_type = AUDIT_KERNEL; | ||
593 | nlh->nlmsg_flags = 0; | ||
594 | nlh->nlmsg_pid = 0; | ||
595 | nlh->nlmsg_seq = 0; | ||
596 | return ab; | 569 | return ab; |
597 | err: | 570 | err: |
598 | audit_buffer_free(ab); | 571 | audit_buffer_free(ab); |
@@ -605,11 +578,12 @@ err: | |||
605 | * syscall, then the syscall is marked as auditable and an audit record | 578 | * syscall, then the syscall is marked as auditable and an audit record |
606 | * will be written at syscall exit. If there is no associated task, tsk | 579 | * will be written at syscall exit. If there is no associated task, tsk |
607 | * should be NULL. */ | 580 | * should be NULL. */ |
608 | struct audit_buffer *audit_log_start(struct audit_context *ctx) | 581 | struct audit_buffer *audit_log_start(struct audit_context *ctx, int type, int pid) |
609 | { | 582 | { |
610 | struct audit_buffer *ab = NULL; | 583 | struct audit_buffer *ab = NULL; |
611 | struct timespec t; | 584 | struct timespec t; |
612 | unsigned int serial; | 585 | unsigned int serial; |
586 | struct nlmsghdr *nlh; | ||
613 | 587 | ||
614 | if (!audit_initialized) | 588 | if (!audit_initialized) |
615 | return NULL; | 589 | return NULL; |
@@ -626,12 +600,19 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx) | |||
626 | return NULL; | 600 | return NULL; |
627 | } | 601 | } |
628 | 602 | ||
629 | ab = audit_buffer_alloc(ctx, GFP_ATOMIC); | 603 | ab = audit_buffer_alloc(GFP_ATOMIC); |
630 | if (!ab) { | 604 | if (!ab) { |
631 | audit_log_lost("out of memory in audit_log_start"); | 605 | audit_log_lost("out of memory in audit_log_start"); |
632 | return NULL; | 606 | return NULL; |
633 | } | 607 | } |
634 | 608 | ||
609 | ab->ctx = ctx; | ||
610 | nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0)); | ||
611 | nlh->nlmsg_type = type; | ||
612 | nlh->nlmsg_flags = 0; | ||
613 | nlh->nlmsg_pid = pid; | ||
614 | nlh->nlmsg_seq = 0; | ||
615 | |||
635 | if (!audit_get_stamp(ab->ctx, &t, &serial)) { | 616 | if (!audit_get_stamp(ab->ctx, &t, &serial)) { |
636 | t = CURRENT_TIME; | 617 | t = CURRENT_TIME; |
637 | serial = 0; | 618 | serial = 0; |
@@ -828,12 +809,13 @@ void audit_log_end(struct audit_buffer *ab) | |||
828 | /* Log an audit record. This is a convenience function that calls | 809 | /* Log an audit record. This is a convenience function that calls |
829 | * audit_log_start, audit_log_vformat, and audit_log_end. It may be | 810 | * audit_log_start, audit_log_vformat, and audit_log_end. It may be |
830 | * called in any context. */ | 811 | * called in any context. */ |
831 | void audit_log(struct audit_context *ctx, const char *fmt, ...) | 812 | void audit_log_type(struct audit_context *ctx, int type, int pid, |
813 | const char *fmt, ...) | ||
832 | { | 814 | { |
833 | struct audit_buffer *ab; | 815 | struct audit_buffer *ab; |
834 | va_list args; | 816 | va_list args; |
835 | 817 | ||
836 | ab = audit_log_start(ctx); | 818 | ab = audit_log_start(ctx, type, pid); |
837 | if (ab) { | 819 | if (ab) { |
838 | va_start(args, fmt); | 820 | va_start(args, fmt); |
839 | audit_log_vformat(ab, fmt, args); | 821 | audit_log_vformat(ab, fmt, args); |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 94338abf76f5..d089263253a7 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -648,7 +648,7 @@ static void audit_log_exit(struct audit_context *context) | |||
648 | int i; | 648 | int i; |
649 | struct audit_buffer *ab; | 649 | struct audit_buffer *ab; |
650 | 650 | ||
651 | ab = audit_log_start(context); | 651 | ab = audit_log_start(context, AUDIT_KERNEL, 0); |
652 | if (!ab) | 652 | if (!ab) |
653 | return; /* audit_panic has been called */ | 653 | return; /* audit_panic has been called */ |
654 | audit_log_format(ab, "syscall=%d", context->major); | 654 | audit_log_format(ab, "syscall=%d", context->major); |
@@ -680,7 +680,7 @@ static void audit_log_exit(struct audit_context *context) | |||
680 | while (context->aux) { | 680 | while (context->aux) { |
681 | struct audit_aux_data *aux; | 681 | struct audit_aux_data *aux; |
682 | 682 | ||
683 | ab = audit_log_start(context); | 683 | ab = audit_log_start(context, AUDIT_KERNEL, 0); |
684 | if (!ab) | 684 | if (!ab) |
685 | continue; /* audit_panic has been called */ | 685 | continue; /* audit_panic has been called */ |
686 | 686 | ||
@@ -701,7 +701,7 @@ static void audit_log_exit(struct audit_context *context) | |||
701 | } | 701 | } |
702 | 702 | ||
703 | for (i = 0; i < context->name_count; i++) { | 703 | for (i = 0; i < context->name_count; i++) { |
704 | ab = audit_log_start(context); | 704 | ab = audit_log_start(context, AUDIT_KERNEL, 0); |
705 | if (!ab) | 705 | if (!ab) |
706 | continue; /* audit_panic has been called */ | 706 | continue; /* audit_panic has been called */ |
707 | audit_log_format(ab, "item=%d", i); | 707 | audit_log_format(ab, "item=%d", i); |
@@ -1005,22 +1005,13 @@ int audit_get_stamp(struct audit_context *ctx, | |||
1005 | return 0; | 1005 | return 0; |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | extern int audit_set_type(struct audit_buffer *ab, int type); | ||
1009 | |||
1010 | int audit_set_loginuid(struct task_struct *task, uid_t loginuid) | 1008 | int audit_set_loginuid(struct task_struct *task, uid_t loginuid) |
1011 | { | 1009 | { |
1012 | if (task->audit_context) { | 1010 | if (task->audit_context) { |
1013 | struct audit_buffer *ab; | 1011 | audit_log_type(NULL, AUDIT_LOGIN, 0, |
1014 | 1012 | "login pid=%d uid=%u old loginuid=%u new loginuid=%u", | |
1015 | ab = audit_log_start(NULL); | 1013 | task->pid, task->uid, task->audit_context->loginuid, |
1016 | if (ab) { | 1014 | loginuid); |
1017 | audit_log_format(ab, "login pid=%d uid=%u " | ||
1018 | "old loginuid=%u new loginuid=%u", | ||
1019 | task->pid, task->uid, | ||
1020 | task->audit_context->loginuid, loginuid); | ||
1021 | audit_set_type(ab, AUDIT_LOGIN); | ||
1022 | audit_log_end(ab); | ||
1023 | } | ||
1024 | task->audit_context->loginuid = loginuid; | 1015 | task->audit_context->loginuid = loginuid; |
1025 | } | 1016 | } |
1026 | return 0; | 1017 | return 0; |
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 85a6f66a873f..9e71a1bbe011 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
@@ -549,7 +549,7 @@ void avc_audit(u32 ssid, u32 tsid, | |||
549 | return; | 549 | return; |
550 | } | 550 | } |
551 | 551 | ||
552 | ab = audit_log_start(current->audit_context); | 552 | ab = audit_log_start(current->audit_context, AUDIT_KERNEL, 0); |
553 | if (!ab) | 553 | if (!ab) |
554 | return; /* audit_panic has been called */ | 554 | return; /* audit_panic has been called */ |
555 | audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted"); | 555 | audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted"); |