diff options
author | Eric Paris <eparis@redhat.com> | 2008-01-07 18:14:19 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-02-01 14:24:39 -0500 |
commit | 50397bd1e471391d27f64efad9271459c913de87 (patch) | |
tree | 2b23b983ebcb9085cbf38c1688ba0c0f28ccfd2f /kernel | |
parent | 1a6b9f2317f18db768010252c957d99daf40678f (diff) |
[AUDIT] clean up audit_receive_msg()
generally clean up audit_receive_msg() don't free random memory if
selinux_sid_to_string fails for some reason. Move generic auditing
to a helper function
Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/audit.c | 169 |
1 files changed, 66 insertions, 103 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 7e29372da284..549b2f55b649 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -152,8 +152,10 @@ struct audit_buffer { | |||
152 | 152 | ||
153 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) | 153 | static void audit_set_pid(struct audit_buffer *ab, pid_t pid) |
154 | { | 154 | { |
155 | struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); | 155 | if (ab) { |
156 | nlh->nlmsg_pid = pid; | 156 | struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); |
157 | nlh->nlmsg_pid = pid; | ||
158 | } | ||
157 | } | 159 | } |
158 | 160 | ||
159 | void audit_panic(const char *message) | 161 | void audit_panic(const char *message) |
@@ -511,6 +513,33 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) | |||
511 | return err; | 513 | return err; |
512 | } | 514 | } |
513 | 515 | ||
516 | static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | ||
517 | u32 pid, u32 uid, uid_t auid, u32 sid) | ||
518 | { | ||
519 | int rc = 0; | ||
520 | char *ctx = NULL; | ||
521 | u32 len; | ||
522 | |||
523 | if (!audit_enabled) { | ||
524 | *ab = NULL; | ||
525 | return rc; | ||
526 | } | ||
527 | |||
528 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); | ||
529 | audit_log_format(*ab, "user pid=%d uid=%u auid=%u", | ||
530 | pid, uid, auid); | ||
531 | if (sid) { | ||
532 | rc = selinux_sid_to_string(sid, &ctx, &len); | ||
533 | if (rc) | ||
534 | audit_log_format(*ab, " ssid=%u", sid); | ||
535 | else | ||
536 | audit_log_format(*ab, " subj=%s", ctx); | ||
537 | kfree(ctx); | ||
538 | } | ||
539 | |||
540 | return rc; | ||
541 | } | ||
542 | |||
514 | static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 543 | static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
515 | { | 544 | { |
516 | u32 uid, pid, seq, sid; | 545 | u32 uid, pid, seq, sid; |
@@ -521,7 +550,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
521 | u16 msg_type = nlh->nlmsg_type; | 550 | u16 msg_type = nlh->nlmsg_type; |
522 | uid_t loginuid; /* loginuid of sender */ | 551 | uid_t loginuid; /* loginuid of sender */ |
523 | struct audit_sig_info *sig_data; | 552 | struct audit_sig_info *sig_data; |
524 | char *ctx; | 553 | char *ctx = NULL; |
525 | u32 len; | 554 | u32 len; |
526 | 555 | ||
527 | err = audit_netlink_ok(skb, msg_type); | 556 | err = audit_netlink_ok(skb, msg_type); |
@@ -602,36 +631,22 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
602 | if (err) | 631 | if (err) |
603 | break; | 632 | break; |
604 | } | 633 | } |
605 | ab = audit_log_start(NULL, GFP_KERNEL, msg_type); | 634 | audit_log_common_recv_msg(&ab, msg_type, pid, uid, |
606 | if (ab) { | 635 | loginuid, sid); |
607 | audit_log_format(ab, | 636 | |
608 | "user pid=%d uid=%u auid=%u", | 637 | if (msg_type != AUDIT_USER_TTY) |
609 | pid, uid, loginuid); | 638 | audit_log_format(ab, " msg='%.1024s'", |
610 | if (sid) { | 639 | (char *)data); |
611 | if (selinux_sid_to_string( | 640 | else { |
612 | sid, &ctx, &len)) { | 641 | int size; |
613 | audit_log_format(ab, | 642 | |
614 | " ssid=%u", sid); | 643 | audit_log_format(ab, " msg="); |
615 | /* Maybe call audit_panic? */ | 644 | size = nlmsg_len(nlh); |
616 | } else | 645 | audit_log_n_untrustedstring(ab, size, |
617 | audit_log_format(ab, | 646 | data); |
618 | " subj=%s", ctx); | ||
619 | kfree(ctx); | ||
620 | } | ||
621 | if (msg_type != AUDIT_USER_TTY) | ||
622 | audit_log_format(ab, " msg='%.1024s'", | ||
623 | (char *)data); | ||
624 | else { | ||
625 | int size; | ||
626 | |||
627 | audit_log_format(ab, " msg="); | ||
628 | size = nlmsg_len(nlh); | ||
629 | audit_log_n_untrustedstring(ab, size, | ||
630 | data); | ||
631 | } | ||
632 | audit_set_pid(ab, pid); | ||
633 | audit_log_end(ab); | ||
634 | } | 647 | } |
648 | audit_set_pid(ab, pid); | ||
649 | audit_log_end(ab); | ||
635 | } | 650 | } |
636 | break; | 651 | break; |
637 | case AUDIT_ADD: | 652 | case AUDIT_ADD: |
@@ -639,27 +654,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
639 | if (nlmsg_len(nlh) < sizeof(struct audit_rule)) | 654 | if (nlmsg_len(nlh) < sizeof(struct audit_rule)) |
640 | return -EINVAL; | 655 | return -EINVAL; |
641 | if (audit_enabled == AUDIT_LOCKED) { | 656 | if (audit_enabled == AUDIT_LOCKED) { |
642 | ab = audit_log_start(NULL, GFP_KERNEL, | 657 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
643 | AUDIT_CONFIG_CHANGE); | 658 | uid, loginuid, sid); |
644 | if (ab) { | 659 | |
645 | audit_log_format(ab, | 660 | audit_log_format(ab, " audit_enabled=%d res=0", |
646 | "pid=%d uid=%u auid=%u", | 661 | audit_enabled); |
647 | pid, uid, loginuid); | 662 | audit_log_end(ab); |
648 | if (sid) { | ||
649 | if (selinux_sid_to_string( | ||
650 | sid, &ctx, &len)) { | ||
651 | audit_log_format(ab, | ||
652 | " ssid=%u", sid); | ||
653 | /* Maybe call audit_panic? */ | ||
654 | } else | ||
655 | audit_log_format(ab, | ||
656 | " subj=%s", ctx); | ||
657 | kfree(ctx); | ||
658 | } | ||
659 | audit_log_format(ab, " audit_enabled=%d res=0", | ||
660 | audit_enabled); | ||
661 | audit_log_end(ab); | ||
662 | } | ||
663 | return -EPERM; | 663 | return -EPERM; |
664 | } | 664 | } |
665 | /* fallthrough */ | 665 | /* fallthrough */ |
@@ -673,27 +673,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
673 | if (nlmsg_len(nlh) < sizeof(struct audit_rule_data)) | 673 | if (nlmsg_len(nlh) < sizeof(struct audit_rule_data)) |
674 | return -EINVAL; | 674 | return -EINVAL; |
675 | if (audit_enabled == AUDIT_LOCKED) { | 675 | if (audit_enabled == AUDIT_LOCKED) { |
676 | ab = audit_log_start(NULL, GFP_KERNEL, | 676 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
677 | AUDIT_CONFIG_CHANGE); | 677 | uid, loginuid, sid); |
678 | if (ab) { | 678 | |
679 | audit_log_format(ab, | 679 | audit_log_format(ab, " audit_enabled=%d res=0", |
680 | "pid=%d uid=%u auid=%u", | 680 | audit_enabled); |
681 | pid, uid, loginuid); | 681 | audit_log_end(ab); |
682 | if (sid) { | ||
683 | if (selinux_sid_to_string( | ||
684 | sid, &ctx, &len)) { | ||
685 | audit_log_format(ab, | ||
686 | " ssid=%u", sid); | ||
687 | /* Maybe call audit_panic? */ | ||
688 | } else | ||
689 | audit_log_format(ab, | ||
690 | " subj=%s", ctx); | ||
691 | kfree(ctx); | ||
692 | } | ||
693 | audit_log_format(ab, " audit_enabled=%d res=0", | ||
694 | audit_enabled); | ||
695 | audit_log_end(ab); | ||
696 | } | ||
697 | return -EPERM; | 682 | return -EPERM; |
698 | } | 683 | } |
699 | /* fallthrough */ | 684 | /* fallthrough */ |
@@ -704,19 +689,10 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
704 | break; | 689 | break; |
705 | case AUDIT_TRIM: | 690 | case AUDIT_TRIM: |
706 | audit_trim_trees(); | 691 | audit_trim_trees(); |
707 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 692 | |
708 | if (!ab) | 693 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
709 | break; | 694 | uid, loginuid, sid); |
710 | audit_log_format(ab, "auid=%u", loginuid); | 695 | |
711 | if (sid) { | ||
712 | u32 len; | ||
713 | ctx = NULL; | ||
714 | if (selinux_sid_to_string(sid, &ctx, &len)) | ||
715 | audit_log_format(ab, " ssid=%u", sid); | ||
716 | else | ||
717 | audit_log_format(ab, " subj=%s", ctx); | ||
718 | kfree(ctx); | ||
719 | } | ||
720 | audit_log_format(ab, " op=trim res=1"); | 696 | audit_log_format(ab, " op=trim res=1"); |
721 | audit_log_end(ab); | 697 | audit_log_end(ab); |
722 | break; | 698 | break; |
@@ -746,22 +722,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
746 | /* OK, here comes... */ | 722 | /* OK, here comes... */ |
747 | err = audit_tag_tree(old, new); | 723 | err = audit_tag_tree(old, new); |
748 | 724 | ||
749 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 725 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, |
750 | if (!ab) { | 726 | uid, loginuid, sid); |
751 | kfree(old); | 727 | |
752 | kfree(new); | ||
753 | break; | ||
754 | } | ||
755 | audit_log_format(ab, "auid=%u", loginuid); | ||
756 | if (sid) { | ||
757 | u32 len; | ||
758 | ctx = NULL; | ||
759 | if (selinux_sid_to_string(sid, &ctx, &len)) | ||
760 | audit_log_format(ab, " ssid=%u", sid); | ||
761 | else | ||
762 | audit_log_format(ab, " subj=%s", ctx); | ||
763 | kfree(ctx); | ||
764 | } | ||
765 | audit_log_format(ab, " op=make_equiv old="); | 728 | audit_log_format(ab, " op=make_equiv old="); |
766 | audit_log_untrustedstring(ab, old); | 729 | audit_log_untrustedstring(ab, old); |
767 | audit_log_format(ab, " new="); | 730 | audit_log_format(ab, " new="); |