summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2016-11-29 16:53:26 -0500
committerPaul Moore <paul@paul-moore.com>2016-12-14 13:06:04 -0500
commita09cfa470817ac086cf68418da13a2b91c2744ef (patch)
treea701499dc5828aa54314d843917ea35a60cc436c /kernel
parent6c54e7899693dee3db67ea996e9be0e10f67920f (diff)
audit: don't ever sleep on a command record/message
Sleeping on a command record/message in audit_log_start() could slow something, e.g. auditd, from doing something important, e.g. clean shutdown, which could present problems on a heavily loaded system. This patch allows tasks to bypass any queue restrictions if they are logging a command record/message. Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index b447a6b1fdc8..f20eee0db7e6 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1488,11 +1488,19 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
if (unlikely(!audit_filter(type, AUDIT_FILTER_TYPE)))
return NULL;
- /* don't ever fail/sleep on auditd since we need auditd to drain the
- * queue; also, when we are checking for auditd, compare PIDs using
- * task_tgid_vnr() since auditd_pid is set in audit_receive_msg() using
- * a PID anchored in the caller's namespace */
- if (!(audit_pid && audit_pid == task_tgid_vnr(current))) {
+ /* don't ever fail/sleep on these two conditions:
+ * 1. auditd generated record - since we need auditd to drain the
+ * queue; also, when we are checking for auditd, compare PIDs using
+ * task_tgid_vnr() since auditd_pid is set in audit_receive_msg()
+ * using a PID anchored in the caller's namespace
+ * 2. audit command message - record types 1000 through 1099 inclusive
+ * are command messages/records used to manage the kernel subsystem
+ * and the audit userspace, blocking on these messages could cause
+ * problems under load so don't do it (note: not all of these
+ * command types are valid as record types, but it is quicker to
+ * just check two ints than a series of ints in a if/switch stmt) */
+ if (!((audit_pid && audit_pid == task_tgid_vnr(current)) ||
+ (type >= 1000 && type <= 1099))) {
long sleep_time = audit_backlog_wait_time;
while (audit_backlog_limit &&