Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp720266pxb; Tue, 2 Feb 2021 16:38:29 -0800 (PST) X-Google-Smtp-Source: ABdhPJz01czbr/r++VLnsXR7308avvbBptvcjL0fP6lnGGb82XKCbbdB0MD1gZ1RZmpLpit5fFnE X-Received: by 2002:a17:906:7d4f:: with SMTP id l15mr568414ejp.95.1612312709015; Tue, 02 Feb 2021 16:38:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1612312709; cv=none; d=google.com; s=arc-20160816; b=lBHBSocbEGacAew8ZoZ/wyuF+9AGngZWRFNfHwgaQqYaQ1mCUf8IalZUQWnTDe6G1Y 4bn4nBaWCnlvs3rp2FvsOYUZ15macMG1tkdv9kxH6aSKsx7FK393DowFB3lsu/D8tYUy fUcdigQdsFqaHp1a5LnobzjY+2qEHFU0QodAO+DELGHeGZhqHMkFL4xdpwJcQQzFgaU9 MeHmyyrhrpB0zRxii7urs/NSmSqGHHNgj7OHaVUPj30x51XtlpgHby0sVyI8zl6BUbtW adcGmvKx472zOYqTOcSXw2TgqQtpNJexA9vxChLTAoFC13OvQXBH2YskTqeuqoW/NApd GOHw== 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=+ebTA6r8GbD80ZBkzn2qCvO6JUNfP4vzAjQz+yNt1qY=; b=OJLQqrrG3WMNK5CvFWKDmXvifejAe4zTrn4ZHxu4C1o1IVJ+sIxdmqbibJv69e1rxg RwQX4ceuh8WMwq42HdNezvJy0COTNjTobMx83TxxSycKcSqTQU1r7X4ry024I/UuXY0X uY6sQWpe0gMOBaMQXSNsu+5FdqwjsmO5+h10H6WY4NjyzOXNe5xP+W2mvxjIGldl64Wi bnLqnGbCOMpvS2wftjTysPckhb+gzho1U9PeVMvYzRUGtIKwKxeRDUwhmZ1vamy0p4js 4LHELIDxBIlcPdb+VTMJNUjOQk4aR+8cIfGlTmX9ASMa0GoSPbFZK8GtpOzOAhXLu+wG f2kw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="ir/CM/0A"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w1si284849ejn.628.2021.02.02.16.38.05; Tue, 02 Feb 2021 16:38:29 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="ir/CM/0A"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 S238508AbhBBS1G (ORCPT + 99 others); Tue, 2 Feb 2021 13:27:06 -0500 Received: from mail.kernel.org ([198.145.29.99]:48030 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233639AbhBBOGC (ORCPT ); Tue, 2 Feb 2021 09:06:02 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 2EE0864F89; Tue, 2 Feb 2021 13:49:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1612273746; bh=j+xZwxu3KrOGfnOrUx8aKqFaLLUXF/iAgHe03ZnFEvE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ir/CM/0AwQ93MDARXvk7uFV4jNRATy+lxy2YNsFnM24IhaRIuRKJEedb5QQdrIWhE ym46MA1wPeNU3k0nRPel2wmSie3c+o0hRLHgiaiAHDZjh/ZsTX9SY6tQZ1h7H2DDWZ IYjAB1BpYMVwrXk9CabneLnb2EfWBNjyCJO8iUL4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Greg Kroah-Hartman , Thomas Gleixner , Ingo Molnar , "Peter Zijlstra (Intel)" , Lee Jones Subject: [PATCH 4.4 15/28] futex: Provide state handling for exec() as well Date: Tue, 2 Feb 2021 14:38:35 +0100 Message-Id: <20210202132941.800726495@linuxfoundation.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210202132941.180062901@linuxfoundation.org> References: <20210202132941.180062901@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Lee Jones 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 @@ -3234,7 +3234,7 @@ static void exit_robust_list(struct task curr, pip); } -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); @@ -3274,7 +3274,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. @@ -3290,10 +3290,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,