Received: by 2002:a05:6358:45e:b0:b5:b6eb:e1f9 with SMTP id 30csp3073096rwe; Mon, 29 Aug 2022 05:30:14 -0700 (PDT) X-Google-Smtp-Source: AA6agR5MXI0CcRa6Hori0MwOzxqQ5oBoD7mPE7UASIVX9SX+H9IhoLnb6ctPlksO1iBeEyH9ieZY X-Received: by 2002:a17:902:bb95:b0:16e:e3f4:8195 with SMTP id m21-20020a170902bb9500b0016ee3f48195mr16107146pls.130.1661776213826; Mon, 29 Aug 2022 05:30:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1661776213; cv=none; d=google.com; s=arc-20160816; b=DgG7FDmheCGTkDEUb45nvtwGypGg38MZjLP7bm2PK8JCnSWjwWp6wr0qcGGBXzaatF MVfQIwZ8HNVQcYL3Ot6ozPbMgSRbmAMMEFFYZ/LP/ndil4IPMIwdmRzQYbeLD/mM24oB pX3avIaxx/rtBmOsNsNfwnc5gEaau8r8No9aprielw1TrjTfdGGAvD/gh9miQn1QYaUQ cgR37Q3Rq5si20sfd8ZIqBj3B6cZAhrZMgA/SiuOp7fOLKO6UxFr+GL8MNjWpoNPAR06 NNT7pWffpNUHmXxgpMasq1tnyT8ldN3V859ZGYrADwFYkS35wzisyLcog2undl2boXIY wCBg== 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:subject:cc:to :from:dkim-signature; bh=bankuvvNEK0BwGjtjyPY1DDYQXj5zfURgMSycAwa2yI=; b=kwAa0JID7P9G1CsUH1XWRbcNOJQg1L04gd3bP42RvVN+CYPf9azIvzhAskyota6GJj xP0EKNay852LV0aUwN/jd2/ydnWaYJkYgL0gUw+qQQWsz1bzCdJ+CK6hwMhwd7NcFTUu ljy6VtqKiIAgXduDPLHseOa/H5LD4/e/LrzAFF2fwSI5LGWtXvyGlz4WVSOwcQSrSfp4 mHmzovQYNLc2y1gURVBdS9wpYpu60z3b5BWEXT/ZgrcZrk6JYYA1qALg/Aij5HlRV/5/ dECpAPH8OqwSEIZxG3SbRKsnuiBrScirw+s7tNJmre3Xu73MjIb9IocRtWwApaiIetAW B0wg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=LHwy3soV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u13-20020a63234d000000b0042a0dab10aasi8959865pgm.482.2022.08.29.05.30.02; Mon, 29 Aug 2022 05:30:13 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-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; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=LHwy3soV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230352AbiH2LUL (ORCPT + 99 others); Mon, 29 Aug 2022 07:20:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55364 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231637AbiH2LSy (ORCPT ); Mon, 29 Aug 2022 07:18:54 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4CEB51C114; Mon, 29 Aug 2022 04:12:46 -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 EF70161218; Mon, 29 Aug 2022 11:12:40 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 06CBFC433C1; Mon, 29 Aug 2022 11:12:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1661771560; bh=sqwZwaMa4ltO+ZnF2OW0LOrSQsC+7lCx8oJFCuGBDEU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LHwy3soV2P3ENyRE0fHFujPQ49DdwL2AM2i5GEuWJ8dBoFuUDSde3JMhRx/TCYqot CbF7TIIi9z0X+UM59chcjTvVzchJc7ODQ+q5GezNTNAhFzMiqd+ocTB6RqlEmC86tM oTZ9UoF8oDZdlbSmtpij8J5sAsrXYDnF1FMAtAGw= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Rustam Subkhankulov , Juergen Gross , Jan Beulich , Oleksandr Tyshchenko Subject: [PATCH 5.15 116/136] xen/privcmd: fix error exit of privcmd_ioctl_dm_op() Date: Mon, 29 Aug 2022 12:59:43 +0200 Message-Id: <20220829105809.451088886@linuxfoundation.org> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220829105804.609007228@linuxfoundation.org> References: <20220829105804.609007228@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,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-kernel@vger.kernel.org From: Juergen Gross commit c5deb27895e017a0267de0a20d140ad5fcc55a54 upstream. The error exit of privcmd_ioctl_dm_op() is calling unlock_pages() potentially with pages being NULL, leading to a NULL dereference. Additionally lock_pages() doesn't check for pin_user_pages_fast() having been completely successful, resulting in potentially not locking all pages into memory. This could result in sporadic failures when using the related memory in user mode. Fix all of that by calling unlock_pages() always with the real number of pinned pages, which will be zero in case pages being NULL, and by checking the number of pages pinned by pin_user_pages_fast() matching the expected number of pages. Cc: Fixes: ab520be8cd5d ("xen/privcmd: Add IOCTL_PRIVCMD_DM_OP") Reported-by: Rustam Subkhankulov Signed-off-by: Juergen Gross Reviewed-by: Jan Beulich Reviewed-by: Oleksandr Tyshchenko Link: https://lore.kernel.org/r/20220825141918.3581-1-jgross@suse.com Signed-off-by: Juergen Gross Signed-off-by: Greg Kroah-Hartman --- drivers/xen/privcmd.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c @@ -581,27 +581,30 @@ static int lock_pages( struct privcmd_dm_op_buf kbufs[], unsigned int num, struct page *pages[], unsigned int nr_pages, unsigned int *pinned) { - unsigned int i; + unsigned int i, off = 0; - for (i = 0; i < num; i++) { + for (i = 0; i < num; ) { unsigned int requested; int page_count; requested = DIV_ROUND_UP( offset_in_page(kbufs[i].uptr) + kbufs[i].size, - PAGE_SIZE); + PAGE_SIZE) - off; if (requested > nr_pages) return -ENOSPC; page_count = pin_user_pages_fast( - (unsigned long) kbufs[i].uptr, + (unsigned long)kbufs[i].uptr + off * PAGE_SIZE, requested, FOLL_WRITE, pages); - if (page_count < 0) - return page_count; + if (page_count <= 0) + return page_count ? : -EFAULT; *pinned += page_count; nr_pages -= page_count; pages += page_count; + + off = (requested == page_count) ? 0 : off + page_count; + i += !off; } return 0; @@ -677,10 +680,8 @@ static long privcmd_ioctl_dm_op(struct f } rc = lock_pages(kbufs, kdata.num, pages, nr_pages, &pinned); - if (rc < 0) { - nr_pages = pinned; + if (rc < 0) goto out; - } for (i = 0; i < kdata.num; i++) { set_xen_guest_handle(xbufs[i].h, kbufs[i].uptr); @@ -692,7 +693,7 @@ static long privcmd_ioctl_dm_op(struct f xen_preemptible_hcall_end(); out: - unlock_pages(pages, nr_pages); + unlock_pages(pages, pinned); kfree(xbufs); kfree(pages); kfree(kbufs);