From patchwork Sun Aug 26 06:42:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kroah-Hartman X-Patchwork-Id: 10576251 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9AABE109C for ; Sun, 26 Aug 2018 06:43:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 798BB29B4C for ; Sun, 26 Aug 2018 06:43:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6931B29B7E; Sun, 26 Aug 2018 06:43:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 85C3F29B4C for ; Sun, 26 Aug 2018 06:43:53 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 33D5E6B3976; Sun, 26 Aug 2018 02:43:52 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 29B1F6B3977; Sun, 26 Aug 2018 02:43:52 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0EEE26B3978; Sun, 26 Aug 2018 02:43:52 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) by kanga.kvack.org (Postfix) with ESMTP id C124E6B3976 for ; Sun, 26 Aug 2018 02:43:51 -0400 (EDT) Received: by mail-pf1-f199.google.com with SMTP id e15-v6so9278603pfi.5 for ; Sat, 25 Aug 2018 23:43:51 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references:user-agent :mime-version; bh=bdv6zMDFlMOZRqPSeZnID9UHzlEVTyK8Cxk/lv3oTzQ=; b=Ao8vbmLXiztpwbK0HCPpeU3boCNIzK7MEprEEibm2sTRTPpGmkwRLuNYCEzgSQXKHs HlWYNPv/IT0Xik+e7IjsyqTJYy6hqb8LqTYisz8HvytCzYBINzFLmtNO1Z/seYqudzXG JWEc+vs72cX/mDxxKza/OSk8cf7M5Sy83qxpY6Jqe4E5kN/5KelOICBw/WD/fGKhmWhs k8QxktnFdLcK3BatzXgKgtD+3hyDyidx0eSMdN30v4/0OcZ6QFrEM+V5yreUlst66BDO kuctxV6XdRpv5O9Mn1+DZdCe7WbhjMneoRGVcZkJkY1kCwD6xiKIMI1JG1OXNlmGwpH1 6DRQ== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of gregkh@linuxfoundation.org designates 140.211.169.12 as permitted sender) smtp.mailfrom=gregkh@linuxfoundation.org X-Gm-Message-State: APzg51D4yfULZeIafty4xxvq8Od5BS0wdqjwDhuuFI7RN2GPubs8rmo9 IH3aPlZSO34meKPJfzGDTOMd9aeYpK3lSlhHv1fkiXZBCMhBddxBqAR1P7KPxXv0cQ8HH8d1Stx ASYZn3vm45rqqMhZmknJqbOPWexewiFrcQcUub4loBWOBvOcs7KJQ5nvWzY9NS1Sj5g== X-Received: by 2002:a17:902:9f86:: with SMTP id g6-v6mr8198039plq.304.1535265831426; Sat, 25 Aug 2018 23:43:51 -0700 (PDT) X-Google-Smtp-Source: ANB0VdYI4vJVR0FTlZv8+LLONFD/cWayn/qFlHy9BLsfM/+vc3BLxqgX4NwnFeUmqB5mlJLfliq+ X-Received: by 2002:a17:902:9f86:: with SMTP id g6-v6mr8198008plq.304.1535265830494; Sat, 25 Aug 2018 23:43:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535265830; cv=none; d=google.com; s=arc-20160816; b=vopak/zmbRv1Ksrk72fgT4bjSdsn2vPov5lFXb/stIyL2ilAifwGqECLttv4VDTALV 9Rt46UvAqVtOcAU+ZNcm6p2J8UV9dFiEIJ62KfSPzwDGUDiD3gzhjXMhqENo17066OST YuolpTHxT9hVUt4pJn0flPockY/4+Puaj4c8QdOdicAJf3AKst5oOxb2rxjF6Ps52C8B 3wyutCIZKUIErITs357B9CSFuq549VtFZmqhzchXIb/vl5v/nE/VvirJSfXWKN8zdIfU 6LkBxvc+u110Who4UgzZsCYQD1OxpbJtbXcGmnr55Ea4PeIRH9wbcgyX0Z4E93MboJxs IFjw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=bdv6zMDFlMOZRqPSeZnID9UHzlEVTyK8Cxk/lv3oTzQ=; b=O7kbcPeK32WGXBwG5SqlQkOSlaLqAqcmorNDH+dfmgcTF4VYdvbwn2erTqAmGO5NMj HYlMrXAx2oaSnlvuzEiygPW/yAjHl22XDQLdOVA1IeR1PxkIpHsMY8X+PdcHEITKEZTQ 7TCQ3Sqor5j69/nh0mDHF672zGmtju64xoYB/3mdACqQnQ0gKAwuZhKU4htw6X0DXr1B Il97OVMUSOcq6VgY9zhRKOwfFh4yzsZmv4Ch/Mb4PvDWDFLDEm0PMYz37J2uEz4qwrYK bQvJuZQWxDSo5GdlgjtooIQsaboULOaYvFGW1IlZkcN/2OzR8Qz0M+FAZZsosBSlAttU oEcA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of gregkh@linuxfoundation.org designates 140.211.169.12 as permitted sender) smtp.mailfrom=gregkh@linuxfoundation.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org. [140.211.169.12]) by mx.google.com with ESMTPS id p35-v6si10794747pgb.209.2018.08.25.23.43.50 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 25 Aug 2018 23:43:50 -0700 (PDT) Received-SPF: pass (google.com: domain of gregkh@linuxfoundation.org designates 140.211.169.12 as permitted sender) client-ip=140.211.169.12; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gregkh@linuxfoundation.org designates 140.211.169.12 as permitted sender) smtp.mailfrom=gregkh@linuxfoundation.org Received: from localhost (5355525A.cm-6-6b.dynamic.ziggo.nl [83.85.82.90]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 4A83125A; Sun, 26 Aug 2018 06:43:49 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eric Biggers , Dave Hansen , Andrew Morton , Andy Lutomirski , Borislav Petkov , Brian Gerst , Christoph Hellwig , Denys Vlasenko , Dmitry Vyukov , Linus Torvalds , Michal Hocko , Peter Zijlstra , Rik van Riel , Tetsuo Handa , Thomas Gleixner , linux-mm@kvack.org, Ingo Molnar , Ben Hutchings Subject: [PATCH 4.4 2/5] x86/mm: Fix use-after-free of ldt_struct Date: Sun, 26 Aug 2018 08:42:54 +0200 Message-Id: <20180826064103.324031685@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180826064102.584749876@linuxfoundation.org> References: <20180826064102.584749876@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP 4.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Eric Biggers commit ccd5b3235180eef3cfec337df1c8554ab151b5cc upstream. The following commit: 39a0526fb3f7 ("x86/mm: Factor out LDT init from context init") renamed init_new_context() to init_new_context_ldt() and added a new init_new_context() which calls init_new_context_ldt(). However, the error code of init_new_context_ldt() was ignored. Consequently, if a memory allocation in alloc_ldt_struct() failed during a fork(), the ->context.ldt of the new task remained the same as that of the old task (due to the memcpy() in dup_mm()). ldt_struct's are not intended to be shared, so a use-after-free occurred after one task exited. Fix the bug by making init_new_context() pass through the error code of init_new_context_ldt(). This bug was found by syzkaller, which encountered the following splat: BUG: KASAN: use-after-free in free_ldt_struct.part.2+0x10a/0x150 arch/x86/kernel/ldt.c:116 Read of size 4 at addr ffff88006d2cb7c8 by task kworker/u9:0/3710 CPU: 1 PID: 3710 Comm: kworker/u9:0 Not tainted 4.13.0-rc4-next-20170811 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:16 [inline] dump_stack+0x194/0x257 lib/dump_stack.c:52 print_address_description+0x73/0x250 mm/kasan/report.c:252 kasan_report_error mm/kasan/report.c:351 [inline] kasan_report+0x24e/0x340 mm/kasan/report.c:409 __asan_report_load4_noabort+0x14/0x20 mm/kasan/report.c:429 free_ldt_struct.part.2+0x10a/0x150 arch/x86/kernel/ldt.c:116 free_ldt_struct arch/x86/kernel/ldt.c:173 [inline] destroy_context_ldt+0x60/0x80 arch/x86/kernel/ldt.c:171 destroy_context arch/x86/include/asm/mmu_context.h:157 [inline] __mmdrop+0xe9/0x530 kernel/fork.c:889 mmdrop include/linux/sched/mm.h:42 [inline] exec_mmap fs/exec.c:1061 [inline] flush_old_exec+0x173c/0x1ff0 fs/exec.c:1291 load_elf_binary+0x81f/0x4ba0 fs/binfmt_elf.c:855 search_binary_handler+0x142/0x6b0 fs/exec.c:1652 exec_binprm fs/exec.c:1694 [inline] do_execveat_common.isra.33+0x1746/0x22e0 fs/exec.c:1816 do_execve+0x31/0x40 fs/exec.c:1860 call_usermodehelper_exec_async+0x457/0x8f0 kernel/umh.c:100 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431 Allocated by task 3700: save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59 save_stack+0x43/0xd0 mm/kasan/kasan.c:447 set_track mm/kasan/kasan.c:459 [inline] kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551 kmem_cache_alloc_trace+0x136/0x750 mm/slab.c:3627 kmalloc include/linux/slab.h:493 [inline] alloc_ldt_struct+0x52/0x140 arch/x86/kernel/ldt.c:67 write_ldt+0x7b7/0xab0 arch/x86/kernel/ldt.c:277 sys_modify_ldt+0x1ef/0x240 arch/x86/kernel/ldt.c:307 entry_SYSCALL_64_fastpath+0x1f/0xbe Freed by task 3700: save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59 save_stack+0x43/0xd0 mm/kasan/kasan.c:447 set_track mm/kasan/kasan.c:459 [inline] kasan_slab_free+0x71/0xc0 mm/kasan/kasan.c:524 __cache_free mm/slab.c:3503 [inline] kfree+0xca/0x250 mm/slab.c:3820 free_ldt_struct.part.2+0xdd/0x150 arch/x86/kernel/ldt.c:121 free_ldt_struct arch/x86/kernel/ldt.c:173 [inline] destroy_context_ldt+0x60/0x80 arch/x86/kernel/ldt.c:171 destroy_context arch/x86/include/asm/mmu_context.h:157 [inline] __mmdrop+0xe9/0x530 kernel/fork.c:889 mmdrop include/linux/sched/mm.h:42 [inline] __mmput kernel/fork.c:916 [inline] mmput+0x541/0x6e0 kernel/fork.c:927 copy_process.part.36+0x22e1/0x4af0 kernel/fork.c:1931 copy_process kernel/fork.c:1546 [inline] _do_fork+0x1ef/0xfb0 kernel/fork.c:2025 SYSC_clone kernel/fork.c:2135 [inline] SyS_clone+0x37/0x50 kernel/fork.c:2129 do_syscall_64+0x26c/0x8c0 arch/x86/entry/common.c:287 return_from_SYSCALL_64+0x0/0x7a Here is a C reproducer: #include #include #include #include #include #include #include static void *fork_thread(void *_arg) { fork(); } int main(void) { struct user_desc desc = { .entry_number = 8191 }; syscall(__NR_modify_ldt, 1, &desc, sizeof(desc)); for (;;) { if (fork() == 0) { pthread_t t; srand(getpid()); pthread_create(&t, NULL, fork_thread, NULL); usleep(rand() % 10000); syscall(__NR_exit_group, 0); } wait(NULL); } } Note: the reproducer takes advantage of the fact that alloc_ldt_struct() may use vmalloc() to allocate a large ->entries array, and after commit: 5d17a73a2ebe ("vmalloc: back off when the current task is killed") it is possible for userspace to fail a task's vmalloc() by sending a fatal signal, e.g. via exit_group(). It would be more difficult to reproduce this bug on kernels without that commit. This bug only affected kernels with CONFIG_MODIFY_LDT_SYSCALL=y. Signed-off-by: Eric Biggers Acked-by: Dave Hansen Cc: [v4.6+] Cc: Andrew Morton Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Christoph Hellwig Cc: Denys Vlasenko Cc: Dmitry Vyukov Cc: Linus Torvalds Cc: Michal Hocko Cc: Peter Zijlstra Cc: Rik van Riel Cc: Tetsuo Handa Cc: Thomas Gleixner Cc: linux-mm@kvack.org Fixes: 39a0526fb3f7 ("x86/mm: Factor out LDT init from context init") Link: http://lkml.kernel.org/r/20170824175029.76040-1-ebiggers3@gmail.com Signed-off-by: Ingo Molnar Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- arch/x86/include/asm/mmu_context.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -109,8 +109,7 @@ static inline int init_new_context(struc struct mm_struct *mm) { mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id); - init_new_context_ldt(tsk, mm); - return 0; + return init_new_context_ldt(tsk, mm); } static inline void destroy_context(struct mm_struct *mm) {