diff options
Diffstat (limited to 'kernel/audit.c')
-rw-r--r-- | kernel/audit.c | 175 |
1 files changed, 140 insertions, 35 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 0a813d2883e5..04fe2e301b61 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/audit.h> | 52 | #include <linux/audit.h> |
53 | 53 | ||
54 | #include <net/sock.h> | 54 | #include <net/sock.h> |
55 | #include <net/netlink.h> | ||
55 | #include <linux/skbuff.h> | 56 | #include <linux/skbuff.h> |
56 | #include <linux/netlink.h> | 57 | #include <linux/netlink.h> |
57 | 58 | ||
@@ -72,7 +73,7 @@ static int audit_failure = AUDIT_FAIL_PRINTK; | |||
72 | * contains the (non-zero) pid. */ | 73 | * contains the (non-zero) pid. */ |
73 | int audit_pid; | 74 | int audit_pid; |
74 | 75 | ||
75 | /* If audit_limit is non-zero, limit the rate of sending audit records | 76 | /* If audit_rate_limit is non-zero, limit the rate of sending audit records |
76 | * to that number per second. This prevents DoS attacks, but results in | 77 | * to that number per second. This prevents DoS attacks, but results in |
77 | * audit records being dropped. */ | 78 | * audit records being dropped. */ |
78 | static int audit_rate_limit; | 79 | static int audit_rate_limit; |
@@ -102,7 +103,7 @@ static struct sock *audit_sock; | |||
102 | * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of | 103 | * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of |
103 | * being placed on the freelist). */ | 104 | * being placed on the freelist). */ |
104 | static DEFINE_SPINLOCK(audit_freelist_lock); | 105 | static DEFINE_SPINLOCK(audit_freelist_lock); |
105 | static int audit_freelist_count = 0; | 106 | static int audit_freelist_count; |
106 | static LIST_HEAD(audit_freelist); | 107 | static LIST_HEAD(audit_freelist); |
107 | 108 | ||
108 | static struct sk_buff_head audit_skb_queue; | 109 | static struct sk_buff_head audit_skb_queue; |
@@ -113,7 +114,7 @@ static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); | |||
113 | /* The netlink socket is only to be read by 1 CPU, which lets us assume | 114 | /* The netlink socket is only to be read by 1 CPU, which lets us assume |
114 | * that list additions and deletions never happen simultaneously in | 115 | * that list additions and deletions never happen simultaneously in |
115 | * auditsc.c */ | 116 | * auditsc.c */ |
116 | DECLARE_MUTEX(audit_netlink_sem); | 117 | DEFINE_MUTEX(audit_netlink_mutex); |
117 | 118 | ||
118 | /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting | 119 | /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting |
119 | * audit records. Since printk uses a 1024 byte buffer, this buffer | 120 | * audit records. Since printk uses a 1024 byte buffer, this buffer |
@@ -142,7 +143,7 @@ static void audit_set_pid(struct audit_buffer *ab, pid_t pid) | |||
142 | nlh->nlmsg_pid = pid; | 143 | nlh->nlmsg_pid = pid; |
143 | } | 144 | } |
144 | 145 | ||
145 | static void audit_panic(const char *message) | 146 | void audit_panic(const char *message) |
146 | { | 147 | { |
147 | switch (audit_failure) | 148 | switch (audit_failure) |
148 | { | 149 | { |
@@ -186,8 +187,14 @@ static inline int audit_rate_check(void) | |||
186 | return retval; | 187 | return retval; |
187 | } | 188 | } |
188 | 189 | ||
189 | /* Emit at least 1 message per second, even if audit_rate_check is | 190 | /** |
190 | * throttling. */ | 191 | * audit_log_lost - conditionally log lost audit message event |
192 | * @message: the message stating reason for lost audit message | ||
193 | * | ||
194 | * Emit at least 1 message per second, even if audit_rate_check is | ||
195 | * throttling. | ||
196 | * Always increment the lost messages counter. | ||
197 | */ | ||
191 | void audit_log_lost(const char *message) | 198 | void audit_log_lost(const char *message) |
192 | { | 199 | { |
193 | static unsigned long last_msg = 0; | 200 | static unsigned long last_msg = 0; |
@@ -218,7 +225,6 @@ void audit_log_lost(const char *message) | |||
218 | audit_backlog_limit); | 225 | audit_backlog_limit); |
219 | audit_panic(message); | 226 | audit_panic(message); |
220 | } | 227 | } |
221 | |||
222 | } | 228 | } |
223 | 229 | ||
224 | static int audit_set_rate_limit(int limit, uid_t loginuid) | 230 | static int audit_set_rate_limit(int limit, uid_t loginuid) |
@@ -300,8 +306,22 @@ static int kauditd_thread(void *dummy) | |||
300 | remove_wait_queue(&kauditd_wait, &wait); | 306 | remove_wait_queue(&kauditd_wait, &wait); |
301 | } | 307 | } |
302 | } | 308 | } |
309 | return 0; | ||
303 | } | 310 | } |
304 | 311 | ||
312 | /** | ||
313 | * audit_send_reply - send an audit reply message via netlink | ||
314 | * @pid: process id to send reply to | ||
315 | * @seq: sequence number | ||
316 | * @type: audit message type | ||
317 | * @done: done (last) flag | ||
318 | * @multi: multi-part message flag | ||
319 | * @payload: payload data | ||
320 | * @size: payload size | ||
321 | * | ||
322 | * Allocates an skb, builds the netlink message, and sends it to the pid. | ||
323 | * No failure notifications. | ||
324 | */ | ||
305 | void audit_send_reply(int pid, int seq, int type, int done, int multi, | 325 | void audit_send_reply(int pid, int seq, int type, int done, int multi, |
306 | void *payload, int size) | 326 | void *payload, int size) |
307 | { | 327 | { |
@@ -342,15 +362,19 @@ static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type) | |||
342 | switch (msg_type) { | 362 | switch (msg_type) { |
343 | case AUDIT_GET: | 363 | case AUDIT_GET: |
344 | case AUDIT_LIST: | 364 | case AUDIT_LIST: |
365 | case AUDIT_LIST_RULES: | ||
345 | case AUDIT_SET: | 366 | case AUDIT_SET: |
346 | case AUDIT_ADD: | 367 | case AUDIT_ADD: |
368 | case AUDIT_ADD_RULE: | ||
347 | case AUDIT_DEL: | 369 | case AUDIT_DEL: |
370 | case AUDIT_DEL_RULE: | ||
348 | case AUDIT_SIGNAL_INFO: | 371 | case AUDIT_SIGNAL_INFO: |
349 | if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL)) | 372 | if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL)) |
350 | err = -EPERM; | 373 | err = -EPERM; |
351 | break; | 374 | break; |
352 | case AUDIT_USER: | 375 | case AUDIT_USER: |
353 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: | 376 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: |
377 | case AUDIT_FIRST_USER_MSG2...AUDIT_LAST_USER_MSG2: | ||
354 | if (!cap_raised(eff_cap, CAP_AUDIT_WRITE)) | 378 | if (!cap_raised(eff_cap, CAP_AUDIT_WRITE)) |
355 | err = -EPERM; | 379 | err = -EPERM; |
356 | break; | 380 | break; |
@@ -376,7 +400,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
376 | if (err) | 400 | if (err) |
377 | return err; | 401 | return err; |
378 | 402 | ||
379 | /* As soon as there's any sign of userspace auditd, start kauditd to talk to it */ | 403 | /* As soon as there's any sign of userspace auditd, |
404 | * start kauditd to talk to it */ | ||
380 | if (!kauditd_task) | 405 | if (!kauditd_task) |
381 | kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd"); | 406 | kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd"); |
382 | if (IS_ERR(kauditd_task)) { | 407 | if (IS_ERR(kauditd_task)) { |
@@ -430,6 +455,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
430 | break; | 455 | break; |
431 | case AUDIT_USER: | 456 | case AUDIT_USER: |
432 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: | 457 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: |
458 | case AUDIT_FIRST_USER_MSG2...AUDIT_LAST_USER_MSG2: | ||
433 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) | 459 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) |
434 | return 0; | 460 | return 0; |
435 | 461 | ||
@@ -448,12 +474,23 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
448 | break; | 474 | break; |
449 | case AUDIT_ADD: | 475 | case AUDIT_ADD: |
450 | case AUDIT_DEL: | 476 | case AUDIT_DEL: |
451 | if (nlh->nlmsg_len < sizeof(struct audit_rule)) | 477 | if (nlmsg_len(nlh) < sizeof(struct audit_rule)) |
452 | return -EINVAL; | 478 | return -EINVAL; |
453 | /* fallthrough */ | 479 | /* fallthrough */ |
454 | case AUDIT_LIST: | 480 | case AUDIT_LIST: |
455 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 481 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
456 | uid, seq, data, loginuid); | 482 | uid, seq, data, nlmsg_len(nlh), |
483 | loginuid); | ||
484 | break; | ||
485 | case AUDIT_ADD_RULE: | ||
486 | case AUDIT_DEL_RULE: | ||
487 | if (nlmsg_len(nlh) < sizeof(struct audit_rule_data)) | ||
488 | return -EINVAL; | ||
489 | /* fallthrough */ | ||
490 | case AUDIT_LIST_RULES: | ||
491 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | ||
492 | uid, seq, data, nlmsg_len(nlh), | ||
493 | loginuid); | ||
457 | break; | 494 | break; |
458 | case AUDIT_SIGNAL_INFO: | 495 | case AUDIT_SIGNAL_INFO: |
459 | sig_data.uid = audit_sig_uid; | 496 | sig_data.uid = audit_sig_uid; |
@@ -469,9 +506,11 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
469 | return err < 0 ? err : 0; | 506 | return err < 0 ? err : 0; |
470 | } | 507 | } |
471 | 508 | ||
472 | /* Get message from skb (based on rtnetlink_rcv_skb). Each message is | 509 | /* |
510 | * Get message from skb (based on rtnetlink_rcv_skb). Each message is | ||
473 | * processed by audit_receive_msg. Malformed skbs with wrong length are | 511 | * processed by audit_receive_msg. Malformed skbs with wrong length are |
474 | * discarded silently. */ | 512 | * discarded silently. |
513 | */ | ||
475 | static void audit_receive_skb(struct sk_buff *skb) | 514 | static void audit_receive_skb(struct sk_buff *skb) |
476 | { | 515 | { |
477 | int err; | 516 | int err; |
@@ -499,14 +538,14 @@ static void audit_receive(struct sock *sk, int length) | |||
499 | struct sk_buff *skb; | 538 | struct sk_buff *skb; |
500 | unsigned int qlen; | 539 | unsigned int qlen; |
501 | 540 | ||
502 | down(&audit_netlink_sem); | 541 | mutex_lock(&audit_netlink_mutex); |
503 | 542 | ||
504 | for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { | 543 | for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { |
505 | skb = skb_dequeue(&sk->sk_receive_queue); | 544 | skb = skb_dequeue(&sk->sk_receive_queue); |
506 | audit_receive_skb(skb); | 545 | audit_receive_skb(skb); |
507 | kfree_skb(skb); | 546 | kfree_skb(skb); |
508 | } | 547 | } |
509 | up(&audit_netlink_sem); | 548 | mutex_unlock(&audit_netlink_mutex); |
510 | } | 549 | } |
511 | 550 | ||
512 | 551 | ||
@@ -519,8 +558,9 @@ static int __init audit_init(void) | |||
519 | THIS_MODULE); | 558 | THIS_MODULE); |
520 | if (!audit_sock) | 559 | if (!audit_sock) |
521 | audit_panic("cannot initialize netlink socket"); | 560 | audit_panic("cannot initialize netlink socket"); |
561 | else | ||
562 | audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; | ||
522 | 563 | ||
523 | audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; | ||
524 | skb_queue_head_init(&audit_skb_queue); | 564 | skb_queue_head_init(&audit_skb_queue); |
525 | audit_initialized = 1; | 565 | audit_initialized = 1; |
526 | audit_enabled = audit_default; | 566 | audit_enabled = audit_default; |
@@ -600,7 +640,10 @@ err: | |||
600 | return NULL; | 640 | return NULL; |
601 | } | 641 | } |
602 | 642 | ||
603 | /* Compute a serial number for the audit record. Audit records are | 643 | /** |
644 | * audit_serial - compute a serial number for the audit record | ||
645 | * | ||
646 | * Compute a serial number for the audit record. Audit records are | ||
604 | * written to user-space as soon as they are generated, so a complete | 647 | * written to user-space as soon as they are generated, so a complete |
605 | * audit record may be written in several pieces. The timestamp of the | 648 | * audit record may be written in several pieces. The timestamp of the |
606 | * record and this serial number are used by the user-space tools to | 649 | * record and this serial number are used by the user-space tools to |
@@ -612,8 +655,8 @@ err: | |||
612 | * audit context (for those records that have a context), and emit them | 655 | * audit context (for those records that have a context), and emit them |
613 | * all at syscall exit. However, this could delay the reporting of | 656 | * all at syscall exit. However, this could delay the reporting of |
614 | * significant errors until syscall exit (or never, if the system | 657 | * significant errors until syscall exit (or never, if the system |
615 | * halts). */ | 658 | * halts). |
616 | 659 | */ | |
617 | unsigned int audit_serial(void) | 660 | unsigned int audit_serial(void) |
618 | { | 661 | { |
619 | static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED; | 662 | static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED; |
@@ -649,6 +692,21 @@ static inline void audit_get_stamp(struct audit_context *ctx, | |||
649 | * will be written at syscall exit. If there is no associated task, tsk | 692 | * will be written at syscall exit. If there is no associated task, tsk |
650 | * should be NULL. */ | 693 | * should be NULL. */ |
651 | 694 | ||
695 | /** | ||
696 | * audit_log_start - obtain an audit buffer | ||
697 | * @ctx: audit_context (may be NULL) | ||
698 | * @gfp_mask: type of allocation | ||
699 | * @type: audit message type | ||
700 | * | ||
701 | * Returns audit_buffer pointer on success or NULL on error. | ||
702 | * | ||
703 | * Obtain an audit buffer. This routine does locking to obtain the | ||
704 | * audit buffer, but then no locking is required for calls to | ||
705 | * audit_log_*format. If the task (ctx) is a task that is currently in a | ||
706 | * syscall, then the syscall is marked as auditable and an audit record | ||
707 | * will be written at syscall exit. If there is no associated task, then | ||
708 | * task context (ctx) should be NULL. | ||
709 | */ | ||
652 | struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, | 710 | struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, |
653 | int type) | 711 | int type) |
654 | { | 712 | { |
@@ -661,6 +719,9 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, | |||
661 | if (!audit_initialized) | 719 | if (!audit_initialized) |
662 | return NULL; | 720 | return NULL; |
663 | 721 | ||
722 | if (unlikely(audit_filter_type(type))) | ||
723 | return NULL; | ||
724 | |||
664 | if (gfp_mask & __GFP_WAIT) | 725 | if (gfp_mask & __GFP_WAIT) |
665 | reserve = 0; | 726 | reserve = 0; |
666 | else | 727 | else |
@@ -713,6 +774,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, | |||
713 | /** | 774 | /** |
714 | * audit_expand - expand skb in the audit buffer | 775 | * audit_expand - expand skb in the audit buffer |
715 | * @ab: audit_buffer | 776 | * @ab: audit_buffer |
777 | * @extra: space to add at tail of the skb | ||
716 | * | 778 | * |
717 | * Returns 0 (no space) on failed expansion, or available space if | 779 | * Returns 0 (no space) on failed expansion, or available space if |
718 | * successful. | 780 | * successful. |
@@ -729,10 +791,12 @@ static inline int audit_expand(struct audit_buffer *ab, int extra) | |||
729 | return skb_tailroom(skb); | 791 | return skb_tailroom(skb); |
730 | } | 792 | } |
731 | 793 | ||
732 | /* Format an audit message into the audit buffer. If there isn't enough | 794 | /* |
795 | * Format an audit message into the audit buffer. If there isn't enough | ||
733 | * room in the audit buffer, more room will be allocated and vsnprint | 796 | * room in the audit buffer, more room will be allocated and vsnprint |
734 | * will be called a second time. Currently, we assume that a printk | 797 | * will be called a second time. Currently, we assume that a printk |
735 | * can't format message larger than 1024 bytes, so we don't either. */ | 798 | * can't format message larger than 1024 bytes, so we don't either. |
799 | */ | ||
736 | static void audit_log_vformat(struct audit_buffer *ab, const char *fmt, | 800 | static void audit_log_vformat(struct audit_buffer *ab, const char *fmt, |
737 | va_list args) | 801 | va_list args) |
738 | { | 802 | { |
@@ -757,7 +821,8 @@ static void audit_log_vformat(struct audit_buffer *ab, const char *fmt, | |||
757 | /* The printk buffer is 1024 bytes long, so if we get | 821 | /* The printk buffer is 1024 bytes long, so if we get |
758 | * here and AUDIT_BUFSIZ is at least 1024, then we can | 822 | * here and AUDIT_BUFSIZ is at least 1024, then we can |
759 | * log everything that printk could have logged. */ | 823 | * log everything that printk could have logged. */ |
760 | avail = audit_expand(ab, max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail)); | 824 | avail = audit_expand(ab, |
825 | max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail)); | ||
761 | if (!avail) | 826 | if (!avail) |
762 | goto out; | 827 | goto out; |
763 | len = vsnprintf(skb->tail, avail, fmt, args2); | 828 | len = vsnprintf(skb->tail, avail, fmt, args2); |
@@ -768,8 +833,14 @@ out: | |||
768 | return; | 833 | return; |
769 | } | 834 | } |
770 | 835 | ||
771 | /* Format a message into the audit buffer. All the work is done in | 836 | /** |
772 | * audit_log_vformat. */ | 837 | * audit_log_format - format a message into the audit buffer. |
838 | * @ab: audit_buffer | ||
839 | * @fmt: format string | ||
840 | * @...: optional parameters matching @fmt string | ||
841 | * | ||
842 | * All the work is done in audit_log_vformat. | ||
843 | */ | ||
773 | void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) | 844 | void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) |
774 | { | 845 | { |
775 | va_list args; | 846 | va_list args; |
@@ -781,9 +852,18 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) | |||
781 | va_end(args); | 852 | va_end(args); |
782 | } | 853 | } |
783 | 854 | ||
784 | /* This function will take the passed buf and convert it into a string of | 855 | /** |
785 | * ascii hex digits. The new string is placed onto the skb. */ | 856 | * audit_log_hex - convert a buffer to hex and append it to the audit skb |
786 | void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, | 857 | * @ab: the audit_buffer |
858 | * @buf: buffer to convert to hex | ||
859 | * @len: length of @buf to be converted | ||
860 | * | ||
861 | * No return value; failure to expand is silently ignored. | ||
862 | * | ||
863 | * This function will take the passed buf and convert it into a string of | ||
864 | * ascii hex digits. The new string is placed onto the skb. | ||
865 | */ | ||
866 | void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, | ||
787 | size_t len) | 867 | size_t len) |
788 | { | 868 | { |
789 | int i, avail, new_len; | 869 | int i, avail, new_len; |
@@ -812,10 +892,16 @@ void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, | |||
812 | skb_put(skb, len << 1); /* new string is twice the old string */ | 892 | skb_put(skb, len << 1); /* new string is twice the old string */ |
813 | } | 893 | } |
814 | 894 | ||
815 | /* This code will escape a string that is passed to it if the string | 895 | /** |
816 | * contains a control character, unprintable character, double quote mark, | 896 | * audit_log_unstrustedstring - log a string that may contain random characters |
897 | * @ab: audit_buffer | ||
898 | * @string: string to be logged | ||
899 | * | ||
900 | * This code will escape a string that is passed to it if the string | ||
901 | * contains a control character, unprintable character, double quote mark, | ||
817 | * or a space. Unescaped strings will start and end with a double quote mark. | 902 | * or a space. Unescaped strings will start and end with a double quote mark. |
818 | * Strings that are escaped are printed in hex (2 digits per char). */ | 903 | * Strings that are escaped are printed in hex (2 digits per char). |
904 | */ | ||
819 | void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) | 905 | void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) |
820 | { | 906 | { |
821 | const unsigned char *p = string; | 907 | const unsigned char *p = string; |
@@ -854,10 +940,15 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix, | |||
854 | kfree(path); | 940 | kfree(path); |
855 | } | 941 | } |
856 | 942 | ||
857 | /* The netlink_* functions cannot be called inside an irq context, so | 943 | /** |
858 | * the audit buffer is places on a queue and a tasklet is scheduled to | 944 | * audit_log_end - end one audit record |
945 | * @ab: the audit_buffer | ||
946 | * | ||
947 | * The netlink_* functions cannot be called inside an irq context, so | ||
948 | * the audit buffer is placed on a queue and a tasklet is scheduled to | ||
859 | * remove them from the queue outside the irq context. May be called in | 949 | * remove them from the queue outside the irq context. May be called in |
860 | * any context. */ | 950 | * any context. |
951 | */ | ||
861 | void audit_log_end(struct audit_buffer *ab) | 952 | void audit_log_end(struct audit_buffer *ab) |
862 | { | 953 | { |
863 | if (!ab) | 954 | if (!ab) |
@@ -878,9 +969,18 @@ void audit_log_end(struct audit_buffer *ab) | |||
878 | audit_buffer_free(ab); | 969 | audit_buffer_free(ab); |
879 | } | 970 | } |
880 | 971 | ||
881 | /* Log an audit record. This is a convenience function that calls | 972 | /** |
882 | * audit_log_start, audit_log_vformat, and audit_log_end. It may be | 973 | * audit_log - Log an audit record |
883 | * called in any context. */ | 974 | * @ctx: audit context |
975 | * @gfp_mask: type of allocation | ||
976 | * @type: audit message type | ||
977 | * @fmt: format string to use | ||
978 | * @...: variable parameters matching the format string | ||
979 | * | ||
980 | * This is a convenience function that calls audit_log_start, | ||
981 | * audit_log_vformat, and audit_log_end. It may be called | ||
982 | * in any context. | ||
983 | */ | ||
884 | void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, | 984 | void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, |
885 | const char *fmt, ...) | 985 | const char *fmt, ...) |
886 | { | 986 | { |
@@ -895,3 +995,8 @@ void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, | |||
895 | audit_log_end(ab); | 995 | audit_log_end(ab); |
896 | } | 996 | } |
897 | } | 997 | } |
998 | |||
999 | EXPORT_SYMBOL(audit_log_start); | ||
1000 | EXPORT_SYMBOL(audit_log_end); | ||
1001 | EXPORT_SYMBOL(audit_log_format); | ||
1002 | EXPORT_SYMBOL(audit_log); | ||