Skip to content

Commit

Permalink
Audit: collect sessionid in netlink messages
Browse files Browse the repository at this point in the history
Previously I added sessionid output to all audit messages where it was
available but we still didn't know the sessionid of the sender of
netlink messages.  This patch adds that information to netlink messages
so we can audit who sent netlink messages.

Signed-off-by: Eric Paris <eparis@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
eparis authored and Al Viro committed Apr 28, 2008
1 parent 436c405 commit 2532386
Show file tree
Hide file tree
Showing 17 changed files with 132 additions and 87 deletions.
7 changes: 1 addition & 6 deletions drivers/char/tty_audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,9 @@ void tty_audit_fork(struct signal_struct *sig)
/**
* tty_audit_push_task - Flush task's pending audit data
*/
void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid)
void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid)
{
struct tty_audit_buf *buf;
/* FIXME I think this is correct. Check against netlink once that is
* I really need to read this code more closely. But that's for
* another patch.
*/
unsigned int sessionid = audit_get_sessionid(tsk);

spin_lock_irq(&tsk->sighand->siglock);
buf = tsk->signal->tty_audit_buf;
Expand Down
3 changes: 2 additions & 1 deletion include/linux/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,8 @@ extern int audit_update_lsm_rules(void);
extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
extern int audit_filter_type(int type);
extern int audit_receive_filter(int type, int pid, int uid, int seq,
void *data, size_t datasz, uid_t loginuid, u32 sid);
void *data, size_t datasz, uid_t loginuid,
u32 sessionid, u32 sid);
extern int audit_enabled;
#else
#define audit_log(c,g,t,f,...) do { ; } while (0)
Expand Down
1 change: 1 addition & 0 deletions include/linux/netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ struct netlink_skb_parms
__u32 dst_group;
kernel_cap_t eff_cap;
__u32 loginuid; /* Login (audit) uid */
__u32 sessionid; /* Session id (audit) */
__u32 sid; /* SELinux security id */
};

Expand Down
4 changes: 2 additions & 2 deletions include/linux/tty.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ extern void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
extern void tty_audit_exit(void);
extern void tty_audit_fork(struct signal_struct *sig);
extern void tty_audit_push(struct tty_struct *tty);
extern void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid);
extern void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid);
extern void tty_audit_opening(void);
#else
static inline void tty_audit_add_data(struct tty_struct *tty,
Expand All @@ -367,7 +367,7 @@ static inline void tty_audit_fork(struct signal_struct *sig)
static inline void tty_audit_push(struct tty_struct *tty)
{
}
static inline void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid)
static inline void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid)
{
}
static inline void tty_audit_opening(void)
Expand Down
1 change: 1 addition & 0 deletions include/net/netlabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ struct cipso_v4_doi;
struct netlbl_audit {
u32 secid;
uid_t loginuid;
u32 sessionid;
};

/*
Expand Down
23 changes: 12 additions & 11 deletions include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -597,8 +597,9 @@ struct xfrm_spi_skb_cb {
/* Audit Information */
struct xfrm_audit
{
u32 loginuid;
u32 secid;
uid_t loginuid;
u32 sessionid;
};

#ifdef CONFIG_AUDITSYSCALL
Expand All @@ -616,13 +617,13 @@ static inline struct audit_buffer *xfrm_audit_start(const char *op)
return audit_buf;
}

static inline void xfrm_audit_helper_usrinfo(u32 auid, u32 secid,
static inline void xfrm_audit_helper_usrinfo(uid_t auid, u32 ses, u32 secid,
struct audit_buffer *audit_buf)
{
char *secctx;
u32 secctx_len;

audit_log_format(audit_buf, " auid=%u", auid);
audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
if (secid != 0 &&
security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) {
audit_log_format(audit_buf, " subj=%s", secctx);
Expand All @@ -632,13 +633,13 @@ static inline void xfrm_audit_helper_usrinfo(u32 auid, u32 secid,
}

extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
u32 auid, u32 secid);
u32 auid, u32 ses, u32 secid);
extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
u32 auid, u32 secid);
u32 auid, u32 ses, u32 secid);
extern void xfrm_audit_state_add(struct xfrm_state *x, int result,
u32 auid, u32 secid);
u32 auid, u32 ses, u32 secid);
extern void xfrm_audit_state_delete(struct xfrm_state *x, int result,
u32 auid, u32 secid);
u32 auid, u32 ses, u32 secid);
extern void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
struct sk_buff *skb);
extern void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
Expand All @@ -647,10 +648,10 @@ extern void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
extern void xfrm_audit_state_icvfail(struct xfrm_state *x,
struct sk_buff *skb, u8 proto);
#else
#define xfrm_audit_policy_add(x, r, a, s) do { ; } while (0)
#define xfrm_audit_policy_delete(x, r, a, s) do { ; } while (0)
#define xfrm_audit_state_add(x, r, a, s) do { ; } while (0)
#define xfrm_audit_state_delete(x, r, a, s) do { ; } while (0)
#define xfrm_audit_policy_add(x, r, a, se, s) do { ; } while (0)
#define xfrm_audit_policy_delete(x, r, a, se, s) do { ; } while (0)
#define xfrm_audit_state_add(x, r, a, se, s) do { ; } while (0)
#define xfrm_audit_state_delete(x, r, a, se, s) do { ; } while (0)
#define xfrm_audit_state_replay_overflow(x, s) do { ; } while (0)
#define xfrm_audit_state_notfound_simple(s, f) do { ; } while (0)
#define xfrm_audit_state_notfound(s, f, sp, sq) do { ; } while (0)
Expand Down
72 changes: 40 additions & 32 deletions kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,15 @@ void audit_log_lost(const char *message)
}

