From: Ibrahim Zein In bpf_bprintf_prepare(), the bounds check for %pI4 and %pI6 format specifiers uses sizeof_cur_ip (4 for IPv4, 16 for IPv6), which is the raw byte count of the IP address. However, snprintf() returns the length of the formatted string, not the raw bytes. For IPv4 this can be up to 15 characters ("255.255.255.255") and for IPv6 up to 39. tmp_buf is then advanced by (err + 1) using the full string length, which can push tmp_buf past tmp_buf_end. The next iteration's bounds check underflows due to unsigned arithmetic and passes, allowing a write past the end of the per-CPU bin_args buffer. Fix this by checking against the maximum formatted string size instead of the raw byte count: 16 bytes for IPv4 and 40 bytes for IPv6. Signed-off-by: Ibrahim Zein --- --- a/kernel/bpf/helpers.c 2026-03-18 18:04:49.000000000 -0400 +++ b/kernel/bpf/helpers.c 2026-03-18 18:09:39.126681954 -0400 @@ -930,7 +930,7 @@ goto nocopy_fmt; sizeof_cur_ip = (fmt[i] == '4') ? 4 : 16; - if (tmp_buf_end - tmp_buf < sizeof_cur_ip) { + if (tmp_buf_end - tmp_buf < (size_t)((fmt[i] == '4') ? 16 : 40)) { err = -ENOSPC; goto out; } --- a/kernel/bpf/helpers.c 2026-03-18 18:04:49.000000000 -0400 +++ b/kernel/bpf/helpers.c 2026-03-18 18:09:39.126681954 -0400 @@ -930,7 +930,7 @@ goto nocopy_fmt; sizeof_cur_ip = (fmt[i] == '4') ? 4 : 16; - if (tmp_buf_end - tmp_buf < sizeof_cur_ip) { + if (tmp_buf_end - tmp_buf < (size_t)((fmt[i] == '4') ? 16 : 40)) { err = -ENOSPC; goto out; }