mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 22:51:35 +00:00
Merge branch 'audit.b46' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current
* 'audit.b46' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current: [AUDIT] Add uid, gid fields to ANOM_PROMISCUOUS message [AUDIT] ratelimit printk messages audit [patch 2/2] audit: complement va_copy with va_end() [patch 1/2] kernel/audit.c: warning fix [AUDIT] create context if auditing was ever enabled [AUDIT] clean up audit_receive_msg() [AUDIT] make audit=0 really stop audit messages [AUDIT] break large execve argument logging into smaller messages [AUDIT] include audit type in audit message when using printk [AUDIT] do not panic on exclude messages in audit_log_pid_context() [AUDIT] Add End of Event record [AUDIT] add session id to audit messages [AUDIT] collect uid, loginuid, and comm in OBJ_PID records [AUDIT] return EINTR not ERESTART* [PATCH] get rid of loginuid races [PATCH] switch audit_get_loginuid() to task_struct *
This commit is contained in:
commit
dd5f5fed6c
@ -1134,13 +1134,6 @@ check the amount of free space (value is in seconds). Default settings are: 4,
|
||||
resume it if we have a value of 3 or more percent; consider information about
|
||||
the amount of free space valid for 30 seconds
|
||||
|
||||
audit_argv_kb
|
||||
-------------
|
||||
|
||||
The file contains a single value denoting the limit on the argv array size
|
||||
for execve (in KiB). This limit is only applied when system call auditing for
|
||||
execve is enabled, otherwise the value is ignored.
|
||||
|
||||
ctrl-alt-del
|
||||
------------
|
||||
|
||||
|
@ -73,6 +73,7 @@ static void tty_audit_buf_put(struct tty_audit_buf *buf)
|
||||
* @tsk with @loginuid. @buf->mutex must be locked.
|
||||
*/
|
||||
static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
|
||||
unsigned int sessionid,
|
||||
struct tty_audit_buf *buf)
|
||||
{
|
||||
struct audit_buffer *ab;
|
||||
@ -85,9 +86,9 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
|
||||
if (ab) {
|
||||
char name[sizeof(tsk->comm)];
|
||||
|
||||
audit_log_format(ab, "tty pid=%u uid=%u auid=%u major=%d "
|
||||
"minor=%d comm=", tsk->pid, tsk->uid,
|
||||
loginuid, buf->major, buf->minor);
|
||||
audit_log_format(ab, "tty pid=%u uid=%u auid=%u ses=%u "
|
||||
"major=%d minor=%d comm=", tsk->pid, tsk->uid,
|
||||
loginuid, sessionid, buf->major, buf->minor);
|
||||
get_task_comm(name, tsk);
|
||||
audit_log_untrustedstring(ab, name);
|
||||
audit_log_format(ab, " data=");
|
||||
@ -105,8 +106,9 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
|
||||
*/
|
||||
static void tty_audit_buf_push_current(struct tty_audit_buf *buf)
|
||||
{
|
||||
tty_audit_buf_push(current, audit_get_loginuid(current->audit_context),
|
||||
buf);
|
||||
uid_t auid = audit_get_loginuid(current);
|
||||
unsigned int sessionid = audit_get_sessionid(current);
|
||||
tty_audit_buf_push(current, auid, sessionid, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -152,6 +154,11 @@ void tty_audit_fork(struct signal_struct *sig)
|
||||
void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid)
|
||||
{
|
||||
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;
|
||||
@ -162,7 +169,7 @@ void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid)
|
||||
return;
|
||||
|
||||
mutex_lock(&buf->mutex);
|
||||
tty_audit_buf_push(tsk, loginuid, buf);
|
||||
tty_audit_buf_push(tsk, loginuid, sessionid, buf);
|
||||
mutex_unlock(&buf->mutex);
|
||||
|
||||
tty_audit_buf_put(buf);
|
||||
|
@ -984,7 +984,7 @@ static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
|
||||
if (!task)
|
||||
return -ESRCH;
|
||||
length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
|
||||
audit_get_loginuid(task->audit_context));
|
||||
audit_get_loginuid(task));
|
||||
put_task_struct(task);
|
||||
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
|
||||
}
|
||||
|
@ -98,6 +98,7 @@
|
||||
#define AUDIT_FD_PAIR 1317 /* audit record for pipe/socketpair */
|
||||
#define AUDIT_OBJ_PID 1318 /* ptrace target */
|
||||
#define AUDIT_TTY 1319 /* Input on an administrative TTY */
|
||||
#define AUDIT_EOE 1320 /* End of multi-record event */
|
||||
|
||||
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
|
||||
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
|
||||
@ -409,7 +410,8 @@ extern unsigned int audit_serial(void);
|
||||
extern void auditsc_get_stamp(struct audit_context *ctx,
|
||||
struct timespec *t, unsigned int *serial);
|
||||
extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
|
||||
extern uid_t audit_get_loginuid(struct audit_context *ctx);
|
||||
#define audit_get_loginuid(t) ((t)->loginuid)
|
||||
#define audit_get_sessionid(t) ((t)->sessionid)
|
||||
extern void audit_log_task_context(struct audit_buffer *ab);
|
||||
extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp);
|
||||
extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
|
||||
@ -488,7 +490,8 @@ extern int audit_signals;
|
||||
#define audit_inode_child(d,i,p) do { ; } while (0)
|
||||
#define audit_core_dumps(i) do { ; } while (0)
|
||||
#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
|
||||
#define audit_get_loginuid(c) ({ -1; })
|
||||
#define audit_get_loginuid(t) (-1)
|
||||
#define audit_get_sessionid(t) (-1)
|
||||
#define audit_log_task_context(b) do { ; } while (0)
|
||||
#define audit_ipc_obj(i) ({ 0; })
|
||||
#define audit_ipc_set_perm(q,u,g,m) ({ 0; })
|
||||
@ -522,9 +525,11 @@ extern void audit_log_end(struct audit_buffer *ab);
|
||||
extern void audit_log_hex(struct audit_buffer *ab,
|
||||
const unsigned char *buf,
|
||||
size_t len);
|
||||
extern const char * audit_log_untrustedstring(struct audit_buffer *ab,
|
||||
extern int audit_string_contains_control(const char *string,
|
||||
size_t len);
|
||||
extern void audit_log_untrustedstring(struct audit_buffer *ab,
|
||||
const char *string);
|
||||
extern const char * audit_log_n_untrustedstring(struct audit_buffer *ab,
|
||||
extern void audit_log_n_untrustedstring(struct audit_buffer *ab,
|
||||
size_t n,
|
||||
const char *string);
|
||||
extern void audit_log_d_path(struct audit_buffer *ab,
|
||||
|
@ -114,6 +114,13 @@ extern struct group_info init_groups;
|
||||
.pid = &init_struct_pid, \
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
#define INIT_IDS \
|
||||
.loginuid = -1, \
|
||||
.sessionid = -1,
|
||||
#else
|
||||
#define INIT_IDS
|
||||
#endif
|
||||
/*
|
||||
* INIT_TASK is used to set up the first task table, touch at
|
||||
* your own risk!. Base=0, limit=0x1fffff (=2MB)
|
||||
@ -173,6 +180,7 @@ extern struct group_info init_groups;
|
||||
[PIDTYPE_SID] = INIT_PID_LINK(PIDTYPE_SID), \
|
||||
}, \
|
||||
.dirties = INIT_PROP_LOCAL_SINGLE(dirties), \
|
||||
INIT_IDS \
|
||||
INIT_TRACE_IRQFLAGS \
|
||||
INIT_LOCKDEP \
|
||||
}
|
||||
|
@ -1139,6 +1139,10 @@ struct task_struct {
|
||||
void *security;
|
||||
#endif
|
||||
struct audit_context *audit_context;
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
uid_t loginuid;
|
||||
unsigned int sessionid;
|
||||
#endif
|
||||
seccomp_t seccomp;
|
||||
|
||||
/* Thread group tracking */
|
||||
|
442
kernel/audit.c
442
kernel/audit.c
@ -66,10 +66,11 @@
|
||||
* (Initialization happens after skb_init is called.) */
|
||||
static int audit_initialized;
|
||||
|
||||
/* 0 - no auditing
|
||||
* 1 - auditing enabled
|
||||
* 2 - auditing enabled and configuration is locked/unchangeable. */
|
||||
#define AUDIT_OFF 0
|
||||
#define AUDIT_ON 1
|
||||
#define AUDIT_LOCKED 2
|
||||
int audit_enabled;
|
||||
int audit_ever_enabled;
|
||||
|
||||
/* Default state when kernel boots without any parameters. */
|
||||
static int audit_default;
|
||||
@ -152,8 +153,10 @@ struct audit_buffer {
|
||||
|
||||
static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
|
||||
{
|
||||
struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
|
||||
nlh->nlmsg_pid = pid;
|
||||
if (ab) {
|
||||
struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
|
||||
nlh->nlmsg_pid = pid;
|
||||
}
|
||||
}
|
||||
|
||||
void audit_panic(const char *message)
|
||||
@ -163,7 +166,8 @@ void audit_panic(const char *message)
|
||||
case AUDIT_FAIL_SILENT:
|
||||
break;
|
||||
case AUDIT_FAIL_PRINTK:
|
||||
printk(KERN_ERR "audit: %s\n", message);
|
||||
if (printk_ratelimit())
|
||||
printk(KERN_ERR "audit: %s\n", message);
|
||||
break;
|
||||
case AUDIT_FAIL_PANIC:
|
||||
panic("audit: %s\n", message);
|
||||
@ -231,161 +235,107 @@ void audit_log_lost(const char *message)
|
||||
}
|
||||
|
||||
if (print) {
|
||||
printk(KERN_WARNING
|
||||
"audit: audit_lost=%d audit_rate_limit=%d audit_backlog_limit=%d\n",
|
||||
atomic_read(&audit_lost),
|
||||
audit_rate_limit,
|
||||
audit_backlog_limit);
|
||||
if (printk_ratelimit())
|
||||
printk(KERN_WARNING
|
||||
"audit: audit_lost=%d audit_rate_limit=%d "
|
||||
"audit_backlog_limit=%d\n",
|
||||
atomic_read(&audit_lost),
|
||||
audit_rate_limit,
|
||||
audit_backlog_limit);
|
||||
audit_panic(message);
|
||||
}
|
||||
}
|
||||
|
||||
static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid)
|
||||
static int audit_log_config_change(char *function_name, int new, int old,
|
||||
uid_t loginuid, u32 sid, int allow_changes)
|
||||
{
|
||||
int res, rc = 0, old = audit_rate_limit;
|
||||
|
||||
/* check if we are locked */
|
||||
if (audit_enabled == 2)
|
||||
res = 0;
|
||||
else
|
||||
res = 1;
|
||||
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);
|
||||
if (sid) {
|
||||
char *ctx = NULL;
|
||||
u32 len;
|
||||
if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
|
||||
audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
|
||||
"audit_rate_limit=%d old=%d by auid=%u"
|
||||
" subj=%s res=%d",
|
||||
limit, old, loginuid, ctx, res);
|
||||
|
||||
rc = selinux_sid_to_string(sid, &ctx, &len);
|
||||
if (rc) {
|
||||
audit_log_format(ab, " sid=%u", sid);
|
||||
allow_changes = 0; /* Something weird, deny request */
|
||||
} else {
|
||||
audit_log_format(ab, " subj=%s", ctx);
|
||||
kfree(ctx);
|
||||
} else
|
||||
res = 0; /* Something weird, deny request */
|
||||
}
|
||||
}
|
||||
audit_log_format(ab, " res=%d", allow_changes);
|
||||
audit_log_end(ab);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int audit_do_config_change(char *function_name, int *to_change,
|
||||
int new, uid_t loginuid, u32 sid)
|
||||
{
|
||||
int allow_changes, rc = 0, old = *to_change;
|
||||
|
||||
/* check if we are locked */
|
||||
if (audit_enabled == AUDIT_LOCKED)
|
||||
allow_changes = 0;
|
||||
else
|
||||
allow_changes = 1;
|
||||
|
||||
if (audit_enabled != AUDIT_OFF) {
|
||||
rc = audit_log_config_change(function_name, new, old,
|
||||
loginuid, sid, allow_changes);
|
||||
if (rc)
|
||||
allow_changes = 0;
|
||||
}
|
||||
audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
|
||||
"audit_rate_limit=%d old=%d by auid=%u res=%d",
|
||||
limit, old, loginuid, res);
|
||||
|
||||
/* If we are allowed, make the change */
|
||||
if (res == 1)
|
||||
audit_rate_limit = limit;
|
||||
if (allow_changes == 1)
|
||||
*to_change = new;
|
||||
/* Not allowed, update reason */
|
||||
else if (rc == 0)
|
||||
rc = -EPERM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid)
|
||||
{
|
||||
return audit_do_config_change("audit_rate_limit", &audit_rate_limit,
|
||||
limit, loginuid, sid);
|
||||
}
|
||||
|
||||
static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid)
|
||||
{
|
||||
int res, rc = 0, old = audit_backlog_limit;
|
||||
|
||||
/* check if we are locked */
|
||||
if (audit_enabled == 2)
|
||||
res = 0;
|
||||
else
|
||||
res = 1;
|
||||
|
||||
if (sid) {
|
||||
char *ctx = NULL;
|
||||
u32 len;
|
||||
if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
|
||||
audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
|
||||
"audit_backlog_limit=%d old=%d by auid=%u"
|
||||
" subj=%s res=%d",
|
||||
limit, old, loginuid, ctx, res);
|
||||
kfree(ctx);
|
||||
} else
|
||||
res = 0; /* Something weird, deny request */
|
||||
}
|
||||
audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
|
||||
"audit_backlog_limit=%d old=%d by auid=%u res=%d",
|
||||
limit, old, loginuid, res);
|
||||
|
||||
/* If we are allowed, make the change */
|
||||
if (res == 1)
|
||||
audit_backlog_limit = limit;
|
||||
/* Not allowed, update reason */
|
||||
else if (rc == 0)
|
||||
rc = -EPERM;
|
||||
return rc;
|
||||
return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit,
|
||||
limit, loginuid, sid);
|
||||
}
|
||||
|
||||
static int audit_set_enabled(int state, uid_t loginuid, u32 sid)
|
||||
{
|
||||
int res, rc = 0, old = audit_enabled;
|
||||
|
||||
if (state < 0 || state > 2)
|
||||
int rc;
|
||||
if (state < AUDIT_OFF || state > AUDIT_LOCKED)
|
||||
return -EINVAL;
|
||||
|
||||
/* check if we are locked */
|
||||
if (audit_enabled == 2)
|
||||
res = 0;
|
||||
else
|
||||
res = 1;
|
||||
rc = audit_do_config_change("audit_enabled", &audit_enabled, state,
|
||||
loginuid, sid);
|
||||
|
||||
if (sid) {
|
||||
char *ctx = NULL;
|
||||
u32 len;
|
||||
if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
|
||||
audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
|
||||
"audit_enabled=%d old=%d by auid=%u"
|
||||
" subj=%s res=%d",
|
||||
state, old, loginuid, ctx, res);
|
||||
kfree(ctx);
|
||||
} else
|
||||
res = 0; /* Something weird, deny request */
|
||||
}
|
||||
audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
|
||||
"audit_enabled=%d old=%d by auid=%u res=%d",
|
||||
state, old, loginuid, res);
|
||||
if (!rc)
|
||||
audit_ever_enabled |= !!state;
|
||||
|
||||
/* If we are allowed, make the change */
|
||||
if (res == 1)
|
||||
audit_enabled = state;
|
||||
/* Not allowed, update reason */
|
||||
else if (rc == 0)
|
||||
rc = -EPERM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int audit_set_failure(int state, uid_t loginuid, u32 sid)
|
||||
{
|
||||
int res, rc = 0, old = audit_failure;
|
||||
|
||||
if (state != AUDIT_FAIL_SILENT
|
||||
&& state != AUDIT_FAIL_PRINTK
|
||||
&& state != AUDIT_FAIL_PANIC)
|
||||
return -EINVAL;
|
||||
|
||||
/* check if we are locked */
|
||||
if (audit_enabled == 2)
|
||||
res = 0;
|
||||
else
|
||||
res = 1;
|
||||
|
||||
if (sid) {
|
||||
char *ctx = NULL;
|
||||
u32 len;
|
||||
if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
|
||||
audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
|
||||
"audit_failure=%d old=%d by auid=%u"
|
||||
" subj=%s res=%d",
|
||||
state, old, loginuid, ctx, res);
|
||||
kfree(ctx);
|
||||
} else
|
||||
res = 0; /* Something weird, deny request */
|
||||
}
|
||||
audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
|
||||
"audit_failure=%d old=%d by auid=%u res=%d",
|
||||
state, old, loginuid, res);
|
||||
|
||||
/* If we are allowed, make the change */
|
||||
if (res == 1)
|
||||
audit_failure = state;
|
||||
/* Not allowed, update reason */
|
||||
else if (rc == 0)
|
||||
rc = -EPERM;
|
||||
return rc;
|
||||
return audit_do_config_change("audit_failure", &audit_failure, state,
|
||||
loginuid, sid);
|
||||
}
|
||||
|
||||
static int kauditd_thread(void *dummy)
|
||||
@ -405,7 +355,11 @@ static int kauditd_thread(void *dummy)
|
||||
audit_pid = 0;
|
||||
}
|
||||
} else {
|
||||
printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0));
|
||||
if (printk_ratelimit())
|
||||
printk(KERN_NOTICE "%s\n", skb->data +
|
||||
NLMSG_SPACE(0));
|
||||
else
|
||||
audit_log_lost("printk limit exceeded\n");
|
||||
kfree_skb(skb);
|
||||
}
|
||||
} else {
|
||||
@ -573,6 +527,33 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type,
|
||||
u32 pid, u32 uid, uid_t auid, u32 sid)
|
||||
{
|
||||
int rc = 0;
|
||||
char *ctx = NULL;
|
||||
u32 len;
|
||||
|
||||
if (!audit_enabled) {
|
||||
*ab = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
*ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
|
||||
audit_log_format(*ab, "user pid=%d uid=%u auid=%u",
|
||||
pid, uid, auid);
|
||||
if (sid) {
|
||||
rc = selinux_sid_to_string(sid, &ctx, &len);
|
||||
if (rc)
|
||||
audit_log_format(*ab, " ssid=%u", sid);
|
||||
else
|
||||
audit_log_format(*ab, " subj=%s", ctx);
|
||||
kfree(ctx);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
{
|
||||
u32 uid, pid, seq, sid;
|
||||
@ -583,7 +564,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
u16 msg_type = nlh->nlmsg_type;
|
||||
uid_t loginuid; /* loginuid of sender */
|
||||
struct audit_sig_info *sig_data;
|
||||
char *ctx;
|
||||
char *ctx = NULL;
|
||||
u32 len;
|
||||
|
||||
err = audit_netlink_ok(skb, msg_type);
|
||||
@ -634,23 +615,14 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
if (err < 0) return err;
|
||||
}
|
||||
if (status_get->mask & AUDIT_STATUS_PID) {
|
||||
int old = audit_pid;
|
||||
if (sid) {
|
||||
if ((err = selinux_sid_to_string(
|
||||
sid, &ctx, &len)))
|
||||
return err;
|
||||
else
|
||||
audit_log(NULL, GFP_KERNEL,
|
||||
AUDIT_CONFIG_CHANGE,
|
||||
"audit_pid=%d old=%d by auid=%u subj=%s",
|
||||
status_get->pid, old,
|
||||
loginuid, ctx);
|
||||
kfree(ctx);
|
||||
} else
|
||||
audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
|
||||
"audit_pid=%d old=%d by auid=%u",
|
||||
status_get->pid, old, loginuid);
|
||||
audit_pid = status_get->pid;
|
||||
int new_pid = status_get->pid;
|
||||
|
||||
if (audit_enabled != AUDIT_OFF)
|
||||
audit_log_config_change("audit_pid", new_pid,
|
||||
audit_pid, loginuid,
|
||||
sid, 1);
|
||||
|
||||
audit_pid = new_pid;
|
||||
}
|
||||
if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
|
||||
err = audit_set_rate_limit(status_get->rate_limit,
|
||||
@ -673,64 +645,35 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
|
||||
if (ab) {
|
||||
audit_log_format(ab,
|
||||
"user pid=%d uid=%u auid=%u",
|
||||
pid, uid, loginuid);
|
||||
if (sid) {
|
||||
if (selinux_sid_to_string(
|
||||
sid, &ctx, &len)) {
|
||||
audit_log_format(ab,
|
||||
" ssid=%u", sid);
|
||||
/* Maybe call audit_panic? */
|
||||
} else
|
||||
audit_log_format(ab,
|
||||
" subj=%s", ctx);
|
||||
kfree(ctx);
|
||||
}
|
||||
if (msg_type != AUDIT_USER_TTY)
|
||||
audit_log_format(ab, " msg='%.1024s'",
|
||||
(char *)data);
|
||||
else {
|
||||
int size;
|
||||
audit_log_common_recv_msg(&ab, msg_type, pid, uid,
|
||||
loginuid, sid);
|
||||
|
||||
audit_log_format(ab, " msg=");
|
||||
size = nlmsg_len(nlh);
|
||||
audit_log_n_untrustedstring(ab, size,
|
||||
data);
|
||||
}
|
||||
audit_set_pid(ab, pid);
|
||||
audit_log_end(ab);
|
||||
if (msg_type != AUDIT_USER_TTY)
|
||||
audit_log_format(ab, " msg='%.1024s'",
|
||||
(char *)data);
|
||||
else {
|
||||
int size;
|
||||
|
||||
audit_log_format(ab, " msg=");
|
||||
size = nlmsg_len(nlh);
|
||||
audit_log_n_untrustedstring(ab, size,
|
||||
data);
|
||||
}
|
||||
audit_set_pid(ab, pid);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
break;
|
||||
case AUDIT_ADD:
|
||||
case AUDIT_DEL:
|
||||
if (nlmsg_len(nlh) < sizeof(struct audit_rule))
|
||||
return -EINVAL;
|
||||
if (audit_enabled == 2) {
|
||||
ab = audit_log_start(NULL, GFP_KERNEL,
|
||||
AUDIT_CONFIG_CHANGE);
|
||||
if (ab) {
|
||||
audit_log_format(ab,
|
||||
"pid=%d uid=%u auid=%u",
|
||||
pid, uid, loginuid);
|
||||
if (sid) {
|
||||
if (selinux_sid_to_string(
|
||||
sid, &ctx, &len)) {
|
||||
audit_log_format(ab,
|
||||
" ssid=%u", sid);
|
||||
/* Maybe call audit_panic? */
|
||||
} else
|
||||
audit_log_format(ab,
|
||||
" subj=%s", ctx);
|
||||
kfree(ctx);
|
||||
}
|
||||
audit_log_format(ab, " audit_enabled=%d res=0",
|
||||
audit_enabled);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
if (audit_enabled == AUDIT_LOCKED) {
|
||||
audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid,
|
||||
uid, loginuid, sid);
|
||||
|
||||
audit_log_format(ab, " audit_enabled=%d res=0",
|
||||
audit_enabled);
|
||||
audit_log_end(ab);
|
||||
return -EPERM;
|
||||
}
|
||||
/* fallthrough */
|
||||
@ -743,28 +686,13 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
case AUDIT_DEL_RULE:
|
||||
if (nlmsg_len(nlh) < sizeof(struct audit_rule_data))
|
||||
return -EINVAL;
|
||||
if (audit_enabled == 2) {
|
||||
ab = audit_log_start(NULL, GFP_KERNEL,
|
||||
AUDIT_CONFIG_CHANGE);
|
||||
if (ab) {
|
||||
audit_log_format(ab,
|
||||
"pid=%d uid=%u auid=%u",
|
||||
pid, uid, loginuid);
|
||||
if (sid) {
|
||||
if (selinux_sid_to_string(
|
||||
sid, &ctx, &len)) {
|
||||
audit_log_format(ab,
|
||||
" ssid=%u", sid);
|
||||
/* Maybe call audit_panic? */
|
||||
} else
|
||||
audit_log_format(ab,
|
||||
" subj=%s", ctx);
|
||||
kfree(ctx);
|
||||
}
|
||||
audit_log_format(ab, " audit_enabled=%d res=0",
|
||||
audit_enabled);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
if (audit_enabled == AUDIT_LOCKED) {
|
||||
audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid,
|
||||
uid, loginuid, sid);
|
||||
|
||||
audit_log_format(ab, " audit_enabled=%d res=0",
|
||||
audit_enabled);
|
||||
audit_log_end(ab);
|
||||
return -EPERM;
|
||||
}
|
||||
/* fallthrough */
|
||||
@ -775,19 +703,10 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
break;
|
||||
case AUDIT_TRIM:
|
||||
audit_trim_trees();
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
|
||||
if (!ab)
|
||||
break;
|
||||
audit_log_format(ab, "auid=%u", loginuid);
|
||||
if (sid) {
|
||||
u32 len;
|
||||
ctx = NULL;
|
||||
if (selinux_sid_to_string(sid, &ctx, &len))
|
||||
audit_log_format(ab, " ssid=%u", sid);
|
||||
else
|
||||
audit_log_format(ab, " subj=%s", ctx);
|
||||
kfree(ctx);
|
||||
}
|
||||
|
||||
audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid,
|
||||
uid, loginuid, sid);
|
||||
|
||||
audit_log_format(ab, " op=trim res=1");
|
||||
audit_log_end(ab);
|
||||
break;
|
||||
@ -817,22 +736,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
/* OK, here comes... */
|
||||
err = audit_tag_tree(old, new);
|
||||
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
|
||||
if (!ab) {
|
||||
kfree(old);
|
||||
kfree(new);
|
||||
break;
|
||||
}
|
||||
audit_log_format(ab, "auid=%u", loginuid);
|
||||
if (sid) {
|
||||
u32 len;
|
||||
ctx = NULL;
|
||||
if (selinux_sid_to_string(sid, &ctx, &len))
|
||||
audit_log_format(ab, " ssid=%u", sid);
|
||||
else
|
||||
audit_log_format(ab, " subj=%s", ctx);
|
||||
kfree(ctx);
|
||||
}
|
||||
audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid,
|
||||
uid, loginuid, sid);
|
||||
|
||||
audit_log_format(ab, " op=make_equiv old=");
|
||||
audit_log_untrustedstring(ab, old);
|
||||
audit_log_format(ab, " new=");
|
||||
@ -965,6 +871,7 @@ static int __init audit_init(void)
|
||||
skb_queue_head_init(&audit_skb_queue);
|
||||
audit_initialized = 1;
|
||||
audit_enabled = audit_default;
|
||||
audit_ever_enabled |= !!audit_default;
|
||||
|
||||
/* Register the callback with selinux. This callback will be invoked
|
||||
* when a new policy is loaded. */
|
||||
@ -992,8 +899,10 @@ static int __init audit_enable(char *str)
|
||||
printk(KERN_INFO "audit: %s%s\n",
|
||||
audit_default ? "enabled" : "disabled",
|
||||
audit_initialized ? "" : " (after initialization)");
|
||||
if (audit_initialized)
|
||||
if (audit_initialized) {
|
||||
audit_enabled = audit_default;
|
||||
audit_ever_enabled |= !!audit_default;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1130,7 +1039,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
|
||||
{
|
||||
struct audit_buffer *ab = NULL;
|
||||
struct timespec t;
|
||||
unsigned int serial;
|
||||
unsigned int uninitialized_var(serial);
|
||||
int reserve;
|
||||
unsigned long timeout_start = jiffies;
|
||||
|
||||
@ -1164,7 +1073,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
|
||||
remove_wait_queue(&audit_backlog_wait, &wait);
|
||||
continue;
|
||||
}
|
||||
if (audit_rate_check())
|
||||
if (audit_rate_check() && printk_ratelimit())
|
||||
printk(KERN_WARNING
|
||||
"audit: audit_backlog=%d > "
|
||||
"audit_backlog_limit=%d\n",
|
||||
@ -1249,6 +1158,7 @@ static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
|
||||
goto out;
|
||||
len = vsnprintf(skb_tail_pointer(skb), avail, fmt, args2);
|
||||
}
|
||||
va_end(args2);
|
||||
if (len > 0)
|
||||
skb_put(skb, len);
|
||||
out:
|
||||
@ -1349,6 +1259,21 @@ static void audit_log_n_string(struct audit_buffer *ab, size_t slen,
|
||||
skb_put(skb, slen + 2); /* don't include null terminator */
|
||||
}
|
||||
|
||||
/**
|
||||
* audit_string_contains_control - does a string need to be logged in hex
|
||||
* @string - string to be checked
|
||||
* @len - max length of the string to check
|
||||
*/
|
||||
int audit_string_contains_control(const char *string, size_t len)
|
||||
{
|
||||
const unsigned char *p;
|
||||
for (p = string; p < (const unsigned char *)string + len && *p; p++) {
|
||||
if (*p == '"' || *p < 0x21 || *p > 0x7f)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* audit_log_n_untrustedstring - log a string that may contain random characters
|
||||
* @ab: audit_buffer
|
||||
@ -1363,19 +1288,13 @@ static void audit_log_n_string(struct audit_buffer *ab, size_t slen,
|
||||
* The caller specifies the number of characters in the string to log, which may
|
||||
* or may not be the entire string.
|
||||
*/
|
||||
const char *audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len,
|
||||
const char *string)
|
||||
void audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len,
|
||||
const char *string)
|
||||
{
|
||||
const unsigned char *p;
|
||||
|
||||
for (p = string; p < (const unsigned char *)string + len && *p; p++) {
|
||||
if (*p == '"' || *p < 0x21 || *p > 0x7f) {
|
||||
audit_log_hex(ab, string, len);
|
||||
return string + len + 1;
|
||||
}
|
||||
}
|
||||
audit_log_n_string(ab, len, string);
|
||||
return p + 1;
|
||||
if (audit_string_contains_control(string, len))
|
||||
audit_log_hex(ab, string, len);
|
||||
else
|
||||
audit_log_n_string(ab, len, string);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1386,9 +1305,9 @@ const char *audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len,
|
||||
* Same as audit_log_n_untrustedstring(), except that strlen is used to
|
||||
* determine string length.
|
||||
*/
|
||||
const char *audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
|
||||
void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
|
||||
{
|
||||
return audit_log_n_untrustedstring(ab, strlen(string), string);
|
||||
audit_log_n_untrustedstring(ab, strlen(string), string);
|
||||
}
|
||||
|
||||
/* This is a helper-function to print the escaped d_path */
|
||||
@ -1437,8 +1356,11 @@ void audit_log_end(struct audit_buffer *ab)
|
||||
skb_queue_tail(&audit_skb_queue, ab->skb);
|
||||
ab->skb = NULL;
|
||||
wake_up_interruptible(&kauditd_wait);
|
||||
} else if (printk_ratelimit()) {
|
||||
struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
|
||||
printk(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, ab->skb->data + NLMSG_SPACE(0));
|
||||
} else {
|
||||
printk(KERN_NOTICE "%s\n", ab->skb->data + NLMSG_SPACE(0));
|
||||
audit_log_lost("printk limit exceeded\n");
|
||||
}
|
||||
}
|
||||
audit_buffer_free(ab);
|
||||
|
@ -95,6 +95,8 @@ extern struct inotify_handle *audit_ih;
|
||||
/* Inotify events we care about. */
|
||||
#define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF
|
||||
|
||||
extern int audit_enabled;
|
||||
|
||||
void audit_free_parent(struct inotify_watch *i_watch)
|
||||
{
|
||||
struct audit_parent *parent;
|
||||
@ -974,7 +976,6 @@ static void audit_update_watch(struct audit_parent *parent,
|
||||
struct audit_watch *owatch, *nwatch, *nextw;
|
||||
struct audit_krule *r, *nextr;
|
||||
struct audit_entry *oentry, *nentry;
|
||||
struct audit_buffer *ab;
|
||||
|
||||
mutex_lock(&audit_filter_mutex);
|
||||
list_for_each_entry_safe(owatch, nextw, &parent->watches, wlist) {
|
||||
@ -1014,13 +1015,18 @@ static void audit_update_watch(struct audit_parent *parent,
|
||||
call_rcu(&oentry->rcu, audit_free_rule_rcu);
|
||||
}
|
||||
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
|
||||
audit_log_format(ab, "op=updated rules specifying path=");
|
||||
audit_log_untrustedstring(ab, owatch->path);
|
||||
audit_log_format(ab, " with dev=%u ino=%lu\n", dev, ino);
|
||||
audit_log_format(ab, " list=%d res=1", r->listnr);
|
||||
audit_log_end(ab);
|
||||
|
||||
if (audit_enabled) {
|
||||
struct audit_buffer *ab;
|
||||
ab = audit_log_start(NULL, GFP_KERNEL,
|
||||
AUDIT_CONFIG_CHANGE);
|
||||
audit_log_format(ab,
|
||||
"op=updated rules specifying path=");
|
||||
audit_log_untrustedstring(ab, owatch->path);
|
||||
audit_log_format(ab, " with dev=%u ino=%lu\n",
|
||||
dev, ino);
|
||||
audit_log_format(ab, " list=%d res=1", r->listnr);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
audit_remove_watch(owatch);
|
||||
goto add_watch_to_parent; /* event applies to a single watch */
|
||||
}
|
||||
@ -1039,25 +1045,28 @@ static void audit_remove_parent_watches(struct audit_parent *parent)
|
||||
struct audit_watch *w, *nextw;
|
||||
struct audit_krule *r, *nextr;
|
||||
struct audit_entry *e;
|
||||
struct audit_buffer *ab;
|
||||
|
||||
mutex_lock(&audit_filter_mutex);
|
||||
parent->flags |= AUDIT_PARENT_INVALID;
|
||||
list_for_each_entry_safe(w, nextw, &parent->watches, wlist) {
|
||||
list_for_each_entry_safe(r, nextr, &w->rules, rlist) {
|
||||
e = container_of(r, struct audit_entry, rule);
|
||||
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
|
||||
audit_log_format(ab, "op=remove rule path=");
|
||||
audit_log_untrustedstring(ab, w->path);
|
||||
if (r->filterkey) {
|
||||
audit_log_format(ab, " key=");
|
||||
audit_log_untrustedstring(ab, r->filterkey);
|
||||
} else
|
||||
audit_log_format(ab, " key=(null)");
|
||||
audit_log_format(ab, " list=%d res=1", r->listnr);
|
||||
audit_log_end(ab);
|
||||
|
||||
if (audit_enabled) {
|
||||
struct audit_buffer *ab;
|
||||
ab = audit_log_start(NULL, GFP_KERNEL,
|
||||
AUDIT_CONFIG_CHANGE);
|
||||
audit_log_format(ab, "op=remove rule path=");
|
||||
audit_log_untrustedstring(ab, w->path);
|
||||
if (r->filterkey) {
|
||||
audit_log_format(ab, " key=");
|
||||
audit_log_untrustedstring(ab,
|
||||
r->filterkey);
|
||||
} else
|
||||
audit_log_format(ab, " key=(null)");
|
||||
audit_log_format(ab, " list=%d res=1",
|
||||
r->listnr);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
list_del(&r->rlist);
|
||||
list_del_rcu(&e->list);
|
||||
call_rcu(&e->rcu, audit_free_rule_rcu);
|
||||
@ -1495,6 +1504,9 @@ static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action,
|
||||
{
|
||||
struct audit_buffer *ab;
|
||||
|
||||
if (!audit_enabled)
|
||||
return;
|
||||
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
|
||||
if (!ab)
|
||||
return;
|
||||
|
355
kernel/auditsc.c
355
kernel/auditsc.c
@ -70,6 +70,7 @@
|
||||
#include "audit.h"
|
||||
|
||||
extern struct list_head audit_filter_list[];
|
||||
extern int audit_ever_enabled;
|
||||
|
||||
/* AUDIT_NAMES is the number of slots we reserve in the audit_context
|
||||
* for saving names from getname(). */
|
||||
@ -78,6 +79,9 @@ extern struct list_head audit_filter_list[];
|
||||
/* Indicates that audit should log the full pathname. */
|
||||
#define AUDIT_NAME_FULL -1
|
||||
|
||||
/* no execve audit message should be longer than this (userspace limits) */
|
||||
#define MAX_EXECVE_AUDIT_LEN 7500
|
||||
|
||||
/* number of audit rules */
|
||||
int audit_n_rules;
|
||||
|
||||
@ -176,7 +180,11 @@ struct audit_aux_data_fd_pair {
|
||||
struct audit_aux_data_pids {
|
||||
struct audit_aux_data d;
|
||||
pid_t target_pid[AUDIT_AUX_PIDS];
|
||||
uid_t target_auid[AUDIT_AUX_PIDS];
|
||||
uid_t target_uid[AUDIT_AUX_PIDS];
|
||||
unsigned int target_sessionid[AUDIT_AUX_PIDS];
|
||||
u32 target_sid[AUDIT_AUX_PIDS];
|
||||
char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN];
|
||||
int pid_count;
|
||||
};
|
||||
|
||||
@ -192,7 +200,6 @@ struct audit_context {
|
||||
enum audit_state state;
|
||||
unsigned int serial; /* serial number for record */
|
||||
struct timespec ctime; /* time of syscall entry */
|
||||
uid_t loginuid; /* login uid (identity) */
|
||||
int major; /* syscall number */
|
||||
unsigned long argv[4]; /* syscall arguments */
|
||||
int return_valid; /* return code is valid */
|
||||
@ -215,7 +222,11 @@ struct audit_context {
|
||||
int arch;
|
||||
|
||||
pid_t target_pid;
|
||||
uid_t target_auid;
|
||||
uid_t target_uid;
|
||||
unsigned int target_sessionid;
|
||||
u32 target_sid;
|
||||
char target_comm[TASK_COMM_LEN];
|
||||
|
||||
struct audit_tree_refs *trees, *first_trees;
|
||||
int tree_count;
|
||||
@ -506,7 +517,7 @@ static int audit_filter_rules(struct task_struct *tsk,
|
||||
case AUDIT_LOGINUID:
|
||||
result = 0;
|
||||
if (ctx)
|
||||
result = audit_comparator(ctx->loginuid, f->op, f->val);
|
||||
result = audit_comparator(tsk->loginuid, f->op, f->val);
|
||||
break;
|
||||
case AUDIT_SUBJ_USER:
|
||||
case AUDIT_SUBJ_ROLE:
|
||||
@ -702,7 +713,24 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk,
|
||||
if (likely(!context))
|
||||
return NULL;
|
||||
context->return_valid = return_valid;
|
||||
context->return_code = return_code;
|
||||
|
||||
/*
|
||||
* we need to fix up the return code in the audit logs if the actual
|
||||
* return codes are later going to be fixed up by the arch specific
|
||||
* signal handlers
|
||||
*
|
||||
* This is actually a test for:
|
||||
* (rc == ERESTARTSYS ) || (rc == ERESTARTNOINTR) ||
|
||||
* (rc == ERESTARTNOHAND) || (rc == ERESTART_RESTARTBLOCK)
|
||||
*
|
||||
* but is faster than a bunch of ||
|
||||
*/
|
||||
if (unlikely(return_code <= -ERESTARTSYS) &&
|
||||
(return_code >= -ERESTART_RESTARTBLOCK) &&
|
||||
(return_code != -ENOIOCTLCMD))
|
||||
context->return_code = -EINTR;
|
||||
else
|
||||
context->return_code = return_code;
|
||||
|
||||
if (context->in_syscall && !context->dummy && !context->auditable) {
|
||||
enum audit_state state;
|
||||
@ -783,11 +811,8 @@ static inline void audit_free_aux(struct audit_context *context)
|
||||
static inline void audit_zero_context(struct audit_context *context,
|
||||
enum audit_state state)
|
||||
{
|
||||
uid_t loginuid = context->loginuid;
|
||||
|
||||
memset(context, 0, sizeof(*context));
|
||||
context->state = state;
|
||||
context->loginuid = loginuid;
|
||||
}
|
||||
|
||||
static inline struct audit_context *audit_alloc_context(enum audit_state state)
|
||||
@ -814,7 +839,7 @@ int audit_alloc(struct task_struct *tsk)
|
||||
struct audit_context *context;
|
||||
enum audit_state state;
|
||||
|
||||
if (likely(!audit_enabled))
|
||||
if (likely(!audit_ever_enabled))
|
||||
return 0; /* Return if not auditing. */
|
||||
|
||||
state = audit_filter_task(tsk);
|
||||
@ -826,11 +851,6 @@ int audit_alloc(struct task_struct *tsk)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Preserve login uid */
|
||||
context->loginuid = -1;
|
||||
if (current->audit_context)
|
||||
context->loginuid = current->audit_context->loginuid;
|
||||
|
||||
tsk->audit_context = context;
|
||||
set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
|
||||
return 0;
|
||||
@ -922,7 +942,8 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk
|
||||
}
|
||||
|
||||
static int audit_log_pid_context(struct audit_context *context, pid_t pid,
|
||||
u32 sid)
|
||||
uid_t auid, uid_t uid, unsigned int sessionid,
|
||||
u32 sid, char *comm)
|
||||
{
|
||||
struct audit_buffer *ab;
|
||||
char *s = NULL;
|
||||
@ -931,52 +952,71 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
|
||||
|
||||
ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
|
||||
if (!ab)
|
||||
return 1;
|
||||
return rc;
|
||||
|
||||
audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, auid,
|
||||
uid, sessionid);
|
||||
if (selinux_sid_to_string(sid, &s, &len)) {
|
||||
audit_log_format(ab, "opid=%d obj=(none)", pid);
|
||||
audit_log_format(ab, " obj=(none)");
|
||||
rc = 1;
|
||||
} else
|
||||
audit_log_format(ab, "opid=%d obj=%s", pid, s);
|
||||
audit_log_format(ab, " obj=%s", s);
|
||||
audit_log_format(ab, " ocomm=");
|
||||
audit_log_untrustedstring(ab, comm);
|
||||
audit_log_end(ab);
|
||||
kfree(s);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void audit_log_execve_info(struct audit_buffer *ab,
|
||||
struct audit_aux_data_execve *axi)
|
||||
/*
|
||||
* to_send and len_sent accounting are very loose estimates. We aren't
|
||||
* really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being
|
||||
* within about 500 bytes (next page boundry)
|
||||
*
|
||||
* why snprintf? an int is up to 12 digits long. if we just assumed when
|
||||
* logging that a[%d]= was going to be 16 characters long we would be wasting
|
||||
* space in every audit message. In one 7500 byte message we can log up to
|
||||
* about 1000 min size arguments. That comes down to about 50% waste of space
|
||||
* if we didn't do the snprintf to find out how long arg_num_len was.
|
||||
*/
|
||||
static int audit_log_single_execve_arg(struct audit_context *context,
|
||||
struct audit_buffer **ab,
|
||||
int arg_num,
|
||||
size_t *len_sent,
|
||||
const char __user *p,
|
||||
char *buf)
|
||||
{
|
||||
int i;
|
||||
long len, ret;
|
||||
const char __user *p;
|
||||
char *buf;
|
||||
char arg_num_len_buf[12];
|
||||
const char __user *tmp_p = p;
|
||||
/* how many digits are in arg_num? 3 is the length of a=\n */
|
||||
size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 3;
|
||||
size_t len, len_left, to_send;
|
||||
size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN;
|
||||
unsigned int i, has_cntl = 0, too_long = 0;
|
||||
int ret;
|
||||
|
||||
if (axi->mm != current->mm)
|
||||
return; /* execve failed, no additional info */
|
||||
/* strnlen_user includes the null we don't want to send */
|
||||
len_left = len = strnlen_user(p, MAX_ARG_STRLEN) - 1;
|
||||
|
||||
p = (const char __user *)axi->mm->arg_start;
|
||||
/*
|
||||
* We just created this mm, if we can't find the strings
|
||||
* we just copied into it something is _very_ wrong. Similar
|
||||
* for strings that are too long, we should not have created
|
||||
* any.
|
||||
*/
|
||||
if (unlikely((len = -1) || len > MAX_ARG_STRLEN - 1)) {
|
||||
WARN_ON(1);
|
||||
send_sig(SIGKILL, current, 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < axi->argc; i++, p += len) {
|
||||
len = strnlen_user(p, MAX_ARG_STRLEN);
|
||||
/*
|
||||
* We just created this mm, if we can't find the strings
|
||||
* we just copied into it something is _very_ wrong. Similar
|
||||
* for strings that are too long, we should not have created
|
||||
* any.
|
||||
*/
|
||||
if (!len || len > MAX_ARG_STRLEN) {
|
||||
WARN_ON(1);
|
||||
send_sig(SIGKILL, current, 0);
|
||||
}
|
||||
|
||||
buf = kmalloc(len, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
audit_panic("out of memory for argv string\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ret = copy_from_user(buf, p, len);
|
||||
/* walk the whole argument looking for non-ascii chars */
|
||||
do {
|
||||
if (len_left > MAX_EXECVE_AUDIT_LEN)
|
||||
to_send = MAX_EXECVE_AUDIT_LEN;
|
||||
else
|
||||
to_send = len_left;
|
||||
ret = copy_from_user(buf, tmp_p, to_send);
|
||||
/*
|
||||
* There is no reason for this copy to be short. We just
|
||||
* copied them here, and the mm hasn't been exposed to user-
|
||||
@ -986,13 +1026,130 @@ static void audit_log_execve_info(struct audit_buffer *ab,
|
||||
WARN_ON(1);
|
||||
send_sig(SIGKILL, current, 0);
|
||||
}
|
||||
buf[to_send] = '\0';
|
||||
has_cntl = audit_string_contains_control(buf, to_send);
|
||||
if (has_cntl) {
|
||||
/*
|
||||
* hex messages get logged as 2 bytes, so we can only
|
||||
* send half as much in each message
|
||||
*/
|
||||
max_execve_audit_len = MAX_EXECVE_AUDIT_LEN / 2;
|
||||
break;
|
||||
}
|
||||
len_left -= to_send;
|
||||
tmp_p += to_send;
|
||||
} while (len_left > 0);
|
||||
|
||||
audit_log_format(ab, "a%d=", i);
|
||||
audit_log_untrustedstring(ab, buf);
|
||||
audit_log_format(ab, "\n");
|
||||
len_left = len;
|
||||
|
||||
kfree(buf);
|
||||
if (len > max_execve_audit_len)
|
||||
too_long = 1;
|
||||
|
||||
/* rewalk the argument actually logging the message */
|
||||
for (i = 0; len_left > 0; i++) {
|
||||
int room_left;
|
||||
|
||||
if (len_left > max_execve_audit_len)
|
||||
to_send = max_execve_audit_len;
|
||||
else
|
||||
to_send = len_left;
|
||||
|
||||
/* do we have space left to send this argument in this ab? */
|
||||
room_left = MAX_EXECVE_AUDIT_LEN - arg_num_len - *len_sent;
|
||||
if (has_cntl)
|
||||
room_left -= (to_send * 2);
|
||||
else
|
||||
room_left -= to_send;
|
||||
if (room_left < 0) {
|
||||
*len_sent = 0;
|
||||
audit_log_end(*ab);
|
||||
*ab = audit_log_start(context, GFP_KERNEL, AUDIT_EXECVE);
|
||||
if (!*ab)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* first record needs to say how long the original string was
|
||||
* so we can be sure nothing was lost.
|
||||
*/
|
||||
if ((i == 0) && (too_long))
|
||||
audit_log_format(*ab, "a%d_len=%ld ", arg_num,
|
||||
has_cntl ? 2*len : len);
|
||||
|
||||
/*
|
||||
* normally arguments are small enough to fit and we already
|
||||
* filled buf above when we checked for control characters
|
||||
* so don't bother with another copy_from_user
|
||||
*/
|
||||
if (len >= max_execve_audit_len)
|
||||
ret = copy_from_user(buf, p, to_send);
|
||||
else
|
||||
ret = 0;
|
||||
if (ret) {
|
||||
WARN_ON(1);
|
||||
send_sig(SIGKILL, current, 0);
|
||||
}
|
||||
buf[to_send] = '\0';
|
||||
|
||||
/* actually log it */
|
||||
audit_log_format(*ab, "a%d", arg_num);
|
||||
if (too_long)
|
||||
audit_log_format(*ab, "[%d]", i);
|
||||
audit_log_format(*ab, "=");
|
||||
if (has_cntl)
|
||||
audit_log_hex(*ab, buf, to_send);
|
||||
else
|
||||
audit_log_format(*ab, "\"%s\"", buf);
|
||||
audit_log_format(*ab, "\n");
|
||||
|
||||
p += to_send;
|
||||
len_left -= to_send;
|
||||
*len_sent += arg_num_len;
|
||||
if (has_cntl)
|
||||
*len_sent += to_send * 2;
|
||||
else
|
||||
*len_sent += to_send;
|
||||
}
|
||||
/* include the null we didn't log */
|
||||
return len + 1;
|
||||
}
|
||||
|
||||
static void audit_log_execve_info(struct audit_context *context,
|
||||
struct audit_buffer **ab,
|
||||
struct audit_aux_data_execve *axi)
|
||||
{
|
||||
int i;
|
||||
size_t len, len_sent = 0;
|
||||
const char __user *p;
|
||||
char *buf;
|
||||
|
||||
if (axi->mm != current->mm)
|
||||
return; /* execve failed, no additional info */
|
||||
|
||||
p = (const char __user *)axi->mm->arg_start;
|
||||
|
||||
audit_log_format(*ab, "argc=%d ", axi->argc);
|
||||
|
||||
/*
|
||||
* we need some kernel buffer to hold the userspace args. Just
|
||||
* allocate one big one rather than allocating one of the right size
|
||||
* for every single argument inside audit_log_single_execve_arg()
|
||||
* should be <8k allocation so should be pretty safe.
|
||||
*/
|
||||
buf = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
audit_panic("out of memory for argv string\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < axi->argc; i++) {
|
||||
len = audit_log_single_execve_arg(context, ab, i,
|
||||
&len_sent, p, buf);
|
||||
if (len <= 0)
|
||||
break;
|
||||
p += len;
|
||||
}
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
|
||||
@ -1039,7 +1196,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
|
||||
" a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
|
||||
" ppid=%d pid=%d auid=%u uid=%u gid=%u"
|
||||
" euid=%u suid=%u fsuid=%u"
|
||||
" egid=%u sgid=%u fsgid=%u tty=%s",
|
||||
" egid=%u sgid=%u fsgid=%u tty=%s ses=%u",
|
||||
context->argv[0],
|
||||
context->argv[1],
|
||||
context->argv[2],
|
||||
@ -1047,11 +1204,12 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
|
||||
context->name_count,
|
||||
context->ppid,
|
||||
context->pid,
|
||||
context->loginuid,
|
||||
tsk->loginuid,
|
||||
context->uid,
|
||||
context->gid,
|
||||
context->euid, context->suid, context->fsuid,
|
||||
context->egid, context->sgid, context->fsgid, tty);
|
||||
context->egid, context->sgid, context->fsgid, tty,
|
||||
tsk->sessionid);
|
||||
|
||||
mutex_unlock(&tty_mutex);
|
||||
|
||||
@ -1135,7 +1293,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
|
||||
|
||||
case AUDIT_EXECVE: {
|
||||
struct audit_aux_data_execve *axi = (void *)aux;
|
||||
audit_log_execve_info(ab, axi);
|
||||
audit_log_execve_info(context, &ab, axi);
|
||||
break; }
|
||||
|
||||
case AUDIT_SOCKETCALL: {
|
||||
@ -1168,13 +1326,19 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
|
||||
|
||||
for (i = 0; i < axs->pid_count; i++)
|
||||
if (audit_log_pid_context(context, axs->target_pid[i],
|
||||
axs->target_sid[i]))
|
||||
axs->target_auid[i],
|
||||
axs->target_uid[i],
|
||||
axs->target_sessionid[i],
|
||||
axs->target_sid[i],
|
||||
axs->target_comm[i]))
|
||||
call_panic = 1;
|
||||
}
|
||||
|
||||
if (context->target_pid &&
|
||||
audit_log_pid_context(context, context->target_pid,
|
||||
context->target_sid))
|
||||
context->target_auid, context->target_uid,
|
||||
context->target_sessionid,
|
||||
context->target_sid, context->target_comm))
|
||||
call_panic = 1;
|
||||
|
||||
if (context->pwd && context->pwdmnt) {
|
||||
@ -1242,6 +1406,11 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
|
||||
|
||||
audit_log_end(ab);
|
||||
}
|
||||
|
||||
/* Send end of event record to help user space know we are finished */
|
||||
ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
|
||||
if (ab)
|
||||
audit_log_end(ab);
|
||||
if (call_panic)
|
||||
audit_panic("error converting sid to string");
|
||||
}
|
||||
@ -1766,6 +1935,9 @@ void auditsc_get_stamp(struct audit_context *ctx,
|
||||
ctx->auditable = 1;
|
||||
}
|
||||
|
||||
/* global counter which is incremented every time something logs in */
|
||||
static atomic_t session_id = ATOMIC_INIT(0);
|
||||
|
||||
/**
|
||||
* audit_set_loginuid - set a task's audit_context loginuid
|
||||
* @task: task whose audit context is being modified
|
||||
@ -1777,40 +1949,28 @@ void auditsc_get_stamp(struct audit_context *ctx,
|
||||
*/
|
||||
int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
|
||||
{
|
||||
unsigned int sessionid = atomic_inc_return(&session_id);
|
||||
struct audit_context *context = task->audit_context;
|
||||
|
||||
if (context) {
|
||||
/* Only log if audit is enabled */
|
||||
if (context->in_syscall) {
|
||||
struct audit_buffer *ab;
|
||||
if (context && context->in_syscall) {
|
||||
struct audit_buffer *ab;
|
||||
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
|
||||
if (ab) {
|
||||
audit_log_format(ab, "login pid=%d uid=%u "
|
||||
"old auid=%u new auid=%u",
|
||||
task->pid, task->uid,
|
||||
context->loginuid, loginuid);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
|
||||
if (ab) {
|
||||
audit_log_format(ab, "login pid=%d uid=%u "
|
||||
"old auid=%u new auid=%u"
|
||||
" old ses=%u new ses=%u",
|
||||
task->pid, task->uid,
|
||||
task->loginuid, loginuid,
|
||||
task->sessionid, sessionid);
|
||||
audit_log_end(ab);
|
||||
}
|
||||
context->loginuid = loginuid;
|
||||
}
|
||||
task->sessionid = sessionid;
|
||||
task->loginuid = loginuid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* audit_get_loginuid - get the loginuid for an audit_context
|
||||
* @ctx: the audit_context
|
||||
*
|
||||
* Returns the context's loginuid or -1 if @ctx is NULL.
|
||||
*/
|
||||
uid_t audit_get_loginuid(struct audit_context *ctx)
|
||||
{
|
||||
return ctx ? ctx->loginuid : -1;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(audit_get_loginuid);
|
||||
|
||||
/**
|
||||
* __audit_mq_open - record audit data for a POSIX MQ open
|
||||
* @oflag: open flag
|
||||
@ -2070,8 +2230,6 @@ int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode
|
||||
return 0;
|
||||
}
|
||||
|
||||
int audit_argv_kb = 32;
|
||||
|
||||
int audit_bprm(struct linux_binprm *bprm)
|
||||
{
|
||||
struct audit_aux_data_execve *ax;
|
||||
@ -2080,14 +2238,6 @@ int audit_bprm(struct linux_binprm *bprm)
|
||||
if (likely(!audit_enabled || !context || context->dummy))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Even though the stack code doesn't limit the arg+env size any more,
|
||||
* the audit code requires that _all_ arguments be logged in a single
|
||||
* netlink skb. Hence cap it :-(
|
||||
*/
|
||||
if (bprm->argv_len > (audit_argv_kb << 10))
|
||||
return -E2BIG;
|
||||
|
||||
ax = kmalloc(sizeof(*ax), GFP_KERNEL);
|
||||
if (!ax)
|
||||
return -ENOMEM;
|
||||
@ -2193,7 +2343,11 @@ void __audit_ptrace(struct task_struct *t)
|
||||
struct audit_context *context = current->audit_context;
|
||||
|
||||
context->target_pid = t->pid;
|
||||
context->target_auid = audit_get_loginuid(t);
|
||||
context->target_uid = t->uid;
|
||||
context->target_sessionid = audit_get_sessionid(t);
|
||||
selinux_get_task_sid(t, &context->target_sid);
|
||||
memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2216,8 +2370,8 @@ int __audit_signal_info(int sig, struct task_struct *t)
|
||||
if (audit_pid && t->tgid == audit_pid) {
|
||||
if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) {
|
||||
audit_sig_pid = tsk->pid;
|
||||
if (ctx)
|
||||
audit_sig_uid = ctx->loginuid;
|
||||
if (tsk->loginuid != -1)
|
||||
audit_sig_uid = tsk->loginuid;
|
||||
else
|
||||
audit_sig_uid = tsk->uid;
|
||||
selinux_get_task_sid(tsk, &audit_sig_sid);
|
||||
@ -2230,7 +2384,11 @@ int __audit_signal_info(int sig, struct task_struct *t)
|
||||
* in audit_context */
|
||||
if (!ctx->target_pid) {
|
||||
ctx->target_pid = t->tgid;
|
||||
ctx->target_auid = audit_get_loginuid(t);
|
||||
ctx->target_uid = t->uid;
|
||||
ctx->target_sessionid = audit_get_sessionid(t);
|
||||
selinux_get_task_sid(t, &ctx->target_sid);
|
||||
memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2247,7 +2405,11 @@ int __audit_signal_info(int sig, struct task_struct *t)
|
||||
BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);
|
||||
|
||||
axp->target_pid[axp->pid_count] = t->tgid;
|
||||
axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
|
||||
axp->target_uid[axp->pid_count] = t->uid;
|
||||
axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
|
||||
selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]);
|
||||
memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
|
||||
axp->pid_count++;
|
||||
|
||||
return 0;
|
||||
@ -2264,6 +2426,8 @@ void audit_core_dumps(long signr)
|
||||
{
|
||||
struct audit_buffer *ab;
|
||||
u32 sid;
|
||||
uid_t auid = audit_get_loginuid(current);
|
||||
unsigned int sessionid = audit_get_sessionid(current);
|
||||
|
||||
if (!audit_enabled)
|
||||
return;
|
||||
@ -2272,9 +2436,8 @@ void audit_core_dumps(long signr)
|
||||
return;
|
||||
|
||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
|
||||
audit_log_format(ab, "auid=%u uid=%u gid=%u",
|
||||
audit_get_loginuid(current->audit_context),
|
||||
current->uid, current->gid);
|
||||
audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u",
|
||||
auid, current->uid, current->gid, sessionid);
|
||||
selinux_get_task_sid(current, &sid);
|
||||
if (sid) {
|
||||
char *ctx = NULL;
|
||||
|
@ -81,7 +81,6 @@ extern int percpu_pagelist_fraction;
|
||||
extern int compat_log;
|
||||
extern int maps_protect;
|
||||
extern int sysctl_stat_interval;
|
||||
extern int audit_argv_kb;
|
||||
extern int latencytop_enabled;
|
||||
|
||||
/* Constants used for minimum and maximum */
|
||||
@ -390,16 +389,6 @@ static struct ctl_table kern_table[] = {
|
||||
.mode = 0644,
|
||||
.proc_handler = &proc_dointvec,
|
||||
},
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
{
|
||||
.ctl_name = CTL_UNNUMBERED,
|
||||
.procname = "audit_argv_kb",
|
||||
.data = &audit_argv_kb,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = &proc_dointvec,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.ctl_name = KERN_CORE_PATTERN,
|
||||
.procname = "core_pattern",
|
||||
|
@ -2752,12 +2752,15 @@ static void __dev_set_promiscuity(struct net_device *dev, int inc)
|
||||
printk(KERN_INFO "device %s %s promiscuous mode\n",
|
||||
dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
|
||||
"left");
|
||||
audit_log(current->audit_context, GFP_ATOMIC,
|
||||
AUDIT_ANOM_PROMISCUOUS,
|
||||
"dev=%s prom=%d old_prom=%d auid=%u",
|
||||
dev->name, (dev->flags & IFF_PROMISC),
|
||||
(old_flags & IFF_PROMISC),
|
||||
audit_get_loginuid(current->audit_context));
|
||||
if (audit_enabled)
|
||||
audit_log(current->audit_context, GFP_ATOMIC,
|
||||
AUDIT_ANOM_PROMISCUOUS,
|
||||
"dev=%s prom=%d old_prom=%d auid=%u uid=%u gid=%u ses=%u",
|
||||
dev->name, (dev->flags & IFF_PROMISC),
|
||||
(old_flags & IFF_PROMISC),
|
||||
audit_get_loginuid(current),
|
||||
current->uid, current->gid,
|
||||
audit_get_sessionid(current));
|
||||
|
||||
if (dev->change_rx_flags)
|
||||
dev->change_rx_flags(dev, IFF_PROMISC);
|
||||
|
@ -1466,7 +1466,7 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
|
||||
err = xfrm_state_update(x);
|
||||
|
||||
xfrm_audit_state_add(x, err ? 0 : 1,
|
||||
audit_get_loginuid(current->audit_context), 0);
|
||||
audit_get_loginuid(current), 0);
|
||||
|
||||
if (err < 0) {
|
||||
x->km.state = XFRM_STATE_DEAD;
|
||||
@ -1520,7 +1520,7 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
|
||||
km_state_notify(x, &c);
|
||||
out:
|
||||
xfrm_audit_state_delete(x, err ? 0 : 1,
|
||||
audit_get_loginuid(current->audit_context), 0);
|
||||
audit_get_loginuid(current), 0);
|
||||
xfrm_state_put(x);
|
||||
|
||||
return err;
|
||||
@ -1695,7 +1695,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
|
||||
if (proto == 0)
|
||||
return -EINVAL;
|
||||
|
||||
audit_info.loginuid = audit_get_loginuid(current->audit_context);
|
||||
audit_info.loginuid = audit_get_loginuid(current);
|
||||
audit_info.secid = 0;
|
||||
err = xfrm_state_flush(proto, &audit_info);
|
||||
if (err)
|
||||
@ -2273,7 +2273,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
|
||||
hdr->sadb_msg_type != SADB_X_SPDUPDATE);
|
||||
|
||||
xfrm_audit_policy_add(xp, err ? 0 : 1,
|
||||
audit_get_loginuid(current->audit_context), 0);
|
||||
audit_get_loginuid(current), 0);
|
||||
|
||||
if (err)
|
||||
goto out;
|
||||
@ -2356,7 +2356,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
|
||||
return -ENOENT;
|
||||
|
||||
xfrm_audit_policy_delete(xp, err ? 0 : 1,
|
||||
audit_get_loginuid(current->audit_context), 0);
|
||||
audit_get_loginuid(current), 0);
|
||||
|
||||
if (err)
|
||||
goto out;
|
||||
@ -2617,7 +2617,7 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
|
||||
|
||||
if (delete) {
|
||||
xfrm_audit_policy_delete(xp, err ? 0 : 1,
|
||||
audit_get_loginuid(current->audit_context), 0);
|
||||
audit_get_loginuid(current), 0);
|
||||
|
||||
if (err)
|
||||
goto out;
|
||||
@ -2694,7 +2694,7 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg
|
||||
struct xfrm_audit audit_info;
|
||||
int err;
|
||||
|
||||
audit_info.loginuid = audit_get_loginuid(current->audit_context);
|
||||
audit_info.loginuid = audit_get_loginuid(current);
|
||||
audit_info.secid = 0;
|
||||
err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
|
||||
if (err)
|
||||
|
@ -1238,7 +1238,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
||||
|
||||
NETLINK_CB(skb).pid = nlk->pid;
|
||||
NETLINK_CB(skb).dst_group = dst_group;
|
||||
NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context);
|
||||
NETLINK_CB(skb).loginuid = audit_get_loginuid(current);
|
||||
selinux_get_task_sid(current, &(NETLINK_CB(skb).sid));
|
||||
memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
|
||||
|
||||
|
@ -493,7 +493,7 @@ expired:
|
||||
km_state_expired(x, 1, 0);
|
||||
|
||||
xfrm_audit_state_delete(x, err ? 0 : 1,
|
||||
audit_get_loginuid(current->audit_context), 0);
|
||||
audit_get_loginuid(current), 0);
|
||||
|
||||
out:
|
||||
spin_unlock(&x->lock);
|
||||
|
@ -172,9 +172,10 @@ static ssize_t sel_write_enforce(struct file * file, const char __user * buf,
|
||||
if (length)
|
||||
goto out;
|
||||
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
|
||||
"enforcing=%d old_enforcing=%d auid=%u", new_value,
|
||||
selinux_enforcing,
|
||||
audit_get_loginuid(current->audit_context));
|
||||
"enforcing=%d old_enforcing=%d auid=%u ses=%u",
|
||||
new_value, selinux_enforcing,
|
||||
audit_get_loginuid(current),
|
||||
audit_get_sessionid(current));
|
||||
selinux_enforcing = new_value;
|
||||
if (selinux_enforcing)
|
||||
avc_ss_reset(0);
|
||||
@ -243,8 +244,9 @@ static ssize_t sel_write_disable(struct file * file, const char __user * buf,
|
||||
if (length < 0)
|
||||
goto out;
|
||||
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
|
||||
"selinux=0 auid=%u",
|
||||
audit_get_loginuid(current->audit_context));
|
||||
"selinux=0 auid=%u ses=%u",
|
||||
audit_get_loginuid(current),
|
||||
audit_get_sessionid(current));
|
||||
}
|
||||
|
||||
length = count;
|
||||
@ -356,8 +358,9 @@ out1:
|
||||
(security_get_allow_unknown() ? "allow" : "deny")));
|
||||
|
||||
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
|
||||
"policy loaded auid=%u",
|
||||
audit_get_loginuid(current->audit_context));
|
||||
"policy loaded auid=%u ses=%u",
|
||||
audit_get_loginuid(current),
|
||||
audit_get_sessionid(current));
|
||||
out:
|
||||
mutex_unlock(&sel_mutex);
|
||||
vfree(data);
|
||||
|
@ -1905,11 +1905,12 @@ int security_set_bools(int len, int *values)
|
||||
if (!!values[i] != policydb.bool_val_to_struct[i]->state) {
|
||||
audit_log(current->audit_context, GFP_ATOMIC,
|
||||
AUDIT_MAC_CONFIG_CHANGE,
|
||||
"bool=%s val=%d old_val=%d auid=%u",
|
||||
"bool=%s val=%d old_val=%d auid=%u ses=%u",
|
||||
policydb.p_bool_val_to_name[i],
|
||||
!!values[i],
|
||||
policydb.bool_val_to_struct[i]->state,
|
||||
audit_get_loginuid(current->audit_context));
|
||||
audit_get_loginuid(current),
|
||||
audit_get_sessionid(current));
|
||||
}
|
||||
if (values[i]) {
|
||||
policydb.bool_val_to_struct[i]->state = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user