Received: by 2002:a25:d783:0:0:0:0:0 with SMTP id o125csp421658ybg; Thu, 19 Mar 2020 02:12:15 -0700 (PDT) X-Google-Smtp-Source: ADFU+vvjAYAcztjUUfEV8tS/5AEQFHhnhUxQh0/gmeGYPCIpU8BUSFBKncb8zmkAAoGnaUJKZw7P X-Received: by 2002:a9d:ed5:: with SMTP id 79mr1338852otj.249.1584609135501; Thu, 19 Mar 2020 02:12:15 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1584609135; cv=pass; d=google.com; s=arc-20160816; b=yrriSinzRN9/xOSwcDuHibf18HQU8405br9Q334E1sTdRhOemH9sYV6EUWkzay43oh z2AYJJXdrZL+xdcV/fxvSg8fMAJFDJPXH21dzxle+kp0T2mzzYZrx126C3T6m62PARKr /7i3foPKwkf7D9xz/iisZz3MzihzqCEch8jb4sxr9n5GRzWhWtkgTkE1KPswRsxixTMI KCbr+/Kg6z0yErD/VQBuxGZyOH8rVWeFwVtarkpYpv8o3H0k5y5u05ZrDAgwP/5/TTQ7 IDOEhWM8jV7gMcNSL+IT4JmUpAwThyLnJ5rkeMMfDPeTopqUbFd5P9fA+SC2L/7OPjPi MSsA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:content-transfer-encoding :content-language:in-reply-to:user-agent:date:message-id:from :references:cc:to:subject; bh=M6Zf693PqKTwm+2AFvFdyTwzkzlXWQHguT96lAyBWjs=; b=Sq5KjXMcHaaWWi98/HtwHj9e/o5OGPziLuwi5Y37/rSfs/kHdiO6wEZJQWE1g9CZ5G hPe5t1ZXWOnuN9L4WselOtwMq0xq8azIk5RS2BbckiNaeRFrQMZ+3r90a0HvPrG1XsBS K2f5KTKKEpJcKtVHs3eUuulc8d12QejCEmzk466KYLEzzQX48eyzWycz2Khwkbe90URT znj6ZqcxTJPF7ZS7WUceGWy48ZYxbsJGVgQAEcpt8zdD3pxrSnIClhcbD5lVnSp7uVjN TRTbfqkBkVhSdEKlOqQI5EPHPZ7vn6n5/+fRL7N602Wdfw/pivGrY6PpPpXARkEV5tuC WOqg== ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1 spf=pass spfdomain=hotmail.de dkim=pass dkdomain=hotmail.de dmarc=pass fromdomain=hotmail.de); spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d19si987068otq.162.2020.03.19.02.12.00; Thu, 19 Mar 2020 02:12:15 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; arc=pass (i=1 spf=pass spfdomain=hotmail.de dkim=pass dkdomain=hotmail.de dmarc=pass fromdomain=hotmail.de); spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726802AbgCSJLZ (ORCPT + 99 others); Thu, 19 Mar 2020 05:11:25 -0400 Received: from mail-oln040092074098.outbound.protection.outlook.com ([40.92.74.98]:5349 "EHLO EUR04-DB3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725768AbgCSJLY (ORCPT ); Thu, 19 Mar 2020 05:11:24 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=EBCJ44uvG6TRKCY1RaBEa2A0CTq7l7PaePBTx37XZQS6sRZm07l9GF8baau7UUsPsEUHctvOWnYvllB9/mmZC/ZlWAp3PRCfm/z3eHZPfJdCn8EO1cc1cSsF2Uio6T2RAtMGpkgLMaL4E/w2MzzBJ+KX4X/hZaN6S9y5znNKblkjMpYhkG2Tmj+9aJYBOJ9z1QzVahpuaLgCuNASpgRp+IU+tiA2nwYcvGQz7h1+BolZjVkZjiOrQZO2SrO5fGeMaN4XegmWxQ5gv2jQHh6BxRUAUHMN4iarLxrUOqKeSAlkdgqTzDg2RCgR4vuqlZspMz08+YqHC0GDk4YKO7dmJw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=M6Zf693PqKTwm+2AFvFdyTwzkzlXWQHguT96lAyBWjs=; b=HQffjxRopqYAzwQzOgZ6UmNuyV/BKSMEBjTtlANLTDPA/nIUmJ2TFIhEiGfKXEkZXBvQcHIv6XCKauqnBzjAyRnVa+evWzen8X+EADsFj1To/evoAGC+FirOK6dnvmftY4O4BDleoNp1OkZsEY6BdFm8BkItDfyy1WoppskCCYXkdLFAYmc0TwIjhqyT/KDnHgqkENRmYo/zQuRimt8kJXAKJtKbi2EnnbFa8VE0MJX0wADB1viN+j21ruDUDoOAUYhwG4AHdxsqel3du2fEp5xBZ62p9RW3zX7APrj6O/hVhhl0cp+p2R5XEdbqaMh1bU9n2dKUbdoJ4HR+NKwMrg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=hotmail.de; dmarc=pass action=none header.from=hotmail.de; dkim=pass header.d=hotmail.de; arc=none Received: from DB3EUR04FT050.eop-eur04.prod.protection.outlook.com (2a01:111:e400:7e0c::39) by DB3EUR04HT066.eop-eur04.prod.protection.outlook.com (2a01:111:e400:7e0c::112) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2814.13; Thu, 19 Mar 2020 09:11:19 +0000 Received: from AM6PR03MB5170.eurprd03.prod.outlook.com (10.152.24.54) by DB3EUR04FT050.mail.protection.outlook.com (10.152.25.40) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2814.13 via Frontend Transport; Thu, 19 Mar 2020 09:11:19 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:5D2793E39F81A693413BF2209189FA08859817F1A54A74D20D8ECB61A115CD01;UpperCasedChecksum:FC53E4E716F6644F3C21D7F2D4647851A908713AD995630AAA47BAC2308BE132;SizeAsReceived:10329;Count:50 Received: from AM6PR03MB5170.eurprd03.prod.outlook.com ([fe80::1956:d274:cab3:b4dd]) by AM6PR03MB5170.eurprd03.prod.outlook.com ([fe80::1956:d274:cab3:b4dd%6]) with mapi id 15.20.2835.017; Thu, 19 Mar 2020 09:11:19 +0000 Subject: [PATCH v4 3/5] exec: Add a exec_update_mutex to replace cred_guard_mutex To: Kirill Tkhai , "Eric W. Biederman" Cc: Christian Brauner , Kees Cook , Jann Horn , Jonathan Corbet , Alexander Viro , Andrew Morton , Alexey Dobriyan , Thomas Gleixner , Oleg Nesterov , Frederic Weisbecker , Andrei Vagin , Ingo Molnar , "Peter Zijlstra (Intel)" , Yuyang Du , David Hildenbrand , Sebastian Andrzej Siewior , Anshuman Khandual , David Howells , James Morris , Greg Kroah-Hartman , Shakeel Butt , Jason Gunthorpe , Christian Kellner , Andrea Arcangeli , Aleksa Sarai , "Dmitry V. Levin" , "linux-doc@vger.kernel.org" , "linux-kernel@vger.kernel.org" , "linux-fsdevel@vger.kernel.org" , "linux-mm@kvack.org" , "stable@vger.kernel.org" , "linux-api@vger.kernel.org" References: <87tv32cxmf.fsf_-_@x220.int.ebiederm.org> <87v9ne5y4y.fsf_-_@x220.int.ebiederm.org> <87zhcq4jdj.fsf_-_@x220.int.ebiederm.org> <87d09hn4kt.fsf@x220.int.ebiederm.org> <87lfo5lju6.fsf@x220.int.ebiederm.org> <6002ac56-025a-d50f-e89d-1bf42a072323@virtuozzo.com> <532ce6a3-f0df-e3e4-6966-473c608246e1@virtuozzo.com> <13c4d333-9c33-8036-3142-dac22c392c60@virtuozzo.com> From: Bernd Edlinger Message-ID: Date: Thu, 19 Mar 2020 10:11:16 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 In-Reply-To: Content-Type: text/plain; charset=windows-1252 Content-Language: en-US Content-Transfer-Encoding: 7bit X-ClientProxiedBy: AM0PR10CA0024.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:208:17c::34) To AM6PR03MB5170.eurprd03.prod.outlook.com (2603:10a6:20b:ca::23) X-Microsoft-Original-Message-ID: <32e92c05-07dd-5bb3-17eb-eec9b0bc63f1@hotmail.de> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from [192.168.1.101] (92.77.140.102) by AM0PR10CA0024.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:208:17c::34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2835.19 via Frontend Transport; Thu, 19 Mar 2020 09:11:17 +0000 X-Microsoft-Original-Message-ID: <32e92c05-07dd-5bb3-17eb-eec9b0bc63f1@hotmail.de> X-TMN: [TIoTuy8cwk9b8aiqKMmCajnpMrUil7X8] X-MS-PublicTrafficType: Email X-IncomingHeaderCount: 50 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-Correlation-Id: c74fc608-d767-4308-95f2-08d7cbe57c39 X-MS-TrafficTypeDiagnostic: DB3EUR04HT066: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: rGGJl70h+06uEfmQocyxHAqviykCxbYslziNNQl5WeILa/4XEemUuclQ8+kSDhZ1uTgW7hww+TFAIFncRYTpH1Fuc/xc8rUho2oYMF71eX6NSSTesnZTMHx80zczOQTdQA+8RckcRADDxy2Los6xn/DsWUzbYn2XWTwSGih9BEk26VHZkbXIKcn/oxIzX0eAolheSGeynG4N2r6tDps3TvqSIfpkAFNEyV63six4/y0= X-MS-Exchange-AntiSpam-MessageData: /NxAVRebzc4Y4XpE1PDkV5XCJldgohAEUC1wkAYV390iNCNs5zFm61+/w63JnRjwzA0IlARcwy4mCmnx55wmOFkEG46JNat15fGki9g8p6X+PsRXhDwt4q1oZB+4jmn92ASGsaI1UK7p1bh2pxea3g== X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: c74fc608-d767-4308-95f2-08d7cbe57c39 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Mar 2020 09:11:19.3389 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB3EUR04HT066 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The cred_guard_mutex is problematic. The cred_guard_mutex is held over the userspace accesses as the arguments from userspace are read. The cred_guard_mutex is held of PTRACE_EVENT_EXIT as the the other threads are killed. The cred_guard_mutex is held over "put_user(0, tsk->clear_child_tid)" in exit_mm(). Any of those can result in deadlock, as the cred_guard_mutex is held over a possible indefinite userspace waits for userspace. Add exec_update_mutex that is only held over exec updating process with the new contents of exec, so that code that needs not to be confused by exec changing the mm and the cred in ways that can not happen during ordinary execution of a process. The plan is to switch the users of cred_guard_mutex to exec_udpate_mutex one by one. This lets us move forward while still being careful and not introducing any regressions. Link: https://lore.kernel.org/lkml/20160921152946.GA24210@dhcp22.suse.cz/ Link: https://lore.kernel.org/lkml/AM6PR03MB5170B06F3A2B75EFB98D071AE4E60@AM6PR03MB5170.eurprd03.prod.outlook.com/ Link: https://lore.kernel.org/linux-fsdevel/20161102181806.GB1112@redhat.com/ Link: https://lore.kernel.org/lkml/20160923095031.GA14923@redhat.com/ Link: https://lore.kernel.org/lkml/20170213141452.GA30203@redhat.com/ Ref: 45c1a159b85b ("Add PTRACE_O_TRACEVFORKDONE and PTRACE_O_TRACEEXIT facilities.") Ref: 456f17cd1a28 ("[PATCH] user-vm-unlock-2.5.31-A2") Signed-off-by: "Eric W. Biederman" Signed-off-by: Bernd Edlinger --- fs/exec.c | 22 +++++++++++++++++++--- include/linux/binfmts.h | 8 +++++++- include/linux/sched/signal.h | 9 ++++++++- init/init_task.c | 1 + kernel/fork.c | 1 + 5 files changed, 36 insertions(+), 5 deletions(-) v3: this update fixes lock-order and adds an explicit data member in linux_binprm v4: add a function comment to exec_mmap diff --git a/fs/exec.c b/fs/exec.c index d820a72..0e46ec5 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1010,16 +1010,26 @@ ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len) } EXPORT_SYMBOL(read_code); +/* + * Maps the mm_struct mm into the current task struct. + * On success, this function returns with the mutex + * exec_update_mutex locked. + */ static int exec_mmap(struct mm_struct *mm) { struct task_struct *tsk; struct mm_struct *old_mm, *active_mm; + int ret; /* Notify parent that we're no longer interested in the old VM */ tsk = current; old_mm = current->mm; exec_mm_release(tsk, old_mm); + ret = mutex_lock_killable(&tsk->signal->exec_update_mutex); + if (ret) + return ret; + if (old_mm) { sync_mm_rss(old_mm); /* @@ -1031,9 +1041,11 @@ static int exec_mmap(struct mm_struct *mm) down_read(&old_mm->mmap_sem); if (unlikely(old_mm->core_state)) { up_read(&old_mm->mmap_sem); + mutex_unlock(&tsk->signal->exec_update_mutex); return -EINTR; } } + task_lock(tsk); active_mm = tsk->active_mm; membarrier_exec_mmap(mm); @@ -1288,11 +1300,12 @@ int flush_old_exec(struct linux_binprm * bprm) goto out; /* - * After clearing bprm->mm (to mark that current is using the - * prepared mm now), we have nothing left of the original + * After setting bprm->called_exec_mmap (to mark that current is + * using the prepared mm now), we have nothing left of the original * process. If anything from here on returns an error, the check * in search_binary_handler() will SEGV current. */ + bprm->called_exec_mmap = 1; bprm->mm = NULL; #ifdef CONFIG_POSIX_TIMERS @@ -1438,6 +1451,8 @@ static void free_bprm(struct linux_binprm *bprm) { free_arg_pages(bprm); if (bprm->cred) { + if (bprm->called_exec_mmap) + mutex_unlock(¤t->signal->exec_update_mutex); mutex_unlock(¤t->signal->cred_guard_mutex); abort_creds(bprm->cred); } @@ -1487,6 +1502,7 @@ void install_exec_creds(struct linux_binprm *bprm) * credentials; any time after this it may be unlocked. */ security_bprm_committed_creds(bprm); + mutex_unlock(¤t->signal->exec_update_mutex); mutex_unlock(¤t->signal->cred_guard_mutex); } EXPORT_SYMBOL(install_exec_creds); @@ -1678,7 +1694,7 @@ int search_binary_handler(struct linux_binprm *bprm) read_lock(&binfmt_lock); put_binfmt(fmt); - if (retval < 0 && !bprm->mm) { + if (retval < 0 && bprm->called_exec_mmap) { /* we got to flush_old_exec() and failed after it */ read_unlock(&binfmt_lock); force_sigsegv(SIGSEGV); diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index b40fc63..a345d9f 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -44,7 +44,13 @@ struct linux_binprm { * exec has happened. Used to sanitize execution environment * and to set AT_SECURE auxv for glibc. */ - secureexec:1; + secureexec:1, + /* + * Set by flush_old_exec, when exec_mmap has been called. + * This is past the point of no return, when the + * exec_update_mutex has been taken. + */ + called_exec_mmap:1; #ifdef __alpha__ unsigned int taso:1; #endif diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 8805025..a29df79 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -224,7 +224,14 @@ struct signal_struct { struct mutex cred_guard_mutex; /* guard against foreign influences on * credential calculations - * (notably. ptrace) */ + * (notably. ptrace) + * Deprecated do not use in new code. + * Use exec_update_mutex instead. + */ + struct mutex exec_update_mutex; /* Held while task_struct is being + * updated during exec, and may have + * inconsistent permissions. + */ } __randomize_layout; /* diff --git a/init/init_task.c b/init/init_task.c index 9e5cbe5..bd403ed 100644 --- a/init/init_task.c +++ b/init/init_task.c @@ -26,6 +26,7 @@ .multiprocess = HLIST_HEAD_INIT, .rlim = INIT_RLIMITS, .cred_guard_mutex = __MUTEX_INITIALIZER(init_signals.cred_guard_mutex), + .exec_update_mutex = __MUTEX_INITIALIZER(init_signals.exec_update_mutex), #ifdef CONFIG_POSIX_TIMERS .posix_timers = LIST_HEAD_INIT(init_signals.posix_timers), .cputimer = { diff --git a/kernel/fork.c b/kernel/fork.c index 8642530..036b692 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1594,6 +1594,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) sig->oom_score_adj_min = current->signal->oom_score_adj_min; mutex_init(&sig->cred_guard_mutex); + mutex_init(&sig->exec_update_mutex); return 0; } -- 1.9.1