audit: catch possible NULL audit buffers
It's possible for audit_log_start() to return NULL. Handle it in the various callers. Signed-off-by: Kees Cook <keescook@chromium.org> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Eric Paris <eparis@redhat.com> Cc: Jeff Layton <jlayton@redhat.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Julien Tinnes <jln@google.com> Cc: Will Drewry <wad@google.com> Cc: Steve Grubb <sgrubb@redhat.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
7b9205bd77
commit
0644ec0cc8
|
@ -272,6 +272,8 @@ static int audit_log_config_change(char *function_name, int new, int old,
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
|
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
|
||||||
|
if (unlikely(!ab))
|
||||||
|
return rc;
|
||||||
audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new,
|
audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new,
|
||||||
old, from_kuid(&init_user_ns, loginuid), sessionid);
|
old, from_kuid(&init_user_ns, loginuid), sessionid);
|
||||||
if (sid) {
|
if (sid) {
|
||||||
|
@ -619,6 +621,8 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type,
|
||||||
}
|
}
|
||||||
|
|
||||||
*ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
|
*ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
|
||||||
|
if (unlikely(!*ab))
|
||||||
|
return rc;
|
||||||
audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u",
|
audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u",
|
||||||
task_tgid_vnr(current),
|
task_tgid_vnr(current),
|
||||||
from_kuid(&init_user_ns, current_uid()),
|
from_kuid(&init_user_ns, current_uid()),
|
||||||
|
|
|
@ -449,19 +449,13 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kill_rules(struct audit_tree *tree)
|
static void audit_log_remove_rule(struct audit_krule *rule)
|
||||||
{
|
{
|
||||||
struct audit_krule *rule, *next;
|
|
||||||
struct audit_entry *entry;
|
|
||||||
struct audit_buffer *ab;
|
struct audit_buffer *ab;
|
||||||
|
|
||||||
list_for_each_entry_safe(rule, next, &tree->rules, rlist) {
|
|
||||||
entry = container_of(rule, struct audit_entry, rule);
|
|
||||||
|
|
||||||
list_del_init(&rule->rlist);
|
|
||||||
if (rule->tree) {
|
|
||||||
/* not a half-baked one */
|
|
||||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
|
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
|
||||||
|
if (unlikely(!ab))
|
||||||
|
return;
|
||||||
audit_log_format(ab, "op=");
|
audit_log_format(ab, "op=");
|
||||||
audit_log_string(ab, "remove rule");
|
audit_log_string(ab, "remove rule");
|
||||||
audit_log_format(ab, " dir=");
|
audit_log_format(ab, " dir=");
|
||||||
|
@ -469,6 +463,20 @@ static void kill_rules(struct audit_tree *tree)
|
||||||
audit_log_key(ab, rule->filterkey);
|
audit_log_key(ab, rule->filterkey);
|
||||||
audit_log_format(ab, " list=%d res=1", rule->listnr);
|
audit_log_format(ab, " list=%d res=1", rule->listnr);
|
||||||
audit_log_end(ab);
|
audit_log_end(ab);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kill_rules(struct audit_tree *tree)
|
||||||
|
{
|
||||||
|
struct audit_krule *rule, *next;
|
||||||
|
struct audit_entry *entry;
|
||||||
|
|
||||||
|
list_for_each_entry_safe(rule, next, &tree->rules, rlist) {
|
||||||
|
entry = container_of(rule, struct audit_entry, rule);
|
||||||
|
|
||||||
|
list_del_init(&rule->rlist);
|
||||||
|
if (rule->tree) {
|
||||||
|
/* not a half-baked one */
|
||||||
|
audit_log_remove_rule(rule);
|
||||||
rule->tree = NULL;
|
rule->tree = NULL;
|
||||||
list_del_rcu(&entry->list);
|
list_del_rcu(&entry->list);
|
||||||
list_del(&entry->rule.list);
|
list_del(&entry->rule.list);
|
||||||
|
|
|
@ -240,6 +240,8 @@ static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watc
|
||||||
if (audit_enabled) {
|
if (audit_enabled) {
|
||||||
struct audit_buffer *ab;
|
struct audit_buffer *ab;
|
||||||
ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE);
|
ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE);
|
||||||
|
if (unlikely(!ab))
|
||||||
|
return;
|
||||||
audit_log_format(ab, "auid=%u ses=%u op=",
|
audit_log_format(ab, "auid=%u ses=%u op=",
|
||||||
from_kuid(&init_user_ns, audit_get_loginuid(current)),
|
from_kuid(&init_user_ns, audit_get_loginuid(current)),
|
||||||
audit_get_sessionid(current));
|
audit_get_sessionid(current));
|
||||||
|
|
|
@ -1464,14 +1464,14 @@ static void show_special(struct audit_context *context, int *call_panic)
|
||||||
audit_log_end(ab);
|
audit_log_end(ab);
|
||||||
ab = audit_log_start(context, GFP_KERNEL,
|
ab = audit_log_start(context, GFP_KERNEL,
|
||||||
AUDIT_IPC_SET_PERM);
|
AUDIT_IPC_SET_PERM);
|
||||||
|
if (unlikely(!ab))
|
||||||
|
return;
|
||||||
audit_log_format(ab,
|
audit_log_format(ab,
|
||||||
"qbytes=%lx ouid=%u ogid=%u mode=%#ho",
|
"qbytes=%lx ouid=%u ogid=%u mode=%#ho",
|
||||||
context->ipc.qbytes,
|
context->ipc.qbytes,
|
||||||
context->ipc.perm_uid,
|
context->ipc.perm_uid,
|
||||||
context->ipc.perm_gid,
|
context->ipc.perm_gid,
|
||||||
context->ipc.perm_mode);
|
context->ipc.perm_mode);
|
||||||
if (!ab)
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
break; }
|
break; }
|
||||||
case AUDIT_MQ_OPEN: {
|
case AUDIT_MQ_OPEN: {
|
||||||
|
@ -2720,6 +2720,8 @@ void audit_core_dumps(long signr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
|
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
|
||||||
|
if (unlikely(!ab))
|
||||||
|
return;
|
||||||
audit_log_abend(ab, "memory violation", signr);
|
audit_log_abend(ab, "memory violation", signr);
|
||||||
audit_log_end(ab);
|
audit_log_end(ab);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue