In the Linux kernel, the following vulnerability has been resolved:
bpf: Fail verification for sign-extension of packet data/dataend/datameta
syzbot reported a kernel crash due to commit 1f1e864b6555 ("bpf: Handle sign-extenstin ctx member accesses"). The reason is due to sign-extension of 32-bit load for packet data/dataend/datameta uapi field.
The original code looks like: r2 = (s32 *)(r1 + 76) / load _skbuff->data / r3 = *(u32 *)(r1 + 80) / load _skbuff->dataend */ r0 = r2 r0 += 8 if r3 > r0 goto +1 ... Note that _sk_buff->data load has 32-bit sign extension.
After verification and convertctxaccesses(), the final asm code looks like: r2 = *(u64 *)(r1 +208) r2 = (s32)r2 r3 = *(u64 *)(r1 +80) r0 = r2 r0 += 8 if r3 > r0 goto pc+1 ... Note that 'r2 = (s32)r2' may make the kernel _skbuff->data address invalid which may cause runtime failure.
Currently, in C code, typically we have void *data = (void *)(long)skb->data; void *dataend = (void *)(long)skb->dataend; ... and it will generate r2 = *(u64 *)(r1 +208) r3 = *(u64 *)(r1 +80) r0 = r2 r0 += 8 if r3 > r0 goto pc+1
If we allow sign-extension, void *data = (void *)(long)(int)skb->data; void *dataend = (void *)(long)skb->dataend; ... the generated code looks like r2 = *(u64 *)(r1 +208) r2 <<= 32 r2 s>>= 32 r3 = *(u64 *)(r1 +80) r0 = r2 r0 += 8 if r3 > r0 goto pc+1 and this will cause verification failure since "r2 <<= 32" is not allowed as "r2" is a packet pointer.
To fix this issue for case r2 = (s32 *)(r1 + 76) / load _skbuff->data */ this patch added additional checking in isvalidaccess() callback function for packet data/dataend/datameta access. If those accesses are with sign-extenstion, the verification will fail.
[1] https://lore.kernel.org/bpf/000000000000c90eee061d236d37@google.com/
[
{
"signature_type": "Line",
"deprecated": false,
"signature_version": "v1",
"digest": {
"line_hashes": [
"213201101030800499285910994576244278575",
"247932281150537362413236619127275189094",
"46720367024459716552299877570031308770",
"229367194086341421189029505143159211057",
"105640292645301672533770256024070616327",
"228848391996664071887209317992277485975",
"283249997861829770118240234272410706708",
"56060636403885564783846523497000022510",
"259980376538824189192540891030004207275",
"64537590120050028730725586303692626035",
"63586208439265118773612931665900230912",
"304758175703950562905925028488897410363",
"193945555105656936453847297800470789796",
"92778119124696710105417907511262808396",
"332992987406106909278423365561874187032",
"222954063491716849023886511712578847180",
"9777190538230176372600444704547929550",
"246436347397673852189836145836350256171",
"176925466594854443946178729363979533710",
"301463687943001880685926041809198750827",
"227136953384577869991901824036467324373",
"211800805135359253083073590000814340823",
"9362857776398261297670526572934424935",
"177909802307427018953583576489530858801"
],
"threshold": 0.9
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f1620c93a1ec950d87ef327a565d3907736d3340",
"target": {
"file": "net/core/filter.c"
},
"id": "CVE-2024-47702-00b80249"
},
{
"signature_type": "Line",
"deprecated": false,
"signature_version": "v1",
"digest": {
"line_hashes": [
"261649615371707848851046543448118621199",
"18283973709664150948998653157362869132",
"15204302371400136201516145634900084641",
"190675395833750446812202107786598495297",
"14220072202940059569038907319916004007",
"323658905660255062653096943408261045464",
"298026916085523376473025761354208403708",
"59760665147075405107026517371813194396",
"156168445919062449694253627201559555537",
"20216509034370746452259515364639762343",
"64183175467853019871637498473918557373",
"62583183523511168887323117344145163695",
"244970169182185041338809011241612401659"
],
"threshold": 0.9
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f09757fe97a225ae505886eac572e4cbfba96537",
"target": {
"file": "kernel/bpf/verifier.c"
},
"id": "CVE-2024-47702-0269299b"
},
{
"signature_type": "Function",
"deprecated": false,
"signature_version": "v1",
"digest": {
"length": 773.0,
"function_hash": "50184415726059922676428600837782877085"
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f1620c93a1ec950d87ef327a565d3907736d3340",
"target": {
"file": "net/core/filter.c",
"function": "xdp_is_valid_access"
},
"id": "CVE-2024-47702-1c1963f8"
},
{
"signature_type": "Function",
"deprecated": false,
"signature_version": "v1",
"digest": {
"length": 694.0,
"function_hash": "209019787520341414166566666764928612539"
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f1620c93a1ec950d87ef327a565d3907736d3340",
"target": {
"file": "net/core/filter.c",
"function": "flow_dissector_is_valid_access"
},
"id": "CVE-2024-47702-20031b46"
},
{
"signature_type": "Function",
"deprecated": false,
"signature_version": "v1",
"digest": {
"length": 6388.0,
"function_hash": "219455418688549128354058006064076080552"
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f09757fe97a225ae505886eac572e4cbfba96537",
"target": {
"file": "kernel/bpf/verifier.c",
"function": "check_mem_access"
},
"id": "CVE-2024-47702-29c1a3d7"
},
{
"signature_type": "Function",
"deprecated": false,
"signature_version": "v1",
"digest": {
"length": 836.0,
"function_hash": "106250209827318960054914140850019032054"
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f09757fe97a225ae505886eac572e4cbfba96537",
"target": {
"file": "kernel/bpf/verifier.c",
"function": "check_ctx_access"
},
"id": "CVE-2024-47702-65af47c4"
},
{
"signature_type": "Line",
"deprecated": false,
"signature_version": "v1",
"digest": {
"line_hashes": [
"203021959299064783826346565905698444507",
"27348678084215009324148177881322997092",
"122077231707744836626323556070010677254",
"173884615042533260242151329384490098431"
],
"threshold": 0.9
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f1620c93a1ec950d87ef327a565d3907736d3340",
"target": {
"file": "include/linux/bpf.h"
},
"id": "CVE-2024-47702-80001f4d"
},
{
"signature_type": "Function",
"deprecated": false,
"signature_version": "v1",
"digest": {
"length": 1607.0,
"function_hash": "50074888512922224882139675923834320846"
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f1620c93a1ec950d87ef327a565d3907736d3340",
"target": {
"file": "net/core/filter.c",
"function": "bpf_skb_is_valid_access"
},
"id": "CVE-2024-47702-831c399f"
},
{
"signature_type": "Line",
"deprecated": false,
"signature_version": "v1",
"digest": {
"line_hashes": [
"261649615371707848851046543448118621199",
"18283973709664150948998653157362869132",
"15204302371400136201516145634900084641",
"190675395833750446812202107786598495297",
"14220072202940059569038907319916004007",
"323658905660255062653096943408261045464",
"298026916085523376473025761354208403708",
"59760665147075405107026517371813194396",
"156168445919062449694253627201559555537",
"20216509034370746452259515364639762343",
"64183175467853019871637498473918557373",
"62583183523511168887323117344145163695",
"244970169182185041338809011241612401659"
],
"threshold": 0.9
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f1620c93a1ec950d87ef327a565d3907736d3340",
"target": {
"file": "kernel/bpf/verifier.c"
},
"id": "CVE-2024-47702-8ef6d9c3"
},
{
"signature_type": "Function",
"deprecated": false,
"signature_version": "v1",
"digest": {
"length": 694.0,
"function_hash": "209019787520341414166566666764928612539"
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f09757fe97a225ae505886eac572e4cbfba96537",
"target": {
"file": "net/core/filter.c",
"function": "flow_dissector_is_valid_access"
},
"id": "CVE-2024-47702-a232a9dd"
},
{
"signature_type": "Function",
"deprecated": false,
"signature_version": "v1",
"digest": {
"length": 1607.0,
"function_hash": "50074888512922224882139675923834320846"
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f09757fe97a225ae505886eac572e4cbfba96537",
"target": {
"file": "net/core/filter.c",
"function": "bpf_skb_is_valid_access"
},
"id": "CVE-2024-47702-c52d7b6b"
},
{
"signature_type": "Line",
"deprecated": false,
"signature_version": "v1",
"digest": {
"line_hashes": [
"213201101030800499285910994576244278575",
"247932281150537362413236619127275189094",
"46720367024459716552299877570031308770",
"229367194086341421189029505143159211057",
"105640292645301672533770256024070616327",
"228848391996664071887209317992277485975",
"283249997861829770118240234272410706708",
"56060636403885564783846523497000022510",
"259980376538824189192540891030004207275",
"64537590120050028730725586303692626035",
"63586208439265118773612931665900230912",
"304758175703950562905925028488897410363",
"193945555105656936453847297800470789796",
"92778119124696710105417907511262808396",
"332992987406106909278423365561874187032",
"222954063491716849023886511712578847180",
"9777190538230176372600444704547929550",
"246436347397673852189836145836350256171",
"176925466594854443946178729363979533710",
"301463687943001880685926041809198750827",
"227136953384577869991901824036467324373",
"211800805135359253083073590000814340823",
"9362857776398261297670526572934424935",
"177909802307427018953583576489530858801"
],
"threshold": 0.9
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f09757fe97a225ae505886eac572e4cbfba96537",
"target": {
"file": "net/core/filter.c"
},
"id": "CVE-2024-47702-d6e4081c"
},
{
"signature_type": "Function",
"deprecated": false,
"signature_version": "v1",
"digest": {
"length": 836.0,
"function_hash": "106250209827318960054914140850019032054"
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f1620c93a1ec950d87ef327a565d3907736d3340",
"target": {
"file": "kernel/bpf/verifier.c",
"function": "check_ctx_access"
},
"id": "CVE-2024-47702-dbf4d2cf"
},
{
"signature_type": "Function",
"deprecated": false,
"signature_version": "v1",
"digest": {
"length": 773.0,
"function_hash": "50184415726059922676428600837782877085"
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f09757fe97a225ae505886eac572e4cbfba96537",
"target": {
"file": "net/core/filter.c",
"function": "xdp_is_valid_access"
},
"id": "CVE-2024-47702-e580b9d8"
},
{
"signature_type": "Function",
"deprecated": false,
"signature_version": "v1",
"digest": {
"length": 6388.0,
"function_hash": "219455418688549128354058006064076080552"
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f1620c93a1ec950d87ef327a565d3907736d3340",
"target": {
"file": "kernel/bpf/verifier.c",
"function": "check_mem_access"
},
"id": "CVE-2024-47702-f879ff85"
},
{
"signature_type": "Line",
"deprecated": false,
"signature_version": "v1",
"digest": {
"line_hashes": [
"203021959299064783826346565905698444507",
"27348678084215009324148177881322997092",
"122077231707744836626323556070010677254",
"173884615042533260242151329384490098431"
],
"threshold": 0.9
},
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@f09757fe97a225ae505886eac572e4cbfba96537",
"target": {
"file": "include/linux/bpf.h"
},
"id": "CVE-2024-47702-fdfe2334"
}
]