UBUNTU: SAUCE: (no-up) 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.

BugLink: http://bugs.launchpad.net/bugs/1323526

Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Signed-off-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
This commit is contained in:
Javier Martinez Canillas
2014-04-25 11:17:10 +02:00
committed by Tim Gardner
parent f5131911fb
commit 9cac646bc9

View File

@@ -486,7 +486,8 @@ static int __file_path_perm(int op, struct aa_label *label,
/* TODO: fix path lookup flags */
flags = PATH_DELEGATE_DELETED | labels_profile(label)->path_flags |
(S_ISDIR(cond.mode) ? PATH_IS_DIR : 0);
__get_buffers(buffer);
get_buffers(buffer);
error = path_name(op, label, &file->f_path, flags, buffer, &name, &cond,
request, true);
if (error) {
@@ -528,7 +529,8 @@ static int __file_path_perm(int op, struct aa_label *label,
/*update_file_cxt(fcxt, label, request);*/
out:
__put_buffers(buffer);
put_buffers(buffer);
return error;
}