libnvme: nbft: reject heap objects too small for the structures they decode - #3913
Merged
Merged
Conversation
igaw
force-pushed
the
fix-nbft-heap-obj-length
branch
2 times, most recently
from
August 26, 2026 13:23
59ba026 to
b86f217
Compare
…decode The SSNS extended info descriptor already discloses and validates its length, but the HFI trinfo object is still decoded into a fixed-size struct nbft_hfi_info_tcp without any minimum-length check, and the SSNS transport address heap object is fed unguarded to format_ip_addr(), which always reads 16 bytes regardless of the declared object length. The newer HFI ext-info object has the same under-declared length trap. Give __get_heap_obj() a min_len parameter rejecting non-string objects shorter than the structure the caller dereferences. The minimum is derived from the output pointer type via _Generic in the get_heap_obj() macro (strings and byte arrays keep min 0); call sites drop their (char **) casts. _Generic is a C11 feature thus update the project settings. C11 is 15 years old, so should be fair to ask for such a compiler. Signed-off-by: Prabhakar Pujeri <prabhakar.pujeri@dell.com> [wagi: added C11 dependency] Signed-off-by: Daniel Wagner <wagi@kernel.org>
igaw
force-pushed
the
fix-nbft-heap-obj-length
branch
from
August 26, 2026 13:28
b86f217 to
b80d8fa
Compare
prabhakarpujeri
force-pushed
the
fix-nbft-heap-obj-length
branch
from
August 26, 2026 13:34
b80d8fa to
b0241af
Compare
Collaborator
|
droped the reference to libnvme 1. Didn't know about |
Collaborator
|
I am taking care of the patch, please don't update it. I don't have a problem to update the min requirement for the compiler. As far I can tell all major distro ship compilers which are able to deal with C11. And if not, it's about time to update. |
igaw
force-pushed
the
fix-nbft-heap-obj-length
branch
from
August 26, 2026 13:37
b0241af to
b80d8fa
Compare
Collaborator
|
Thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Port of linux-nvme/libnvme#1125 to libnvme3.
The SSNS extended-info descriptor now validates its disclosed length (good), but three heap-object reads can still overrun:
read_hfi_info_tcp()dereferences the trinfo heap object as a fullstruct nbft_hfi_info_tcp(flags, mac, addresses, …) without verifying the object's declared length covers even the fields read unconditionally.subsys_traddr_objis handed toformat_ip_addr(), which alwaysmemcpy()s a 16-bytestruct in6_addrregardless of the declared object length.trinfo_version >= 2ext-info object is dereferenced/read viaread_hfi_info_dhcp()with the same under-declared trap.get_heap_obj()validates only heap containment (in_heap) plus string NUL-termination; a file can point a struct-typed heap object atheap_end - 2and later reads walk past the heap.Fix
__get_heap_obj()gains amin_lenparameter rejecting non-string heap objects shorter than the structure the caller dereferences.get_heap_obj()derives the minimum from the output pointer type via_Generic(strings, byte arrays, and the SSNS ext-info reader keep min 0 — the latter does its own spec-length check); call sites lose their(char **)casts.>= sizeof(struct in6_addr)check for the SSNS transport address beforeformat_ip_addr().Testing