Add audit_log_type
Chris Wright [Wed, 11 May 2005 09:55:10 +0000 (10:55 +0100)]
Add audit_log_type to allow callers to specify type and pid when logging.
Convert audit_log to wrapper around audit_log_type.  Could have
converted all audit_log callers directly, but common case is default
of type AUDIT_KERNEL and pid 0.  Update audit_log_start to take type
and pid values when creating a new audit_buffer.  Move sequences that
did audit_log_start, audit_log_format, audit_set_type, audit_log_end,
to simply call audit_log_type directly.  This obsoletes audit_set_type
and audit_set_pid, so remove them.

Signed-off-by: Chris Wright <chrisw@osdl.org>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>

include/linux/audit.h
kernel/audit.c
kernel/auditsc.c
security/selinux/avc.c

index 58c5589..405332e 100644 (file)
@@ -216,11 +216,14 @@ extern void audit_signal_info(int sig, struct task_struct *t);
 #ifdef CONFIG_AUDIT
 /* These are defined in audit.c */
                                /* Public API */
-extern void                audit_log(struct audit_context *ctx,
-                                     const char *fmt, ...)
-                           __attribute__((format(printf,2,3)));
+#define audit_log(ctx, fmt, args...) \
+       audit_log_type(ctx, AUDIT_KERNEL, 0, fmt, ##args)
+extern void                audit_log_type(struct audit_context *ctx, int type,
+                                     int pid, const char *fmt, ...)
+                           __attribute__((format(printf,4,5)));
 
-extern struct audit_buffer *audit_log_start(struct audit_context *ctx);
+extern struct audit_buffer *audit_log_start(struct audit_context *ctx, int type,
+                                           int pid);
 extern void                audit_log_format(struct audit_buffer *ab,
                                             const char *fmt, ...)
                            __attribute__((format(printf,2,3)));
@@ -240,8 +243,9 @@ extern void             audit_send_reply(int pid, int seq, int type,
                                             void *payload, int size);
 extern void                audit_log_lost(const char *message);
 #else
-#define audit_log(t,f,...) do { ; } while (0)
-#define audit_log_start(t) ({ NULL; })
+#define audit_log(c,f,...) do { ; } while (0)
+#define audit_log_type(c,t,p,f,...) do { ; } while (0)
+#define audit_log_start(c,t,p) ({ NULL; })
 #define audit_log_vformat(b,f,a) do { ; } while (0)
 #define audit_log_format(b,f,...) do { ; } while (0)
 #define audit_log_end(b) do { ; } while (0)
index c18b769..060b554 100644 (file)
@@ -140,18 +140,6 @@ struct audit_buffer {
        struct audit_context *ctx;      /* NULL or associated context */
 };
 
-void audit_set_type(struct audit_buffer *ab, int type)
-{
-       struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data;
-       nlh->nlmsg_type = type;
-}
-
-static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
-{
-       struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data;
-       nlh->nlmsg_pid = pid;
-}
-
 struct audit_entry {
        struct list_head  list;
        struct audit_rule rule;
@@ -344,7 +332,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        void                    *data;
        struct audit_status     *status_get, status_set;
        int                     err;
-       struct audit_buffer     *ab;
        u16                     msg_type = nlh->nlmsg_type;
        uid_t                   loginuid; /* loginuid of sender */
        struct audit_sig_info   sig_data;
@@ -396,19 +383,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                                                        loginuid);
                break;
        case AUDIT_USER:
-               ab = audit_log_start(NULL);
-               if (!ab)
-                       break;  /* audit_panic has been called */
-               audit_log_format(ab,
+               audit_log_type(NULL, AUDIT_USER, pid,
                                 "user pid=%d uid=%d length=%d loginuid=%u"
                                 " msg='%.1024s'",
                                 pid, uid,
                                 (int)(nlh->nlmsg_len
                                       - ((char *)data - (char *)nlh)),
                                 loginuid, (char *)data);
-               audit_set_type(ab, AUDIT_USER);
-               audit_set_pid(ab, pid);
-               audit_log_end(ab);
                break;
        case AUDIT_ADD:
        case AUDIT_DEL:
@@ -560,12 +541,10 @@ static void audit_buffer_free(struct audit_buffer *ab)
        spin_unlock_irqrestore(&audit_freelist_lock, flags);
 }
 
-static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
-                                               int gfp_mask)
+static struct audit_buffer * audit_buffer_alloc(int gfp_mask)
 {
        unsigned long flags;
        struct audit_buffer *ab = NULL;
-       struct nlmsghdr *nlh;
 
        spin_lock_irqsave(&audit_freelist_lock, flags);
        if (!list_empty(&audit_freelist)) {
@@ -587,12 +566,6 @@ static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
        if (!ab->skb)
                goto err;
 
-       ab->ctx   = ctx;
-       nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
-       nlh->nlmsg_type = AUDIT_KERNEL;
-       nlh->nlmsg_flags = 0;
-       nlh->nlmsg_pid = 0;
-       nlh->nlmsg_seq = 0;
        return ab;
 err:
        audit_buffer_free(ab);
@@ -605,11 +578,12 @@ err:
  * syscall, then the syscall is marked as auditable and an audit record
  * will be written at syscall exit.  If there is no associated task, tsk
  * should be NULL. */
-struct audit_buffer *audit_log_start(struct audit_context *ctx)
+struct audit_buffer *audit_log_start(struct audit_context *ctx, int type, int pid)
 {
        struct audit_buffer     *ab     = NULL;
        struct timespec         t;
        unsigned int            serial;
+       struct nlmsghdr *nlh;
 
        if (!audit_initialized)
                return NULL;
@@ -626,12 +600,19 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
                return NULL;
        }
 
-       ab = audit_buffer_alloc(ctx, GFP_ATOMIC);
+       ab = audit_buffer_alloc(GFP_ATOMIC);
        if (!ab) {
                audit_log_lost("out of memory in audit_log_start");
                return NULL;
        }
 
+       ab->ctx   = ctx;
+       nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
+       nlh->nlmsg_type = type;
+       nlh->nlmsg_flags = 0;
+       nlh->nlmsg_pid = pid;
+       nlh->nlmsg_seq = 0;
+
        if (!audit_get_stamp(ab->ctx, &t, &serial)) {
                t = CURRENT_TIME;
                serial = 0;
@@ -828,12 +809,13 @@ void audit_log_end(struct audit_buffer *ab)
 /* Log an audit record.  This is a convenience function that calls
  * audit_log_start, audit_log_vformat, and audit_log_end.  It may be
  * called in any context. */
-void audit_log(struct audit_context *ctx, const char *fmt, ...)
+void audit_log_type(struct audit_context *ctx, int type, int pid,
+                   const char *fmt, ...)
 {
        struct audit_buffer *ab;
        va_list args;
 
-       ab = audit_log_start(ctx);
+       ab = audit_log_start(ctx, type, pid);
        if (ab) {
                va_start(args, fmt);
                audit_log_vformat(ab, fmt, args);
index 94338ab..d089263 100644 (file)
@@ -648,7 +648,7 @@ static void audit_log_exit(struct audit_context *context)
        int i;
        struct audit_buffer *ab;
 
-       ab = audit_log_start(context);
+       ab = audit_log_start(context, AUDIT_KERNEL, 0);
        if (!ab)
                return;         /* audit_panic has been called */
        audit_log_format(ab, "syscall=%d", context->major);
@@ -680,7 +680,7 @@ static void audit_log_exit(struct audit_context *context)
        while (context->aux) {
                struct audit_aux_data *aux;
 
-               ab = audit_log_start(context);
+               ab = audit_log_start(context, AUDIT_KERNEL, 0);
                if (!ab)
                        continue; /* audit_panic has been called */
 
@@ -701,7 +701,7 @@ static void audit_log_exit(struct audit_context *context)
        }
 
        for (i = 0; i < context->name_count; i++) {
-               ab = audit_log_start(context);
+               ab = audit_log_start(context, AUDIT_KERNEL, 0);
                if (!ab)
                        continue; /* audit_panic has been called */
                audit_log_format(ab, "item=%d", i);
@@ -1005,22 +1005,13 @@ int audit_get_stamp(struct audit_context *ctx,
        return 0;
 }
 
-extern int audit_set_type(struct audit_buffer *ab, int type);
-
 int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
 {
        if (task->audit_context) {
-               struct audit_buffer *ab;
-
-               ab = audit_log_start(NULL);
-               if (ab) {
-                       audit_log_format(ab, "login pid=%d uid=%u "
-                               "old loginuid=%u new loginuid=%u",
-                               task->pid, task->uid, 
-                               task->audit_context->loginuid, loginuid);
-                       audit_set_type(ab, AUDIT_LOGIN);
-                       audit_log_end(ab);
-               }
+               audit_log_type(NULL, AUDIT_LOGIN, 0,
+                         "login pid=%d uid=%u old loginuid=%u new loginuid=%u",
+                         task->pid, task->uid, task->audit_context->loginuid,
+                         loginuid);
                task->audit_context->loginuid = loginuid;
        }
        return 0;
index 85a6f66..9e71a1b 100644 (file)
@@ -549,7 +549,7 @@ void avc_audit(u32 ssid, u32 tsid,
                        return;
        }
 
-       ab = audit_log_start(current->audit_context);
+       ab = audit_log_start(current->audit_context, AUDIT_KERNEL, 0);
        if (!ab)
                return;         /* audit_panic has been called */
        audit_log_format(ab, "avc:  %s ", denied ? "denied" : "granted");