[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