Received: by 2002:a5b:505:0:0:0:0:0 with SMTP id o5csp26850ybp; Thu, 3 Oct 2019 09:41:57 -0700 (PDT) X-Google-Smtp-Source: APXvYqyfx9XmrEDWcNilR/rwDXE+SV4Enxh3XKs/cT1aL8CEWwovo33GvQx67j8wcMSRlaHb/kHt X-Received: by 2002:a17:906:244a:: with SMTP id a10mr8556511ejb.137.1570120917241; Thu, 03 Oct 2019 09:41:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570120917; cv=none; d=google.com; s=arc-20160816; b=l+2B6qw2NfsDC4un/6FH+NHUiGOuWJtkx/nItaGBsOefup9Ldf/sSd5FBVKNkKDM7B YDzAKe3rle+NlVwzOouWDXEjQc2kIwxFdCdWamkMQDPDgqX/CxoCQgscsf6KewJK+ibd Ade+1bMFPlNgIRgfKarmxDdExBf7sCayCOwcmJJBRSfvU+mwhCINVkyxzhs0oSzSzGpI RpJ8r+zV4QjB3Bp0z2F92X//ah/zakWGZAQv6CJbZQp/OCC3PBV7gjB3ATG+eR5sreCf P1S4I1gw+bWbiDTmFi1S5XPoK00fEKJ1dztDEzevVOmYvFCSoGH1vw4YCmQPnX1l6DQK zrBA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=P8m6BV6n3Bro+ctlu0Tr+UspXwfQlqLKkGZfEL8lY7Q=; b=XxYjOgzlJWbmN4mPKXaJZ+Gq26HsgeA3fV/5za3r87fi4buT4iFiPtWU060yGzTnST rBde0oS31b3YCdzqWptNeAZMw8rGIQqlm3AOcGTrIY6YlhZR2Qkp0nBAmnmMsp6mEY4a OXFcTVvuW1yDT1JsSIKJOSubTVDqt27dcA5li8156291sFhSo+QWUgQidcyABouLcNae Djgq04h/QCDGwjTXPgaMM1hMol0lujED8xgKRvSwsKSMxIk9UwmskAt2HxH455eHhYvE BvVXXOyYup7881uXVfGpJNsdoPQvzpAX6sA+PXYEU93oMWHJnHs12Ii/StvB/DzwPg2L VwGg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=kRGOpQqp; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ng7si1491125ejb.91.2019.10.03.09.41.32; Thu, 03 Oct 2019 09:41:57 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=kRGOpQqp; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404704AbfJCQiS (ORCPT + 99 others); Thu, 3 Oct 2019 12:38:18 -0400 Received: from mail.kernel.org ([198.145.29.99]:47948 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2404789AbfJCQiR (ORCPT ); Thu, 3 Oct 2019 12:38:17 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 71CB520830; Thu, 3 Oct 2019 16:38:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1570120696; bh=RgbKOuX3h2QbdzinijI7/wH56GttneKB9fd77dI5Lzs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kRGOpQqp/GQSS6J0IWt/4mQDxlRaWK5BTwCSTVFtAFV/KW+/NlQjmjxOatKpCwjRZ pTdml9f1hC1VqQSSr1geBbVGmuJmlSJB9yV2K+1KCPayXGw+lkAi9uKJOTJw9TpQHt Gm/zJvvfeqh5OJ81hlkdMadQZllBFJTA/g3Sbxtk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Benjamin Coddington , Chuck Lever , Anna Schumaker Subject: [PATCH 5.2 290/313] SUNRPC: Fix buffer handling of GSS MIC without slack Date: Thu, 3 Oct 2019 17:54:28 +0200 Message-Id: <20191003154601.664343882@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191003154533.590915454@linuxfoundation.org> References: <20191003154533.590915454@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Benjamin Coddington commit 5f1bc39979d868a0358c683864bec3fc8395440b upstream. The GSS Message Integrity Check data for krb5i may lie partially in the XDR reply buffer's pages and tail. If so, we try to copy the entire MIC into free space in the tail. But as the estimations of the slack space required for authentication and verification have improved there may be less free space in the tail to complete this copy -- see commit 2c94b8eca1a2 ("SUNRPC: Use au_rslack when computing reply buffer size"). In fact, there may only be room in the tail for a single copy of the MIC, and not part of the MIC and then another complete copy. The real world failure reported is that `ls` of a directory on NFS may sometimes return -EIO, which can be traced back to xdr_buf_read_netobj() failing to find available free space in the tail to copy the MIC. Fix this by checking for the case of the MIC crossing the boundaries of head, pages, and tail. If so, shift the buffer until the MIC is contained completely within the pages or tail. This allows the remainder of the function to create a sub buffer that directly address the complete MIC. Signed-off-by: Benjamin Coddington Cc: stable@vger.kernel.org # v5.1 Reviewed-by: Chuck Lever Signed-off-by: Anna Schumaker Signed-off-by: Greg Kroah-Hartman --- net/sunrpc/xdr.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -1237,16 +1237,29 @@ xdr_encode_word(struct xdr_buf *buf, uns EXPORT_SYMBOL_GPL(xdr_encode_word); /* If the netobj starting offset bytes from the start of xdr_buf is contained - * entirely in the head or the tail, set object to point to it; otherwise - * try to find space for it at the end of the tail, copy it there, and - * set obj to point to it. */ + * entirely in the head, pages, or tail, set object to point to it; otherwise + * shift the buffer until it is contained entirely within the pages or tail. + */ int xdr_buf_read_netobj(struct xdr_buf *buf, struct xdr_netobj *obj, unsigned int offset) { struct xdr_buf subbuf; + unsigned int boundary; if (xdr_decode_word(buf, offset, &obj->len)) return -EFAULT; - if (xdr_buf_subsegment(buf, &subbuf, offset + 4, obj->len)) + offset += 4; + + /* Is the obj partially in the head? */ + boundary = buf->head[0].iov_len; + if (offset < boundary && (offset + obj->len) > boundary) + xdr_shift_buf(buf, boundary - offset); + + /* Is the obj partially in the pages? */ + boundary += buf->page_len; + if (offset < boundary && (offset + obj->len) > boundary) + xdr_shrink_pagelen(buf, boundary - offset); + + if (xdr_buf_subsegment(buf, &subbuf, offset, obj->len)) return -EFAULT; /* Is the obj contained entirely in the head? */ @@ -1258,11 +1271,7 @@ int xdr_buf_read_netobj(struct xdr_buf * if (subbuf.tail[0].iov_len == obj->len) return 0; - /* use end of tail as storage for obj: - * (We don't copy to the beginning because then we'd have - * to worry about doing a potentially overlapping copy. - * This assumes the object is at most half the length of the - * tail.) */ + /* Find a contiguous area in @buf to hold all of @obj */ if (obj->len > buf->buflen - buf->len) return -ENOMEM; if (buf->tail[0].iov_len != 0)