static int audit_log_config_change(char *function_name, int new, int old,
uid_t loginuid, u32 sid, int allow_changes)
uid_t loginuid, u32 sessionid, u32 sid,
int allow_changes)
{
struct audit_buffer *ab;
int rc = 0;

ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
audit_log_format(ab, "%s=%d old=%d by auid=%u", function_name, new,
old, loginuid);
audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new,
old, loginuid, sessionid);
if (sid) {
char *ctx = NULL;
u32 len;
Expand All @@ -279,7 +280,8 @@ static int audit_log_config_change(char *function_name, int new, int old,
}

static int audit_do_config_change(char *function_name, int *to_change,
int new, uid_t loginuid, u32 sid)
int new, uid_t loginuid, u32 sessionid,
u32 sid)
{
int allow_changes, rc = 0, old = *to_change;

Expand All @@ -290,8 +292,8 @@ static int audit_do_config_change(char *function_name, int *to_change,
allow_changes = 1;

if (audit_enabled != AUDIT_OFF) {
rc = audit_log_config_change(function_name, new, old,
loginuid, sid, allow_changes);
rc = audit_log_config_change(function_name, new, old, loginuid,
sessionid, sid, allow_changes);
if (rc)
allow_changes = 0;
}
Expand All @@ -305,42 +307,44 @@ static int audit_do_config_change(char *function_name, int *to_change,
return rc;
}

static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid)
static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sessionid,
u32 sid)
{
return audit_do_config_change("audit_rate_limit", &audit_rate_limit,
limit, loginuid, sid);
limit, loginuid, sessionid, sid);
}

static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid)
static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sessionid,
u32 sid)
{
return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit,
limit, loginuid, sid);
limit, loginuid, sessionid, sid);
}

static int audit_set_enabled(int state, uid_t loginuid, u32 sid)
static int audit_set_enabled(int state, uid_t loginuid, u32 sessionid, u32 sid)
{
int rc;
if (state < AUDIT_OFF || state > AUDIT_LOCKED)
return -EINVAL;

rc = audit_do_config_change("audit_enabled", &audit_enabled, state,
loginuid, sid);
loginuid, sessionid, sid);

if (!rc)
audit_ever_enabled |= !!state;

return rc;
}

static int audit_set_failure(int state, uid_t loginuid, u32 sid)
static int audit_set_failure(int state, uid_t loginuid, u32 sessionid, u32 sid)
{
if (state != AUDIT_FAIL_SILENT
&& state != AUDIT_FAIL_PRINTK
&& state != AUDIT_FAIL_PANIC)
return -EINVAL;

return audit_do_config_change("audit_failure", &audit_failure, state,
loginuid, sid);
loginuid, sessionid, sid);
}

static int kauditd_thread(void *dummy)
Expand Down Expand Up @@ -385,7 +389,7 @@ static int kauditd_thread(void *dummy)
return 0;
}

static int audit_prepare_user_tty(pid_t pid, uid_t loginuid)
static int audit_prepare_user_tty(pid_t pid, uid_t loginuid, u32 sessionid)
{
struct task_struct *tsk;
int err;
Expand All @@ -404,7 +408,7 @@ static int audit_prepare_user_tty(pid_t pid, uid_t loginuid)
if (err)
goto out;

tty_audit_push_task(tsk, loginuid);
tty_audit_push_task(tsk, loginuid, sessionid);
out:
read_unlock(&tasklist_lock);
return err;
Expand Down Expand Up @@ -534,7 +538,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
}

