git: 693664482649 - stable/14 - proc: Disallow re-enabling of process itimers during exit
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 15 Apr 2025 02:25:38 UTC
The branch stable/14 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=69366448264956c18d0b46f900593442ed8e79ba
commit 69366448264956c18d0b46f900593442ed8e79ba
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-03-31 01:22:14 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-04-15 02:25:24 +0000
proc: Disallow re-enabling of process itimers during exit
During process exit, it's possible for the exiting thread to send a
signal to its process, via killjobc(). This happens after the itimer is
drained. If itimers are stopped, i.e., P2_ITSTOPPED is set, then
itimer_proc_continue() will resume the callout after it has been
drained.
Fix the problem by simply clearing P2_ITSTOPPED as part of the drain.
Then, a signal received after that point will not re-enable the callout.
For good measure, also make sure that we don't reset the itimer callout
in an exiting process.
Reported by: syzkaller
Reviewed by: kib
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D49529
(cherry picked from commit a6268f89d58c1962d2372a664a35eaecbf367fbb)
---
sys/kern/kern_exit.c | 1 +
sys/kern/kern_time.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 788b58da450d..0c3070f2e360 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -377,6 +377,7 @@ exit1(struct thread *td, int rval, int signo)
* Stop the real interval timer. If the handler is currently
* executing, prevent it from rearming itself and let it finish.
*/
+ p->p_flag2 &= ~P2_ITSTOPPED;
if (timevalisset(&p->p_realtimer.it_value) &&
callout_stop(&p->p_itcallout) == 0) {
timevalclear(&p->p_realtimer.it_interval);
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index d109dbb509dd..000394d7f4b8 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -885,6 +885,8 @@ realitexpire_reset_callout(struct proc *p, sbintime_t *isbtp)
{
sbintime_t prec;
+ if ((p->p_flag & P_WEXIT) != 0)
+ return;
prec = isbtp == NULL ? tvtosbt(p->p_realtimer.it_interval) : *isbtp;
callout_reset_sbt(&p->p_itcallout, tvtosbt(p->p_realtimer.it_value),
prec >> tc_precexp, realitexpire, p, C_ABSOLUTE);