From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-qt1-f170.google.com (mail-qt1-f170.google.com [209.85.160.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F043264619 for ; Sat, 23 May 2026 01:40:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.170 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779500442; cv=none; b=V8wdvKWbEhzVKzQHC3q8y9C1tY1iLKBzGilOLMdYBrbdAu787p+X8DR4eCdJGuRDilLEvHqTSxtYccVMw5oV8Uz/BAYKOZHXw1Hkx3wsIfPjHdMcCJCvQABLd0bvNTea/P1SFz2CFl/R2PMhGIyp6ltfVWAbE2yBCNzBpMcHfpA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779500442; c=relaxed/simple; bh=ESbQr55fNsYNb1/DBObk305jbsHQFrKluJIJGXJV+Xk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QxAF4KeGIgeBNi6dji7Md5HQioKMOh7S2IK1HHwP0zsrBbeomUeuGy8W3PGNt2s0lLGYMqAAV/zK5uwowXXUD2jbeDaci+3WE1evUXOsmc7qLgFsQRGsB6YQehPWloa/27ZUHph1kpea6RpBYzbohrXLNVRBYU2iVz5OWThnwWs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=foIDOb2j; arc=none smtp.client-ip=209.85.160.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="foIDOb2j" Received: by mail-qt1-f170.google.com with SMTP id d75a77b69052e-516d65a15f6so16485191cf.1 for ; Fri, 22 May 2026 18:40:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779500440; x=1780105240; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=e4WE67d3yOm7V6IzrZ9cvMKTT03sFO+GY/Hwtj8Zxsg=; b=foIDOb2jfGLOQ3OOoprusSJVKU3peVCY0QB811LXiW9JAqfug+hATMOoloC+S9xFBI Z33I+sDwxEyTcJYIiewRCsCpuPq+NUI6FM5fXZ99LbmlX8jvKdTdv+1SYlXjLQ9eq0/C oHzLj+V756CX21HnLuGzu/hNoTLCgDwgvhqjqgVaqTwI1wJUApyT62CJboA2MbEY9dgB VHzzGMYhz04Kn6q9F7eDkIgtBGAhxZjj9K10ZHETZi7iZ4/LhUOKLD7fNcYscoC28Q5r GfgvB6vY+Cd2gBsYnw80gEt7EkQvV8TTP74z7RnhngC3AvEYflQ623PIo80r6eHy8Hts GCEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779500440; x=1780105240; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=e4WE67d3yOm7V6IzrZ9cvMKTT03sFO+GY/Hwtj8Zxsg=; b=aAvXq0IXlder26CdQngW+BtNVtfAGAVb20u8/KM+n0D6gvEm4wSgn6soh7qHLBckXA 5gpmZ1/ntV0FAoCfLBpUg4TjRjakWyBnnr3dMqlh79oB+rkMU08UakC8KIrNTv5Eu42D ReGXHnrldR2TxSa/a8VvHIaKcFVwjxlMJqmMQ5nBrLWphrlnCzFbrU/eYiwtepqQY62n XI3wudjWfb2EXnaL7J+wJES2i/UZncQlE4n3PGcO3YcMj8+x8t9YXXF0rYYKiJN4iams 8Bpa+8+jqln7Nt5b9/CG1rjBOTtRELrhP2LGMegeTrfOWiy7/l1YH4vAuamw8SIMCpvo i3ag== X-Forwarded-Encrypted: i=1; AFNElJ+PdlBIT8hf6obkN8Lfl2FQ13zMydC5a5UeFp6lYE0ABu0iAd87GH72jdSjdav6UHDOCfE3BX6WD6jI1vE=@vger.kernel.org X-Gm-Message-State: AOJu0Yxaa5HNefIWjasa8cDi+FOCZgRPaLU3Nl914CjqySGEnX9JVFIP ll00NNQ3c0SBEoDX5GXG5hHpFIqtfyPC7ue3wdudHMAEA01/TrfAw3WiP0I9HUWvYRw= X-Gm-Gg: Acq92OHJhcL/OZQV2zKzdQBP8BkN9nq0OPAIhS+491IzHUb2qhg4BWCz+xFlEI8nxqq +iuvG+q7RQBsYXz/PkSyb3H4aOdaJqdML2aoRNUAK/kjAZCK3Xhd04VkLOPDr0a41FSKXJK5I+7 RG4mJ3mi3Fj4IECxSPehDd4iwKnyHN/yK4U1Fb82htLvX545OEs2NjPvi4IY1+knT7CX/VSW0Od U6agpLag6x4fbAUjyGt5K1Gt91CooGi65kF0nMjdD8hkZKvJJQFnqv0o17W0BaQY2zeIG4PKLwv hHyCfq8WvbuZHmO2QW0uc7skHgntAXI22hebrwNaSSm5K6tZjrhDBwCLe3V1ifFT8Y1x0Da3uou jSDfEunEKAPRSLBQI+Gn5t9eK0NDi4mgnzfx/1KNYEBDoYB5MN7mpPbsn14yhrb2uKN/G2sVVAk kvLlAUg3PgHnjvAho61wZHdDgbXTZXlAMUZE60pdYiWDdGnrzOUsd9eVCU+7tGWJM+NPUsfNrWl HMQhxDl35SE8lohqNYZ X-Received: by 2002:a05:622a:5a8a:b0:50f:340f:ff35 with SMTP id d75a77b69052e-516d58a9118mr67895161cf.26.1779500439995; Fri, 22 May 2026 18:40:39 -0700 (PDT) Received: from server0 (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-516d8b247c4sm28559031cf.7.2026.05.22.18.40.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 May 2026 18:40:39 -0700 (PDT) From: Michael Bommarito To: Trond Myklebust , Anna Schumaker Cc: Jeff Layton , Tom Haynes , Peng Tao , Kees Cook , Mike Snitzer , Tigran Mkrtchyan , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH 1/2] NFSv4/pNFS: reject zero-length r_addr in nfs4_decode_mp_ds_addr Date: Fri, 22 May 2026 21:40:32 -0400 Message-ID: <20260523014033.2459677-2-michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260523014033.2459677-1-michael.bommarito@gmail.com> References: <20260523014033.2459677-1-michael.bommarito@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 7bit nfs4_decode_mp_ds_addr() decodes the r_netid and r_addr opaques of a netaddr4 from a GETDEVICEINFO multipath-DS body, then immediately calls strrchr(buf, '.') to locate the port separator. Both decodes use xdr_stream_decode_string_dup(), and the current code checks only "nlen < 0" / "rlen < 0" before dereferencing the returned string. When the on-wire opaque has length zero, xdr_stream_decode_opaque_inline() returns 0 and xdr_stream_decode_string_dup() falls through to its "*str = NULL; return ret" tail, leaving buf NULL with a return value of 0. The "< 0" check does not catch this, and the next line is strrchr(NULL, '.'), a kernel NULL pointer dereference reachable from any pNFS-flexfile client mounted against a malicious or compromised metadata server. Reject the zero-length cases explicitly so the decoder fails with -EBADMSG (treated as a malformed GETDEVICEINFO body) instead of panicking the client. Cc: stable@vger.kernel.org Fixes: 6b7f3cf96364 ("nfs41: pull decode_ds_addr from file layout to generic pnfs") Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Michael Bommarito --- fs/nfs/pnfs_nfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) Reproduced via a malicious NFSv4.1/pNFS server returning a flexfile GETDEVICEINFO body with multipath_count >= 3 and one valid (netid, uaddr) pair. Linux 7.0-rc7 + KASAN, QEMU/KVM. Stock kernel: Oops: general protection fault [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] RIP: 0010:strrchr+0x24/0x80 Call Trace: nfs4_decode_mp_ds_addr+0xca/0x570 nfs4_ff_alloc_deviceid_node+0x357/0x1370 nfs4_find_get_deviceid+0x6b6/0xa90 nfs4_ff_layout_prepare_ds+0x3cf/0xa40 ff_layout_choose_ds_for_read+0x14c/0x350 ff_layout_pg_init_read+0x2a2/0xb90 ... nfs_file_splice_read+0xcf/0x190 do_sendfile+0x8eb/0xdf0 Kernel panic - not syncing: Fatal exception Deterministic for any multipath_count >= 3; multipath_count <= 2 does not crash because the loop ends before consuming the malformed trailing bytes. Patched kernel rejects the same crafted body and a baseline multipath_count = 1 mount + read completes normally. diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index 12632a706da88..0ff43dbcb7cd7 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c @@ -1075,14 +1075,14 @@ nfs4_decode_mp_ds_addr(struct net *net, struct xdr_stream *xdr, gfp_t gfp_flags) /* r_netid */ nlen = xdr_stream_decode_string_dup(xdr, &netid, XDR_MAX_NETOBJ, gfp_flags); - if (unlikely(nlen < 0)) + if (unlikely(nlen <= 0)) goto out_err; /* r_addr: ip/ip6addr with port in dec octets - see RFC 5665 */ /* port is ".ABC.DEF", 8 chars max */ rlen = xdr_stream_decode_string_dup(xdr, &buf, INET6_ADDRSTRLEN + IPV6_SCOPE_ID_LEN + 8, gfp_flags); - if (unlikely(rlen < 0)) + if (unlikely(rlen <= 0)) goto out_free_netid; /* replace port '.' with '-' */ -- 2.53.0