diff options
Diffstat (limited to 'kernel/audit.c')
| -rw-r--r-- | kernel/audit.c | 205 |
1 files changed, 158 insertions, 47 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index df57b493e1cb..7dfac7031bd7 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -56,6 +56,7 @@ | |||
| 56 | #include <linux/skbuff.h> | 56 | #include <linux/skbuff.h> |
| 57 | #include <linux/netlink.h> | 57 | #include <linux/netlink.h> |
| 58 | #include <linux/selinux.h> | 58 | #include <linux/selinux.h> |
| 59 | #include <linux/inotify.h> | ||
| 59 | 60 | ||
| 60 | #include "audit.h" | 61 | #include "audit.h" |
| 61 | 62 | ||
| @@ -89,6 +90,7 @@ static int audit_backlog_wait_overflow = 0; | |||
| 89 | /* The identity of the user shutting down the audit system. */ | 90 | /* The identity of the user shutting down the audit system. */ |
| 90 | uid_t audit_sig_uid = -1; | 91 | uid_t audit_sig_uid = -1; |
| 91 | pid_t audit_sig_pid = -1; | 92 | pid_t audit_sig_pid = -1; |
| 93 | u32 audit_sig_sid = 0; | ||
| 92 | 94 | ||
| 93 | /* Records can be lost in several ways: | 95 | /* Records can be lost in several ways: |
| 94 | 0) [suppressed in audit_alloc] | 96 | 0) [suppressed in audit_alloc] |
| @@ -102,6 +104,12 @@ static atomic_t audit_lost = ATOMIC_INIT(0); | |||
| 102 | /* The netlink socket. */ | 104 | /* The netlink socket. */ |
| 103 | static struct sock *audit_sock; | 105 | static struct sock *audit_sock; |
| 104 | 106 | ||
| 107 | /* Inotify handle. */ | ||
| 108 | struct inotify_handle *audit_ih; | ||
| 109 | |||
| 110 | /* Hash for inode-based rules */ | ||
| 111 | struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; | ||
| 112 | |||
| 105 | /* The audit_freelist is a list of pre-allocated audit buffers (if more | 113 | /* The audit_freelist is a list of pre-allocated audit buffers (if more |
| 106 | * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of | 114 | * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of |
| 107 | * being placed on the freelist). */ | 115 | * being placed on the freelist). */ |
| @@ -114,10 +122,8 @@ static struct task_struct *kauditd_task; | |||
| 114 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); | 122 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); |
| 115 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); | 123 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); |
| 116 | 124 | ||
| 117 | /* The netlink socket is only to be read by 1 CPU, which lets us assume | 125 | /* Serialize requests from userspace. */ |
| 118 | * that list additions and deletions never happen simultaneously in | 126 | static DEFINE_MUTEX(audit_cmd_mutex); |
| 119 | * auditsc.c */ | ||
| 120 | DEFINE_MUTEX(audit_netlink_mutex); | ||
| 121 | 127 | ||
| 122 | /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting | 128 | /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting |
| 123 | * audit records. Since printk uses a 1024 byte buffer, this buffer | 129 | * audit records. Since printk uses a 1024 byte buffer, this buffer |
| @@ -250,7 +256,7 @@ static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid) | |||
| 250 | "audit_rate_limit=%d old=%d by auid=%u", | 256 | "audit_rate_limit=%d old=%d by auid=%u", |
| 251 | limit, old, loginuid); | 257 | limit, old, loginuid); |
| 252 | audit_rate_limit = limit; | 258 | audit_rate_limit = limit; |
| 253 | return old; | 259 | return 0; |
| 254 | } | 260 | } |
| 255 | 261 | ||
| 256 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) | 262 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) |
| @@ -273,7 +279,7 @@ static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) | |||
| 273 | "audit_backlog_limit=%d old=%d by auid=%u", | 279 | "audit_backlog_limit=%d old=%d by auid=%u", |
| 274 | limit, old, loginuid); | 280 | limit, old, loginuid); |
| 275 | audit_backlog_limit = limit; | 281 | audit_backlog_limit = limit; |
| 276 | return old; | 282 | return 0; |
| 277 | } | 283 | } |
| 278 | 284 | ||
| 279 | static int audit_set_enabled(int state, uid_t loginuid, u32 sid) | 285 | static int audit_set_enabled(int state, uid_t loginuid, u32 sid) |
| @@ -299,7 +305,7 @@ static int audit_set_enabled(int state, uid_t loginuid, u32 sid) | |||
| 299 | "audit_enabled=%d old=%d by auid=%u", | 305 | "audit_enabled=%d old=%d by auid=%u", |
| 300 | state, old, loginuid); | 306 | state, old, loginuid); |
| 301 | audit_enabled = state; | 307 | audit_enabled = state; |
| 302 | return old; | 308 | return 0; |
| 303 | } | 309 | } |
| 304 | 310 | ||
| 305 | static int audit_set_failure(int state, uid_t loginuid, u32 sid) | 311 | static int audit_set_failure(int state, uid_t loginuid, u32 sid) |
| @@ -327,7 +333,7 @@ static int audit_set_failure(int state, uid_t loginuid, u32 sid) | |||
| 327 | "audit_failure=%d old=%d by auid=%u", | 333 | "audit_failure=%d old=%d by auid=%u", |
| 328 | state, old, loginuid); | 334 | state, old, loginuid); |
| 329 | audit_failure = state; | 335 | audit_failure = state; |
| 330 | return old; | 336 | return 0; |
| 331 | } | 337 | } |
| 332 | 338 | ||
| 333 | static int kauditd_thread(void *dummy) | 339 | static int kauditd_thread(void *dummy) |
| @@ -363,9 +369,52 @@ static int kauditd_thread(void *dummy) | |||
| 363 | remove_wait_queue(&kauditd_wait, &wait); | 369 | remove_wait_queue(&kauditd_wait, &wait); |
| 364 | } | 370 | } |
| 365 | } | 371 | } |
| 372 | } | ||
| 373 | |||
| 374 | int audit_send_list(void *_dest) | ||
| 375 | { | ||
| 376 | struct audit_netlink_list *dest = _dest; | ||
| 377 | int pid = dest->pid; | ||
| 378 | struct sk_buff *skb; | ||
| 379 | |||
| 380 | /* wait for parent to finish and send an ACK */ | ||
| 381 | mutex_lock(&audit_cmd_mutex); | ||
| 382 | mutex_unlock(&audit_cmd_mutex); | ||
| 383 | |||
| 384 | while ((skb = __skb_dequeue(&dest->q)) != NULL) | ||
| 385 | netlink_unicast(audit_sock, skb, pid, 0); | ||
| 386 | |||
| 387 | kfree(dest); | ||
| 388 | |||
| 366 | return 0; | 389 | return 0; |
| 367 | } | 390 | } |
| 368 | 391 | ||
| 392 | struct sk_buff *audit_make_reply(int pid, int seq, int type, int done, | ||
| 393 | int multi, void *payload, int size) | ||
| 394 | { | ||
| 395 | struct sk_buff *skb; | ||
| 396 | struct nlmsghdr *nlh; | ||
| 397 | int len = NLMSG_SPACE(size); | ||
| 398 | void *data; | ||
| 399 | int flags = multi ? NLM_F_MULTI : 0; | ||
| 400 | int t = done ? NLMSG_DONE : type; | ||
| 401 | |||
| 402 | skb = alloc_skb(len, GFP_KERNEL); | ||
| 403 | if (!skb) | ||
| 404 | return NULL; | ||
| 405 | |||
| 406 | nlh = NLMSG_PUT(skb, pid, seq, t, size); | ||
| 407 | nlh->nlmsg_flags = flags; | ||
| 408 | data = NLMSG_DATA(nlh); | ||
| 409 | memcpy(data, payload, size); | ||
| 410 | return skb; | ||
| 411 | |||
| 412 | nlmsg_failure: /* Used by NLMSG_PUT */ | ||
| 413 | if (skb) | ||
| 414 | kfree_skb(skb); | ||
| 415 | return NULL; | ||
| 416 | } | ||
| 417 | |||
| 369 | /** | 418 | /** |
| 370 | * audit_send_reply - send an audit reply message via netlink | 419 | * audit_send_reply - send an audit reply message via netlink |
| 371 | * @pid: process id to send reply to | 420 | * @pid: process id to send reply to |
| @@ -383,29 +432,13 @@ void audit_send_reply(int pid, int seq, int type, int done, int multi, | |||
| 383 | void *payload, int size) | 432 | void *payload, int size) |
| 384 | { | 433 | { |
| 385 | struct sk_buff *skb; | 434 | struct sk_buff *skb; |
| 386 | struct nlmsghdr *nlh; | 435 | 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) | 436 | if (!skb) |
| 394 | return; | 437 | 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, | 438 | /* Ignore failure. It'll only happen if the sender goes away, |
| 402 | because our timeout is set to infinite. */ | 439 | because our timeout is set to infinite. */ |
| 403 | netlink_unicast(audit_sock, skb, pid, 0); | 440 | netlink_unicast(audit_sock, skb, pid, 0); |
| 404 | return; | 441 | return; |
| 405 | |||
| 406 | nlmsg_failure: /* Used by NLMSG_PUT */ | ||
| 407 | if (skb) | ||
| 408 | kfree_skb(skb); | ||
| 409 | } | 442 | } |
| 410 | 443 | ||
| 411 | /* | 444 | /* |
| @@ -451,7 +484,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 451 | struct audit_buffer *ab; | 484 | struct audit_buffer *ab; |
| 452 | u16 msg_type = nlh->nlmsg_type; | 485 | u16 msg_type = nlh->nlmsg_type; |
| 453 | uid_t loginuid; /* loginuid of sender */ | 486 | uid_t loginuid; /* loginuid of sender */ |
| 454 | struct audit_sig_info sig_data; | 487 | struct audit_sig_info *sig_data; |
| 488 | char *ctx; | ||
| 489 | u32 len; | ||
| 455 | 490 | ||
| 456 | err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type); | 491 | err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type); |
| 457 | if (err) | 492 | if (err) |
| @@ -503,12 +538,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 503 | if (status_get->mask & AUDIT_STATUS_PID) { | 538 | if (status_get->mask & AUDIT_STATUS_PID) { |
| 504 | int old = audit_pid; | 539 | int old = audit_pid; |
| 505 | if (sid) { | 540 | if (sid) { |
| 506 | char *ctx = NULL; | 541 | if ((err = selinux_ctxid_to_string( |
| 507 | u32 len; | ||
| 508 | int rc; | ||
| 509 | if ((rc = selinux_ctxid_to_string( | ||
| 510 | sid, &ctx, &len))) | 542 | sid, &ctx, &len))) |
| 511 | return rc; | 543 | return err; |
| 512 | else | 544 | else |
| 513 | audit_log(NULL, GFP_KERNEL, | 545 | audit_log(NULL, GFP_KERNEL, |
| 514 | AUDIT_CONFIG_CHANGE, | 546 | AUDIT_CONFIG_CHANGE, |
| @@ -523,10 +555,10 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 523 | audit_pid = status_get->pid; | 555 | audit_pid = status_get->pid; |
| 524 | } | 556 | } |
| 525 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) | 557 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) |
| 526 | audit_set_rate_limit(status_get->rate_limit, | 558 | err = audit_set_rate_limit(status_get->rate_limit, |
| 527 | loginuid, sid); | 559 | loginuid, sid); |
| 528 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) | 560 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) |
| 529 | audit_set_backlog_limit(status_get->backlog_limit, | 561 | err = audit_set_backlog_limit(status_get->backlog_limit, |
| 530 | loginuid, sid); | 562 | loginuid, sid); |
| 531 | break; | 563 | break; |
| 532 | case AUDIT_USER: | 564 | case AUDIT_USER: |
| @@ -544,8 +576,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 544 | "user pid=%d uid=%u auid=%u", | 576 | "user pid=%d uid=%u auid=%u", |
| 545 | pid, uid, loginuid); | 577 | pid, uid, loginuid); |
| 546 | if (sid) { | 578 | if (sid) { |
| 547 | char *ctx = NULL; | ||
| 548 | u32 len; | ||
| 549 | if (selinux_ctxid_to_string( | 579 | if (selinux_ctxid_to_string( |
| 550 | sid, &ctx, &len)) { | 580 | sid, &ctx, &len)) { |
| 551 | audit_log_format(ab, | 581 | audit_log_format(ab, |
| @@ -584,10 +614,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 584 | loginuid, sid); | 614 | loginuid, sid); |
| 585 | break; | 615 | break; |
| 586 | case AUDIT_SIGNAL_INFO: | 616 | case AUDIT_SIGNAL_INFO: |
| 587 | sig_data.uid = audit_sig_uid; | 617 | err = selinux_ctxid_to_string(audit_sig_sid, &ctx, &len); |
| 588 | sig_data.pid = audit_sig_pid; | 618 | if (err) |
| 619 | return err; | ||
| 620 | sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); | ||
| 621 | if (!sig_data) { | ||
| 622 | kfree(ctx); | ||
| 623 | return -ENOMEM; | ||
| 624 | } | ||
| 625 | sig_data->uid = audit_sig_uid; | ||
| 626 | sig_data->pid = audit_sig_pid; | ||
| 627 | memcpy(sig_data->ctx, ctx, len); | ||
| 628 | kfree(ctx); | ||
| 589 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, | 629 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, |
| 590 | 0, 0, &sig_data, sizeof(sig_data)); | 630 | 0, 0, sig_data, sizeof(*sig_data) + len); |
| 631 | kfree(sig_data); | ||
| 591 | break; | 632 | break; |
| 592 | default: | 633 | default: |
| 593 | err = -EINVAL; | 634 | err = -EINVAL; |
| @@ -629,20 +670,30 @@ static void audit_receive(struct sock *sk, int length) | |||
| 629 | struct sk_buff *skb; | 670 | struct sk_buff *skb; |
| 630 | unsigned int qlen; | 671 | unsigned int qlen; |
| 631 | 672 | ||
| 632 | mutex_lock(&audit_netlink_mutex); | 673 | mutex_lock(&audit_cmd_mutex); |
| 633 | 674 | ||
| 634 | for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { | 675 | for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { |
| 635 | skb = skb_dequeue(&sk->sk_receive_queue); | 676 | skb = skb_dequeue(&sk->sk_receive_queue); |
| 636 | audit_receive_skb(skb); | 677 | audit_receive_skb(skb); |
| 637 | kfree_skb(skb); | 678 | kfree_skb(skb); |
| 638 | } | 679 | } |
| 639 | mutex_unlock(&audit_netlink_mutex); | 680 | mutex_unlock(&audit_cmd_mutex); |
| 640 | } | 681 | } |
| 641 | 682 | ||
| 683 | #ifdef CONFIG_AUDITSYSCALL | ||
| 684 | static const struct inotify_operations audit_inotify_ops = { | ||
| 685 | .handle_event = audit_handle_ievent, | ||
| 686 | .destroy_watch = audit_free_parent, | ||
| 687 | }; | ||
| 688 | #endif | ||
| 642 | 689 | ||
| 643 | /* Initialize audit support at boot time. */ | 690 | /* Initialize audit support at boot time. */ |
| 644 | static int __init audit_init(void) | 691 | static int __init audit_init(void) |
| 645 | { | 692 | { |
| 693 | #ifdef CONFIG_AUDITSYSCALL | ||
| 694 | int i; | ||
| 695 | #endif | ||
| 696 | |||
| 646 | printk(KERN_INFO "audit: initializing netlink socket (%s)\n", | 697 | printk(KERN_INFO "audit: initializing netlink socket (%s)\n", |
| 647 | audit_default ? "enabled" : "disabled"); | 698 | audit_default ? "enabled" : "disabled"); |
| 648 | audit_sock = netlink_kernel_create(NETLINK_AUDIT, 0, audit_receive, | 699 | audit_sock = netlink_kernel_create(NETLINK_AUDIT, 0, audit_receive, |
| @@ -661,6 +712,16 @@ static int __init audit_init(void) | |||
| 661 | selinux_audit_set_callback(&selinux_audit_rule_update); | 712 | selinux_audit_set_callback(&selinux_audit_rule_update); |
| 662 | 713 | ||
| 663 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); | 714 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); |
| 715 | |||
| 716 | #ifdef CONFIG_AUDITSYSCALL | ||
| 717 | audit_ih = inotify_init(&audit_inotify_ops); | ||
| 718 | if (IS_ERR(audit_ih)) | ||
| 719 | audit_panic("cannot initialize inotify handle"); | ||
| 720 | |||
| 721 | for (i = 0; i < AUDIT_INODE_BUCKETS; i++) | ||
| 722 | INIT_LIST_HEAD(&audit_inode_hash[i]); | ||
| 723 | #endif | ||
| 724 | |||
| 664 | return 0; | 725 | return 0; |
| 665 | } | 726 | } |
| 666 | __initcall(audit_init); | 727 | __initcall(audit_init); |
| @@ -690,10 +751,12 @@ static void audit_buffer_free(struct audit_buffer *ab) | |||
| 690 | kfree_skb(ab->skb); | 751 | kfree_skb(ab->skb); |
| 691 | 752 | ||
| 692 | spin_lock_irqsave(&audit_freelist_lock, flags); | 753 | spin_lock_irqsave(&audit_freelist_lock, flags); |
| 693 | if (++audit_freelist_count > AUDIT_MAXFREE) | 754 | if (audit_freelist_count > AUDIT_MAXFREE) |
| 694 | kfree(ab); | 755 | kfree(ab); |
| 695 | else | 756 | else { |
| 757 | audit_freelist_count++; | ||
| 696 | list_add(&ab->list, &audit_freelist); | 758 | list_add(&ab->list, &audit_freelist); |
| 759 | } | ||
| 697 | spin_unlock_irqrestore(&audit_freelist_lock, flags); | 760 | spin_unlock_irqrestore(&audit_freelist_lock, flags); |
| 698 | } | 761 | } |
| 699 | 762 | ||
| @@ -988,28 +1051,76 @@ void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, | |||
| 988 | skb_put(skb, len << 1); /* new string is twice the old string */ | 1051 | skb_put(skb, len << 1); /* new string is twice the old string */ |
| 989 | } | 1052 | } |
| 990 | 1053 | ||
| 1054 | /* | ||
| 1055 | * Format a string of no more than slen characters into the audit buffer, | ||
| 1056 | * enclosed in quote marks. | ||
| 1057 | */ | ||
| 1058 | static void audit_log_n_string(struct audit_buffer *ab, size_t slen, | ||
| 1059 | const char *string) | ||
| 1060 | { | ||
| 1061 | int avail, new_len; | ||
| 1062 | unsigned char *ptr; | ||
| 1063 | struct sk_buff *skb; | ||
| 1064 | |||
| 1065 | BUG_ON(!ab->skb); | ||
| 1066 | skb = ab->skb; | ||
| 1067 | avail = skb_tailroom(skb); | ||
| 1068 | new_len = slen + 3; /* enclosing quotes + null terminator */ | ||
| 1069 | if (new_len > avail) { | ||
| 1070 | avail = audit_expand(ab, new_len); | ||
| 1071 | if (!avail) | ||
| 1072 | return; | ||
| 1073 | } | ||
| 1074 | ptr = skb->tail; | ||
| 1075 | *ptr++ = '"'; | ||
| 1076 | memcpy(ptr, string, slen); | ||
| 1077 | ptr += slen; | ||
| 1078 | *ptr++ = '"'; | ||
| 1079 | *ptr = 0; | ||
| 1080 | skb_put(skb, slen + 2); /* don't include null terminator */ | ||
| 1081 | } | ||
| 1082 | |||
| 991 | /** | 1083 | /** |
| 992 | * audit_log_unstrustedstring - log a string that may contain random characters | 1084 | * audit_log_n_unstrustedstring - log a string that may contain random characters |
| 993 | * @ab: audit_buffer | 1085 | * @ab: audit_buffer |
| 1086 | * @len: lenth of string (not including trailing null) | ||
| 994 | * @string: string to be logged | 1087 | * @string: string to be logged |
| 995 | * | 1088 | * |
| 996 | * This code will escape a string that is passed to it if the string | 1089 | * This code will escape a string that is passed to it if the string |
| 997 | * contains a control character, unprintable character, double quote mark, | 1090 | * contains a control character, unprintable character, double quote mark, |
| 998 | * or a space. Unescaped strings will start and end with a double quote mark. | 1091 | * or a space. Unescaped strings will start and end with a double quote mark. |
| 999 | * Strings that are escaped are printed in hex (2 digits per char). | 1092 | * Strings that are escaped are printed in hex (2 digits per char). |
| 1093 | * | ||
| 1094 | * The caller specifies the number of characters in the string to log, which may | ||
| 1095 | * or may not be the entire string. | ||
| 1000 | */ | 1096 | */ |
| 1001 | void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) | 1097 | const char *audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len, |
| 1098 | const char *string) | ||
| 1002 | { | 1099 | { |
| 1003 | const unsigned char *p = string; | 1100 | const unsigned char *p = string; |
| 1004 | 1101 | ||
| 1005 | while (*p) { | 1102 | while (*p) { |
| 1006 | if (*p == '"' || *p < 0x21 || *p > 0x7f) { | 1103 | if (*p == '"' || *p < 0x21 || *p > 0x7f) { |
| 1007 | audit_log_hex(ab, string, strlen(string)); | 1104 | audit_log_hex(ab, string, len); |
| 1008 | return; | 1105 | return string + len + 1; |
| 1009 | } | 1106 | } |
| 1010 | p++; | 1107 | p++; |
| 1011 | } | 1108 | } |
| 1012 | audit_log_format(ab, "\"%s\"", string); | 1109 | audit_log_n_string(ab, len, string); |
| 1110 | return p + 1; | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | /** | ||
| 1114 | * audit_log_unstrustedstring - log a string that may contain random characters | ||
| 1115 | * @ab: audit_buffer | ||
| 1116 | * @string: string to be logged | ||
| 1117 | * | ||
| 1118 | * Same as audit_log_n_unstrustedstring(), except that strlen is used to | ||
| 1119 | * determine string length. | ||
| 1120 | */ | ||
| 1121 | const char *audit_log_untrustedstring(struct audit_buffer *ab, const char *string) | ||
| 1122 | { | ||
| 1123 | return audit_log_n_untrustedstring(ab, strlen(string), string); | ||
| 1013 | } | 1124 | } |
| 1014 | 1125 | ||
| 1015 | /* This is a helper-function to print the escaped d_path */ | 1126 | /* This is a helper-function to print the escaped d_path */ |
