Skip to content

Commit a2a2a2a

Browse files
pcmooregregkh
authored andcommitted
audit: don't take task_lock() in audit_exe_compare() code path
commit 47846d5 upstream. The get_task_exe_file() function locks the given task with task_lock() which when used inside audit_exe_compare() can cause deadlocks on systems that generate audit records when the task_lock() is held. We resolve this problem with two changes: ignoring those cases where the task being audited is not the current task, and changing our approach to obtaining the executable file struct to not require task_lock(). With the intent of the audit exe filter being to filter on audit events generated by processes started by the specified executable, it makes sense that we would only want to use the exe filter on audit records associated with the currently executing process, e.g. @current. If we are asked to filter records using a non-@current task_struct we can safely ignore the exe filter without negatively impacting the admin's expectations for the exe filter. Knowing that we only have to worry about filtering the currently executing task in audit_exe_compare() we can do away with the task_lock() and call get_mm_exe_file() with @current->mm directly. Cc: <stable@vger.kernel.org> Fixes: 5efc244 ("audit: fix exe_file access in audit_exe_compare") Reported-by: Andreas Steinmetz <anstein99@googlemail.com> Reviewed-by: John Johansen <john.johanse@canonical.com> Reviewed-by: Mateusz Guzik <mjguzik@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 04d2fea commit a2a2a2a

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

kernel/audit_watch.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,11 +527,18 @@ int audit_exe_compare(struct task_struct *tsk, struct audit_fsnotify_mark *mark)
527527
unsigned long ino;
528528
dev_t dev;
529529

530-
exe_file = get_task_exe_file(tsk);
530+
/* only do exe filtering if we are recording @current events/records */
531+
if (tsk != current)
532+
return 0;
533+
534+
if (WARN_ON_ONCE(!current->mm))
535+
return 0;
536+
exe_file = get_mm_exe_file(current->mm);
531537
if (!exe_file)
532538
return 0;
533539
ino = file_inode(exe_file)->i_ino;
534540
dev = file_inode(exe_file)->i_sb->s_dev;
535541
fput(exe_file);
542+
536543
return audit_mark_compare(mark, ino, dev);
537544
}

0 commit comments

Comments
 (0)