From patchwork Mon Feb 1 15:12:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lee Jones X-Patchwork-Id: 374267 Delivered-To: patch@linaro.org Received: by 2002:a02:b18a:0:0:0:0:0 with SMTP id t10csp1383175jah; Mon, 1 Feb 2021 07:16:11 -0800 (PST) X-Google-Smtp-Source: ABdhPJxzNlLLWk9TvsGiDHqU3eRxS8f4qB/YrPAhB5sfIy8FtCR0lCTm9GdG/WB8gTa54HQdy8a8 X-Received: by 2002:a17:906:3ad0:: with SMTP id z16mr18355091ejd.72.1612192571675; Mon, 01 Feb 2021 07:16:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1612192571; cv=none; d=google.com; s=arc-20160816; b=ajuTQMN3eiUjBaIP0ZFc9NeBybjYKrcdhbzHCAYfRkUW1P8yLMyt5ip/g2gIvt1mn3 vY5ZSICczFIJNSM/r9leb4jh8YmgjXiwUyOu7Li+AuDivu9ZikMunO+kZcJDLRTA43S4 KYngDTL9Y3fVrxCrjy8gyXUo5JkWZEw1KMIx43tkRpkoj3n1npbfVH94mgVi+G4ylq88 Q9NJQrI1YgUd4F671+ESOVmr2K5B3Fo/rRMbYI4G7IwiqeG9OeThp0uhQjHSrG4u7UAC 8LTjXVfu9mnpxXN+mgn+TWQtBt8HHQYU/ICMMl8B6HUA6yF/jVJrhM1sEqIDvfSU9qFn 2C+A== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=MCVDRoiJdy/Do7csl/30kMZE1zZamBX1lgP8roH5D6M=; b=XC7PSRXXzuwGSIkN+7w7R0P5FaFfM+Er+JiU08fQMDNQpDk0feadFMGDLrs61Whh0X lB6fNYEsXkKV2z/S5n0/9tVBGJ5tN61dUn1thXetfi5MexuZsuwDed41I5JBYiBu0SLi TjZe7TfPWJWvLGI2kwu+xP7MqT37SI/WHneg8mYlL4dah68JAo2J/bK3aiQcpx/7YWb9 imyBmsqNry6IDiRjvo83X2wZmi+4+kcQxcusz4xRjWG1P+hOl6LcI1xaniIe6vBDoYfN MHw7oezLeqcJdFNHIJ0jDdASMiE2ZSAt9PQ7ecUSRym9ADH5jt8F7enMc1/Li4nnCs7M kugA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=J0w3ovp+; spf=pass (google.com: domain of stable-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id f29si11574766edj.297.2021.02.01.07.16.11; Mon, 01 Feb 2021 07:16:11 -0800 (PST) Received-SPF: pass (google.com: domain of stable-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=@linaro.org header.s=google header.b=J0w3ovp+; spf=pass (google.com: domain of stable-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231320AbhBAPPC (ORCPT + 13 others); Mon, 1 Feb 2021 10:15:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231440AbhBAPO5 (ORCPT ); Mon, 1 Feb 2021 10:14:57 -0500 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F13FC061793 for ; Mon, 1 Feb 2021 07:13:45 -0800 (PST) Received: by mail-wm1-x32f.google.com with SMTP id u14so12938060wml.4 for ; Mon, 01 Feb 2021 07:13:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=MCVDRoiJdy/Do7csl/30kMZE1zZamBX1lgP8roH5D6M=; b=J0w3ovp+vCnLYkGRkQmCZ5FrnFU7ex17dn7x5K7Lanyd942kM8Ds9aw6A37qAVCaqE gKyJADcqGLD3xtd/vGi51UshfYvnfNO7ZoyOBaFnRTl+93uMy50Z3lkKP8CEjzcyQCqI y9OM7lMce+gVaCF63DzI9EDh/MzOckGMmFAlvACObd2MMSFscAMeFDkkjunhYwEvnvft m6DmK97o8D3E1ir8x6snqV5Jg8hAhH5sbGYZCDPAK+s1Bzxr+2G0lH5qQEuL9MgMQfkz sHHEGc68AfLV4/aLLTJtaBvrIWv32XGakJBFmTKfbRW4Gm+Ho9rTdN6kvbVvgT91uBer fW8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=MCVDRoiJdy/Do7csl/30kMZE1zZamBX1lgP8roH5D6M=; b=t4UrTgqGLk/eeGVkqsedaSAM3Wy6qTjZRTbUtmhNv6gACqxrb0KZc1t9sRaCAHQGFw UYbOlnoX6+ZOoWf9glxJyJFgeBjYZRMTjVy2vl0K1OBCu9R5rzgqDObEGLhBqMTtlBL5 V+bcyd/BEtHFiKd0IQY/hGCZrDD6P94yPumpBVb4sGTsXaGCTNXPDvOm1XC949oSQ8DC rFvslfM5QPbNdusSRoc9P791iPvKQi8TPWB+qjAC0CWycrw5s0LAWrjY/rKjvT+rxVBn XIaz2E90GZk7sE5Z5ncrH8XlyPAScuh6lTimU96M3DlbhHmZsdjmi5HU1rqJVtpVirsL B/VQ== X-Gm-Message-State: AOAM530yGlKIdhJfXBfQaIFS/t2xlqPqEzvIK15uftEVOhrgVsQVRbOo UFNM8MKqAYW8TsGadCKBFIQn9+SMeT8sWF8P X-Received: by 2002:a1c:4c0a:: with SMTP id z10mr7427390wmf.163.1612192423862; Mon, 01 Feb 2021 07:13:43 -0800 (PST) Received: from dell.default ([91.110.221.188]) by smtp.gmail.com with ESMTPSA id 192sm23323381wme.27.2021.02.01.07.13.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Feb 2021 07:13:43 -0800 (PST) From: Lee Jones To: stable@vger.kernel.org Cc: Thomas Gleixner , Ingo Molnar , Peter Zijlstra , Greg Kroah-Hartman , Lee Jones Subject: [PATCH 09/12] futex: Provide state handling for exec() as well Date: Mon, 1 Feb 2021 15:12:11 +0000 Message-Id: <20210201151214.2193508-10-lee.jones@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210201151214.2193508-1-lee.jones@linaro.org> References: <20210201151214.2193508-1-lee.jones@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: stable@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 --- kernel/futex.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) -- 2.25.1 diff --git a/kernel/futex.c b/kernel/futex.c index 0efcb55455c2a..feef5ce071aa5 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -3234,7 +3234,7 @@ static void exit_robust_list(struct task_struct *curr) 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_struct *tsk) 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_struct *tsk) 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,