static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type,
u32 pid, u32 uid, uid_t auid, u32 sid)
u32 pid, u32 uid, uid_t auid, u32 ses,
u32 sid)
{
int rc = 0;
char *ctx = NULL;
Expand All @@ -546,8 +551,8 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type,
}

*ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
audit_log_format(*ab, "user pid=%d uid=%u auid=%u",
pid, uid, auid);
audit_log_format(*ab, "user pid=%d uid=%u auid=%u ses=%u",
pid, uid, auid, ses);
if (sid) {
rc = security_secid_to_secctx(sid, &ctx, &len);
if (rc)
Expand All @@ -570,6 +575,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
struct audit_buffer *ab;
u16 msg_type = nlh->nlmsg_type;
uid_t loginuid; /* loginuid of sender */
u32 sessionid;
struct audit_sig_info *sig_data;
char *ctx = NULL;
u32 len;
Expand All @@ -591,6 +597,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
pid = NETLINK_CREDS(skb)->pid;
uid = NETLINK_CREDS(skb)->uid;
loginuid = NETLINK_CB(skb).loginuid;
sessionid = NETLINK_CB(skb).sessionid;
sid = NETLINK_CB(skb).sid;
seq = nlh->nlmsg_seq;
data = NLMSG_DATA(nlh);
Expand All @@ -613,12 +620,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
status_get = (struct audit_status *)data;
if (status_get->mask & AUDIT_STATUS_ENABLED) {
err = audit_set_enabled(status_get->enabled,
loginuid, sid);
loginuid, sessionid, sid);
if (err < 0) return err;
}
if (status_get->mask & AUDIT_STATUS_FAILURE) {
err = audit_set_failure(status_get->failure,
loginuid, sid);
loginuid, sessionid, sid);
if (err < 0) return err;
}
if (status_get->mask & AUDIT_STATUS_PID) {
Expand All @@ -627,17 +634,17 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (audit_enabled != AUDIT_OFF)
audit_log_config_change("audit_pid", new_pid,
audit_pid, loginuid,
sid, 1);
sessionid, sid, 1);

audit_pid = new_pid;
audit_nlk_pid = NETLINK_CB(skb).pid;
}
if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
err = audit_set_rate_limit(status_get->rate_limit,
loginuid, sid);
loginuid, sessionid, sid);
if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT)
err = audit_set_backlog_limit(status_get->backlog_limit,
loginuid, sid);
loginuid, sessionid, sid);
break;
case AUDIT_USER:
case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
Expand All @@ -649,12 +656,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (err == 1) {
err = 0;
if (msg_type == AUDIT_USER_TTY) {
err = audit_prepare_user_tty(pid, loginuid);
err = audit_prepare_user_tty(pid, loginuid,
sessionid);
if (err)
break;
}
audit_log_common_recv_msg(&ab, msg_type, pid, uid,
loginuid, sid);
loginuid, sessionid, sid);

if (msg_type != AUDIT_USER_TTY)
audit_log_format(ab, " msg='%.1024s'",
Expand All @@ -677,7 +685,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return -EINVAL;
if (audit_enabled == AUDIT_LOCKED) {
audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid,
uid, loginuid, sid);
uid, loginuid, sessionid, sid);

audit_log_format(ab, " audit_enabled=%d res=0",
audit_enabled);
Expand All @@ -688,15 +696,15 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
case AUDIT_LIST:
err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
uid, seq, data, nlmsg_len(nlh),
loginuid, sid);
loginuid, sessionid, sid);
break;
case AUDIT_ADD_RULE:
case AUDIT_DEL_RULE:
if (nlmsg_len(nlh) < sizeof(struct audit_rule_data))
return -EINVAL;
if (audit_enabled == AUDIT_LOCKED) {
audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid,
uid, loginuid, sid);
uid, loginuid, sessionid, sid);

audit_log_format(ab, " audit_enabled=%d res=0",
audit_enabled);
Expand All @@ -707,13 +715,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
case AUDIT_LIST_RULES:
err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
uid, seq, data, nlmsg_len(nlh),
loginuid, sid);
loginuid, sessionid, sid);
break;
case AUDIT_TRIM:
audit_trim_trees();

audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid,
uid, loginuid, sid);
uid, loginuid, sessionid, sid);

audit_log_format(ab, " op=trim res=1");
audit_log_end(ab);
Expand Down Expand Up @@ -745,7 +753,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
err = audit_tag_tree(old, new);

audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid,
uid, loginuid, sid);
uid, loginuid, sessionid, sid);

audit_log_format(ab, " op=make_equiv old=");
audit_log_untrustedstring(ab, old);
Expand Down
Loading

0 comments on commit 2532386

Please sign in to comment.