Received: by 2002:a05:6358:5282:b0:b5:90e7:25cb with SMTP id g2csp3993231rwa; Tue, 23 Aug 2022 14:06:41 -0700 (PDT) X-Google-Smtp-Source: AA6agR6psbRArsEMW91cJHNZJO8CZxSqLG5S4ms+PkBh4S0HoGU6esmS44LEYQ6RHAdNKNFsKJQH X-Received: by 2002:a17:907:8a07:b0:731:48ba:792e with SMTP id sc7-20020a1709078a0700b0073148ba792emr886619ejc.397.1661288801568; Tue, 23 Aug 2022 14:06:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1661288801; cv=none; d=google.com; s=arc-20160816; b=H61wKH7o9cksWl92oKMmrdat1k1drX6dqLwjLIafxa8VQiErja9mMJ+iPaxtZecOQb zaC+XmcZi85QLAppGfOru2o89/9LkCMModfps36YHSsl8WBDD0KVoA34fugPSnoTGmkw atCpwrM3GijqrR/BoUAUbcyWH3E8gAGCbeX9H1oXmPFlPh8DzdJ+9ryow/sWuidH227Y IvHICeS4UT3q4ng//DVtUMf3xUtlul6h54ayKSk+ICkJtFkokM/8xIQyXpnK/0WKuXTB HmpUUIStelkVRkh5xBV6Po0U9amrC5JRTYIrz+juUnDsWlofNDIhLI8Taqz3GrDenTk2 J0Kg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:to:from:subject; bh=Oh8jL0vrkqBNoDlEuq7QkVFvvzAtSzHDDw1zhnFfyZU=; b=GQKFKCxmhAyR5pU3T29bZSj5a3Odmy4iOUAbOJQadS/0xuDmYeWbaOwgnWtf8rvT2t qLfoILARJJxi4InkT6nNnviNKR8DKJ/lb/uOSFQUaJypYWE2C6Uw9zaWFWJF8/uejFvl ERvDq43WeBP+vGqBmETsvkYv8WdYDjnd6gE3sQffqcAuSmAw9B3Ri5S4NGN925SwdeQB k7yOrijoA+SKo1apHAHgw6e+Jtt3GSYSGN8AnvodmaGf6gASEPIz7Fh0BHoJK/EQyNPc lYvaBwIyQ521+js8r0SWjuFbpO8QsOo1mmHQUmUMVPr87/aro/RJeaqJJx+sZbVRYY7F 5FaQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=oracle.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id go20-20020a1709070d9400b0073d615565fesi708416ejc.494.2022.08.23.14.06.16; Tue, 23 Aug 2022 14:06:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=oracle.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229954AbiHWVFa (ORCPT + 99 others); Tue, 23 Aug 2022 17:05:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47800 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231296AbiHWVAW (ORCPT ); Tue, 23 Aug 2022 17:00:22 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6350F79605 for ; Tue, 23 Aug 2022 14:00:22 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 009A4615A6 for ; Tue, 23 Aug 2022 21:00:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3DE67C433D6; Tue, 23 Aug 2022 21:00:21 +0000 (UTC) Subject: [PATCH v1 3/7] NFSD: Check for junk after RPC Call messages From: Chuck Lever To: linux-nfs@vger.kernel.org Date: Tue, 23 Aug 2022 17:00:20 -0400 Message-ID: <166128842018.2788.3153078415664547122.stgit@manet.1015granger.net> In-Reply-To: <166128840714.2788.7887913547062461761.stgit@manet.1015granger.net> References: <166128840714.2788.7887913547062461761.stgit@manet.1015granger.net> User-Agent: StGit/1.5.dev2+g9ce680a5 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-6.7 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_DNSWL_HI,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org The current RPC server code allows incoming RPC messages up to about a megabyte in size. For TCP, this is based on the size value contained in the RPC record marker. Currently, NFSD ignores anything in the message that is past the end of the encoded RPC Call message. A very large RPC message can arrive with just an NFSv3 LOOKUP operation in it, and NFSD ignores the rest of the message until the next RPC fragment in the TCP stream. That ignored data still consumes pages in the svc_rqst's page array, however. The current arrangement is that each svc_rqst gets about 260 pages, assuming that all supported NFS operations will never require more than a total of 260 pages to decode a Call message and construct its corresponding Reply message. A clever attacker can add garbage at the end of a READ-like request, which generally has a small Call message and a potentially large Reply message with a payload . That makes both the Call message and the Reply message large, and runs the svc_rqst out of pages. At the very least, this can result in a short or empty READ or READDIR result. So, let's teach NFSD to look for such shenanigans and reject any Call where the incoming RPC frame has content remaining in the receive buffer after NFSD has decoded all of the Call arguments. Signed-off-by: Chuck Lever --- fs/nfsd/nfssvc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 4bb5baa17040..5face047ce1a 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -1027,6 +1027,7 @@ nfsd(void *vrqstp) int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) { const struct svc_procedure *proc = rqstp->rq_procinfo; + struct xdr_stream *xdr = &rqstp->rq_arg_stream; /* * Give the xdr decoder a chance to change this if it wants @@ -1035,7 +1036,9 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) rqstp->rq_cachetype = proc->pc_cachetype; svcxdr_init_decode(rqstp); - if (!proc->pc_decode(rqstp, &rqstp->rq_arg_stream)) + if (!proc->pc_decode(rqstp, xdr)) + goto out_decode_err; + if (xdr_stream_remaining(xdr)) goto out_decode_err; switch (nfsd_cache_lookup(rqstp)) {