History

audit: fix potential integer overflow in audit_log_n_hex()

The function calculates new_len as len << 1 for hex encoding. This has two overflow risks: the shift itself can overflow when len is large, and the result can be truncated when assigned to new_len (declared as int) from the size_t calculation. Fix by using check_shl_overflow() to catch shift overflow and changing new_len and loop counter i to size_t to prevent truncation.

Ricardo Robaina committed 4 months ago

Commit 65dfde51 parent c9a71da1 file · +9 −2Browse files

Unified · Split

kernel/audit.c+9−2
@@ -62,6 +62,7 @@ · 61 unmodified lines
6262 #include <net/ip.h>
6363 #include <net/ipv6.h>
6464 #include <linux/sctp.h>
65+#include <linux/overflow.h>
6566
6667 #include "audit.h"
6768
@@ -2080,7 +2081,8 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) · 2012 unmodified lines
20802081 void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,
20812082 size_t len)
20822083 {
2083− int i, avail, new_len;
2084+ int avail;
2085+ size_t i, new_len;
20842086 unsigned char *ptr;
20852087 struct sk_buff *skb;
20862088
@@ -2090,7 +2092,12 @@ void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf, · 3 unmodified lines
20902092 BUG_ON(!ab->skb);
20912093 skb = ab->skb;
20922094 avail = skb_tailroom(skb);
2093− new_len = len<<1;
2095+
2096+ if (check_shl_overflow(len, 1, &new_len)) {
2097+ audit_log_format(ab, "?");
2098+ return;
2099+ }
2100+
20942101 if (new_len >= avail) {
20952102 /* Round the buffer request up to the next multiple */
20962103 new_len = AUDIT_BUFSIZ*(((new_len-avail)/AUDIT_BUFSIZ) + 1);