From patchwork Sat Oct 22 07:19:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg KH X-Patchwork-Id: 7200 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4242:0:0:0:0:0 with SMTP id s2csp1089658wrr; Sat, 22 Oct 2022 00:44:01 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4vM/4Rd8mQv3TsuAh1ojrwVeOvbikFmWMULhigSufj6Kgmlu3VXYZkNe/xKfumpxMwd/zd X-Received: by 2002:a17:902:cecd:b0:185:46d3:8cad with SMTP id d13-20020a170902cecd00b0018546d38cadmr22948525plg.83.1666424640909; Sat, 22 Oct 2022 00:44:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666424640; cv=none; d=google.com; s=arc-20160816; b=s5wDNzWbVS3i9DdeDqgk6+6O3qFNbxXpeFmYdhi8V0WUnhyDgMHxcdUj9B3XThBkxm EjWhRP075ko5y/gRxQDbW+PzKZNHd45JI6iPhCv2bIIg2fT12e8l01+QdA4Z4khojoXg /wEscOyGkF2Hg+Zbzd/QU8A1haPIwKAE/v6Yt4jwc1o3UvchQr2SGA4nix5guoEfjgAj Y7mobIxDdvbcOmpRDHvGs0LXrcSvKSW866gySwRgGpzctfB0PQnN1vwp8gHBOMI3gSeo qHHvVxFVjRum+iJCyIAorPzkfxR51FTN3PnGDj1KPp/juBoqCA6W1JZAzgT7rvEXr5LB sk3A== 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=VW6d+ncnIv0u8wFSUOsQBDT7Zt7mce3KkN+ZfAmEO5E=; b=KvWYyRIdtiU7tMeGo5w5bwjx4MhKyrMg6jFVfeJASU3x8LTgO0/wpMzbH8z4xcjEOB uzQa9mZRbTjyktp6qJOAbTHnOeDEmjEP/9IJbsqQyqXMvXiPQDOQuUIzxZWuhrLd8R6q OqOLyJJo22xSGSuahDZ8JfWwFhJXlwgc4/tPPOCCHEQ36x5H8q+Gx/jBYCRhPMzz0o/C 9PMZ6GML/Co72t2NDTLV977+s6KoWhcNjdPONxPHeytysoGRgpX3mL5O5hi98sMsXr0S nzV0/10VMl0r5Rp8JaaWSl4nvoLVBZNeDG4zeb8tUUiZGzW/TOVzAHygMdPcfnWR3V7c g15g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=X4tAELJ+; 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: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id z14-20020a170902d54e00b00183f6ff535dsi27324547plf.490.2022.10.22.00.43.48; Sat, 22 Oct 2022 00:44:00 -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=X4tAELJ+; 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 S231237AbiJVHnY (ORCPT + 99 others); Sat, 22 Oct 2022 03:43:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47088 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231274AbiJVHmm (ORCPT ); Sat, 22 Oct 2022 03:42:42 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C5F2D65004; Sat, 22 Oct 2022 00:41:22 -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 C136A60AFA; Sat, 22 Oct 2022 07:37:33 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D848AC433C1; Sat, 22 Oct 2022 07:37:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1666424253; bh=dJ6NpRGfTiudBlY78zUwNyNL6KxXExXZrduB0FLK+cE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=X4tAELJ+8WJa6iTPLCMBdopVPDGh6RLUAnatSSaui2wStx9H9ZFt6CRWSxr1NW3dr RzRoLlHgYO6bsxRmqe+w3BWqBE2yrnoQW8n0ghpMxec7pViVUHyz1+z+hba+ejjAMU i0e6r+feABG4vd9gbrwZC0Q75wSzmCaiAsBjUVXQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Carlos Llamas , Catalin Marinas , Andrii Nakryiko , Liam Howlett , "Christian Brauner (Microsoft)" , Michal Hocko , Suren Baghdasaryan , Andrew Morton Subject: [PATCH 5.19 078/717] mm/mmap: undo ->mmap() when arch_validate_flags() fails Date: Sat, 22 Oct 2022 09:19:17 +0200 Message-Id: <20221022072429.031061362@linuxfoundation.org> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221022072415.034382448@linuxfoundation.org> References: <20221022072415.034382448@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 X-Spam-Status: No, score=-7.3 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 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 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747372883911056641?= X-GMAIL-MSGID: =?utf-8?q?1747372883911056641?= From: Carlos Llamas commit deb0f6562884b5b4beb883d73e66a7d3a1b96d99 upstream. Commit c462ac288f2c ("mm: Introduce arch_validate_flags()") added a late check in mmap_region() to let architectures validate vm_flags. The check needs to happen after calling ->mmap() as the flags can potentially be modified during this callback. If arch_validate_flags() check fails we unmap and free the vma. However, the error path fails to undo the ->mmap() call that previously succeeded and depending on the specific ->mmap() implementation this translates to reference increments, memory allocations and other operations what will not be cleaned up. There are several places (mainly device drivers) where this is an issue. However, one specific example is bpf_map_mmap() which keeps count of the mappings in map->writecnt. The count is incremented on ->mmap() and then decremented on vm_ops->close(). When arch_validate_flags() fails this count is off since bpf_map_mmap_close() is never called. One can reproduce this issue in arm64 devices with MTE support. Here the vm_flags are checked to only allow VM_MTE if VM_MTE_ALLOWED has been set previously. From userspace then is enough to pass the PROT_MTE flag to mmap() syscall to trigger the arch_validate_flags() failure. The following program reproduces this issue: #include #include #include #include #include int main(void) { union bpf_attr attr = { .map_type = BPF_MAP_TYPE_ARRAY, .key_size = sizeof(int), .value_size = sizeof(long long), .max_entries = 256, .map_flags = BPF_F_MMAPABLE, }; int fd; fd = syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr)); mmap(NULL, 4096, PROT_WRITE | PROT_MTE, MAP_SHARED, fd, 0); return 0; } By manually adding some log statements to the vm_ops callbacks we can confirm that when passing PROT_MTE to mmap() the map->writecnt is off upon ->release(): With PROT_MTE flag: root@debian:~# ./bpf-test [ 111.263874] bpf_map_write_active_inc: map=9 writecnt=1 [ 111.288763] bpf_map_release: map=9 writecnt=1 Without PROT_MTE flag: root@debian:~# ./bpf-test [ 157.816912] bpf_map_write_active_inc: map=10 writecnt=1 [ 157.830442] bpf_map_write_active_dec: map=10 writecnt=0 [ 157.832396] bpf_map_release: map=10 writecnt=0 This patch fixes the above issue by calling vm_ops->close() when the arch_validate_flags() check fails, after this we can proceed to unmap and free the vma on the error path. Link: https://lkml.kernel.org/r/20220930003844.1210987-1-cmllamas@google.com Fixes: c462ac288f2c ("mm: Introduce arch_validate_flags()") Signed-off-by: Carlos Llamas Reviewed-by: Catalin Marinas Acked-by: Andrii Nakryiko Reviewed-by: Liam Howlett Cc: Christian Brauner (Microsoft) Cc: Michal Hocko Cc: Suren Baghdasaryan Cc: [5.10+] Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- mm/mmap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1845,7 +1845,7 @@ unsigned long mmap_region(struct file *f if (!arch_validate_flags(vma->vm_flags)) { error = -EINVAL; if (file) - goto unmap_and_free_vma; + goto close_and_free_vma; else goto free_vma; } @@ -1892,6 +1892,9 @@ out: return addr; +close_and_free_vma: + if (vma->vm_ops && vma->vm_ops->close) + vma->vm_ops->close(vma); unmap_and_free_vma: fput(vma->vm_file); vma->vm_file = NULL;