From patchwork Tue Apr 26 22:52:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Eric W. Biederman" X-Patchwork-Id: 1622728 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=lWQ4PuTM; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Knxxb4HdRz9s3q for ; Wed, 27 Apr 2022 08:53:23 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Subject:MIME-Version:References: In-Reply-To:Message-Id:Date:Cc:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=X72EGzWb1myk/HaB7ZU88MVY+Qbrcu/nGB1JD3obNqE=; b=lWQ4PuTMykIPPxEzudpQfpz+Dh 8a7Hu16AdgLog7yGRPQuLvnTUtAeXuVdK+LfbCK71gR7fnLmcflfQZfIVCt3VS7G9eu2HyAztTw4i u2x6JQoZP5q5VD387ZbDbwlU9faaSvMTuuI4jK2/Dlxahk2l2GH5uV10iCDwLMih7KKHSwcUpd6mR VGUJ+tUkkgfh99N1zJqMJIzF+BGcvYYsZKrwiKJiaXUHuMhAgEpuWj+gqkNn/OBmSUYt5Erivkpk+ 8BGgG4gT3ludWSgcvo1DkZJCnDef9UrdJHpjr059v+YknfzGmgjiXTTqPoJGWsowb2atppWfBAztB qhjh9sVA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1njU3X-00GXFK-8I; Tue, 26 Apr 2022 22:53:15 +0000 Received: from out03.mta.xmission.com ([166.70.13.233]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1njU3T-00GXCa-Ns for linux-um@lists.infradead.org; Tue, 26 Apr 2022 22:53:14 +0000 Received: from in02.mta.xmission.com ([166.70.13.52]:60124) by out03.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1njU3S-007Fzy-R5; Tue, 26 Apr 2022 16:53:10 -0600 Received: from ip68-227-174-4.om.om.cox.net ([68.227.174.4]:35772 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1njU3R-006ASW-E4; Tue, 26 Apr 2022 16:53:10 -0600 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: rjw@rjwysocki.net, Oleg Nesterov , mingo@kernel.org, vincent.guittot@linaro.org, dietmar.eggemann@arm.com, rostedt@goodmis.org, mgorman@suse.de, bigeasy@linutronix.de, Will Deacon , tj@kernel.org, linux-pm@vger.kernel.org, Peter Zijlstra , Richard Weinberger , Anton Ivanov , Johannes Berg , linux-um@lists.infradead.org, Chris Zankel , Max Filippov , inux-xtensa@linux-xtensa.org, Kees Cook , Jann Horn , "Eric W. Biederman" Date: Tue, 26 Apr 2022 17:52:11 -0500 Message-Id: <20220426225211.308418-9-ebiederm@xmission.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <878rrrh32q.fsf_-_@email.froward.int.ebiederm.org> References: <878rrrh32q.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 X-XM-SPF: eid=1njU3R-006ASW-E4; ; ; mid=<20220426225211.308418-9-ebiederm@xmission.com>; ; ; hst=in02.mta.xmission.com; ; ; ip=68.227.174.4; ; ; frm=ebiederm@xmission.com; ; ; spf=softfail X-XM-AID: U2FsdGVkX19w1+3yMGSvM4LpuQLqkwbjRk3gRrqwCXE= X-SA-Exim-Connect-IP: 68.227.174.4 X-SA-Exim-Mail-From: ebiederm@xmission.com X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on sa01.xmission.com X-Spam-Level: **** X-Spam-Status: No, score=4.8 required=8.0 tests=ALL_TRUSTED,BAYES_50, DCC_CHECK_NEGATIVE,T_SCC_BODY_TEXT_LINE,T_TooManySym_01, T_TooManySym_02,XMNoVowels,XM_Body_Dirty_Words,XM_SPF_SoftFail autolearn=disabled version=3.4.2 X-Spam-Virus: No X-Spam-Report: * -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP * 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% * [score: 0.5000] * 1.5 XMNoVowels Alpha-numberic number with no vowels * -0.0 DCC_CHECK_NEGATIVE Not listed in DCC * [sa01 1397; Body=1 Fuz1=1 Fuz2=1] * 1.0 XM_Body_Dirty_Words Contains a dirty word * 0.0 T_TooManySym_01 4+ unique symbols in subject * 2.5 XM_SPF_SoftFail SPF-SoftFail * -0.0 T_SCC_BODY_TEXT_LINE No description available. * 0.0 T_TooManySym_02 5+ unique symbols in subject X-Spam-DCC: XMission; sa01 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: ****;linux-kernel@vger.kernel.org X-Spam-Relay-Country: X-Spam-Timing: total 561 ms - load_scoreonly_sql: 0.03 (0.0%), signal_user_changed: 3.9 (0.7%), b_tie_ro: 2.8 (0.5%), parse: 0.72 (0.1%), extract_message_metadata: 10 (1.8%), get_uri_detail_list: 1.75 (0.3%), tests_pri_-1000: 11 (2.0%), tests_pri_-950: 1.07 (0.2%), tests_pri_-900: 0.84 (0.2%), tests_pri_-90: 119 (21.3%), check_bayes: 118 (21.1%), b_tokenize: 9 (1.7%), b_tok_get_all: 9 (1.6%), b_comp_prob: 1.99 (0.4%), b_tok_touch_all: 94 (16.8%), b_finish: 0.63 (0.1%), tests_pri_0: 403 (71.9%), check_dkim_signature: 0.43 (0.1%), check_dkim_adsp: 1.77 (0.3%), poll_dns_idle: 0.41 (0.1%), tests_pri_10: 1.71 (0.3%), tests_pri_500: 7 (1.2%), rewrite_mail: 0.00 (0.0%) Subject: [PATCH 9/9] ptrace: Don't change __state X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220426_155311_826159_F90E94F0 X-CRM114-Status: GOOD ( 17.39 ) X-Spam-Score: -0.7 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Stop playing with tsk->__state to remove TASK_WAKEKILL while a ptrace command is executing. Instead implement a new jobtl flag JOBCTL_DELAY_WAKEKILL. This new flag is set in jobctl_freeze_task and cleared when ptrace_stop is awoken or in jobctl_unfreeze_task (when ptrace_stop remains asleep) [...] Content analysis details: (-0.7 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at https://www.dnswl.org/, low trust [166.70.13.233 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Stop playing with tsk->__state to remove TASK_WAKEKILL while a ptrace command is executing. Instead implement a new jobtl flag JOBCTL_DELAY_WAKEKILL. This new flag is set in jobctl_freeze_task and cleared when ptrace_stop is awoken or in jobctl_unfreeze_task (when ptrace_stop remains asleep). In signal_wake_up_state drop TASK_WAKEKILL from state if TASK_WAKEKILL is used while JOBCTL_DELAY_WAKEKILL is set. This has the same effect as changing TASK_TRACED to __TASK_TRACED as all of the wake_ups that use TASK_KILLABLE go through signal_wake_up except the wake_up in ptrace_unfreeze_traced. Previously the __state value of __TASK_TRACED was changed to TASK_RUNNING when woken up or back to TASK_TRACED when the code was left in ptrace_stop. Now when woken up ptrace_stop now clears JOBCTL_DELAY_WAKEKILL and when left sleeping ptrace_unfreezed_traced clears JOBCTL_DELAY_WAKEKILL. Signed-off-by: "Eric W. Biederman" --- include/linux/sched/jobctl.h | 2 ++ include/linux/sched/signal.h | 3 ++- kernel/ptrace.c | 11 +++++------ kernel/signal.c | 1 + 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/linux/sched/jobctl.h b/include/linux/sched/jobctl.h index fa067de9f1a9..4e154ad8205f 100644 --- a/include/linux/sched/jobctl.h +++ b/include/linux/sched/jobctl.h @@ -19,6 +19,7 @@ struct task_struct; #define JOBCTL_TRAPPING_BIT 21 /* switching to TRACED */ #define JOBCTL_LISTENING_BIT 22 /* ptracer is listening for events */ #define JOBCTL_TRAP_FREEZE_BIT 23 /* trap for cgroup freezer */ +#define JOBCTL_DELAY_WAKEKILL_BIT 24 /* delay killable wakeups */ #define JOBCTL_STOP_DEQUEUED (1UL << JOBCTL_STOP_DEQUEUED_BIT) #define JOBCTL_STOP_PENDING (1UL << JOBCTL_STOP_PENDING_BIT) @@ -28,6 +29,7 @@ struct task_struct; #define JOBCTL_TRAPPING (1UL << JOBCTL_TRAPPING_BIT) #define JOBCTL_LISTENING (1UL << JOBCTL_LISTENING_BIT) #define JOBCTL_TRAP_FREEZE (1UL << JOBCTL_TRAP_FREEZE_BIT) +#define JOBCTL_DELAY_WAKEKILL (1UL << JOBCTL_DELAY_WAKEKILL_BIT) #define JOBCTL_TRAP_MASK (JOBCTL_TRAP_STOP | JOBCTL_TRAP_NOTIFY) #define JOBCTL_PENDING_MASK (JOBCTL_STOP_PENDING | JOBCTL_TRAP_MASK) diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 3c8b34876744..1947c85aa9d9 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -437,7 +437,8 @@ extern void signal_wake_up_state(struct task_struct *t, unsigned int state); static inline void signal_wake_up(struct task_struct *t, bool resume) { - signal_wake_up_state(t, resume ? TASK_WAKEKILL : 0); + bool wakekill = resume && !(t->jobctl & JOBCTL_DELAY_WAKEKILL); + signal_wake_up_state(t, wakekill ? TASK_WAKEKILL : 0); } static inline void ptrace_signal_wake_up(struct task_struct *t, bool resume) { diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 842511ee9a9f..0bea74539320 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -194,7 +194,7 @@ static bool ptrace_freeze_traced(struct task_struct *task) if (task_is_traced(task) && !looks_like_a_spurious_pid(task) && !__fatal_signal_pending(task)) { - WRITE_ONCE(task->__state, __TASK_TRACED); + task->jobctl |= JOBCTL_DELAY_WAKEKILL; ret = true; } @@ -203,7 +203,7 @@ static bool ptrace_freeze_traced(struct task_struct *task) static void ptrace_unfreeze_traced(struct task_struct *task) { - if (READ_ONCE(task->__state) != __TASK_TRACED) + if (!(READ_ONCE(task->jobctl) & JOBCTL_DELAY_WAKEKILL)) return; WARN_ON(!task->ptrace || task->parent != current); @@ -213,11 +213,10 @@ static void ptrace_unfreeze_traced(struct task_struct *task) * Recheck state under the lock to close this race. */ spin_lock_irq(&task->sighand->siglock); - if (READ_ONCE(task->__state) == __TASK_TRACED) { + if (task->jobctl & JOBCTL_DELAY_WAKEKILL) { + task->jobctl &= ~JOBCTL_DELAY_WAKEKILL; if (__fatal_signal_pending(task)) wake_up_state(task, __TASK_TRACED); - else - WRITE_ONCE(task->__state, TASK_TRACED); } spin_unlock_irq(&task->sighand->siglock); } @@ -253,7 +252,7 @@ static int ptrace_check_attach(struct task_struct *child, bool ignore_state) */ if (lock_task_sighand(child, &flags)) { if (child->ptrace && child->parent == current) { - WARN_ON(READ_ONCE(child->__state) == __TASK_TRACED); + WARN_ON(child->jobctl & JOBCTL_DELAY_WAKEKILL); /* * child->sighand can't be NULL, release_task() * does ptrace_unlink() before __exit_signal(). diff --git a/kernel/signal.c b/kernel/signal.c index 584d67deb3cb..2b332f89cbad 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2307,6 +2307,7 @@ static int ptrace_stop(int exit_code, int why, int clear_code, /* LISTENING can be set only during STOP traps, clear it */ current->jobctl &= ~JOBCTL_LISTENING; + current->jobctl &= ~JOBCTL_DELAY_WAKEKILL; /* * Queued signals ignored us while we were stopped for tracing.