From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) (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 944291A3166 for ; Sun, 12 Apr 2026 13:01:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.182 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775998906; cv=none; b=ooyo29zLLwTwpfG+80hsLf1ye54vxB68ev8wwSOZH6da5OusHzHSTn/qs8Z6yGjqLvcZ2QcOzsKkwIKnHCfNr19ujepaQEhZnCy3G6Wp9PpgrFYolSDOFVIUwLTEUg958k8vWpJ55fMoINMtYXsbvCiWXvAgl9qDZQ6crgKj0so= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775998906; c=relaxed/simple; bh=cleIdl+qTbfwmZynQCgtqwVhKgKS41FqDMKHUuTqD50=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=ABqverKj0x2TPEdFBEe9AkPfK3WQdugg75pj1l+1WusvMmxZ2pAd7Jo+N1hy8ZsWk8x9YDJrRaFrSWttsBSd4Ygsdk/NMtckq/TKffPOQ9eyBXh4Apcx2o+GeG05EvFB+ZpmC9q4niqBGTqYJVunlhslhW3lnImd2Ge12a6jobo= 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=UW8EPwP4; arc=none smtp.client-ip=209.85.214.182 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="UW8EPwP4" Received: by mail-pl1-f182.google.com with SMTP id d9443c01a7336-2ad9516a653so16219535ad.0 for ; Sun, 12 Apr 2026 06:01:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775998905; x=1776603705; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=tEuqZf5lySQourIJHgDHr+YWzyz6c3oHQnabpz7xMSk=; b=UW8EPwP4XkrsRi5OPtFJ6I2nKGspJIsaeQg+W9t9/Phv3S7sw0fZ/+sNSp+VN/55vX +hcFcU6ew1+xjs4uY5Kun89B4+rAC65OQIf38LXchR1RFejIS39m+5OtFtx54I7x/4i3 wyExoWzVcq8W+4n5+3j/4ow645GBVWv11zgOtCCIr0w7034WARtRucVKk/Jr9HQQrIVs 87uHP2ocxGicHGCFi5hksXzUiTQbU/73aawnTg8l8xu0E5rXWAAeeOo80wmxhl8cKRAG btOTYi0ameQzH9KyRMKeDWeLDHUTOBwryA+yeA0E/s4cTuKHO5mnUaJfoSir2E7ik+Gq CtuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775998905; x=1776603705; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=tEuqZf5lySQourIJHgDHr+YWzyz6c3oHQnabpz7xMSk=; b=ToZtVS3iesDhfD3vlNSHGTKXu0rRsJ0DYPid3Ms20zul5ABumwAamtFrPjEgkdma5O yIM9VY/7YwJX9LgZwdRTRWMGtmFqzk/9o5Um7ayB55hXTsrR/rzZMRSjYt0tgbcYt4Bk p9VKPMuNlJKFyVzIGoKCvUJlCsTFiRPXkMHrf3yWV840pZmrH44HziFZBI7BfQOIvt5p Sj3YeHuKe27fI78Bq2fRbLM6UI9ce0qwS8wOJAVp4hl0mfwyBdOB2vwkipCJgVuBs3sD q6OBztHb+5RoPM75WeUqLVMS1iSTAM8n8GC940iSDoXYP8Xq4/qgud6DKMYy80uohMrS v7rQ== X-Forwarded-Encrypted: i=1; AFNElJ9oTf3DIyhufZ+wiCr4XnN6hJ7F/THHtQ9yg9qopbexlORM+ashtcOPOAc6LKOfOY+kJPNx3NSjU4UKO+E=@vger.kernel.org X-Gm-Message-State: AOJu0Yz1a3ASumTw2WoW8a70noG5stTauFZsTUAg9/tqmLT86NWq8/Ab 4udWDiv5J3uDCXO0rMZ5pLF+3vroA5EAJUqMtDiM3NtAXzyLbwRniIGO X-Gm-Gg: AeBDieuf6wFr48mam1f2D0GQckikmLvmBAkxn5EYj8bpwoWOfPer179XeQR9cryvZTF bOH0xC+Jwm7G+1P6P/Skwl0QX0DJMNrwROivFVKEjTgwZOLqOViuFsAzPlASrnIJhgr3BgoukNQ nWwRxDL6seH8ZSoJBX89SU/We5nc/oLxzNAmdVADj2YXK/EjVWXdn3XO9NsRD7/dXlf2D+rmpnd cN53XJ2huPslnYsnVfyTvQ4uICZNVmc6CQZM2D5MmVZLZ2LOWcruvwiht35OcnfdBoFpWFPnC6l gx1btuDVitf7pUYnxdRmhlAryADaYkzqFfVF9ttt56xNn0Rkxi2F77PBwCHHSNcjXNEhAtBvluE IbBfIVGZzLkjcQcobAz9hVG6Lrnay6Z2L/X0frDw84y3FSsBmQE0LoT+Q0VE3eTtAXmYy9R3olb 8xoH2/6PXzUsI8oKEiyllN8JvfD/SSiuqgQEhylCybiSgjXuIGzyEEAoaPkow7oBrE+ferU+I8w 23mcQ0THuSot5O/OhHexUY2ZMDP X-Received: by 2002:a17:903:288:b0:2ae:46b9:c653 with SMTP id d9443c01a7336-2b2d5a43e92mr101961225ad.33.1775998904099; Sun, 12 Apr 2026 06:01:44 -0700 (PDT) Received: from localhost.localdomain (ec2-54-199-123-161.ap-northeast-1.compute.amazonaws.com. [54.199.123.161]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2b2d4ddcda9sm87099115ad.28.2026.04.12.06.01.40 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 12 Apr 2026 06:01:43 -0700 (PDT) From: Xiaobo Liu To: Chuck Lever , Jeff Layton Cc: NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, Xiaobo Liu Subject: [PATCH] nfsd: fix replay buffer length underflow in nfsd4_encode_operation Date: Sun, 12 Apr 2026 21:01:33 +0800 Message-ID: <20260412130133.2308-1-cppcoffee@gmail.com> X-Mailer: git-send-email 2.50.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit When nfsd4_encode_operation() truncates the reply back to op_status_offset + XDR_UNIT, the replay-cache path may still try to compute the encoded payload length from xdr->buf->len. If xdr->buf->len is smaller than op_status_offset + XDR_UNIT, the subtraction underflows and the result is assigned to an int. That can produce an invalid negative/small value, allowing the subsequent NFSD4_REPLAY_ISIZE check to make the wrong decision and use a bogus length for replay-buffer handling. Fix this by validating the buffer length before subtracting. If the encoded length would underflow, force the value into the "too large to cache" path so rp_buflen is cleared instead of reading invalid data. Signed-off-by: Xiaobo Liu --- fs/nfsd/nfs4xdr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 9d2349131..5e9e49057 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -6278,9 +6278,14 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) warn_on_nonidempotent_op(op); xdr_truncate_encode(xdr, op_status_offset + XDR_UNIT); } else if (so) { - int len = xdr->buf->len - (op_status_offset + XDR_UNIT); + unsigned int len; so->so_replay.rp_status = op->status; + if (xdr->buf->len >= op_status_offset + XDR_UNIT) { + len = xdr->buf->len - (op_status_offset + XDR_UNIT); + } else { + len = NFSD4_REPLAY_ISIZE + 1; + } if (len <= NFSD4_REPLAY_ISIZE) { so->so_replay.rp_buflen = len; read_bytes_from_xdr_buf(xdr->buf, -- 2.34.1