AppArmor v3α6 triggers a kernel bug on CONFIG_PREEMPT=y

Bug #1312527 reported by David F.
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
AppArmor
Confirmed
High
Unassigned

Bug Description

The AppArmor version currently in the kernel of Trusty Tahr and Unique Unicorn (v3 alpha 6, commit 3cb3b90762b3e21fbe410879cdb644180335abb2) triggers a kernel bug when compiled with CONFIG_PREEMPT=y.

Tags: aa-kernel
Revision history for this message
David F. (malteworld) wrote :
Revision history for this message
David F. (malteworld) wrote :

It appears function __file_path_perm() of source file security/apparmor/file.c performs the unsynchronised operations __get_buffers() and __put_buffers() instead of the synchronised get_buffers() and put_buffers(). The attached patch fixes the issue for me.

description: updated
Revision history for this message
Seth Arnold (seth-arnold) wrote :

Here's the patch headers to prevent them from being lost:

From b9af0b3427359a06d1f8ed0d49b1087d62312429 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <email address hidden>
Date: Fri, 25 Apr 2014 11:17:10 +0200
Subject: [PATCH 1/1] AppArmor: fix bug that constantly spam the console

The apparmor/dbus support needs to allocate buffers in
atomic context (i.e: holding a spinlock) since that is
not possible, it declares a static per cpu array of
buffers and has accessor macros to get and put buffers.

Since the buffer array is a per cpu variable, it can
only be concurrently accessed by the same cpu and this
can only happen if the kernel is preempted.

So the get_buffers() macro disables preemption with
preempt_disable() so the buffer can be accessed safely.

Grabbing a spinlock also makes the kernel to disable
preemption so a raw __get_buffers() function can be used
in this case that does not call preempt_disable().

The raw __get_buffers() function was called from file_path_perm()
since a spinlock was held by the calling revalidate_tty() function.

But this is not the only place where file_path_perm() is called,
it is also called by match_file() which is not in atomic context
and thus doesn't disable preemption before so the __get_buffers()
macro was complaining with a WARN_ON(preempt_count() <= 0) and
spamming the console constantly.

This patch fix the issue by always calling {get,put}_buffers() since
preempt_{disable,enable}() functions are nestable.

Signed-off-by: Javier Martinez Canillas <email address hidden>

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

Was this patch ever applied?

Changed in apparmor:
status: New → Incomplete
Revision history for this message
David F. (malteworld) wrote :

Not as far as I can tell. Neither the object hash nor a "git log --grep" turn up anything.

Changed in apparmor:
status: Incomplete → Confirmed
tags: added: aa-kernel
Changed in apparmor:
importance: Undecided → High
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Patches

Remote bug watches

Bug watches keep track of this bug in other bug trackers.