audit: catch possible NULL buffers
PATCH 1/1 audit: catch possible NULL buffers
It's possible for audit_log_start() to return NULL. Handle it in various callers.
Signed-off-by Kees Cook <[email protected]>
--- kernel/audit.c | 4 ++++ kernel/audit_tree.c | 26 +++++++++++++++++--------- kernel/audit_watch.c | 2 ++ kernel/auditsc.c | 8 ++++++-- 4 files changed, 29 insertions(+), 11 deletions(-)
kernel/audit.c +4 -0
@@ -272,6 +272,8 @@ static int audit_log_config_change(char *function_name, int new, int old,int rc =0 ; 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, old,from_kuid (&init_user_ns, loginuid), sessionid);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); +if (unlikely (!*ab)) +return rc; audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u", task_tgid_vnr(current), from_kuid(&init_user_ns, current_uid()),
kernel/audit_tree.c +17 -9
@@ -449,11 +449,26 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)return 0 ; } +static void audit_log_remove_rule (struct audit_krule *rule) +{ +struct audit_buffer *ab; + + ab =audit_log_start (NULL ,GFP_KERNEL ,AUDIT_CONFIG_CHANGE ); +if (unlikely (!ab)) +return ; +audit_log_format (ab,"op=" ); +audit_log_string (ab,"remove rule" ); +audit_log_format (ab," dir=" ); +audit_log_untrustedstring (ab, rule->tree->pathname); +audit_log_key (ab, rule->filterkey); +audit_log_format (ab," list=%d res=1" , rule->listnr); +audit_log_end (ab); +} +static void kill_rules (struct audit_tree *tree) {struct audit_krule *rule, *next;struct audit_entry *entry; -struct audit_buffer *ab;list_for_each_entry_safe (rule, next, &tree->rules, rlist) { entry = container_of(rule, struct audit_entry, rule);
@@ -461,14 +476,7 @@ static void kill_rules(struct audit_tree *tree)list_del_init (&rule->rlist);if (rule->tree) {/* not a half-baked one */ - ab =audit_log_start (NULL ,GFP_KERNEL ,AUDIT_CONFIG_CHANGE ); -audit_log_format (ab,"op=" ); -audit_log_string (ab,"remove rule" ); -audit_log_format (ab," dir=" ); -audit_log_untrustedstring (ab, rule->tree->pathname); -audit_log_key (ab, rule->filterkey); -audit_log_format (ab," list=%d res=1" , rule->listnr); -audit_log_end (ab); +audit_log_remove_rule (rule); rule->tree =NULL ;list_del_rcu (&entry->list);list_del (&entry->rule.list);
kernel/audit_watch.c +2 -0
@@ -240,6 +240,8 @@ static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watcif (audit_enabled) {struct audit_buffer *ab; ab =audit_log_start (NULL ,GFP_NOFS ,AUDIT_CONFIG_CHANGE ); +if (unlikely (!ab)) +return ;audit_log_format (ab,"auid=%u ses=%u op=" ,from_kuid (&init_user_ns,audit_get_loginuid (current)),audit_get_sessionid (current));
kernel/auditsc.c +6 -2
@@ -1481,14 +1481,14 @@ static void show_special(struct audit_context *context, int *call_panic)audit_log_end (ab); ab =audit_log_start (context,GFP_KERNEL ,AUDIT_IPC_SET_PERM ); +if (unlikely (!ab)) +return ;audit_log_format (ab,"qbytes=%lx ouid=%u ogid=%u mode=%#ho" , context->ipc.qbytes, context->ipc.perm_uid, context->ipc.perm_gid, context->ipc.perm_mode); -if (!ab) -return ; }break ; }case AUDIT_MQ_OPEN : {
@@ -2775,6 +2775,8 @@ void audit_core_dumps(long signr)return ; ab =audit_log_start (NULL ,GFP_KERNEL ,AUDIT_ANOM_ABEND ); +if (unlikely (!ab)) +return ;audit_log_abend (ab,"memory violation" , signr);audit_log_end (ab); }
@@ -2784,6 +2786,8 @@ void __audit_seccomp(unsigned long syscall, long signr, int code)struct audit_buffer *ab; ab =audit_log_start (NULL ,GFP_KERNEL ,AUDIT_ANOM_ABEND ); +if (unlikely (!ab)) +return ;audit_log_abend (ab,"seccomp" , signr);audit_log_format (ab," syscall=%ld" , syscall);audit_log_format (ab," compat=%d" ,is_compat_task ());
Signature · 6 lines
1.7.9.5 -- Kees Cook Chrome OS Security