diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-11 13:08:21 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-11 13:08:21 -0800 |
commit | 5d7e52237c59e37a25da854196fc70e9b09704d9 (patch) | |
tree | 93bfd74c924ecabbe0c05afe97db6a55ad576bd4 /kernel/audit.c | |
parent | a135ce4400bb87f229ab33a663987327d9e0b2a0 (diff) | |
parent | ed98ea2128b6fd83bce13716edf8f5fe6c47f574 (diff) |
Merge tag 'audit-pr-20220110' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit
Pull audit updates from Paul Moore:
"Four audit patches for v5.17:
- Harden the code through additional use of the struct_size() macro
and zero-length arrays to flexible-array conversions.
- Ensure that processes which generate userspace audit records are
not exempt from the kernel's audit throttling when the audit queues
are being overrun"
* tag 'audit-pr-20220110' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit:
audit: replace zero-length array with flexible-array member
audit: use struct_size() helper in audit_[send|make]_reply()
audit: ensure userspace is penalized the same as the kernel when under pressure
audit: use struct_size() helper in kmalloc()
Diffstat (limited to 'kernel/audit.c')
-rw-r--r-- | kernel/audit.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/kernel/audit.c b/kernel/audit.c index 79c146184729..e4bbe2c70c26 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1444,7 +1444,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (err) return err; } - sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); + sig_data = kmalloc(struct_size(sig_data, ctx, len), GFP_KERNEL); if (!sig_data) { if (audit_sig_sid) security_release_secctx(ctx, len); @@ -1457,7 +1457,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) security_release_secctx(ctx, len); } audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, - sig_data, sizeof(*sig_data) + len); + sig_data, struct_size(sig_data, ctx, len)); kfree(sig_data); break; case AUDIT_TTY_GET: { @@ -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; |