Received: by 2002:a05:6358:45e:b0:b5:b6eb:e1f9 with SMTP id 30csp3085567rwe; Mon, 29 Aug 2022 05:42:28 -0700 (PDT) X-Google-Smtp-Source: AA6agR4jAvwbWOKU4XoophTVy/tTCvKa4bLUZzUZGrA5ye4+rcmahnCmRmaWPlAuFlb7READCNAO X-Received: by 2002:a17:902:e80e:b0:16f:14ea:897b with SMTP id u14-20020a170902e80e00b0016f14ea897bmr15974343plg.6.1661776948715; Mon, 29 Aug 2022 05:42:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1661776948; cv=none; d=google.com; s=arc-20160816; b=I5CVEHT5rrmWbLtjzm6NfsLPJRZjG+pxEOdggnDpSmhuOvRSLgKelcyMMohbUvdkTT 66RYMJ9zpwOiNoxA4Qz2Q6x9r438SwK7czENycWcuixr31CyRxcScx+PQuHq/Ynf4raI gESF71+hjIO4OUaqROAvN/DyPMF8Rw7SivzEKp18pFysukNSb9N3iIxaS4iIyKEHwa6a xVQ4AkoYF2DCFvT7nq4FjjMVWmGsejlnnG0xoIIdrUGZqZQ7W3iNxvvf5X0xpmynJD8T cGHwFVb1Qg4u4KD7weNd5JFI/iNUq74yceJ9fgZBWIVSla5kVwS2l1Pj80GjHmmkdgNI ESfA== 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=thGG0cq0L70qD1PYSHtU1szSkstVMsFdGAJt7pLgB14UHlK2swcDdKdvK75gg7Kjci kmvYUoRZbqCuM1zFaOv9UeTxEiCBf3HksFafIgM/UWt4pBjfM5J9HsZicFwd7lmYuWcJ 52z7dNlP3T9rpOFEOOm4ppeNbpXZLjLSGx/pbtB+7yzSQPwMtBkX2t58yvix+tmM/XSQ Kla1OzK5o9sn+jIz0HuzqEMv8Odzk9eDSu4sOO1pwzK3+XYSG3cxY1HcMA4yn3KovQ0c UeQ1F6d3z4xviKpCNI1W9YZO5CddOJa//BJQgUqWyhS7JwZex1WqSZLp9P7FkVRGrfge nF9w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Ap5TsoJV; 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 j10-20020aa78dca000000b00537bb009bebsi8061630pfr.287.2022.08.29.05.42.17; Mon, 29 Aug 2022 05:42:28 -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=Ap5TsoJV; 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 S231379AbiH2Ls5 (ORCPT + 99 others); Mon, 29 Aug 2022 07:48:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40770 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230470AbiH2Lse (ORCPT ); Mon, 29 Aug 2022 07:48:34 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B49889917; Mon, 29 Aug 2022 04:32:01 -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 ams.source.kernel.org (Postfix) with ESMTPS id BB09FB80FAF; Mon, 29 Aug 2022 11:17:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 037ABC433D6; Mon, 29 Aug 2022 11:17:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1661771878; bh=sqwZwaMa4ltO+ZnF2OW0LOrSQsC+7lCx8oJFCuGBDEU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ap5TsoJVg8esKzgaj8QhfERta/RmrVncpaM/J5g9OQr1bQ0BWr6J2P0SPthP++BfY 11rZSmxNsZYp4IZcI/NxsdIH9f02/pDv6DjDjz2vTrXUaaIWWnbQMQH8J+0dUHBrjY FLYHgy74qgqPnhWX4FcI12Wg7ZhE7Fu9fODWjmoY= 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.19 128/158] xen/privcmd: fix error exit of privcmd_ioctl_dm_op() Date: Mon, 29 Aug 2022 12:59:38 +0200 Message-Id: <20220829105814.449509146@linuxfoundation.org> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220829105808.828227973@linuxfoundation.org> References: <20220829105808.828227973@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);