Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp747142ybl; Wed, 4 Dec 2019 10:11:14 -0800 (PST) X-Google-Smtp-Source: APXvYqwmW96ArtGMR/MlhLMKxEN4Wjiy1wCTX9e3OsI6Y8sTEfPH5rFdg4SIwExysLp9ylO7QAxG X-Received: by 2002:a05:6830:128e:: with SMTP id z14mr3450290otp.184.1575483074165; Wed, 04 Dec 2019 10:11:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1575483074; cv=none; d=google.com; s=arc-20160816; b=Z9KF+i31UDfhTMaF1RRtoBOUfixKcdEGxIQBOuoeDdbJLdux86Ju6G9zV1YaPZxn18 078H0ImmODxYio7h73kfJd7b2esEgVoEVHGdwhSaw9/i2tocQnUa2JMy5tGuGVOlEvK4 ILA7xP16G0t//TyMPq9ukDSd8Am9UzQQQdtAQueudzT38jhuQdDH+tUf14GuvATBDDBD 3olYo3pj/9IbVbfqUWI0+4+cvD2X+wIU1LNIMWXHvRHJjwcTi7bKdbiP9XLJJ47SiBUE REAnEuONDj14dauEZB840IRGHYWXEYhZtb7rZjvyXRI8atJQMW4onBo1Rx9zqMZH3wKA u3Bg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=0UdDhCe4aNe/OsfJY4skEJV5Zhw7lto/iY4klODINO4=; b=K5/Vp3eNgbrj268eszQlCADZ99aU4HF4JOQOBbpH99wsie31wZAwGg2Mw1dykVY84m Ni6ctRWPYNbxfv2OCh4L85M6yxv24uxisuF019HoCbzrlOIP8IG0ubPvCP9KiN0ZoWYu tHwaQX/YesVupDw4fxAJ10I5oFISTPAh5Lhr2bDABQ+snAhg7BhKluu1CAGQ6RsnvHLX qQ32Umw7ayL5FKj5XI1KQjMrhKGjslNHvpww/2zOJMTbE+WW2cfTcsnH3hRi5R1VME/J K460cCGAPcdfuXemvRBaIKgpq0XfnQyBa27YZR2kSm2UyDT1jZIn22sfl1l0Q0l4zhW1 HtCw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="ZVqvFR/f"; 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 k23si3827129otp.181.2019.12.04.10.11.00; Wed, 04 Dec 2019 10:11:14 -0800 (PST) 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; dkim=pass header.i=@kernel.org header.s=default header.b="ZVqvFR/f"; 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 S1730848AbfLDSJx (ORCPT + 99 others); Wed, 4 Dec 2019 13:09:53 -0500 Received: from mail.kernel.org ([198.145.29.99]:36036 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730618AbfLDSJs (ORCPT ); Wed, 4 Dec 2019 13:09:48 -0500 Received: from localhost (unknown [217.68.49.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E038F20674; Wed, 4 Dec 2019 18:09:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1575482987; bh=XyFLkTdl4aDMdEgk811XSgPvz0+1mZPG4xrPfFFvfek=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZVqvFR/f6OQwiOTRWdz46bh2GxHuKVwP5cUCKHaQouufjFzpjKqMtSrJWdwA8ehpU ryeqwM7NwWE1sod5JmDhuN3cWUl2cSLwSOLOEn55Qjg4kBByLNfF9xGgR+2ISRowe7 Luf6chvAl6+32kXsh6mOBwqK6tnP0cThZFrVP3HY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Thomas Gleixner , Ingo Molnar , "Peter Zijlstra (Intel)" Subject: [PATCH 4.14 194/209] futex: Provide state handling for exec() as well Date: Wed, 4 Dec 2019 18:56:46 +0100 Message-Id: <20191204175336.841457063@linuxfoundation.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191204175321.609072813@linuxfoundation.org> References: <20191204175321.609072813@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Thomas Gleixner commit af8cbda2cfcaa5515d61ec500498d46e9a8247e2 upstream. exec() attempts to handle potentially held futexes gracefully by running the futex exit handling code like exit() does. The current implementation has no protection against concurrent incoming waiters. The reason is that the futex state cannot be set to FUTEX_STATE_DEAD after the cleanup because the task struct is still active and just about to execute the new binary. While its arguably buggy when a task holds a futex over exec(), for consistency sake the state handling can at least cover the actual futex exit cleanup section. This provides state consistency protection accross the cleanup. As the futex state of the task becomes FUTEX_STATE_OK after the cleanup has been finished, this cannot prevent subsequent attempts to attach to the task in case that the cleanup was not successfull in mopping up all leftovers. Signed-off-by: Thomas Gleixner Reviewed-by: Ingo Molnar Acked-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20191106224556.753355618@linutronix.de Signed-off-by: Greg Kroah-Hartman --- kernel/futex.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) --- a/kernel/futex.c +++ b/kernel/futex.c @@ -3684,7 +3684,7 @@ static void exit_robust_list(struct task } } -void futex_exec_release(struct task_struct *tsk) +static void futex_cleanup(struct task_struct *tsk) { if (unlikely(tsk->robust_list)) { exit_robust_list(tsk); @@ -3724,7 +3724,7 @@ void futex_exit_recursive(struct task_st tsk->futex_state = FUTEX_STATE_DEAD; } -void futex_exit_release(struct task_struct *tsk) +static void futex_cleanup_begin(struct task_struct *tsk) { /* * Switch the state to FUTEX_STATE_EXITING under tsk->pi_lock. @@ -3740,10 +3740,40 @@ void futex_exit_release(struct task_stru raw_spin_lock_irq(&tsk->pi_lock); tsk->futex_state = FUTEX_STATE_EXITING; raw_spin_unlock_irq(&tsk->pi_lock); +} - futex_exec_release(tsk); +static void futex_cleanup_end(struct task_struct *tsk, int state) +{ + /* + * Lockless store. The only side effect is that an observer might + * take another loop until it becomes visible. + */ + tsk->futex_state = state; +} - tsk->futex_state = FUTEX_STATE_DEAD; +void futex_exec_release(struct task_struct *tsk) +{ + /* + * The state handling is done for consistency, but in the case of + * exec() there is no way to prevent futher damage as the PID stays + * the same. But for the unlikely and arguably buggy case that a + * futex is held on exec(), this provides at least as much state + * consistency protection which is possible. + */ + futex_cleanup_begin(tsk); + futex_cleanup(tsk); + /* + * Reset the state to FUTEX_STATE_OK. The task is alive and about + * exec a new binary. + */ + futex_cleanup_end(tsk, FUTEX_STATE_OK); +} + +void futex_exit_release(struct task_struct *tsk) +{ + futex_cleanup_begin(tsk); + futex_cleanup(tsk); + futex_cleanup_end(tsk, FUTEX_STATE_DEAD); } long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,