[PATCH 3/5] NFSv4/pNFS: check the sscanf return in nfs4_decode_mp_ds_addr
Junrui Luo via B4 Relay <[email protected]> Tue, 04 Aug 2026 18:55:03 +0800
| Newsgroups | gmane.linux.kernel.stable,gmane.linux.nfs,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Junrui Luo <[email protected]> nfs4_decode_mp_ds_addr() splits the r_addr opaque of a netaddr4 into an address part and a trailing ".ABC.DEF" port pair using two strrchr() passes. The address part is validated by rpc_pton(), which is passed an explicit length of portstr - buf and never inspects the port octets. The port octets are converted with sscanf(portstr, "%d-%d", &tmp[0], &tmp[1]) and the return value is discarded. tmp[] is uninitialised and nothing constrains the characters after the last two dots, so an r_addr such as "192.168.1.1.x.y" leaves both elements unwritten. The stale stack contents then become the destination port of the data server connection and are rendered into da_remotestr, potentially leaking client stack memory to the metadata server. Fix by requiring both conversions to succeed and rejecting the address otherwise via the existing out_free_da path, matching the port octet validation in rpc_uaddr2sockaddr(). Fixes: 16b374ca439f ("NFSv4.1: pnfs: filelayout: add driver's LAYOUTGET and GETDEVICEINFO infrastructure") Reported-by: Yuhao Jiang <[email protected]> Assisted-by: Claude:claude-opus-5 Cc: [email protected] Signed-off-by: Junrui Luo <[email protected]> --- fs/nfs/pnfs_nfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index 648c95b78eea..63fb3695fdb9 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c @@ -1114,7 +1114,8 @@ nfs4_decode_mp_ds_addr(struct net *net, struct xdr_stream *xdr, gfp_t gfp_flags) } portstr++; - sscanf(portstr, "%d-%d", &tmp[0], &tmp[1]); + if (sscanf(portstr, "%d-%d", &tmp[0], &tmp[1]) != 2) + goto out_free_da; port = htons((tmp[0] << 8) | (tmp[1])); switch (da->da_addr.ss_family) { -- 2.51.2