diff options
Diffstat (limited to 'kernel/audit.c')
| -rw-r--r-- | kernel/audit.c | 123 |
1 files changed, 79 insertions, 44 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index ef35166fdc29..d321e251d32b 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -79,6 +79,8 @@ static int audit_rate_limit; | |||
| 79 | 79 | ||
| 80 | /* Number of outstanding audit_buffers allowed. */ | 80 | /* Number of outstanding audit_buffers allowed. */ |
| 81 | static int audit_backlog_limit = 64; | 81 | static int audit_backlog_limit = 64; |
| 82 | static int audit_backlog_wait_time = 60 * HZ; | ||
| 83 | static int audit_backlog_wait_overflow = 0; | ||
| 82 | 84 | ||
| 83 | /* The identity of the user shutting down the audit system. */ | 85 | /* The identity of the user shutting down the audit system. */ |
| 84 | uid_t audit_sig_uid = -1; | 86 | uid_t audit_sig_uid = -1; |
| @@ -106,18 +108,12 @@ static LIST_HEAD(audit_freelist); | |||
| 106 | static struct sk_buff_head audit_skb_queue; | 108 | static struct sk_buff_head audit_skb_queue; |
| 107 | static struct task_struct *kauditd_task; | 109 | static struct task_struct *kauditd_task; |
| 108 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); | 110 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); |
| 109 | 111 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); | |
| 110 | /* There are three lists of rules -- one to search at task creation | ||
| 111 | * time, one to search at syscall entry time, and another to search at | ||
| 112 | * syscall exit time. */ | ||
| 113 | static LIST_HEAD(audit_tsklist); | ||
| 114 | static LIST_HEAD(audit_entlist); | ||
| 115 | static LIST_HEAD(audit_extlist); | ||
| 116 | 112 | ||
| 117 | /* The netlink socket is only to be read by 1 CPU, which lets us assume | 113 | /* The netlink socket is only to be read by 1 CPU, which lets us assume |
| 118 | * that list additions and deletions never happen simultaneously in | 114 | * that list additions and deletions never happen simultaneously in |
| 119 | * auditsc.c */ | 115 | * auditsc.c */ |
| 120 | static DECLARE_MUTEX(audit_netlink_sem); | 116 | DECLARE_MUTEX(audit_netlink_sem); |
| 121 | 117 | ||
| 122 | /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting | 118 | /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting |
| 123 | * audit records. Since printk uses a 1024 byte buffer, this buffer | 119 | * audit records. Since printk uses a 1024 byte buffer, this buffer |
| @@ -137,6 +133,7 @@ struct audit_buffer { | |||
| 137 | struct list_head list; | 133 | struct list_head list; |
| 138 | struct sk_buff *skb; /* formatted skb ready to send */ | 134 | struct sk_buff *skb; /* formatted skb ready to send */ |
| 139 | struct audit_context *ctx; /* NULL or associated context */ | 135 | struct audit_context *ctx; /* NULL or associated context */ |
| 136 | int gfp_mask; | ||
| 140 | }; | 137 | }; |
| 141 | 138 | ||
| 142 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) | 139 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) |
| @@ -233,7 +230,7 @@ static int audit_set_rate_limit(int limit, uid_t loginuid) | |||
| 233 | { | 230 | { |
| 234 | int old = audit_rate_limit; | 231 | int old = audit_rate_limit; |
| 235 | audit_rate_limit = limit; | 232 | audit_rate_limit = limit; |
| 236 | audit_log(NULL, AUDIT_CONFIG_CHANGE, | 233 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, |
| 237 | "audit_rate_limit=%d old=%d by auid=%u", | 234 | "audit_rate_limit=%d old=%d by auid=%u", |
| 238 | audit_rate_limit, old, loginuid); | 235 | audit_rate_limit, old, loginuid); |
| 239 | return old; | 236 | return old; |
| @@ -243,7 +240,7 @@ static int audit_set_backlog_limit(int limit, uid_t loginuid) | |||
| 243 | { | 240 | { |
| 244 | int old = audit_backlog_limit; | 241 | int old = audit_backlog_limit; |
| 245 | audit_backlog_limit = limit; | 242 | audit_backlog_limit = limit; |
| 246 | audit_log(NULL, AUDIT_CONFIG_CHANGE, | 243 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, |
| 247 | "audit_backlog_limit=%d old=%d by auid=%u", | 244 | "audit_backlog_limit=%d old=%d by auid=%u", |
| 248 | audit_backlog_limit, old, loginuid); | 245 | audit_backlog_limit, old, loginuid); |
| 249 | return old; | 246 | return old; |
| @@ -255,7 +252,7 @@ static int audit_set_enabled(int state, uid_t loginuid) | |||
| 255 | if (state != 0 && state != 1) | 252 | if (state != 0 && state != 1) |
| 256 | return -EINVAL; | 253 | return -EINVAL; |
| 257 | audit_enabled = state; | 254 | audit_enabled = state; |
| 258 | audit_log(NULL, AUDIT_CONFIG_CHANGE, | 255 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, |
| 259 | "audit_enabled=%d old=%d by auid=%u", | 256 | "audit_enabled=%d old=%d by auid=%u", |
| 260 | audit_enabled, old, loginuid); | 257 | audit_enabled, old, loginuid); |
| 261 | return old; | 258 | return old; |
| @@ -269,7 +266,7 @@ static int audit_set_failure(int state, uid_t loginuid) | |||
| 269 | && state != AUDIT_FAIL_PANIC) | 266 | && state != AUDIT_FAIL_PANIC) |
| 270 | return -EINVAL; | 267 | return -EINVAL; |
| 271 | audit_failure = state; | 268 | audit_failure = state; |
| 272 | audit_log(NULL, AUDIT_CONFIG_CHANGE, | 269 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, |
| 273 | "audit_failure=%d old=%d by auid=%u", | 270 | "audit_failure=%d old=%d by auid=%u", |
| 274 | audit_failure, old, loginuid); | 271 | audit_failure, old, loginuid); |
| 275 | return old; | 272 | return old; |
| @@ -281,6 +278,7 @@ int kauditd_thread(void *dummy) | |||
| 281 | 278 | ||
| 282 | while (1) { | 279 | while (1) { |
| 283 | skb = skb_dequeue(&audit_skb_queue); | 280 | skb = skb_dequeue(&audit_skb_queue); |
| 281 | wake_up(&audit_backlog_wait); | ||
| 284 | if (skb) { | 282 | if (skb) { |
| 285 | if (audit_pid) { | 283 | if (audit_pid) { |
| 286 | int err = netlink_unicast(audit_sock, skb, audit_pid, 0); | 284 | int err = netlink_unicast(audit_sock, skb, audit_pid, 0); |
| @@ -290,7 +288,7 @@ int kauditd_thread(void *dummy) | |||
| 290 | audit_pid = 0; | 288 | audit_pid = 0; |
| 291 | } | 289 | } |
| 292 | } else { | 290 | } else { |
| 293 | printk(KERN_ERR "%s\n", skb->data + NLMSG_SPACE(0)); | 291 | printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0)); |
| 294 | kfree_skb(skb); | 292 | kfree_skb(skb); |
| 295 | } | 293 | } |
| 296 | } else { | 294 | } else { |
| @@ -423,7 +421,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 423 | if (status_get->mask & AUDIT_STATUS_PID) { | 421 | if (status_get->mask & AUDIT_STATUS_PID) { |
| 424 | int old = audit_pid; | 422 | int old = audit_pid; |
| 425 | audit_pid = status_get->pid; | 423 | audit_pid = status_get->pid; |
| 426 | audit_log(NULL, AUDIT_CONFIG_CHANGE, | 424 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, |
| 427 | "audit_pid=%d old=%d by auid=%u", | 425 | "audit_pid=%d old=%d by auid=%u", |
| 428 | audit_pid, old, loginuid); | 426 | audit_pid, old, loginuid); |
| 429 | } | 427 | } |
| @@ -435,15 +433,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 435 | break; | 433 | break; |
| 436 | case AUDIT_USER: | 434 | case AUDIT_USER: |
| 437 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: | 435 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: |
| 438 | ab = audit_log_start(NULL, msg_type); | 436 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) |
| 439 | if (!ab) | 437 | return 0; |
| 440 | break; /* audit_panic has been called */ | 438 | |
| 441 | audit_log_format(ab, | 439 | err = audit_filter_user(&NETLINK_CB(skb), msg_type); |
| 442 | "user pid=%d uid=%u auid=%u" | 440 | if (err == 1) { |
| 443 | " msg='%.1024s'", | 441 | err = 0; |
| 444 | pid, uid, loginuid, (char *)data); | 442 | ab = audit_log_start(NULL, GFP_KERNEL, msg_type); |
| 445 | audit_set_pid(ab, pid); | 443 | if (ab) { |
| 446 | audit_log_end(ab); | 444 | audit_log_format(ab, |
| 445 | "user pid=%d uid=%u auid=%u msg='%.1024s'", | ||
| 446 | pid, uid, loginuid, (char *)data); | ||
| 447 | audit_set_pid(ab, pid); | ||
| 448 | audit_log_end(ab); | ||
| 449 | } | ||
| 450 | } | ||
| 447 | break; | 451 | break; |
| 448 | case AUDIT_ADD: | 452 | case AUDIT_ADD: |
| 449 | case AUDIT_DEL: | 453 | case AUDIT_DEL: |
| @@ -522,7 +526,7 @@ static int __init audit_init(void) | |||
| 522 | skb_queue_head_init(&audit_skb_queue); | 526 | skb_queue_head_init(&audit_skb_queue); |
| 523 | audit_initialized = 1; | 527 | audit_initialized = 1; |
| 524 | audit_enabled = audit_default; | 528 | audit_enabled = audit_default; |
| 525 | audit_log(NULL, AUDIT_KERNEL, "initialized"); | 529 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); |
| 526 | return 0; | 530 | return 0; |
| 527 | } | 531 | } |
| 528 | __initcall(audit_init); | 532 | __initcall(audit_init); |
| @@ -560,7 +564,7 @@ static void audit_buffer_free(struct audit_buffer *ab) | |||
| 560 | } | 564 | } |
| 561 | 565 | ||
| 562 | static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, | 566 | static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, |
| 563 | int gfp_mask, int type) | 567 | unsigned int __nocast gfp_mask, int type) |
| 564 | { | 568 | { |
| 565 | unsigned long flags; | 569 | unsigned long flags; |
| 566 | struct audit_buffer *ab = NULL; | 570 | struct audit_buffer *ab = NULL; |
| @@ -586,6 +590,7 @@ static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx, | |||
| 586 | goto err; | 590 | goto err; |
| 587 | 591 | ||
| 588 | ab->ctx = ctx; | 592 | ab->ctx = ctx; |
| 593 | ab->gfp_mask = gfp_mask; | ||
| 589 | nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0)); | 594 | nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0)); |
| 590 | nlh->nlmsg_type = type; | 595 | nlh->nlmsg_type = type; |
| 591 | nlh->nlmsg_flags = 0; | 596 | nlh->nlmsg_flags = 0; |
| @@ -605,26 +610,27 @@ err: | |||
| 605 | * (timestamp,serial) tuple is unique for each syscall and is live from | 610 | * (timestamp,serial) tuple is unique for each syscall and is live from |
| 606 | * syscall entry to syscall exit. | 611 | * syscall entry to syscall exit. |
| 607 | * | 612 | * |
| 608 | * Atomic values are only guaranteed to be 24-bit, so we count down. | ||
| 609 | * | ||
| 610 | * NOTE: Another possibility is to store the formatted records off the | 613 | * NOTE: Another possibility is to store the formatted records off the |
| 611 | * audit context (for those records that have a context), and emit them | 614 | * audit context (for those records that have a context), and emit them |
| 612 | * all at syscall exit. However, this could delay the reporting of | 615 | * all at syscall exit. However, this could delay the reporting of |
| 613 | * significant errors until syscall exit (or never, if the system | 616 | * significant errors until syscall exit (or never, if the system |
| 614 | * halts). */ | 617 | * halts). */ |
| 618 | |||
| 615 | unsigned int audit_serial(void) | 619 | unsigned int audit_serial(void) |
| 616 | { | 620 | { |
| 617 | static atomic_t serial = ATOMIC_INIT(0xffffff); | 621 | static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED; |
| 618 | unsigned int a, b; | 622 | static unsigned int serial = 0; |
| 619 | 623 | ||
| 624 | unsigned long flags; | ||
| 625 | unsigned int ret; | ||
| 626 | |||
| 627 | spin_lock_irqsave(&serial_lock, flags); | ||
| 620 | do { | 628 | do { |
| 621 | a = atomic_read(&serial); | 629 | ret = ++serial; |
| 622 | if (atomic_dec_and_test(&serial)) | 630 | } while (unlikely(!ret)); |
| 623 | atomic_set(&serial, 0xffffff); | 631 | spin_unlock_irqrestore(&serial_lock, flags); |
| 624 | b = atomic_read(&serial); | ||
| 625 | } while (b != a - 1); | ||
| 626 | 632 | ||
| 627 | return 0xffffff - b; | 633 | return ret; |
| 628 | } | 634 | } |
| 629 | 635 | ||
| 630 | static inline void audit_get_stamp(struct audit_context *ctx, | 636 | static inline void audit_get_stamp(struct audit_context *ctx, |
| @@ -644,17 +650,43 @@ static inline void audit_get_stamp(struct audit_context *ctx, | |||
| 644 | * syscall, then the syscall is marked as auditable and an audit record | 650 | * 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 | 651 | * will be written at syscall exit. If there is no associated task, tsk |
| 646 | * should be NULL. */ | 652 | * should be NULL. */ |
| 647 | struct audit_buffer *audit_log_start(struct audit_context *ctx, int type) | 653 | |
| 654 | struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask, | ||
| 655 | int type) | ||
| 648 | { | 656 | { |
| 649 | struct audit_buffer *ab = NULL; | 657 | struct audit_buffer *ab = NULL; |
| 650 | struct timespec t; | 658 | struct timespec t; |
| 651 | unsigned int serial; | 659 | unsigned int serial; |
| 660 | int reserve; | ||
| 661 | unsigned long timeout_start = jiffies; | ||
| 652 | 662 | ||
| 653 | if (!audit_initialized) | 663 | if (!audit_initialized) |
| 654 | return NULL; | 664 | return NULL; |
| 655 | 665 | ||
| 656 | if (audit_backlog_limit | 666 | if (gfp_mask & __GFP_WAIT) |
| 657 | && skb_queue_len(&audit_skb_queue) > audit_backlog_limit) { | 667 | reserve = 0; |
| 668 | else | ||
| 669 | reserve = 5; /* Allow atomic callers to go up to five | ||
| 670 | entries over the normal backlog limit */ | ||
| 671 | |||
| 672 | while (audit_backlog_limit | ||
| 673 | && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { | ||
| 674 | if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time | ||
| 675 | && time_before(jiffies, timeout_start + audit_backlog_wait_time)) { | ||
| 676 | |||
| 677 | /* Wait for auditd to drain the queue a little */ | ||
| 678 | DECLARE_WAITQUEUE(wait, current); | ||
| 679 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 680 | add_wait_queue(&audit_backlog_wait, &wait); | ||
| 681 | |||
| 682 | if (audit_backlog_limit && | ||
| 683 | skb_queue_len(&audit_skb_queue) > audit_backlog_limit) | ||
| 684 | schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies); | ||
| 685 | |||
| 686 | __set_current_state(TASK_RUNNING); | ||
| 687 | remove_wait_queue(&audit_backlog_wait, &wait); | ||
| 688 | continue; | ||
| 689 | } | ||
| 658 | if (audit_rate_check()) | 690 | if (audit_rate_check()) |
| 659 | printk(KERN_WARNING | 691 | printk(KERN_WARNING |
| 660 | "audit: audit_backlog=%d > " | 692 | "audit: audit_backlog=%d > " |
| @@ -662,10 +694,12 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int type) | |||
| 662 | skb_queue_len(&audit_skb_queue), | 694 | skb_queue_len(&audit_skb_queue), |
| 663 | audit_backlog_limit); | 695 | audit_backlog_limit); |
| 664 | audit_log_lost("backlog limit exceeded"); | 696 | audit_log_lost("backlog limit exceeded"); |
| 697 | audit_backlog_wait_time = audit_backlog_wait_overflow; | ||
| 698 | wake_up(&audit_backlog_wait); | ||
| 665 | return NULL; | 699 | return NULL; |
| 666 | } | 700 | } |
| 667 | 701 | ||
| 668 | ab = audit_buffer_alloc(ctx, GFP_ATOMIC, type); | 702 | ab = audit_buffer_alloc(ctx, gfp_mask, type); |
| 669 | if (!ab) { | 703 | if (!ab) { |
| 670 | audit_log_lost("out of memory in audit_log_start"); | 704 | audit_log_lost("out of memory in audit_log_start"); |
| 671 | return NULL; | 705 | return NULL; |
| @@ -689,7 +723,7 @@ static inline int audit_expand(struct audit_buffer *ab, int extra) | |||
| 689 | { | 723 | { |
| 690 | struct sk_buff *skb = ab->skb; | 724 | struct sk_buff *skb = ab->skb; |
| 691 | int ret = pskb_expand_head(skb, skb_headroom(skb), extra, | 725 | int ret = pskb_expand_head(skb, skb_headroom(skb), extra, |
| 692 | GFP_ATOMIC); | 726 | ab->gfp_mask); |
| 693 | if (ret < 0) { | 727 | if (ret < 0) { |
| 694 | audit_log_lost("out of memory in audit_expand"); | 728 | audit_log_lost("out of memory in audit_expand"); |
| 695 | return 0; | 729 | return 0; |
| @@ -808,7 +842,7 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix, | |||
| 808 | audit_log_format(ab, " %s", prefix); | 842 | audit_log_format(ab, " %s", prefix); |
| 809 | 843 | ||
| 810 | /* We will allow 11 spaces for ' (deleted)' to be appended */ | 844 | /* We will allow 11 spaces for ' (deleted)' to be appended */ |
| 811 | path = kmalloc(PATH_MAX+11, GFP_KERNEL); | 845 | path = kmalloc(PATH_MAX+11, ab->gfp_mask); |
| 812 | if (!path) { | 846 | if (!path) { |
| 813 | audit_log_format(ab, "<no memory>"); | 847 | audit_log_format(ab, "<no memory>"); |
| 814 | return; | 848 | return; |
| @@ -840,7 +874,7 @@ void audit_log_end(struct audit_buffer *ab) | |||
| 840 | ab->skb = NULL; | 874 | ab->skb = NULL; |
| 841 | wake_up_interruptible(&kauditd_wait); | 875 | wake_up_interruptible(&kauditd_wait); |
| 842 | } else { | 876 | } else { |
| 843 | printk("%s\n", ab->skb->data + NLMSG_SPACE(0)); | 877 | printk(KERN_NOTICE "%s\n", ab->skb->data + NLMSG_SPACE(0)); |
| 844 | } | 878 | } |
| 845 | } | 879 | } |
| 846 | audit_buffer_free(ab); | 880 | audit_buffer_free(ab); |
| @@ -849,12 +883,13 @@ void audit_log_end(struct audit_buffer *ab) | |||
| 849 | /* Log an audit record. This is a convenience function that calls | 883 | /* 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 | 884 | * audit_log_start, audit_log_vformat, and audit_log_end. It may be |
| 851 | * called in any context. */ | 885 | * called in any context. */ |
| 852 | void audit_log(struct audit_context *ctx, int type, const char *fmt, ...) | 886 | void audit_log(struct audit_context *ctx, int gfp_mask, int type, |
| 887 | const char *fmt, ...) | ||
| 853 | { | 888 | { |
| 854 | struct audit_buffer *ab; | 889 | struct audit_buffer *ab; |
| 855 | va_list args; | 890 | va_list args; |
| 856 | 891 | ||
| 857 | ab = audit_log_start(ctx, type); | 892 | ab = audit_log_start(ctx, gfp_mask, type); |
| 858 | if (ab) { | 893 | if (ab) { |
| 859 | va_start(args, fmt); | 894 | va_start(args, fmt); |
| 860 | audit_log_vformat(ab, fmt, args); | 895 | audit_log_vformat(ab, fmt, args); |
