Skip to content

Commit

Permalink
AUDIT: Add message types to audit records
Browse files Browse the repository at this point in the history
This patch adds more messages types to the audit subsystem so that audit 
analysis is quicker, intuitive, and more useful.

Signed-off-by: Steve Grubb <sgrubb@redhat.com>
---
I forgot one type in the big patch. I need to add one for user space 
originating SE Linux avc messages. This is used by dbus and nscd.

-Steve
---
Updated to 2.6.12-rc4-mm1.
-dwmw2

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
  • Loading branch information
Steve Grubb authored and David Woodhouse committed May 13, 2005
1 parent 9ea74f0 commit c040499
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 61 deletions.
66 changes: 50 additions & 16 deletions include/linux/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,53 @@
#include <linux/sched.h>
#include <linux/elf.h>

/* Request and reply types */
/* The netlink messages for the audit system is divided into blocks:
* 1000 - 1099 are for commanding the audit system
* 1100 - 1199 user space trusted application messages
* 1200 - 1299 messages internal to the audit daemon
* 1300 - 1399 audit event messages
* 1400 - 1499 SE Linux use
* 1500 - 1999 future use
* 2000 is for otherwise unclassified kernel audit messages
*
* Messages from 1000-1199 are bi-directional. 1200-1299 are exclusively user
* space. Anything over that is kernel --> user space communication.
*/
#define AUDIT_GET 1000 /* Get status */
#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */
#define AUDIT_LIST 1002 /* List filtering rules */
#define AUDIT_ADD 1003 /* Add filtering rule */
#define AUDIT_DEL 1004 /* Delete filtering rule */
#define AUDIT_USER 1005 /* Send a message from user-space */
#define AUDIT_LIST 1002 /* List syscall filtering rules */
#define AUDIT_ADD 1003 /* Add syscall filtering rule */
#define AUDIT_DEL 1004 /* Delete syscall filtering rule */
#define AUDIT_USER 1005 /* Message from userspace -- deprecated */
#define AUDIT_LOGIN 1006 /* Define the login id and information */
#define AUDIT_SIGNAL_INFO 1010 /* Get information about sender of signal*/
#define AUDIT_WATCH_INS 1007 /* Insert file/dir watch entry */
#define AUDIT_WATCH_REM 1008 /* Remove file/dir watch entry */
#define AUDIT_WATCH_LIST 1009 /* List all file/dir watches */
#define AUDIT_SIGNAL_INFO 1010 /* Get info about sender of signal to auditd */

#define AUDIT_USER_AUTH 1100 /* User space authentication */
#define AUDIT_USER_ACCT 1101 /* User space acct change */
#define AUDIT_USER_MGMT 1102 /* User space acct management */
#define AUDIT_CRED_ACQ 1103 /* User space credential acquired */
#define AUDIT_CRED_DISP 1104 /* User space credential disposed */
#define AUDIT_USER_START 1105 /* User space session start */
#define AUDIT_USER_END 1106 /* User space session end */
#define AUDIT_USER_AVC 1107 /* User space avc message */

#define AUDIT_DAEMON_START 1200 /* Daemon startup record */
#define AUDIT_DAEMON_END 1201 /* Daemon normal stop record */
#define AUDIT_DAEMON_ABORT 1202 /* Daemon error stop record */
#define AUDIT_DAEMON_CONFIG 1203 /* Daemon config change */

#define AUDIT_SYSCALL 1300 /* Syscall event */
#define AUDIT_FS_WATCH 1301 /* Filesystem watch event */
#define AUDIT_PATH 1302 /* Filname path information */
#define AUDIT_IPC 1303 /* IPC record */
#define AUDIT_SOCKET 1304 /* Socket record */
#define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */

#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */

#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */

Expand Down Expand Up @@ -216,14 +254,11 @@ extern void audit_signal_info(int sig, struct task_struct *t);
#ifdef CONFIG_AUDIT
/* These are defined in audit.c */
/* Public API */
#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 void audit_log(struct audit_context *ctx, int type,
const char *fmt, ...)
__attribute__((format(printf,3,4)));

extern struct audit_buffer *audit_log_start(struct audit_context *ctx, int type,
int pid);
extern struct audit_buffer *audit_log_start(struct audit_context *ctx,int type);
extern void audit_log_format(struct audit_buffer *ab,
const char *fmt, ...)
__attribute__((format(printf,2,3)));
Expand All @@ -243,9 +278,8 @@ 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(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(c,t,f,...) do { ; } while (0)
#define audit_log_start(c,t) ({ 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)
Expand Down
78 changes: 55 additions & 23 deletions kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ struct audit_buffer {
struct audit_context *ctx; /* NULL or associated context */
};

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;
Expand Down Expand Up @@ -233,7 +239,8 @@ static int audit_set_rate_limit(int limit, uid_t loginuid)
{
int old = audit_rate_limit;
audit_rate_limit = limit;
audit_log(NULL, "audit_rate_limit=%d old=%d by auid %u",
audit_log(NULL, AUDIT_CONFIG_CHANGE,
"audit_rate_limit=%d old=%d by auid %u",
audit_rate_limit, old, loginuid);
return old;
}
Expand All @@ -242,7 +249,8 @@ static int audit_set_backlog_limit(int limit, uid_t loginuid)
{
int old = audit_backlog_limit;
audit_backlog_limit = limit;
audit_log(NULL, "audit_backlog_limit=%d old=%d by auid %u",
audit_log(NULL, AUDIT_CONFIG_CHANGE,
"audit_backlog_limit=%d old=%d by auid %u",
audit_backlog_limit, old, loginuid);
return old;
}
Expand All @@ -253,8 +261,9 @@ static int audit_set_enabled(int state, uid_t loginuid)
if (state != 0 && state != 1)
return -EINVAL;
audit_enabled = state;
audit_log(NULL, "audit_enabled=%d old=%d by auid %u",
audit_enabled, old, loginuid);
audit_log(NULL, AUDIT_CONFIG_CHANGE,
"audit_enabled=%d old=%d by auid %u",
audit_enabled, old, loginuid);
return old;
}

Expand All @@ -266,8 +275,9 @@ static int audit_set_failure(int state, uid_t loginuid)
&& state != AUDIT_FAIL_PANIC)
return -EINVAL;
audit_failure = state;
audit_log(NULL, "audit_failure=%d old=%d by auid %u",
audit_failure, old, loginuid);
audit_log(NULL, AUDIT_CONFIG_CHANGE,
"audit_failure=%d old=%d by auid %u",
audit_failure, old, loginuid);
return old;
}

