Linux: bpf, sockmap: Reject max_entries > INT_MAX in sock_map_alloc
What fixes it
- 909f761868fda329dc69130ef9eb5b5795bcdf00LinuxCVE List
- 814a81c842bd88f6bd8a4ce550d560df071a5d03LinuxCVE List
A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.
Description
In the Linux kernel, the following vulnerability has been resolved:
bpf, sockmap: Reject max_entries > INT_MAX in sock_map_alloc
sock_map_alloc() only rejects max_entries == 0 and otherwise allows any u32 value. sock_map_free() then walks the sks[] array with a signed int iterator:
int i; for (i = 0; i < stab->map.max_entries; i++) struct sock **psk = &stab->sks[i];
When a SOCKMAP is created with max_entries = 0xffffffff (UINT_MAX), the allocation of 32 GiB can succeed on large-memory hosts. During free the counter reaches 0x80000000, wraps to INT_MIN, is sign-extended by movslq and turned into a ~16 GiB negative offset from stab->sks, pointing far below the allocation.
The faulting access is an xchg() write in sock_map_free(). Without KASAN, the same out-of-bounds write can fault on an unmapped vmalloc page or corrupt an unrelated allocation if that vmalloc address is populated. On a KASAN kernel with CONFIG_KASAN_VMALLOC=y, the shadow check for that address hits an unmapped shadow page and oopses first:
BUG: unable to handle page fault for address: fffff521b59c5a00 RIP: 0010:kasan_check_range+0x107/0x190 Call Trace: sock_map_free+0x93/0x190 map_create+0x68d/0xb30 __sys_bpf+0x21e/0x2e70
Vmcore confirmed stab->map.max_entries == 0xffffffff, stab->sks == 0xffffc911ace2d000, and the faulting address sks + (s64)INT_MIN * 8 exactly at 0xffffc90dace2d000. The same buggy path is reached on the normal close()/bpf_map_free_deferred() path whenever such a map is destroyed.
sock_map_alloc() used to bound its allocation size through bpf_map_charge_init(), but the bound was dropped when rlimit-based memory accounting was removed. Reject max_entries > INT_MAX at creation time so the signed iterator in sock_map_free() never sees a value that would overflow.
Triggered by syzkaller and reproduced on both a 6.6-based KASAN kernel and the upstream v7.3-rc2 kernel.
Text from CVE List
Affected versions 16
- Linuxaffected: 0d2c4f9640501ff57ba0be1f5644a02c29a02fa1 before f4a73f49e256bd835368504462be3b57b03febffCVE List
- Linuxaffected: 0d2c4f9640501ff57ba0be1f5644a02c29a02fa1 before c56191af3a578b9cc265fa3bd5fc0752c59c1781CVE List
- Linuxaffected: 0d2c4f9640501ff57ba0be1f5644a02c29a02fa1 before 909f761868fda329dc69130ef9eb5b5795bcdf00CVE List
- Linuxaffected: 0d2c4f9640501ff57ba0be1f5644a02c29a02fa1 before cc70972ddbf0e3398f2f32624d31db78594d50d8CVE List
- Linuxaffected: 0d2c4f9640501ff57ba0be1f5644a02c29a02fa1 before cea597519b9ca6d691c98d92460ead8ece2a07afCVE List
- Linuxaffected: 0d2c4f9640501ff57ba0be1f5644a02c29a02fa1 before ba7d627dbc67d62df2fa66d7b41e743c3ace0ec8CVE List
- Linuxaffected: 0d2c4f9640501ff57ba0be1f5644a02c29a02fa1 before 814a81c842bd88f6bd8a4ce550d560df071a5d03CVE List
- Linuxaffected: 5.11CVE List
- Linuxunaffected: all versions before 5.11CVE List
- Linuxunaffected: 5.15.222 through 5.15.*CVE List
- Linuxunaffected: 6.1.189 through 6.1.*CVE List
- Linuxunaffected: 6.6.158 through 6.6.*CVE List
- Linuxunaffected: 6.12.112 through 6.12.*CVE List
- Linuxunaffected: 6.18.55 through 6.18.*CVE List
- Linuxunaffected: 7.2.9 through 7.2.*CVE List
- Linuxunaffected: 7.3CVE List
References 7
- git.kernel.org/stable/c/f4a73f49e256bd835368504462be3b57b03febffReferencevia CVE List
- git.kernel.org/stable/c/c56191af3a578b9cc265fa3bd5fc0752c59c1781Referencevia CVE List
- git.kernel.org/stable/c/909f761868fda329dc69130ef9eb5b5795bcdf00Referencevia CVE List
- git.kernel.org/stable/c/cc70972ddbf0e3398f2f32624d31db78594d50d8Referencevia CVE List
- git.kernel.org/stable/c/cea597519b9ca6d691c98d92460ead8ece2a07afReferencevia CVE List
- git.kernel.org/stable/c/ba7d627dbc67d62df2fa66d7b41e743c3ace0ec8Referencevia CVE List
- git.kernel.org/stable/c/814a81c842bd88f6bd8a4ce550d560df071a5d03Referencevia CVE List