From patchwork Tue May 30 18:14:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 9755029 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A3F31601D2 for ; Tue, 30 May 2017 18:14:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 933A3267EC for ; Tue, 30 May 2017 18:14:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 87B7D27FA5; Tue, 30 May 2017 18:14:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 00DD7267EC for ; Tue, 30 May 2017 18:14:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751061AbdE3SOp (ORCPT ); Tue, 30 May 2017 14:14:45 -0400 Received: from mail-it0-f67.google.com ([209.85.214.67]:32815 "EHLO mail-it0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751015AbdE3SOo (ORCPT ); Tue, 30 May 2017 14:14:44 -0400 Received: by mail-it0-f67.google.com with SMTP id l145so10309937ita.0; Tue, 30 May 2017 11:14:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:subject:from:to:date:message-id:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=Y8GXXQJLC7A1H+UsddQQ4r6cL+sG4uod4F3OH+MjUhM=; b=pbrwzZtIlqDk/LCrIaLrdWEYxOnBEZk+iQ0jjQgpr5Ykq0Q3exP2PCTbnahn3M3dVe sYE9XWKrG6yQw9EENZXbyh97nzxakcvkFPp00z9lwAav76mfFprpRuIvpk5ZgYw/Y9GG Ec1ovdNC9aCBcnUWLpQpJC09d1aNbIe1RXlvlFI1u4aVbqmDyJtJO+r3KKc9b+4jOKqC ovxpfZc8Sye/heI7NnTVHRCf4Nt9+aIJd9Ih5e9PYx8HvKF1KeY4Ts5PVSw0BbbsPMNh qF6xjoBrZie7qvvPN5mkbf0MtuOAKwTLT0imtqWPzrwC3pe6lXCmg5Uo9kT9dj/Nkt2w y2HA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:subject:from:to:date:message-id :in-reply-to:references:user-agent:mime-version :content-transfer-encoding; bh=Y8GXXQJLC7A1H+UsddQQ4r6cL+sG4uod4F3OH+MjUhM=; b=EyXCPYhXvvo1V/Da4mqc9T+3YomOc5ZFnPOVVLKL5sBWpIQhPSD9WQ1atyv9CF8LLz C6DrOUN42wOBAXAx0oDDu3t0tNPHIS1D+r/xHNdObn5a9zgPxyOpkKcO5B9OdP3QmDqG oXeNXETTt+ui/J6PUtcY1HoVvVy99TO1XIst8wgnrIo4G57V7m0zBwjrJ2mhVJl2Sllg oUXzgA0UvGCglpr5CEKoZBNjTpy/wyb8vSzMHqb4ddjI/M/Dgi7oSa6FVAaEmWohQiD9 GN2XDubHtSTOiIzdIhkqcrlLELXIeGekw2vCAi5KMkrgL7uPLX8bLLsPRTH4NffjymHA 1K2g== X-Gm-Message-State: AODbwcDkhcI09+aUKf/onzGiMkYDc5DhK1GVrJEN3DxqfZCJdwNxtCYF PBurgZh8ugz7sJ98 X-Received: by 10.36.250.4 with SMTP id v4mr3551617ith.116.1496168083710; Tue, 30 May 2017 11:14:43 -0700 (PDT) Received: from klimt.1015granger.net (c-68-46-169-226.hsd1.mi.comcast.net. [68.46.169.226]) by smtp.gmail.com with ESMTPSA id d35sm5815770ioj.5.2017.05.30.11.14.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 May 2017 11:14:43 -0700 (PDT) Subject: [PATCH v1 05/17] svcrdma: Improve Read chunk sanity checking From: Chuck Lever To: linux-rdma@vger.kernel.org, linux-nfs@vger.kernel.org Date: Tue, 30 May 2017 14:14:42 -0400 Message-ID: <20170530181442.2992.70479.stgit@klimt.1015granger.net> In-Reply-To: <20170530175808.2992.60365.stgit@klimt.1015granger.net> References: <20170530175808.2992.60365.stgit@klimt.1015granger.net> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Identify malformed transport headers and unsupported chunk combinations as early as possible. - Reject RPC-over-RDMA messages that contain more than one Read chunk, since this implementation currently does not support more than one per RPC transaction. - Ensure that segment lengths are not crazy. - Remove the segment count check. With a 1KB inline threshold, the largest number of Read segments that can be conveyed is about 40 (for a RDMA_NOMSG Call message). This is nowhere near RPCSVC_MAXPAGES. As far as I can tell, that was just a sanity check and does not enforce an implementation limit. Signed-off-by: Chuck Lever --- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 55 +++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 18 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index 55ad335..885ad95 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -117,15 +117,47 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp, rqstp->rq_arg.tail[0].iov_len = 0; } -static __be32 *xdr_check_read_list(__be32 *p, __be32 *end) +/* This accommodates the largest possible Position-Zero + * Read chunk or Reply chunk, in one segment. + */ +#define MAX_BYTES_SPECIAL_SEG ((u32)((RPCSVC_MAXPAGES + 2) << PAGE_SHIFT)) + +/* Sanity check the Read list. + * + * Implementation limits: + * - This implementation supports only one Read chunk. + * + * Sanity checks: + * - Read list does not overflow buffer. + * - Segment size limited by largest NFS data payload. + * + * The segment count is limited to how many segments can + * fit in the transport header without overflowing the + * buffer. That's about 40 Read segments for a 1KB inline + * threshold. + * + * Returns pointer to the following Write list. + */ +static __be32 *xdr_check_read_list(__be32 *p, const __be32 *end) { - __be32 *next; + u32 position; + bool first; + first = true; while (*p++ != xdr_zero) { - next = p + rpcrdma_readchunk_maxsz - 1; - if (next > end) + if (first) { + position = be32_to_cpup(p++); + first = false; + } else if (be32_to_cpup(p++) != position) { + return NULL; + } + p++; /* handle */ + if (be32_to_cpup(p++) > MAX_BYTES_SPECIAL_SEG) + return NULL; + p += 2; /* offset */ + + if (p > end) return NULL; - p = next; } return p; } @@ -478,16 +510,6 @@ int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt, return ret; } -static unsigned int -rdma_rcl_chunk_count(struct rpcrdma_read_chunk *ch) -{ - unsigned int count; - - for (count = 0; ch->rc_discrim != xdr_zero; ch++) - count++; - return count; -} - /* If there was additional inline content, append it to the end of arg.pages. * Tail copy has to be done after the reader function has determined how many * pages are needed for RDMA READ. @@ -567,9 +589,6 @@ static int rdma_read_chunks(struct svcxprt_rdma *xprt, if (!ch) return 0; - if (rdma_rcl_chunk_count(ch) > RPCSVC_MAXPAGES) - return -EINVAL; - /* The request is completed when the RDMA_READs complete. The * head context keeps all the pages that comprise the * request.