Expand Down Expand Up @@ -316,6 +326,14 @@ static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type)
err = -EPERM;
break;
case AUDIT_USER:
case AUDIT_USER_AUTH:
case AUDIT_USER_ACCT:
case AUDIT_USER_MGMT:
case AUDIT_CRED_ACQ:
case AUDIT_CRED_DISP:
case AUDIT_USER_START:
case AUDIT_USER_END:
case AUDIT_USER_AVC:
if (!cap_raised(eff_cap, CAP_AUDIT_WRITE))
err = -EPERM;
break;
Expand All @@ -332,6 +350,7 @@ 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;
Expand Down Expand Up @@ -373,7 +392,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (status_get->mask & AUDIT_STATUS_PID) {
int old = audit_pid;
audit_pid = status_get->pid;
audit_log(NULL, "audit_pid=%d old=%d by auid %u",
audit_log(NULL, AUDIT_CONFIG_CHANGE,
"audit_pid=%d old=%d by auid %u",
audit_pid, old, loginuid);
}
if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
Expand All @@ -383,13 +403,26 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
loginuid);
break;
case AUDIT_USER:
audit_log_type(NULL, AUDIT_USER, pid,
case AUDIT_USER_AUTH:
case AUDIT_USER_ACCT:
case AUDIT_USER_MGMT:
case AUDIT_CRED_ACQ:
case AUDIT_CRED_DISP:
case AUDIT_USER_START:
case AUDIT_USER_END:
case AUDIT_USER_AVC:
ab = audit_log_start(NULL, msg_type);
if (!ab)
break; /* audit_panic has been called */
audit_log_format(ab,
"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_pid(ab, pid);
audit_log_end(ab);
break;
case AUDIT_ADD:
case AUDIT_DEL:
Expand Down Expand Up @@ -504,7 +537,7 @@ static int __init audit_init(void)

audit_initialized = 1;
audit_enabled = audit_default;
audit_log(NULL, "initialized");
audit_log(NULL, AUDIT_KERNEL, "initialized");
return 0;
}
__initcall(audit_init);
Expand Down Expand Up @@ -541,10 +574,12 @@ static void audit_buffer_free(struct audit_buffer *ab)
spin_unlock_irqrestore(&audit_freelist_lock, flags);
}

static struct audit_buffer * audit_buffer_alloc(int gfp_mask)
static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
int gfp_mask, int type)
{
unsigned long flags;
struct audit_buffer *ab = NULL;
struct nlmsghdr *nlh;

spin_lock_irqsave(&audit_freelist_lock, flags);
if (!list_empty(&audit_freelist)) {
Expand All @@ -566,6 +601,12 @@ static struct audit_buffer * audit_buffer_alloc(int gfp_mask)
if (!ab->skb)
goto err;

ab->ctx = ctx;
nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
nlh->nlmsg_type = type;
nlh->nlmsg_flags = 0;
nlh->nlmsg_pid = 0;
nlh->nlmsg_seq = 0;
return ab;
err:
audit_buffer_free(ab);
Expand All @@ -578,12 +619,11 @@ static struct audit_buffer * audit_buffer_alloc(int gfp_mask)
* 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, int type, int pid)
struct audit_buffer *audit_log_start(struct audit_context *ctx, int type)
{
struct audit_buffer *ab = NULL;
struct timespec t;
unsigned int serial;
struct nlmsghdr *nlh;

if (!audit_initialized)
return NULL;
Expand All @@ -600,19 +640,12 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int type, int pi
return NULL;
}

ab = audit_buffer_alloc(GFP_ATOMIC);
ab = audit_buffer_alloc(ctx, GFP_ATOMIC, type);
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;
Expand Down Expand Up @@ -809,13 +842,12 @@ 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_type(struct audit_context *ctx, int type, int pid,
const char *fmt, ...)
void audit_log(struct audit_context *ctx, int type, const char *fmt, ...)
{
struct audit_buffer *ab;
va_list args;

ab = audit_log_start(ctx, type, pid);
ab = audit_log_start(ctx, type);
if (ab) {
va_start(args, fmt);
audit_log_vformat(ab, fmt, args);
Expand Down
Loading

0 comments on commit c040499

Please sign in to comment.