| From a2ac4a0a719cbdb829c31ea666305656d05aa30b Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 13 Dec 2021 15:45:20 -0500 |
| Subject: audit: ensure userspace is penalized the same as the kernel when |
| under pressure |
| |
| From: Paul Moore <paul@paul-moore.com> |
| |
| [ Upstream commit 8f110f530635af44fff1f4ee100ecef0bac62510 ] |
| |
| Due to the audit control mutex necessary for serializing audit |
| userspace messages we haven't been able to block/penalize userspace |
| processes that attempt to send audit records while the system is |
| under audit pressure. The result is that privileged userspace |
| applications have a priority boost with respect to audit as they are |
| not bound by the same audit queue throttling as the other tasks on |
| the system. |
| |
| This patch attempts to restore some balance to the system when under |
| audit pressure by blocking these privileged userspace tasks after |
| they have finished their audit processing, and dropped the audit |
| control mutex, but before they return to userspace. |
| |
| Reported-by: Gaosheng Cui <cuigaosheng1@huawei.com> |
| Tested-by: Gaosheng Cui <cuigaosheng1@huawei.com> |
| Reviewed-by: Richard Guy Briggs <rgb@redhat.com> |
| Signed-off-by: Paul Moore <paul@paul-moore.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| kernel/audit.c | 18 +++++++++++++++++- |
| 1 file changed, 17 insertions(+), 1 deletion(-) |
| |
| diff --git a/kernel/audit.c b/kernel/audit.c |
| index d784000921da3..2a38cbaf3ddb7 100644 |
| --- a/kernel/audit.c |
| +++ b/kernel/audit.c |
| @@ -1540,6 +1540,20 @@ static void audit_receive(struct sk_buff *skb) |
| nlh = nlmsg_next(nlh, &len); |
| } |
| audit_ctl_unlock(); |
| + |
| + /* can't block with the ctrl lock, so penalize the sender now */ |
| + if (audit_backlog_limit && |
| + (skb_queue_len(&audit_queue) > audit_backlog_limit)) { |
| + DECLARE_WAITQUEUE(wait, current); |
| + |
| + /* wake kauditd to try and flush the queue */ |
| + wake_up_interruptible(&kauditd_wait); |
| + |
| + add_wait_queue_exclusive(&audit_backlog_wait, &wait); |
| + set_current_state(TASK_UNINTERRUPTIBLE); |
| + schedule_timeout(audit_backlog_wait_time); |
| + remove_wait_queue(&audit_backlog_wait, &wait); |
| + } |
| } |
| |
| /* Log information about who is connecting to the audit multicast socket */ |
| @@ -1824,7 +1838,9 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, |
| * task_tgid_vnr() since auditd_pid is set in audit_receive_msg() |
| * using a PID anchored in the caller's namespace |
| * 2. generator holding the audit_cmd_mutex - we don't want to block |
| - * while holding the mutex */ |
| + * while holding the mutex, although we do penalize the sender |
| + * later in audit_receive() when it is safe to block |
| + */ |
| if (!(auditd_test_task(current) || audit_ctl_owner_current())) { |
| long stime = audit_backlog_wait_time; |
| |
| -- |
| 2.34.1 |
| |