blob: f388c5a8821d819db470b7a89b605e49df627035 [file] [log] [blame]
{
"containers": {
"cna": {
"providerMetadata": {
"orgId": "f4215fc3-5b6b-47ff-a258-f7189bd81038"
},
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\nipvs: fix UB due to uninitialized stack access in ip_vs_protocol_init()\n\nUnder certain kernel configurations when building with Clang/LLVM, the\ncompiler does not generate a return or jump as the terminator\ninstruction for ip_vs_protocol_init(), triggering the following objtool\nwarning during build time:\n\n vmlinux.o: warning: objtool: ip_vs_protocol_init() falls through to next function __initstub__kmod_ip_vs_rr__935_123_ip_vs_rr_init6()\n\nAt runtime, this either causes an oops when trying to load the ipvs\nmodule or a boot-time panic if ipvs is built-in. This same issue has\nbeen reported by the Intel kernel test robot previously.\n\nDigging deeper into both LLVM and the kernel code reveals this to be a\nundefined behavior problem. ip_vs_protocol_init() uses a on-stack buffer\nof 64 chars to store the registered protocol names and leaves it\nuninitialized after definition. The function calls strnlen() when\nconcatenating protocol names into the buffer. With CONFIG_FORTIFY_SOURCE\nstrnlen() performs an extra step to check whether the last byte of the\ninput char buffer is a null character (commit 3009f891bb9f (\"fortify:\nAllow strlen() and strnlen() to pass compile-time known lengths\")).\nThis, together with possibly other configurations, cause the following\nIR to be generated:\n\n define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #5 section \".init.text\" align 16 !kcfi_type !29 {\n %1 = alloca [64 x i8], align 16\n ...\n\n 14: ; preds = %11\n %15 = getelementptr inbounds i8, ptr %1, i64 63\n %16 = load i8, ptr %15, align 1\n %17 = tail call i1 @llvm.is.constant.i8(i8 %16)\n %18 = icmp eq i8 %16, 0\n %19 = select i1 %17, i1 %18, i1 false\n br i1 %19, label %20, label %23\n\n 20: ; preds = %14\n %21 = call i64 @strlen(ptr noundef nonnull dereferenceable(1) %1) #23\n ...\n\n 23: ; preds = %14, %11, %20\n %24 = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) %1, i64 noundef 64) #24\n ...\n }\n\nThe above code calculates the address of the last char in the buffer\n(value %15) and then loads from it (value %16). Because the buffer is\nnever initialized, the LLVM GVN pass marks value %16 as undefined:\n\n %13 = getelementptr inbounds i8, ptr %1, i64 63\n br i1 undef, label %14, label %17\n\nThis gives later passes (SCCP, in particular) more DCE opportunities by\npropagating the undef value further, and eventually removes everything\nafter the load on the uninitialized stack location:\n\n define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #0 section \".init.text\" align 16 !kcfi_type !11 {\n %1 = alloca [64 x i8], align 16\n ...\n\n 12: ; preds = %11\n %13 = getelementptr inbounds i8, ptr %1, i64 63\n unreachable\n }\n\nIn this way, the generated native code will just fall through to the\nnext function, as LLVM does not generate any code for the unreachable IR\ninstruction and leaves the function without a terminator.\n\nZero the on-stack buffer to avoid this possible UB."
}
],
"affected": [
{
"product": "Linux",
"vendor": "Linux",
"defaultStatus": "unaffected",
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"programFiles": [
"net/netfilter/ipvs/ip_vs_proto.c"
],
"versions": [
{
"version": "1da177e4c3f41524e886b7f1b8a0c1fc7321cac2",
"lessThan": "31d1ddc1ce8e8d3f101a679243abb42a313ee88a",
"status": "affected",
"versionType": "git"
},
{
"version": "1da177e4c3f41524e886b7f1b8a0c1fc7321cac2",
"lessThan": "0b2cbed82b7c6504a8a0fbd181f92dd56b432c12",
"status": "affected",
"versionType": "git"
},
{
"version": "1da177e4c3f41524e886b7f1b8a0c1fc7321cac2",
"lessThan": "d6e1776f51c95827142f1d7064118e255e2deec1",
"status": "affected",
"versionType": "git"
},
{
"version": "1da177e4c3f41524e886b7f1b8a0c1fc7321cac2",
"lessThan": "664d0feab92495b6a27edc3d1119e232c0fe8b2b",
"status": "affected",
"versionType": "git"
},
{
"version": "1da177e4c3f41524e886b7f1b8a0c1fc7321cac2",
"lessThan": "124834133b32f9386bb2d8581d9ab92f65e951e4",
"status": "affected",
"versionType": "git"
},
{
"version": "1da177e4c3f41524e886b7f1b8a0c1fc7321cac2",
"lessThan": "48130002e64fd191b7d18efeb4d253fcc23e4688",
"status": "affected",
"versionType": "git"
},
{
"version": "1da177e4c3f41524e886b7f1b8a0c1fc7321cac2",
"lessThan": "146b6f1112eb30a19776d6c323c994e9d67790db",
"status": "affected",
"versionType": "git"
}
]
},
{
"product": "Linux",
"vendor": "Linux",
"defaultStatus": "affected",
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"programFiles": [
"net/netfilter/ipvs/ip_vs_proto.c"
],
"versions": [
{
"version": "2.6.12",
"status": "affected"
},
{
"version": "0",
"lessThan": "2.6.12",
"status": "unaffected",
"versionType": "semver"
},
{
"version": "5.4.287",
"lessThanOrEqual": "5.4.*",
"status": "unaffected",
"versionType": "semver"
},
{
"version": "5.10.231",
"lessThanOrEqual": "5.10.*",
"status": "unaffected",
"versionType": "semver"
},
{
"version": "5.15.174",
"lessThanOrEqual": "5.15.*",
"status": "unaffected",
"versionType": "semver"
},
{
"version": "6.1.120",
"lessThanOrEqual": "6.1.*",
"status": "unaffected",
"versionType": "semver"
},
{
"version": "6.6.66",
"lessThanOrEqual": "6.6.*",
"status": "unaffected",
"versionType": "semver"
},
{
"version": "6.12.5",
"lessThanOrEqual": "6.12.*",
"status": "unaffected",
"versionType": "semver"
},
{
"version": "6.13",
"lessThanOrEqual": "*",
"status": "unaffected",
"versionType": "original_commit_for_fix"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"operator": "OR",
"negate": false,
"cpeMatch": [
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionStartIncluding": "2.6.12",
"versionEndExcluding": "5.4.287"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionStartIncluding": "2.6.12",
"versionEndExcluding": "5.10.231"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionStartIncluding": "2.6.12",
"versionEndExcluding": "5.15.174"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionStartIncluding": "2.6.12",
"versionEndExcluding": "6.1.120"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionStartIncluding": "2.6.12",
"versionEndExcluding": "6.6.66"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionStartIncluding": "2.6.12",
"versionEndExcluding": "6.12.5"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionStartIncluding": "2.6.12",
"versionEndExcluding": "6.13"
}
]
}
]
}
],
"references": [
{
"url": "https://git.kernel.org/stable/c/31d1ddc1ce8e8d3f101a679243abb42a313ee88a"
},
{
"url": "https://git.kernel.org/stable/c/0b2cbed82b7c6504a8a0fbd181f92dd56b432c12"
},
{
"url": "https://git.kernel.org/stable/c/d6e1776f51c95827142f1d7064118e255e2deec1"
},
{
"url": "https://git.kernel.org/stable/c/664d0feab92495b6a27edc3d1119e232c0fe8b2b"
},
{
"url": "https://git.kernel.org/stable/c/124834133b32f9386bb2d8581d9ab92f65e951e4"
},
{
"url": "https://git.kernel.org/stable/c/48130002e64fd191b7d18efeb4d253fcc23e4688"
},
{
"url": "https://git.kernel.org/stable/c/146b6f1112eb30a19776d6c323c994e9d67790db"
}
],
"title": "ipvs: fix UB due to uninitialized stack access in ip_vs_protocol_init()",
"x_generator": {
"engine": "bippy-1.2.0"
}
}
},
"cveMetadata": {
"assignerOrgId": "f4215fc3-5b6b-47ff-a258-f7189bd81038",
"cveID": "CVE-2024-53680",
"requesterUserId": "gregkh@kernel.org",
"serial": "1",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.0"
}