summaryrefslogtreecommitdiffstats
path: root/kernel/audit.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/audit.c')
-rw-r--r--kernel/audit.c101
1 files changed, 94 insertions, 7 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 2924251a6547..f93c2713017d 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -468,6 +468,21 @@ int audit_send_list(void *_dest)
return 0;
}
+#ifdef CONFIG_AUDIT_TREE
+static int prune_tree_thread(void *unused)
+{
+ mutex_lock(&audit_cmd_mutex);
+ audit_prune_trees();
+ mutex_unlock(&audit_cmd_mutex);
+ return 0;
+}
+
+void audit_schedule_prune(void)
+{
+ kthread_run(prune_tree_thread, NULL, "audit_prune_tree");
+}
+#endif
+
struct sk_buff *audit_make_reply(int pid, int seq, int type, int done,
int multi, void *payload, int size)
{
@@ -540,6 +555,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
case AUDIT_SIGNAL_INFO:
case AUDIT_TTY_GET:
case AUDIT_TTY_SET:
+ case AUDIT_TRIM:
+ case AUDIT_MAKE_EQUIV:
if (security_netlink_recv(skb, CAP_AUDIT_CONTROL))
err = -EPERM;
break;
@@ -664,11 +681,11 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (sid) {
if (selinux_sid_to_string(
sid, &ctx, &len)) {
- audit_log_format(ab,
+ audit_log_format(ab,
" ssid=%u", sid);
/* Maybe call audit_panic? */
} else
- audit_log_format(ab,
+ audit_log_format(ab,
" subj=%s", ctx);
kfree(ctx);
}
@@ -756,6 +773,76 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
uid, seq, data, nlmsg_len(nlh),
loginuid, sid);
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_format(ab, " op=trim res=1");
+ audit_log_end(ab);
+ break;
+ case AUDIT_MAKE_EQUIV: {
+ void *bufp = data;
+ u32 sizes[2];
+ size_t len = nlmsg_len(nlh);
+ char *old, *new;
+
+ err = -EINVAL;
+ if (len < 2 * sizeof(u32))
+ break;
+ memcpy(sizes, bufp, 2 * sizeof(u32));
+ bufp += 2 * sizeof(u32);
+ len -= 2 * sizeof(u32);
+ old = audit_unpack_string(&bufp, &len, sizes[0]);
+ if (IS_ERR(old)) {
+ err = PTR_ERR(old);
+ break;
+ }
+ new = audit_unpack_string(&bufp, &len, sizes[1]);
+ if (IS_ERR(new)) {
+ err = PTR_ERR(new);
+ kfree(old);
+ break;
+ }
+ /* 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_format(ab, " op=make_equiv old=");
+ audit_log_untrustedstring(ab, old);
+ audit_log_format(ab, " new=");
+ audit_log_untrustedstring(ab, new);
+ audit_log_format(ab, " res=%d", !err);
+ audit_log_end(ab);
+ kfree(old);
+ kfree(new);
+ break;
+ }
case AUDIT_SIGNAL_INFO:
err = selinux_sid_to_string(audit_sig_sid, &ctx, &len);
if (err)
@@ -769,7 +856,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
sig_data->pid = audit_sig_pid;
memcpy(sig_data->ctx, ctx, len);
kfree(ctx);
- audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO,
+ audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO,
0, 0, sig_data, sizeof(*sig_data) + len);
kfree(sig_data);
break;
@@ -1005,7 +1092,7 @@ unsigned int audit_serial(void)
return ret;
}
-static inline void audit_get_stamp(struct audit_context *ctx,
+static inline void audit_get_stamp(struct audit_context *ctx,
struct timespec *t, unsigned int *serial)
{
if (ctx)
@@ -1056,7 +1143,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
if (gfp_mask & __GFP_WAIT)
reserve = 0;
else
- reserve = 5; /* Allow atomic callers to go up to five
+ reserve = 5; /* Allow atomic callers to go up to five
entries over the normal backlog limit */
while (audit_backlog_limit
@@ -1319,7 +1406,7 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
/* FIXME: can we save some information here? */
audit_log_format(ab, "<too long>");
- } else
+ } else
audit_log_untrustedstring(ab, p);
kfree(path);
}
@@ -1365,7 +1452,7 @@ void audit_log_end(struct audit_buffer *ab)
* audit_log_vformat, and audit_log_end. It may be called
* in any context.
*/
-void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
+void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
const char *fmt, ...)
{
struct audit_buffer *ab;