On Wed, Jun 24, 2026 at 01:03:44AM -0500, Bryam Vargas via B4 Relay wrote:
> __nd_label_validate() reads several index fields straight from the label
> storage medium.  This series fixes two of them.
> 
> Patch 1 (the original report): the bound multiplies the on-media nslot by the
> label size in 32 bits, which wraps, so a crafted nslot passes the config_size
> check and then drives an out-of-bounds memset in nd_label_data_init().
> Evaluate the product in 64 bits.  Tagged for stable.
> 
> Patch 2: the v1.2 label size is computed as 1 << (7 + labelsize), where
> labelsize is a u8 from the medium; a value of 24 or more makes the shift
> undefined.  Reject labelsize > 1 before the shift.
> 
> v3: Drop the "cap nslot at 64K" patch from v2.  A closer reading -- and the
>     Sashiko AI review -- showed it was wrong on both counts: the allocation in
>     nd_label_data_init() is kvzalloc(config_size), not nslot-derived, so the
>     cap shrinks nothing; and the kernel itself writes nslot =
>     nvdimm_num_label_slots() on init, which exceeds 64K once config_size is
>     above ~8.4MB, so the cap would reject a freshly-formatted large device on
>     the next probe -- a self-brick.  Patch 1's exact 64-bit bound already
>     closes the overflow.  Replaced it with the labelsize-shift fix the same
>     review surfaced.
>     v2: 
> https://lore.kernel.org/all/[email protected]/
>     v1: 
> https://lore.kernel.org/all/[email protected]/
> 
> Verified -m64 and -m32: patch 1's 64-bit bound agrees with an exact
> divide-based check, and an out-of-tree module mirroring nd_label_data_init()
> reproduces the KASAN slab-out-of-bounds write unpatched and is clean when
> patched.
> A boundary truth table confirms the self-brick the v2 cap would have caused
> (kernel nslot > 64K for config_size > ~8.4MB) and that rejecting labelsize > 1
> removes the undefined shift while keeping the two valid sizes.  Harness
> available on request.
> 
> A negative ndctl test (test/label-compat.sh) will follow separately, per
> Alison's suggestion.  With the nslot cap dropped it now covers two vectors
> rather than one: an oversize nslot for patch 1 and an oversize labelsize for
> patch 2.
> 
> Signed-off-by: Bryam Vargas <[email protected]>

Applied to libnvdimm-for-next:
https://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git/


Reply via email to