audit: refactor audit_receive_msg() to clarify AUDIT_*_RULE* cases
authorRichard Guy Briggs <rgb@redhat.com>
Wed, 20 Nov 2013 19:01:53 +0000 (14:01 -0500)
committerEric Paris <eparis@redhat.com>
Tue, 14 Jan 2014 03:31:22 +0000 (22:31 -0500)
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>
include/linux/audit.h
kernel/audit.c
kernel/auditfilter.c

index 1690f95..6976219 100644 (file)
@@ -461,8 +461,10 @@ extern int             audit_update_lsm_rules(void);
                                /* Private API (for audit.c only) */
 extern int audit_filter_user(int type);
 extern int audit_filter_type(int type);
-extern int  audit_receive_filter(int type, __u32 portid, int seq,
+extern int audit_rule_change(int type, __u32 portid, int seq,
                                void *data, size_t datasz);
+extern int audit_list_rules_send(__u32 portid, int seq);
+
 extern int audit_enabled;
 #else /* CONFIG_AUDIT */
 static inline __printf(4, 5)
index fdb8528..c460f33 100644 (file)
@@ -903,11 +903,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                        audit_log_end(ab);
                        return -EPERM;
                }
-               /* fallthrough */
-       case AUDIT_LIST_RULES:
-               err = audit_receive_filter(msg_type, NETLINK_CB(skb).portid,
+               err = audit_rule_change(msg_type, NETLINK_CB(skb).portid,
                                           seq, data, nlmsg_len(nlh));
                break;
+       case AUDIT_LIST_RULES:
+               err = audit_list_rules_send(NETLINK_CB(skb).portid, seq);
+               break;
        case AUDIT_TRIM:
                audit_trim_trees();
                audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE);
index d085cfb..6cc8240 100644 (file)
@@ -1023,47 +1023,20 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re
 }
 
 /**
- * audit_receive_filter - apply all rules to the specified message type
+ * audit_rule_change - apply all rules to the specified message type
  * @type: audit message type
  * @portid: target port id for netlink audit messages
  * @seq: netlink audit message sequence (serial) number
  * @data: payload data
  * @datasz: size of payload data
  */
-int audit_receive_filter(int type, __u32 portid, int seq, void *data,
-                        size_t datasz)
+int audit_rule_change(int type, __u32 portid, int seq, void *data,
+                       size_t datasz)
 {
-       struct task_struct *tsk;
-       struct audit_netlink_list *dest;
        int err = 0;
        struct audit_entry *entry;
 
        switch (type) {
-       case AUDIT_LIST_RULES:
-               /* We can't just spew out the rules here because we might fill
-                * the available socket buffer space and deadlock waiting for
-                * auditctl to read from it... which isn't ever going to
-                * happen if we're actually running in the context of auditctl
-                * trying to _send_ the stuff */
-
-               dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
-               if (!dest)
-                       return -ENOMEM;
-               dest->portid = portid;
-               dest->pid = task_pid_vnr(current);
-               skb_queue_head_init(&dest->q);
-
-               mutex_lock(&audit_filter_mutex);
-               audit_list_rules(portid, seq, &dest->q);
-               mutex_unlock(&audit_filter_mutex);
-
-               tsk = kthread_run(audit_send_list, dest, "audit_send_list");
-               if (IS_ERR(tsk)) {
-                       skb_queue_purge(&dest->q);
-                       kfree(dest);
-                       err = PTR_ERR(tsk);
-               }
-               break;
        case AUDIT_ADD_RULE:
                entry = audit_data_to_entry(data, datasz);
                if (IS_ERR(entry))
@@ -1090,6 +1063,44 @@ int audit_receive_filter(int type, __u32 portid, int seq, void *data,
        return err;
 }
 
+/**
+ * audit_list_rules_send - list the audit rules
+ * @portid: target portid for netlink audit messages
+ * @seq: netlink audit message sequence (serial) number
+ */
+int audit_list_rules_send(__u32 portid, int seq)
+{
+       struct task_struct *tsk;
+       struct audit_netlink_list *dest;
+       int err = 0;
+
+       /* We can't just spew out the rules here because we might fill
+        * the available socket buffer space and deadlock waiting for
+        * auditctl to read from it... which isn't ever going to
+        * happen if we're actually running in the context of auditctl
+        * trying to _send_ the stuff */
+
+       dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
+       if (!dest)
+               return -ENOMEM;
+       dest->portid = portid;
+       dest->pid = task_pid_vnr(current);
+       skb_queue_head_init(&dest->q);
+
+       mutex_lock(&audit_filter_mutex);
+       audit_list_rules(portid, seq, &dest->q);
+       mutex_unlock(&audit_filter_mutex);
+
+       tsk = kthread_run(audit_send_list, dest, "audit_send_list");
+       if (IS_ERR(tsk)) {
+               skb_queue_purge(&dest->q);
+               kfree(dest);
+               err = PTR_ERR(tsk);
+       }
+
+       return err;
+}
+
 int audit_comparator(u32 left, u32 op, u32 right)
 {
        switch (op) {