diff options
| author | Richard Guy Briggs <rgb@redhat.com> | 2013-11-20 14:01:53 -0500 |
|---|---|---|
| committer | Eric Paris <eparis@redhat.com> | 2014-01-13 22:31:22 -0500 |
| commit | ce0d9f04699706843e8a494d12cf6c7663d478c7 (patch) | |
| tree | 34cae2d8036f35933d49d3a02c49b37e0d95811b /kernel | |
| parent | a06e56b2a11b5f7d5354b05988f97118c90580d2 (diff) | |
audit: refactor audit_receive_msg() to clarify AUDIT_*_RULE* cases
audit_receive_msg() needlessly contained a fallthrough case that called
audit_receive_filter(), containing no common code between the cases. Separate
them to make the logic clearer. Refactor AUDIT_LIST_RULES, AUDIT_ADD_RULE,
AUDIT_DEL_RULE cases to create audit_rule_change(), audit_list_rules_send()
functions. This should not functionally change the logic.
Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/audit.c | 7 | ||||
| -rw-r--r-- | kernel/auditfilter.c | 71 |
2 files changed, 45 insertions, 33 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index fdb8528ceca3..c460f33c2801 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -903,11 +903,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 903 | audit_log_end(ab); | 903 | audit_log_end(ab); |
| 904 | return -EPERM; | 904 | return -EPERM; |
| 905 | } | 905 | } |
| 906 | /* fallthrough */ | 906 | err = audit_rule_change(msg_type, NETLINK_CB(skb).portid, |
| 907 | case AUDIT_LIST_RULES: | ||
| 908 | err = audit_receive_filter(msg_type, NETLINK_CB(skb).portid, | ||
| 909 | seq, data, nlmsg_len(nlh)); | 907 | seq, data, nlmsg_len(nlh)); |
| 910 | break; | 908 | break; |
| 909 | case AUDIT_LIST_RULES: | ||
| 910 | err = audit_list_rules_send(NETLINK_CB(skb).portid, seq); | ||
| 911 | break; | ||
| 911 | case AUDIT_TRIM: | 912 | case AUDIT_TRIM: |
| 912 | audit_trim_trees(); | 913 | audit_trim_trees(); |
| 913 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); | 914 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index d085cfbe416e..6cc8240b7aaf 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
| @@ -1023,47 +1023,20 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re | |||
| 1023 | } | 1023 | } |
| 1024 | 1024 | ||
| 1025 | /** | 1025 | /** |
| 1026 | * audit_receive_filter - apply all rules to the specified message type | 1026 | * audit_rule_change - apply all rules to the specified message type |
| 1027 | * @type: audit message type | 1027 | * @type: audit message type |
| 1028 | * @portid: target port id for netlink audit messages | 1028 | * @portid: target port id for netlink audit messages |
| 1029 | * @seq: netlink audit message sequence (serial) number | 1029 | * @seq: netlink audit message sequence (serial) number |
| 1030 | * @data: payload data | 1030 | * @data: payload data |
| 1031 | * @datasz: size of payload data | 1031 | * @datasz: size of payload data |
| 1032 | */ | 1032 | */ |
| 1033 | int audit_receive_filter(int type, __u32 portid, int seq, void *data, | 1033 | int audit_rule_change(int type, __u32 portid, int seq, void *data, |
| 1034 | size_t datasz) | 1034 | size_t datasz) |
| 1035 | { | 1035 | { |
| 1036 | struct task_struct *tsk; | ||
| 1037 | struct audit_netlink_list *dest; | ||
| 1038 | int err = 0; | 1036 | int err = 0; |
| 1039 | struct audit_entry *entry; | 1037 | struct audit_entry *entry; |
| 1040 | 1038 | ||
| 1041 | switch (type) { | 1039 | switch (type) { |
| 1042 | case AUDIT_LIST_RULES: | ||
| 1043 | /* We can't just spew out the rules here because we might fill | ||
| 1044 | * the available socket buffer space and deadlock waiting for | ||
| 1045 | * auditctl to read from it... which isn't ever going to | ||
| 1046 | * happen if we're actually running in the context of auditctl | ||
| 1047 | * trying to _send_ the stuff */ | ||
| 1048 | |||
| 1049 | dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); | ||
| 1050 | if (!dest) | ||
| 1051 | return -ENOMEM; | ||
| 1052 | dest->portid = portid; | ||
| 1053 | dest->pid = task_pid_vnr(current); | ||
| 1054 | skb_queue_head_init(&dest->q); | ||
| 1055 | |||
| 1056 | mutex_lock(&audit_filter_mutex); | ||
| 1057 | audit_list_rules(portid, seq, &dest->q); | ||
| 1058 | mutex_unlock(&audit_filter_mutex); | ||
| 1059 | |||
| 1060 | tsk = kthread_run(audit_send_list, dest, "audit_send_list"); | ||
| 1061 | if (IS_ERR(tsk)) { | ||
| 1062 | skb_queue_purge(&dest->q); | ||
| 1063 | kfree(dest); | ||
| 1064 | err = PTR_ERR(tsk); | ||
| 1065 | } | ||
| 1066 | break; | ||
| 1067 | case AUDIT_ADD_RULE: | 1040 | case AUDIT_ADD_RULE: |
| 1068 | entry = audit_data_to_entry(data, datasz); | 1041 | entry = audit_data_to_entry(data, datasz); |
| 1069 | if (IS_ERR(entry)) | 1042 | if (IS_ERR(entry)) |
| @@ -1090,6 +1063,44 @@ int audit_receive_filter(int type, __u32 portid, int seq, void *data, | |||
| 1090 | return err; | 1063 | return err; |
| 1091 | } | 1064 | } |
| 1092 | 1065 | ||
| 1066 | /** | ||
| 1067 | * audit_list_rules_send - list the audit rules | ||
| 1068 | * @portid: target portid for netlink audit messages | ||
| 1069 | * @seq: netlink audit message sequence (serial) number | ||
| 1070 | */ | ||
| 1071 | int audit_list_rules_send(__u32 portid, int seq) | ||
| 1072 | { | ||
| 1073 | struct task_struct *tsk; | ||
| 1074 | struct audit_netlink_list *dest; | ||
| 1075 | int err = 0; | ||
| 1076 | |||
| 1077 | /* We can't just spew out the rules here because we might fill | ||
| 1078 | * the available socket buffer space and deadlock waiting for | ||
| 1079 | * auditctl to read from it... which isn't ever going to | ||
| 1080 | * happen if we're actually running in the context of auditctl | ||
| 1081 | * trying to _send_ the stuff */ | ||
| 1082 | |||
| 1083 | dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); | ||
| 1084 | if (!dest) | ||
| 1085 | return -ENOMEM; | ||
| 1086 | dest->portid = portid; | ||
| 1087 | dest->pid = task_pid_vnr(current); | ||
| 1088 | skb_queue_head_init(&dest->q); | ||
| 1089 | |||
| 1090 | mutex_lock(&audit_filter_mutex); | ||
| 1091 | audit_list_rules(portid, seq, &dest->q); | ||
| 1092 | mutex_unlock(&audit_filter_mutex); | ||
| 1093 | |||
| 1094 | tsk = kthread_run(audit_send_list, dest, "audit_send_list"); | ||
| 1095 | if (IS_ERR(tsk)) { | ||
| 1096 | skb_queue_purge(&dest->q); | ||
| 1097 | kfree(dest); | ||
| 1098 | err = PTR_ERR(tsk); | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | return err; | ||
| 1102 | } | ||
| 1103 | |||
| 1093 | int audit_comparator(u32 left, u32 op, u32 right) | 1104 | int audit_comparator(u32 left, u32 op, u32 right) |
| 1094 | { | 1105 | { |
| 1095 | switch (op) { | 1106 | switch (op) { |
