Received: by 2002:a25:868d:0:0:0:0:0 with SMTP id z13csp1964437ybk; Thu, 21 May 2020 21:16:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzsK07IJ7ThnZhQDtM7xayGSFnSwpXEWcRZi8nc7F1vo0l/3mXphqCefW0KxmefMiegkfFP X-Received: by 2002:a17:906:1917:: with SMTP id a23mr6232147eje.506.1590121011991; Thu, 21 May 2020 21:16:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1590121011; cv=none; d=google.com; s=arc-20160816; b=tW6Sljasck7mqC6Q6v1O8F2AZJpu6bOWoYl6ET8/lfrhUD4lUdRBM1lBWPDKcYprE1 waTXZviveroKoapZ9dieq26TWtDOSO/2jv8wF9tQQvDngP5YcZVEJzjvNG3mWi+doR/F jd6BTSNztNnZ8xG4wMru65bSwLLHBH/5VqGZS3y0+2FCV7qfw2J7kZBne6bs6lo5EGEJ gtXBG+0raTzqc5I/ctS3KmvhH315YhVKz9raKab24YJeUoTT1WpwBJqQjbui3LlYExLJ 4XifIUzYQhX4fAhSIpvPzmKweqWd821qwCC6cQNlsrwBmUYULdpk6rPhmt0+KfM8xv6S Sgew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:dkim-signature:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from; bh=lgtvms+evwCjD3x/lZ3Ysebw94Ksle/umtDMCsm3L+c=; b=dvi6ZUgWZPuTmlqMSm2WTMRdKwbvTQg70NdNML6mOfRRXf0wSPqcw2ZbZxoJ8y4XFn orlWNvbmcgu8NGk+iBEdhOz+geDKbpEQdGLS1KmZ6RToq128yb1/hvJbEqsfg4asmU6z TvApsEfu5FHIJIvI5kiYNgPoT2RV5Ja0zrQzWQ5OqC6M5GxVl6lYT2i3XtDfkYStUEiz ycgaggi6WT+05iL6a/ZFIfazN34eB0wz7PrqCsHrgolISKQ1oKTTjz1SHJH5BjcCzMlj lMwzzltaUbx+wRP9ZzZ2JjNgL45/bQYEgqm3cvpJsr0xWM+1pMRkBq+k31E5eflfRw26 XQBQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@nvidia.com header.s=n1 header.b="Z4x5Qx/G"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bo6si4065288edb.586.2020.05.21.21.16.29; Thu, 21 May 2020 21:16:51 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@nvidia.com header.s=n1 header.b="Z4x5Qx/G"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727914AbgEVEPL (ORCPT + 99 others); Fri, 22 May 2020 00:15:11 -0400 Received: from hqnvemgate24.nvidia.com ([216.228.121.143]:4058 "EHLO hqnvemgate24.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726816AbgEVEPJ (ORCPT ); Fri, 22 May 2020 00:15:09 -0400 Received: from hqpgpgate102.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate24.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Thu, 21 May 2020 21:12:44 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate102.nvidia.com (PGP Universal service); Thu, 21 May 2020 21:15:09 -0700 X-PGP-Universal: processed; by hqpgpgate102.nvidia.com on Thu, 21 May 2020 21:15:09 -0700 Received: from HQMAIL109.nvidia.com (172.20.187.15) by HQMAIL109.nvidia.com (172.20.187.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Fri, 22 May 2020 04:15:09 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL109.nvidia.com (172.20.187.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Fri, 22 May 2020 04:15:08 +0000 Received: from sandstorm.nvidia.com (Not Verified[10.2.48.182]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Thu, 21 May 2020 21:15:08 -0700 From: John Hubbard To: LKML CC: John Hubbard , Bartlomiej Zolnierkiewicz , Arnd Bergmann , Daniel Vetter , "Gustavo A . R . Silva" , Jani Nikula , , Subject: [PATCH 1/2] video: fbdev: fix error handling for get_user_pages_fast() Date: Thu, 21 May 2020 21:15:05 -0700 Message-ID: <20200522041506.39638-2-jhubbard@nvidia.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200522041506.39638-1-jhubbard@nvidia.com> References: <20200522041506.39638-1-jhubbard@nvidia.com> MIME-Version: 1.0 X-NVConfidentiality: public Content-Transfer-Encoding: quoted-printable Content-Type: text/plain DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1590120764; bh=lgtvms+evwCjD3x/lZ3Ysebw94Ksle/umtDMCsm3L+c=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:MIME-Version:X-NVConfidentiality: Content-Transfer-Encoding:Content-Type; b=Z4x5Qx/GuV0Tog+KoMSLIucx2GzopLPT8awTgV0oqpYYTz5l7IXS8Dayvgwys0vkK WJ1Tp/Vgx19mTdabiGSlUgiJK8HYhoFk0NrUI6B6YBFK8/UahHC/HGCNGKUcGHNlzw xCgpmeNtJOD4zXoTeW0ZMCXbdRQQADn2c2+eZ7ITFgOttpe4KUCrExBiKlZGcqOXy6 m7GU/PkAC17Ymq5o4LbX4haeiPBJ/FZOG9B8qgeoCClFq3e4jimzfv/Etn6myKy3jh YdscZLVAGMAQt16da8HdU6N/r8QrZtHRjbc3UjbIzcG0+5Ol62LxmUIExoSe9bYKKm yuPbNSfgmaIpw== Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Dealing with the return value of get_user_pages*() variants has a few classic pitfalls, and this driver found one of them: the return value might be zero, positive, or -errno. And if positive, it might be fewer pages than were requested. And if fewer pages than requested, then the caller should return (via put_page()) the pages that *were* pinned. This driver was doing that *except* that it had a problem with the -errno case, which was being stored in an unsigned int, and which would case an interesting mess if it ever happened: nr_pages would be interpreted as a spectacularly huge unsigned value, rather than a small negative value. Also, it was unnecessarily overriding a potentially informative -errno, with -EINVAL, in some cases. Instead: clamp the nr_pages to zero or positive, so that the error handling works. And return the -errno value from get_user_pages*(), unchanged, if we get one. And explain this with comments, seeing as how it is error-prone. Cc: Bartlomiej Zolnierkiewicz Cc: Arnd Bergmann Cc: Daniel Vetter Cc: Gustavo A. R. Silva Cc: Jani Nikula Cc: dri-devel@lists.freedesktop.org Cc: linux-fbdev@vger.kernel.org Signed-off-by: John Hubbard --- drivers/video/fbdev/pvr2fb.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c index f18d457175d9..ceb6ef590597 100644 --- a/drivers/video/fbdev/pvr2fb.c +++ b/drivers/video/fbdev/pvr2fb.c @@ -654,8 +654,22 @@ static ssize_t pvr2fb_write(struct fb_info *info, cons= t char *buf, =20 ret =3D get_user_pages_fast((unsigned long)buf, nr_pages, FOLL_WRITE, pag= es); if (ret < nr_pages) { - nr_pages =3D ret; - ret =3D -EINVAL; + if (ret < 0) { + /* + * Clamp the unsigned nr_pages to zero so that the + * error handling works. And leave ret at whatever + * -errno value was returned from GUP. + */ + nr_pages =3D 0; + } else { + nr_pages =3D ret; + /* + * Use -EINVAL to represent a mildly desperate guess at + * why we got fewer pages (maybe even zero pages) than + * requested. + */ + ret =3D -EINVAL; + } goto out_unmap; } =20 --=20 2.26.2