Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

apparmor: don't try to replace stale label in ptrace access check

As a comment above begin_current_label_crit_section() explains,
begin_current_label_crit_section() must run in sleepable context because
when label_is_stale() is true, aa_replace_current_label() runs, which uses
prepare_creds(), which can sleep.
Until now, the ptrace access check (which runs with a task lock held)
violated this rule.

Also add a might_sleep() assertion to begin_current_label_crit_section(),
because asserts are less likely to be ignored than comments.

Fixes: b2d09ae449ced ("apparmor: move ptrace checks to using labels")
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>

authored by

Jann Horn and committed by
John Johansen
1f8266ff 5f997580

+4 -2
+2
security/apparmor/include/cred.h
··· 151 151 { 152 152 struct aa_label *label = aa_current_raw_label(); 153 153 154 + might_sleep(); 155 + 154 156 if (label_is_stale(label)) { 155 157 label = aa_get_newest_label(label); 156 158 if (aa_replace_current_label(label) == 0)
+2 -2
security/apparmor/lsm.c
··· 114 114 struct aa_label *tracer, *tracee; 115 115 int error; 116 116 117 - tracer = begin_current_label_crit_section(); 117 + tracer = __begin_current_label_crit_section(); 118 118 tracee = aa_get_task_label(child); 119 119 error = aa_may_ptrace(tracer, tracee, 120 120 (mode & PTRACE_MODE_READ) ? AA_PTRACE_READ 121 121 : AA_PTRACE_TRACE); 122 122 aa_put_label(tracee); 123 - end_current_label_crit_section(tracer); 123 + __end_current_label_crit_section(tracer); 124 124 125 125 return error; 126 126 }