[PATCH 0/5] NFSv4/flexfiles: harden LAYOUTGET and GETDEVICEINFO decode

Junrui Luo via B4 Relay <[email protected]> Tue, 04 Aug 2026 18:55:00 +0800
Newsgroups gmane.linux.kernel.stable,gmane.linux.nfs,gmane.linux.kernel
Message-ID <[email protected]>
All five patches fix bugs the flexfiles layout driver hits while decoding
a reply body from the metadata server.

Patches 1-3 are on the GETDEVICEINFO side.

Patch 1 bounds the multipath address count. Once the xdr_stream is
exhausted, nfs4_decode_mp_ds_addr() returns NULL without consuming a
byte, so every remaining iteration re-fails at the same offset. A server
advertising 0xffffffff addresses in a body that holds none of them spins
the loop for roughly 2^32 iterations with no rescheduling point.

Patch 2 fixes a leak of the r_netid string. Both loops in
nfs4_ff_alloc_deviceid_node() that drain the local dsaddrs list free
da_remotestr and the da itself but not da_netid.

Patch 3 checks the sscanf return in nfs4_decode_mp_ds_addr(). Nothing
constrains the characters after the last two dots of r_addr, so an
address such as "192.168.1.1.x.y" leaves the uninitialised tmp[] array
unwritten. The stale stack contents become the data server port and are
rendered into da_remotestr, which can leak client stack memory back to
the metadata server.

Patches 4-5 are on the LAYOUTGET side.

Patch 4 bounds the filehandle version count, which sizes a kzalloc_objs()
of struct nfs_fh. sizeof(struct nfs_fh) is 130, so a count of 32264 or
more pushes get_order() past MAX_PAGE_ORDER and trips the page
allocator's WARN_ON_ONCE_GFP().

Patch 5 rejects a stripe_unit above U32_MAX. It is decoded and validated
as a u64, but ff_layout_pg_test() narrows it to u32 and
nfs4_ff_layout_calc_dss_id() passes it to do_div(), which narrows the
divisor itself. A non-zero multiple of 2^32 therefore passes the
existing zero check and reaches both dividers as a zero divisor.

The five are independent of each other and can be applied in any order.

Signed-off-by: Junrui Luo <[email protected]>
---
Junrui Luo (5):
      NFSv4/flexfiles: bound the multipath address count
      NFSv4/flexfiles: fix da_netid leak in nfs4_ff_alloc_deviceid_node()
      NFSv4/pNFS: check the sscanf return in nfs4_decode_mp_ds_addr
      NFSv4/flexfiles: bound the filehandle version count
      NFSv4/flexfiles: bound stripe_unit to 32 bits

 fs/nfs/flexfilelayout/flexfilelayout.c    | 6 ++++--
 fs/nfs/flexfilelayout/flexfilelayout.h    | 9 +++++++++
 fs/nfs/flexfilelayout/flexfilelayoutdev.c | 7 +++++++
 fs/nfs/pnfs_nfs.c                         | 3 ++-
 4 files changed, 22 insertions(+), 3 deletions(-)
---
base-commit: 075b74841bd0065a3bda3440873c747938e69b68
change-id: 20260804-nfs-fixes-b9a4d3f4e507

Best regards,
-- 
Junrui Luo <[email protected]>