From patchwork Mon Feb 1 10:01:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lee Jones X-Patchwork-Id: 374226 Delivered-To: patch@linaro.org Received: by 2002:a02:b18a:0:0:0:0:0 with SMTP id t10csp1120316jah; Mon, 1 Feb 2021 02:04:57 -0800 (PST) X-Google-Smtp-Source: ABdhPJxMV8N7vcNoXYvU6jS05fskzceP/BcswbKvCpqA+qEXRK9st+yYL55GGeiINTPruVLuabQG X-Received: by 2002:adf:8b41:: with SMTP id v1mr16930935wra.282.1612173897359; Mon, 01 Feb 2021 02:04:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1612173897; cv=none; d=google.com; s=arc-20160816; b=eAD2tJltnw6bI03469NmqnKlxMA/jdB7Bj7n7YK87YIMKDWfxVu94zVMhbNMXZcuE8 elwJjVmMBL30S2Y6w5DVnVerBv2V2Z3JA5L0n0cfcXjBL93haIImbegZWinB0x2F3Anh NqTYQ6zFd+hv6HeICxgfPPT73poV42Eo7kDQ08+O7JgnVPgxa6H6uYGI1hEwQ+YfiC9E kF5m1ZJN2KyN7eUnBFq74IKLT/J1l+ryPUjpFjw3Sx+kOJiDQsAFq0HO4/HLvzd0cbPy a927sMLrhEOMnTsk2YptrCA440FDKGEGGbXDpEXsnYzOcqnSi6GKjZAdSYp3zNanhnBc hKyQ== 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=Gg480XhfMoGXqP/teEw7Tq4vypgx+NgStVfH6LwTrK4=; b=Hz9mJtClQTAj+QtK1nBeG3kVAaTFy1sr/YeQukNUTMNV4XUpv048eOxKmmID/94xy0 1YJMvCeVoFPGgCECLpnrJbD93+tBdxBV13GDmB6UVqnRqtw2irDwuF9swzCXS26FP+n8 PW7d23IsJ6XhmfwV/XXS4EkFXnN1twe1a7N/KjBuxJvfjU+5yxZgequHOqGibbBql23j Uy4XH0SoTWCN2Wf+IlB6wMBUX1f89eBbRf1NXYw4V4RO8USqrq21HlUU40z5wXNVueNh 1r/FyA95cCOOfTJR2WBHCApdeE1xjuBUER3kpU2oP7+RL46X61tXqfbWZ6fZ+us/fQ/m XpKg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GAPw2+g8; 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 m6si13120787ejl.643.2021.02.01.02.04.57; Mon, 01 Feb 2021 02:04:57 -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=GAPw2+g8; 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 S232508AbhBAKDg (ORCPT + 13 others); Mon, 1 Feb 2021 05:03:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56208 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233009AbhBAKDf (ORCPT ); Mon, 1 Feb 2021 05:03:35 -0500 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EA80AC061793 for ; Mon, 1 Feb 2021 02:02:22 -0800 (PST) Received: by mail-wr1-x42d.google.com with SMTP id s7so12882235wru.5 for ; Mon, 01 Feb 2021 02:02:22 -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=Gg480XhfMoGXqP/teEw7Tq4vypgx+NgStVfH6LwTrK4=; b=GAPw2+g8hF10x6QLkaCRtPjUnas1YfgHqJSLyJkmj6r0J1kybPL+9KQdOCkc27eJnS YntJQMcPex5g0d+Y9o6ptI6hNfKmW9JIZb9x+aVm/6SSZ0vsumNlVMGboAk5EDg84g4I kR71FAKBtou87mbd5Z8yha3PDgvjXUX34dbHgLGgfLBie/ncoxdf9c9Iva4pOGwsQ65X z2gjH5OCxeMNSfLyxWl2viXFDH8TfsZgt91NvfXWji8H4VwsW7gIb2D9y595BwIthGql WUI62EE9IPaJGORSm1qBe23IbqNfy3jk3AayjMjIpDDQfpRK1FLc9P0nG9l0o2Bx1c/5 vfXQ== 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=Gg480XhfMoGXqP/teEw7Tq4vypgx+NgStVfH6LwTrK4=; b=R3XYKTm5vNVvdYIx8o9w3cIJfY6L95tdQLZiDE3tSOzvXSDuvkxjF4glCPqlC6cINZ MFzh8t17Ju2n1N0JhLzNPnFeLLvi5CPCw3Y7znIv5yXVYCWCUmjq7SvUI2NkH9WYgFJq qW2P/K/gGpKw479oBYjilCpjzHxuBQIUNwiYwttEgWwzXjNf1eORB36cJgwSM0nLKDe0 HkBtvLM8L7v+HUP/jWOEO5mB37u9FisakmksfBgKivoqR6F5LhURrDqkKg6czB9Brm1c iDckrUiCTavbq6rDH22Cs9l4C3FyEIEqo2ugqztXY/UWu3taikph9DHB4JK9YQbwVvy5 Y56g== X-Gm-Message-State: AOAM5319/cjBE+ehKX0XybQiHch2/HqqQnDoRwV0zrX8rAiMNzMwoTUu qHm8WePcbkvoiN0AHkuvBdWZkpyUub0bFXYq X-Received: by 2002:adf:eccc:: with SMTP id s12mr10973223wro.383.1612173741148; Mon, 01 Feb 2021 02:02:21 -0800 (PST) Received: from dell.default ([91.110.221.188]) by smtp.gmail.com with ESMTPSA id p15sm26151387wrt.15.2021.02.01.02.02.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Feb 2021 02:02:20 -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 10:01:40 +0000 Message-Id: <20210201100143.2028618-10-lee.jones@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210201100143.2028618-1-lee.jones@linaro.org> References: <20210201100143.2028618-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 f1e8ba64fe8ae..50f61d0e51b59 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -3269,7 +3269,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); @@ -3309,7 +3309,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. @@ -3325,10 +3325,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,