AUDIT: Fix some spelling errors
[safe/jmp/linux-2.6] / kernel / auditsc.c
index 00e87ff..773d28a 100644 (file)
@@ -1,4 +1,4 @@
-/* auditsc.c -- System-call auditing support -*- linux-c -*-
+/* auditsc.c -- System-call auditing support
  * Handles all system-call specific auditing features.
  *
  * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
@@ -123,7 +123,7 @@ struct audit_context {
        int                 major;      /* syscall number */
        unsigned long       argv[4];    /* syscall arguments */
        int                 return_valid; /* return code is valid */
-       int                 return_code;/* syscall return code */
+       long                return_code;/* syscall return code */
        int                 auditable;  /* 1 if record should be written */
        int                 name_count;
        struct audit_names  names[AUDIT_NAMES];
@@ -135,6 +135,7 @@ struct audit_context {
        uid_t               uid, euid, suid, fsuid;
        gid_t               gid, egid, sgid, fsgid;
        unsigned long       personality;
+       int                 arch;
 
 #if AUDIT_DEBUG
        int                 put_count;
@@ -225,7 +226,6 @@ static inline int audit_del_rule(struct audit_rule *rule,
        return -EFAULT;         /* No matching rule */
 }
 
-#ifdef CONFIG_NET
 /* Copy rule from user-space to kernel-space.  Called during
  * AUDIT_ADD. */
 static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
@@ -250,7 +250,8 @@ static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
        return 0;
 }
 
-int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
+int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
+                                                       uid_t loginuid)
 {
        u32                flags;
        struct audit_entry *entry;
@@ -285,6 +286,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
                        err = audit_add_rule(entry, &audit_entlist);
                if (!err && (flags & AUDIT_AT_EXIT))
                        err = audit_add_rule(entry, &audit_extlist);
+               audit_log(NULL, AUDIT_CONFIG_CHANGE, 
+                               "auid %u added an audit rule\n", loginuid);
                break;
        case AUDIT_DEL:
                flags =((struct audit_rule *)data)->flags;
@@ -294,6 +297,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
                        err = audit_del_rule(data, &audit_entlist);
                if (!err && (flags & AUDIT_AT_EXIT))
                        err = audit_del_rule(data, &audit_extlist);
+               audit_log(NULL, AUDIT_CONFIG_CHANGE,
+                               "auid %u removed an audit rule\n", loginuid);
                break;
        default:
                return -EINVAL;
@@ -301,7 +306,6 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
 
        return err;
 }
-#endif
 
 /* Compare a task_struct with an audit_rule.  Return 1 on match, 0
  * otherwise. */
