CVE-2024-53680
Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
11/01/2025
Last modified:
03/11/2025
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
ipvs: fix UB due to uninitialized stack access in ip_vs_protocol_init()<br />
<br />
Under certain kernel configurations when building with Clang/LLVM, the<br />
compiler does not generate a return or jump as the terminator<br />
instruction for ip_vs_protocol_init(), triggering the following objtool<br />
warning during build time:<br />
<br />
vmlinux.o: warning: objtool: ip_vs_protocol_init() falls through to next function __initstub__kmod_ip_vs_rr__935_123_ip_vs_rr_init6()<br />
<br />
At runtime, this either causes an oops when trying to load the ipvs<br />
module or a boot-time panic if ipvs is built-in. This same issue has<br />
been reported by the Intel kernel test robot previously.<br />
<br />
Digging deeper into both LLVM and the kernel code reveals this to be a<br />
undefined behavior problem. ip_vs_protocol_init() uses a on-stack buffer<br />
of 64 chars to store the registered protocol names and leaves it<br />
uninitialized after definition. The function calls strnlen() when<br />
concatenating protocol names into the buffer. With CONFIG_FORTIFY_SOURCE<br />
strnlen() performs an extra step to check whether the last byte of the<br />
input char buffer is a null character (commit 3009f891bb9f ("fortify:<br />
Allow strlen() and strnlen() to pass compile-time known lengths")).<br />
This, together with possibly other configurations, cause the following<br />
IR to be generated:<br />
<br />
define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #5 section ".init.text" align 16 !kcfi_type !29 {<br />
%1 = alloca [64 x i8], align 16<br />
...<br />
<br />
14: ; preds = %11<br />
%15 = getelementptr inbounds i8, ptr %1, i64 63<br />
%16 = load i8, ptr %15, align 1<br />
%17 = tail call i1 @llvm.is.constant.i8(i8 %16)<br />
%18 = icmp eq i8 %16, 0<br />
%19 = select i1 %17, i1 %18, i1 false<br />
br i1 %19, label %20, label %23<br />
<br />
20: ; preds = %14<br />
%21 = call i64 @strlen(ptr noundef nonnull dereferenceable(1) %1) #23<br />
...<br />
<br />
23: ; preds = %14, %11, %20<br />
%24 = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) %1, i64 noundef 64) #24<br />
...<br />
}<br />
<br />
The above code calculates the address of the last char in the buffer<br />
(value %15) and then loads from it (value %16). Because the buffer is<br />
never initialized, the LLVM GVN pass marks value %16 as undefined:<br />
<br />
%13 = getelementptr inbounds i8, ptr %1, i64 63<br />
br i1 undef, label %14, label %17<br />
<br />
This gives later passes (SCCP, in particular) more DCE opportunities by<br />
propagating the undef value further, and eventually removes everything<br />
after the load on the uninitialized stack location:<br />
<br />
define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #0 section ".init.text" align 16 !kcfi_type !11 {<br />
%1 = alloca [64 x i8], align 16<br />
...<br />
<br />
12: ; preds = %11<br />
%13 = getelementptr inbounds i8, ptr %1, i64 63<br />
unreachable<br />
}<br />
<br />
In this way, the generated native code will just fall through to the<br />
next function, as LLVM does not generate any code for the unreachable IR<br />
instruction and leaves the function without a terminator.<br />
<br />
Zero the on-stack buffer to avoid this possible UB.
Impact
Base Score 3.x
5.50
Severity 3.x
MEDIUM
Vulnerable products and versions
| CPE | From | Up to |
|---|---|---|
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 2.6.13 (including) | 5.4.287 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.5 (including) | 5.10.231 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.11 (including) | 5.15.174 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.16 (including) | 6.1.120 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.2 (including) | 6.6.66 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.7 (including) | 6.12.5 (excluding) |
| cpe:2.3:o:linux:linux_kernel:2.6.12:-:*:*:*:*:*:* | ||
| cpe:2.3:o:linux:linux_kernel:2.6.12:rc2:*:*:*:*:*:* | ||
| cpe:2.3:o:linux:linux_kernel:2.6.12:rc3:*:*:*:*:*:* | ||
| cpe:2.3:o:linux:linux_kernel:2.6.12:rc4:*:*:*:*:*:* | ||
| cpe:2.3:o:linux:linux_kernel:2.6.12:rc5:*:*:*:*:*:* | ||
| cpe:2.3:o:linux:linux_kernel:6.13:rc1:*:*:*:*:*:* |
To consult the complete list of CPE names with products and versions, see this page
References to Advisories, Solutions, and Tools
- https://git.kernel.org/stable/c/0b2cbed82b7c6504a8a0fbd181f92dd56b432c12
- https://git.kernel.org/stable/c/124834133b32f9386bb2d8581d9ab92f65e951e4
- https://git.kernel.org/stable/c/146b6f1112eb30a19776d6c323c994e9d67790db
- https://git.kernel.org/stable/c/31d1ddc1ce8e8d3f101a679243abb42a313ee88a
- https://git.kernel.org/stable/c/48130002e64fd191b7d18efeb4d253fcc23e4688
- https://git.kernel.org/stable/c/664d0feab92495b6a27edc3d1119e232c0fe8b2b
- https://git.kernel.org/stable/c/d6e1776f51c95827142f1d7064118e255e2deec1
- https://lists.debian.org/debian-lts-announce/2025/03/msg00001.html
- https://lists.debian.org/debian-lts-announce/2025/03/msg00002.html



