mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-16 14:30:06 -04:00
Merge tag 'audit-pr-20260710' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit
Pull audit fixes from Paul Moore: "Two relatively small audit patches to fix potential data races with the main audit backlog queue as well as possible integer overflows when logging data as hex strings" * tag 'audit-pr-20260710' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit: audit: fix potential integer overflow in audit_log_n_hex() audit: Fix data races of skb_queue_len() readers on audit_queue
This commit is contained in:
@@ -62,6 +62,7 @@
|
||||
#include <net/ip.h>
|
||||
#include <net/ipv6.h>
|
||||
#include <linux/sctp.h>
|
||||
#include <linux/overflow.h>
|
||||
|
||||
#include "audit.h"
|
||||
|
||||
@@ -950,7 +951,7 @@ static int kauditd_thread(void *dummy)
|
||||
* do the multicast send and rotate records from the
|
||||
* main queue to the retry/hold queues */
|
||||
wait_event_freezable(kauditd_wait,
|
||||
(skb_queue_len(&audit_queue) ? 1 : 0));
|
||||
(skb_queue_len_lockless(&audit_queue) ? 1 : 0));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1283,7 +1284,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
s.rate_limit = audit_rate_limit;
|
||||
s.backlog_limit = audit_backlog_limit;
|
||||
s.lost = atomic_read(&audit_lost);
|
||||
s.backlog = skb_queue_len(&audit_queue);
|
||||
s.backlog = skb_queue_len_lockless(&audit_queue);
|
||||
s.feature_bitmap = AUDIT_FEATURE_BITMAP_ALL;
|
||||
s.backlog_wait_time = audit_backlog_wait_time;
|
||||
s.backlog_wait_time_actual = atomic_read(&audit_backlog_wait_time_actual);
|
||||
@@ -1627,7 +1628,7 @@ static void audit_receive(struct sk_buff *skb)
|
||||
|
||||
/* can't block with the ctrl lock, so penalize the sender now */
|
||||
if (audit_backlog_limit &&
|
||||
(skb_queue_len(&audit_queue) > audit_backlog_limit)) {
|
||||
(skb_queue_len_lockless(&audit_queue) > audit_backlog_limit)) {
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
|
||||
/* wake kauditd to try and flush the queue */
|
||||
@@ -1933,7 +1934,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
|
||||
long stime = audit_backlog_wait_time;
|
||||
|
||||
while (audit_backlog_limit &&
|
||||
(skb_queue_len(&audit_queue) > audit_backlog_limit)) {
|
||||
(skb_queue_len_lockless(&audit_queue) > audit_backlog_limit)) {
|
||||
/* wake kauditd to try and flush the queue */
|
||||
wake_up_interruptible(&kauditd_wait);
|
||||
|
||||
@@ -1953,7 +1954,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
|
||||
} else {
|
||||
if (audit_rate_check() && printk_ratelimit())
|
||||
pr_warn("audit_backlog=%d > audit_backlog_limit=%d\n",
|
||||
skb_queue_len(&audit_queue),
|
||||
skb_queue_len_lockless(&audit_queue),
|
||||
audit_backlog_limit);
|
||||
audit_log_lost("backlog limit exceeded");
|
||||
return NULL;
|
||||
@@ -2080,7 +2081,8 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
|
||||
void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,
|
||||
size_t len)
|
||||
{
|
||||
int i, avail, new_len;
|
||||
int avail;
|
||||
size_t i, new_len;
|
||||
unsigned char *ptr;
|
||||
struct sk_buff *skb;
|
||||
|
||||
@@ -2090,7 +2092,12 @@ void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,
|
||||
BUG_ON(!ab->skb);
|
||||
skb = ab->skb;
|
||||
avail = skb_tailroom(skb);
|
||||
new_len = len<<1;
|
||||
|
||||
if (check_shl_overflow(len, 1, &new_len)) {
|
||||
audit_log_format(ab, "?");
|
||||
return;
|
||||
}
|
||||
|
||||
if (new_len >= avail) {
|
||||
/* Round the buffer request up to the next multiple */
|
||||
new_len = AUDIT_BUFSIZ*(((new_len-avail)/AUDIT_BUFSIZ) + 1);
|
||||
|
||||
Reference in New Issue
Block a user