@@ -348,6 +352,10 @@ static int audit_filter_rules(struct task_struct *tsk,
                case AUDIT_PERS:
                        result = (tsk->personality == value);
                        break;
+               case AUDIT_ARCH:
+                       if (ctx) 
+                               result = (ctx->arch == value);
+                       break;
 
                case AUDIT_EXIT:
                        if (ctx && ctx->return_valid)
@@ -355,7 +363,7 @@ static int audit_filter_rules(struct task_struct *tsk,
                        break;
                case AUDIT_SUCCESS:
                        if (ctx && ctx->return_valid)
-                               result = (ctx->return_code >= 0);
+                               result = (ctx->return_valid == AUDITSC_SUCCESS);
                        break;
                case AUDIT_DEVMAJOR:
                        if (ctx) {
@@ -436,7 +444,7 @@ static enum audit_state audit_filter_task(struct task_struct *tsk)
 
 /* At syscall entry and exit time, this filter is called if the
  * audit_state is not low enough that auditing cannot take place, but is
- * also not high enough that we already know we have to write and audit
+ * also not high enough that we already know we have to write an audit
  * record (i.e., the state is AUDIT_SETUP_CONTEXT or  AUDIT_BUILD_CONTEXT).
  */
 static enum audit_state audit_filter_syscall(struct task_struct *tsk,
@@ -642,14 +650,17 @@ 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_SYSCALL);
        if (!ab)
                return;         /* audit_panic has been called */
        audit_log_format(ab, "syscall=%d", context->major);
        if (context->personality != PER_LINUX)
                audit_log_format(ab, " per=%lx", context->personality);
+       audit_log_format(ab, " arch=%x", context->arch);
        if (context->return_valid)
-               audit_log_format(ab, " exit=%d", context->return_code);
+               audit_log_format(ab, " success=%s exit=%ld", 
+                                (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
+                                context->return_code);
        audit_log_format(ab,
                  " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
                  " pid=%d loginuid=%d uid=%d gid=%d"
@@ -671,28 +682,28 @@ static void audit_log_exit(struct audit_context *context)
        while (context->aux) {
                struct audit_aux_data *aux;
 
-               ab = audit_log_start(context);
+               aux = context->aux;
+
+               ab = audit_log_start(context, aux->type);
                if (!ab)
                        continue; /* audit_panic has been called */
 
-               aux = context->aux;
-               context->aux = aux->next;
-
-               audit_log_format(ab, "auxitem=%d", aux->type);
                switch (aux->type) {
-               case AUDIT_AUX_IPCPERM: {
+               case AUDIT_IPC: {
                        struct audit_aux_data_ipcctl *axi = (void *)aux;
                        audit_log_format(ab, 
-                                        " qbytes=%lx uid=%d gid=%d mode=%x",
+                                        " qbytes=%lx iuid=%d igid=%d mode=%x",
                                         axi->qbytes, axi->uid, axi->gid, axi->mode);
                        }
                }
                audit_log_end(ab);
+
+               context->aux = aux->next;
                kfree(aux);
        }
 
        for (i = 0; i < context->name_count; i++) {
-               ab = audit_log_start(context);
+               ab = audit_log_start(context, AUDIT_PATH);
                if (!ab)
                        continue; /* audit_panic has been called */
                audit_log_format(ab, "item=%d", i);
@@ -702,7 +713,7 @@ static void audit_log_exit(struct audit_context *context)
                }
                if (context->names[i].ino != (unsigned long)-1)
                        audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o"
-                                            " uid=%d gid=%d rdev=%02x:%02x",
+                                            " ouid=%d ogid=%d rdev=%02x:%02x",
                                         context->names[i].ino,
                                         MAJOR(context->names[i].dev),
                                         MINOR(context->names[i].dev),
@@ -739,7 +750,7 @@ void audit_free(struct task_struct *tsk)
 /* Compute a serial number for the audit record.  Audit records are
  * written to user-space as soon as they are generated, so a complete
  * audit record may be written in several pieces.  The timestamp of the
- * record and this serial number are used by the user-space daemon to
+ * record and this serial number are used by the user-space tools to
  * determine which pieces belong to the same audit record.  The
  * (timestamp,serial) tuple is unique for each syscall and is live from
  * syscall entry to syscall exit.
@@ -773,7 +784,7 @@ static inline unsigned int audit_serial(void)
  * then the record will be written at syscall exit time (otherwise, it
  * will only be written if another part of the kernel requests that it
  * be written). */
-void audit_syscall_entry(struct task_struct *tsk, int major,
+void audit_syscall_entry(struct task_struct *tsk, int arch, int major,
                         unsigned long a1, unsigned long a2,
                         unsigned long a3, unsigned long a4)
 {
@@ -827,6 +838,7 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
        if (!audit_enabled)
                return;
 
+       context->arch       = arch;
        context->major      = major;
        context->argv[0]    = a1;
        context->argv[1]    = a2;
@@ -850,13 +862,13 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
  * filtering, or because some other part of the kernel write an audit
  * message), then write out the syscall information.  In call cases,
  * free the names stored from getname(). */
-void audit_syscall_exit(struct task_struct *tsk, int return_code)
+void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code)
 {
        struct audit_context *context;
 
        get_task_struct(tsk);
        task_lock(tsk);
-       context = audit_get_context(tsk, 1, return_code);
+       context = audit_get_context(tsk, valid, return_code);
        task_unlock(tsk);
 
        /* Not having a context here is ok, since the parent may have
@@ -869,6 +881,7 @@ void audit_syscall_exit(struct task_struct *tsk, int return_code)
 
        context->in_syscall = 0;
        context->auditable  = 0;
+
        if (context->previous) {
                struct audit_context *new_context = context->previous;
                context->previous  = NULL;
@@ -981,36 +994,33 @@ void audit_inode(const char *name, const struct inode *inode)
        context->names[idx].rdev = inode->i_rdev;
 }
 
-void audit_get_stamp(struct audit_context *ctx,
-                    struct timespec *t, int *serial)
+int audit_get_stamp(struct audit_context *ctx,
+                    struct timespec *t, unsigned int *serial)
 {
        if (ctx) {
                t->tv_sec  = ctx->ctime.tv_sec;
                t->tv_nsec = ctx->ctime.tv_nsec;
                *serial    = ctx->serial;
                ctx->auditable = 1;
-       } else {
-               *t      = CURRENT_TIME;
-               *serial = 0;
+               return 1;
        }
+       return 0;
 }
 
-extern int audit_set_type(struct audit_buffer *ab, int type);
-
-int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid)
+int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
 {
-       if (ctx) {
+       if (task->audit_context) {
                struct audit_buffer *ab;
 
-               ab = audit_log_start(NULL);
+               ab = audit_log_start(NULL, AUDIT_LOGIN);
                if (ab) {
                        audit_log_format(ab, "login pid=%d uid=%u "
                                "old loginuid=%u new loginuid=%u",
-                               ctx->pid, ctx->uid, ctx->loginuid, loginuid);
-                       audit_set_type(ab, AUDIT_LOGIN);
+                               task->pid, task->uid, 
+                               task->audit_context->loginuid, loginuid);
                        audit_log_end(ab);
                }
-               ctx->loginuid = loginuid;
+               task->audit_context->loginuid = loginuid;
        }
        return 0;
 }
@@ -1037,8 +1047,27 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
        ax->gid = gid;
        ax->mode = mode;
 
-       ax->d.type = AUDIT_AUX_IPCPERM;
+       ax->d.type = AUDIT_IPC;
        ax->d.next = context->aux;
        context->aux = (void *)ax;
        return 0;
 }
+
+void audit_signal_info(int sig, struct task_struct *t)
+{
+       extern pid_t audit_sig_pid;
+       extern uid_t audit_sig_uid;
+       extern int audit_pid;
+
+       if (unlikely(audit_pid && t->pid == audit_pid)) {
+               if (sig == SIGTERM || sig == SIGHUP) {
+                       struct audit_context *ctx = current->audit_context;
+                       audit_sig_pid = current->pid;
+                       if (ctx)
+                               audit_sig_uid = ctx->loginuid;
+                       else
+                               audit_sig_uid = current->uid;
+               }
+       }
+}
+