[apparmor] AppArmor kernel audit locks up system
Paul Moore
paul at paul-moore.com
Sat Oct 7 00:07:23 UTC 2023
On Wed, Sep 27, 2023 at 8:20 AM John Johansen
<john.johansen at canonical.com> wrote:
>
> adding paul and the audit list
>
> On 9/26/23 05:56, Andreas Steinmetz wrote:
> > Hi,
> > it happen from time to time while setting up AppArmor properly that
> > instead of creating an audit message AppArmor locks up the system. In
> > most cases I couldn't even get any information, but this time I got
> > some.
> > I don't yet know if this is the case here but in case of "systemd
> > --user" it was a missing grant of cap_sys_resource that caused the
> > lockup. I don't know the exact capability causing the below problem
> > but granting cap_sys_admin, cap_setuid, cap_setgid and
> > cap_sys_resource prevents the lockup so it is definitely capability
> > related. dmesg output follows. Kernel is 6.5.3, distro is Arch Linux.
> >
>
> just to double check, you are using auditd and have some audit filters
> loaded, the code trace indicates yes.
>
> so at a first pass it appears this come when the task calls prlimit64,
> the capability check is denied and apparmor (or really any lsm).
> generates an audit message. The audit message goes into the audit
> subsystems, and there an exe filter which tries to get the task_exe_file
> resulting in deadlock.
>
> do_prlimit()
> task_lock(tsk->group_leader);
> ...
> if (new_rlim->rlim_max > rlim->rlim_max &&
> !capable(CAP_SYS_RESOURCE))
> ...
> case AUDIT_EXE:
> result = audit_exe_compare(current, e->rule.exe)
> ...
> struct file *get_task_exe_file(struct task_struct *task)
> ...
> task_lock(task);
> ...
> ...
> task_unlock(tsk->group_leader);
>
>
> I am not sure how best to handle this.
My apologies for the delay in responding, unfortunately this email was
a bit buried in my inbox and it took me a while to get to it.
Unfortunately, like John, I'm struggling a bit to see how we might
resolve this. Unfortunately, we don't always know the context in
which audit_filter() is going to be called; in some cases we would
need to ensure the task_lock() was held, in others we may already be
holding it on the current CPU. The only thing I'm reasonably certain
about is that audit_exe_compare() can't safely use
get_task_exe_file().
I imagine we could think about grabbing a reference to the mm_struct
and stashing it in the audit_context so that we could access
mm_struct::exe_file with only a RCU lock, but then we have to manage
the mm_struct reference in audit_context and I worry that will be ugly
and/or expensive (likely "and").
Does anyone else have any bright ideas or crazy thoughts on this?
--
paul-moore.com
More information about the AppArmor
mailing list