diff options
Diffstat (limited to 'kernel/audit.c')
| -rw-r--r-- | kernel/audit.c | 153 |
1 files changed, 139 insertions, 14 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 7b0e23a740ce..906ae5a0233a 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -60,7 +60,6 @@ | |||
| 60 | #ifdef CONFIG_SECURITY | 60 | #ifdef CONFIG_SECURITY |
| 61 | #include <linux/security.h> | 61 | #include <linux/security.h> |
| 62 | #endif | 62 | #endif |
| 63 | #include <net/netlink.h> | ||
| 64 | #include <linux/freezer.h> | 63 | #include <linux/freezer.h> |
| 65 | #include <linux/tty.h> | 64 | #include <linux/tty.h> |
| 66 | #include <linux/pid_namespace.h> | 65 | #include <linux/pid_namespace.h> |
| @@ -140,6 +139,17 @@ static struct task_struct *kauditd_task; | |||
| 140 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); | 139 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); |
| 141 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); | 140 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); |
| 142 | 141 | ||
| 142 | static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION, | ||
| 143 | .mask = -1, | ||
| 144 | .features = 0, | ||
| 145 | .lock = 0,}; | ||
| 146 | |||
| 147 | static char *audit_feature_names[2] = { | ||
| 148 | "only_unset_loginuid", | ||
| 149 | "loginuid_immutable", | ||
| 150 | }; | ||
| 151 | |||
| 152 | |||
| 143 | /* Serialize requests from userspace. */ | 153 | /* Serialize requests from userspace. */ |
| 144 | DEFINE_MUTEX(audit_cmd_mutex); | 154 | DEFINE_MUTEX(audit_cmd_mutex); |
| 145 | 155 | ||
| @@ -584,6 +594,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) | |||
| 584 | return -EOPNOTSUPP; | 594 | return -EOPNOTSUPP; |
| 585 | case AUDIT_GET: | 595 | case AUDIT_GET: |
| 586 | case AUDIT_SET: | 596 | case AUDIT_SET: |
| 597 | case AUDIT_GET_FEATURE: | ||
| 598 | case AUDIT_SET_FEATURE: | ||
| 587 | case AUDIT_LIST_RULES: | 599 | case AUDIT_LIST_RULES: |
| 588 | case AUDIT_ADD_RULE: | 600 | case AUDIT_ADD_RULE: |
| 589 | case AUDIT_DEL_RULE: | 601 | case AUDIT_DEL_RULE: |
| @@ -613,7 +625,7 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type) | |||
| 613 | int rc = 0; | 625 | int rc = 0; |
| 614 | uid_t uid = from_kuid(&init_user_ns, current_uid()); | 626 | uid_t uid = from_kuid(&init_user_ns, current_uid()); |
| 615 | 627 | ||
| 616 | if (!audit_enabled) { | 628 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) { |
| 617 | *ab = NULL; | 629 | *ab = NULL; |
| 618 | return rc; | 630 | return rc; |
| 619 | } | 631 | } |
| @@ -628,6 +640,94 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type) | |||
| 628 | return rc; | 640 | return rc; |
| 629 | } | 641 | } |
| 630 | 642 | ||
| 643 | int is_audit_feature_set(int i) | ||
| 644 | { | ||
| 645 | return af.features & AUDIT_FEATURE_TO_MASK(i); | ||
| 646 | } | ||
| 647 | |||
| 648 | |||
| 649 | static int audit_get_feature(struct sk_buff *skb) | ||
| 650 | { | ||
| 651 | u32 seq; | ||
| 652 | |||
| 653 | seq = nlmsg_hdr(skb)->nlmsg_seq; | ||
| 654 | |||
| 655 | audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_GET, 0, 0, | ||
| 656 | &af, sizeof(af)); | ||
| 657 | |||
| 658 | return 0; | ||
| 659 | } | ||
| 660 | |||
| 661 | static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature, | ||
| 662 | u32 old_lock, u32 new_lock, int res) | ||
| 663 | { | ||
| 664 | struct audit_buffer *ab; | ||
| 665 | |||
| 666 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_FEATURE_CHANGE); | ||
| 667 | audit_log_format(ab, "feature=%s new=%d old=%d old_lock=%d new_lock=%d res=%d", | ||
| 668 | audit_feature_names[which], !!old_feature, !!new_feature, | ||
| 669 | !!old_lock, !!new_lock, res); | ||
| 670 | audit_log_end(ab); | ||
| 671 | } | ||
| 672 | |||
| 673 | static int audit_set_feature(struct sk_buff *skb) | ||
| 674 | { | ||
| 675 | struct audit_features *uaf; | ||
| 676 | int i; | ||
| 677 | |||
| 678 | BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > sizeof(audit_feature_names)/sizeof(audit_feature_names[0])); | ||
| 679 | uaf = nlmsg_data(nlmsg_hdr(skb)); | ||
| 680 | |||
| 681 | /* if there is ever a version 2 we should handle that here */ | ||
| 682 | |||
| 683 | for (i = 0; i <= AUDIT_LAST_FEATURE; i++) { | ||
| 684 | u32 feature = AUDIT_FEATURE_TO_MASK(i); | ||
| 685 | u32 old_feature, new_feature, old_lock, new_lock; | ||
| 686 | |||
| 687 | /* if we are not changing this feature, move along */ | ||
| 688 | if (!(feature & uaf->mask)) | ||
| 689 | continue; | ||
| 690 | |||
| 691 | old_feature = af.features & feature; | ||
| 692 | new_feature = uaf->features & feature; | ||
| 693 | new_lock = (uaf->lock | af.lock) & feature; | ||
| 694 | old_lock = af.lock & feature; | ||
| 695 | |||
| 696 | /* are we changing a locked feature? */ | ||
| 697 | if ((af.lock & feature) && (new_feature != old_feature)) { | ||
| 698 | audit_log_feature_change(i, old_feature, new_feature, | ||
| 699 | old_lock, new_lock, 0); | ||
| 700 | return -EPERM; | ||
| 701 | } | ||
| 702 | } | ||
| 703 | /* nothing invalid, do the changes */ | ||
| 704 | for (i = 0; i <= AUDIT_LAST_FEATURE; i++) { | ||
| 705 | u32 feature = AUDIT_FEATURE_TO_MASK(i); | ||
| 706 | u32 old_feature, new_feature, old_lock, new_lock; | ||
| 707 | |||
| 708 | /* if we are not changing this feature, move along */ | ||
| 709 | if (!(feature & uaf->mask)) | ||
| 710 | continue; | ||
| 711 | |||
| 712 | old_feature = af.features & feature; | ||
| 713 | new_feature = uaf->features & feature; | ||
| 714 | old_lock = af.lock & feature; | ||
| 715 | new_lock = (uaf->lock | af.lock) & feature; | ||
| 716 | |||
| 717 | if (new_feature != old_feature) | ||
| 718 | audit_log_feature_change(i, old_feature, new_feature, | ||
| 719 | old_lock, new_lock, 1); | ||
| 720 | |||
| 721 | if (new_feature) | ||
| 722 | af.features |= feature; | ||
| 723 | else | ||
| 724 | af.features &= ~feature; | ||
| 725 | af.lock |= new_lock; | ||
| 726 | } | ||
| 727 | |||
| 728 | return 0; | ||
| 729 | } | ||
| 730 | |||
| 631 | static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 731 | static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
| 632 | { | 732 | { |
| 633 | u32 seq; | 733 | u32 seq; |
| @@ -659,6 +759,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 659 | 759 | ||
| 660 | switch (msg_type) { | 760 | switch (msg_type) { |
| 661 | case AUDIT_GET: | 761 | case AUDIT_GET: |
| 762 | memset(&status_set, 0, sizeof(status_set)); | ||
| 662 | status_set.enabled = audit_enabled; | 763 | status_set.enabled = audit_enabled; |
| 663 | status_set.failure = audit_failure; | 764 | status_set.failure = audit_failure; |
| 664 | status_set.pid = audit_pid; | 765 | status_set.pid = audit_pid; |
| @@ -670,7 +771,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 670 | &status_set, sizeof(status_set)); | 771 | &status_set, sizeof(status_set)); |
| 671 | break; | 772 | break; |
| 672 | case AUDIT_SET: | 773 | case AUDIT_SET: |
| 673 | if (nlh->nlmsg_len < sizeof(struct audit_status)) | 774 | if (nlmsg_len(nlh) < sizeof(struct audit_status)) |
| 674 | return -EINVAL; | 775 | return -EINVAL; |
| 675 | status_get = (struct audit_status *)data; | 776 | status_get = (struct audit_status *)data; |
| 676 | if (status_get->mask & AUDIT_STATUS_ENABLED) { | 777 | if (status_get->mask & AUDIT_STATUS_ENABLED) { |
| @@ -699,6 +800,16 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 699 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) | 800 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) |
| 700 | err = audit_set_backlog_limit(status_get->backlog_limit); | 801 | err = audit_set_backlog_limit(status_get->backlog_limit); |
| 701 | break; | 802 | break; |
| 803 | case AUDIT_GET_FEATURE: | ||
| 804 | err = audit_get_feature(skb); | ||
| 805 | if (err) | ||
| 806 | return err; | ||
| 807 | break; | ||
| 808 | case AUDIT_SET_FEATURE: | ||
| 809 | err = audit_set_feature(skb); | ||
| 810 | if (err) | ||
| 811 | return err; | ||
| 812 | break; | ||
| 702 | case AUDIT_USER: | 813 | case AUDIT_USER: |
| 703 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: | 814 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: |
| 704 | case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: | 815 | case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: |
| @@ -715,7 +826,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 715 | } | 826 | } |
| 716 | audit_log_common_recv_msg(&ab, msg_type); | 827 | audit_log_common_recv_msg(&ab, msg_type); |
| 717 | if (msg_type != AUDIT_USER_TTY) | 828 | if (msg_type != AUDIT_USER_TTY) |
| 718 | audit_log_format(ab, " msg='%.1024s'", | 829 | audit_log_format(ab, " msg='%.*s'", |
| 830 | AUDIT_MESSAGE_TEXT_MAX, | ||
| 719 | (char *)data); | 831 | (char *)data); |
| 720 | else { | 832 | else { |
| 721 | int size; | 833 | int size; |
| @@ -818,7 +930,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 818 | struct task_struct *tsk = current; | 930 | struct task_struct *tsk = current; |
| 819 | 931 | ||
| 820 | spin_lock(&tsk->sighand->siglock); | 932 | spin_lock(&tsk->sighand->siglock); |
| 821 | s.enabled = tsk->signal->audit_tty != 0; | 933 | s.enabled = tsk->signal->audit_tty; |
| 822 | s.log_passwd = tsk->signal->audit_tty_log_passwd; | 934 | s.log_passwd = tsk->signal->audit_tty_log_passwd; |
| 823 | spin_unlock(&tsk->sighand->siglock); | 935 | spin_unlock(&tsk->sighand->siglock); |
| 824 | 936 | ||
| @@ -832,7 +944,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 832 | 944 | ||
| 833 | memset(&s, 0, sizeof(s)); | 945 | memset(&s, 0, sizeof(s)); |
| 834 | /* guard against past and future API changes */ | 946 | /* guard against past and future API changes */ |
| 835 | memcpy(&s, data, min(sizeof(s), (size_t)nlh->nlmsg_len)); | 947 | memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh))); |
| 836 | if ((s.enabled != 0 && s.enabled != 1) || | 948 | if ((s.enabled != 0 && s.enabled != 1) || |
| 837 | (s.log_passwd != 0 && s.log_passwd != 1)) | 949 | (s.log_passwd != 0 && s.log_passwd != 1)) |
| 838 | return -EINVAL; | 950 | return -EINVAL; |
| @@ -1067,13 +1179,6 @@ static void wait_for_auditd(unsigned long sleep_time) | |||
| 1067 | remove_wait_queue(&audit_backlog_wait, &wait); | 1179 | remove_wait_queue(&audit_backlog_wait, &wait); |
| 1068 | } | 1180 | } |
| 1069 | 1181 | ||
| 1070 | /* Obtain an audit buffer. This routine does locking to obtain the | ||
| 1071 | * audit buffer, but then no locking is required for calls to | ||
| 1072 | * audit_log_*format. If the tsk is a task that is currently in a | ||
| 1073 | * syscall, then the syscall is marked as auditable and an audit record | ||
| 1074 | * will be written at syscall exit. If there is no associated task, tsk | ||
| 1075 | * should be NULL. */ | ||
| 1076 | |||
| 1077 | /** | 1182 | /** |
| 1078 | * audit_log_start - obtain an audit buffer | 1183 | * audit_log_start - obtain an audit buffer |
| 1079 | * @ctx: audit_context (may be NULL) | 1184 | * @ctx: audit_context (may be NULL) |
| @@ -1389,7 +1494,7 @@ void audit_log_session_info(struct audit_buffer *ab) | |||
| 1389 | u32 sessionid = audit_get_sessionid(current); | 1494 | u32 sessionid = audit_get_sessionid(current); |
| 1390 | uid_t auid = from_kuid(&init_user_ns, audit_get_loginuid(current)); | 1495 | uid_t auid = from_kuid(&init_user_ns, audit_get_loginuid(current)); |
| 1391 | 1496 | ||
| 1392 | audit_log_format(ab, " auid=%u ses=%u\n", auid, sessionid); | 1497 | audit_log_format(ab, " auid=%u ses=%u", auid, sessionid); |
| 1393 | } | 1498 | } |
| 1394 | 1499 | ||
| 1395 | void audit_log_key(struct audit_buffer *ab, char *key) | 1500 | void audit_log_key(struct audit_buffer *ab, char *key) |
| @@ -1536,6 +1641,26 @@ void audit_log_name(struct audit_context *context, struct audit_names *n, | |||
| 1536 | } | 1641 | } |
| 1537 | } | 1642 | } |
| 1538 | 1643 | ||
| 1644 | /* log the audit_names record type */ | ||
| 1645 | audit_log_format(ab, " nametype="); | ||
| 1646 | switch(n->type) { | ||
| 1647 | case AUDIT_TYPE_NORMAL: | ||
| 1648 | audit_log_format(ab, "NORMAL"); | ||
| 1649 | break; | ||
| 1650 | case AUDIT_TYPE_PARENT: | ||
| 1651 | audit_log_format(ab, "PARENT"); | ||
| 1652 | break; | ||
| 1653 | case AUDIT_TYPE_CHILD_DELETE: | ||
| 1654 | audit_log_format(ab, "DELETE"); | ||
| 1655 | break; | ||
| 1656 | case AUDIT_TYPE_CHILD_CREATE: | ||
| 1657 | audit_log_format(ab, "CREATE"); | ||
| 1658 | break; | ||
| 1659 | default: | ||
| 1660 | audit_log_format(ab, "UNKNOWN"); | ||
| 1661 | break; | ||
| 1662 | } | ||
| 1663 | |||
| 1539 | audit_log_fcaps(ab, n); | 1664 | audit_log_fcaps(ab, n); |
| 1540 | audit_log_end(ab); | 1665 | audit_log_end(ab); |
| 1541 | } | 1666 | } |
