[RFC PATCH 3/5] audit: move from a size_t buffer length to an int buffer length

Paul Moore <[email protected]> Fri, 24 Jul 2026 15:56:21 -0400
Newsgroups org.kernel.vger.audit
Message-ID <[email protected]>
Currently the audit buffer is simply a sk_buff which is limited to an
unsigned int in length and we rely on pskb_expand_head() to grow the
buffer which is limited to a signed int for incremental growth.  Since
a 32-bit signed integer length value should be far more than we would
ever need (or want!) for an audit buffer, move all of the buffer length
types from 'size_t' to 'int' to reduce the potential for conversion and
overflow problems.

Signed-off-by: Paul Moore <[email protected]>
---
 include/linux/audit.h | 18 ++++++++----------
 kernel/audit.c        | 37 +++++++++++++++++++++----------------
 2 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index 45abb3722d30..d327113c913d 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -172,16 +172,14 @@ extern __printf(2, 3)
 void audit_log_format(struct audit_buffer *ab, const char *fmt, ...);
 extern void		    audit_log_end(struct audit_buffer *ab);
 extern bool		    audit_string_contains_control(const char *string,
-							  size_t len);
+							  int len);
 extern void		    audit_log_n_hex(struct audit_buffer *ab,
-					  const unsigned char *buf,
-					  size_t len);
+					    const unsigned char *buf, int len);
 extern void		    audit_log_n_string(struct audit_buffer *ab,
-					       const char *buf,
-					       size_t n);
+					       const char *buf, int len);
 extern void		    audit_log_n_untrustedstring(struct audit_buffer *ab,
 							const char *string,
-							size_t n);
+							int len);
 extern void		    audit_log_untrustedstring(struct audit_buffer *ab,
 						      const char *string);
 extern void		    audit_log_d_path(struct audit_buffer *ab,
@@ -240,13 +238,13 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
 static inline void audit_log_end(struct audit_buffer *ab)
 { }
 static inline void audit_log_n_hex(struct audit_buffer *ab,
-				   const unsigned char *buf, size_t len)
+				   const unsigned char *buf, int len)
 { }
-static inline void audit_log_n_string(struct audit_buffer *ab,
-				      const char *buf, size_t n)
+static inline void audit_log_n_string(struct audit_buffer *ab, const char *buf,
+				      int len)
 { }
 static inline void  audit_log_n_untrustedstring(struct audit_buffer *ab,
-						const char *string, size_t n)
+						const char *string, int len)
 { }
 static inline void audit_log_untrustedstring(struct audit_buffer *ab,
 					     const char *string)
diff --git a/kernel/audit.c b/kernel/audit.c
index 520244544907..9e10adf21c76 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2080,14 +2080,13 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
  * ascii hex digits. The new string is placed onto the skb.
  */
 void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,
-		size_t len)
+		     int len)
 {
-	int avail;
-	size_t i, new_len;
+	int avail, new_len, i;
 	unsigned char *ptr;
 	struct sk_buff *skb;
 
-	if (!ab)
+	if (!ab || len <= 0)
 		return;
 
 	BUG_ON(!ab->skb);
@@ -2109,22 +2108,21 @@ void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,
 	for (i = 0; i < len; i++)
 		ptr = hex_byte_pack_upper(ptr, buf[i]);
 	*ptr = 0;
-	skb_put(skb, len << 1); /* new string is twice the old string */
+	skb_put(skb, new_len);
 }
 
 /*
- * Format a string of no more than slen characters into the audit buffer,
+ * Format a string of no more than len characters into the audit buffer,
  * enclosed in quote marks.
  */
 void audit_log_n_string(struct audit_buffer *ab, const char *string,
-			size_t slen)
+			int len)
 {
-	int avail;
-	size_t new_len;
+	int avail, new_len;
 	unsigned char *ptr;
 	struct sk_buff *skb;
 
-	if (!ab)
+	if (!ab || len <= 0)
 		return;
 
 	BUG_ON(!ab->skb);
@@ -2132,7 +2130,7 @@ void audit_log_n_string(struct audit_buffer *ab, const char *string,
 	avail = skb_tailroom(skb);
 
 	/* enclosing quotes + null terminator */
-	if (check_add_overflow(slen, 3, &new_len)) {
+	if (check_add_overflow(len, 3, &new_len)) {
 		audit_log_format(ab, "?");
 		return;
 	}
@@ -2144,11 +2142,11 @@ void audit_log_n_string(struct audit_buffer *ab, const char *string,
 	}
 	ptr = skb_tail_pointer(skb);
 	*ptr++ = '"';
-	memcpy(ptr, string, slen);
-	ptr += slen;
+	memcpy(ptr, string, len);
+	ptr += len;
 	*ptr++ = '"';
 	*ptr = 0;
-	skb_put(skb, slen + 2);	/* don't include null terminator */
+	skb_put(skb, len + 2); /* don't include null terminator */
 }
 
 /**
@@ -2156,9 +2154,13 @@ void audit_log_n_string(struct audit_buffer *ab, const char *string,
  * @string: string to be checked
  * @len: max length of the string to check
  */
-bool audit_string_contains_control(const char *string, size_t len)
+bool audit_string_contains_control(const char *string, int len)
 {
 	const unsigned char *p;
+
+	if (!string || len <= 0)
+		return false;
+
 	for (p = string; p < (const unsigned char *)string + len; p++) {
 		if (*p == '"' || *p < 0x21 || *p > 0x7e)
 			return true;
@@ -2181,8 +2183,11 @@ bool audit_string_contains_control(const char *string, size_t len)
  * or may not be the entire string.
  */
 void audit_log_n_untrustedstring(struct audit_buffer *ab, const char *string,
-				 size_t len)
+				 int len)
 {
+	if (len <= 0)
+		return;
+
 	if (audit_string_contains_control(string, len))
 		audit_log_n_hex(ab, string, len);
 	else
-- 
2.55.0