Commit 5d7e5223 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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()
parents a135ce44 ed98ea21
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -514,7 +514,7 @@ struct audit_rule_data {
	__u32		values[AUDIT_MAX_FIELDS];
	__u32		fieldflags[AUDIT_MAX_FIELDS];
	__u32		buflen;	/* total length of string fields */
	char		buf[0];	/* string fields buffer */
	char		buf[];	/* string fields buffer */
};

#endif /* _UAPI_LINUX_AUDIT_H_ */
+19 −3
Original line number Diff line number Diff line
@@ -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;

+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ static struct audit_tree *alloc_tree(const char *s)
{
	struct audit_tree *tree;

	tree = kmalloc(sizeof(struct audit_tree) + strlen(s) + 1, GFP_KERNEL);
	tree = kmalloc(struct_size(tree, pathname, strlen(s) + 1), GFP_KERNEL);
	if (tree) {
		refcount_set(&tree->count, 1);
		tree->goner = 0;
+2 −2
Original line number Diff line number Diff line
@@ -637,7 +637,7 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
	void *bufp;
	int i;

	data = kmalloc(sizeof(*data) + krule->buflen, GFP_KERNEL);
	data = kmalloc(struct_size(data, buf, krule->buflen), GFP_KERNEL);
	if (unlikely(!data))
		return NULL;
	memset(data, 0, sizeof(*data));
@@ -1092,7 +1092,7 @@ static void audit_list_rules(int seq, struct sk_buff_head *q)
				break;
			skb = audit_make_reply(seq, AUDIT_LIST_RULES, 0, 1,
					       data,
					       sizeof(*data) + data->buflen);
					       struct_size(data, buf, data->buflen));
			if (skb)
				skb_queue_tail(q, skb);
			kfree(data);