git: c48048ebdbed - releng/13.1 - kevent: Fix an off-by-one in filt_timerexpire_l()

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Tue, 09 Aug 2022 20:01:21 UTC
The branch releng/13.1 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=c48048ebdbed0901dacf1632af3b3db600533e64

commit c48048ebdbed0901dacf1632af3b3db600533e64
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-05-25 00:14:33 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-07-25 21:01:16 +0000

    kevent: Fix an off-by-one in filt_timerexpire_l()
    
    Suppose a periodic kevent timer fires close to its deadline, so that
    now - kc->next is small.  Then delta ends up being 1, and the next timer
    deadline is set to (delta + 1) * kc->to, where kc->to is the timer
    period.  This means that the timer fires at half of the requested rate,
    and the value returned in kn_data is similarly inaccurate.
    
    Approved by:    so
    Security:       FreeBSD-EN-22:16.kqueue
    PR:             264131
    Fixes:          7cb40543e964 ("filt_timerexpire: do not iterate over the interval")
    Reviewed by:    kib
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit 524dadf7a8725dea144571843e611dbdbd59d668)
    (cherry picked from commit 129112f80d2bfe6091ebb8656912fb55d6192e1f)
---
 sys/kern/kern_event.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 2e9773ab5701..e40d4b192dce 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -739,7 +739,7 @@ filt_timerexpire_l(struct knote *kn, bool proc_locked)
 		if (delta == 0)
 			delta = 1;
 		kn->kn_data += delta;
-		kc->next += (delta + 1) * kc->to;
+		kc->next += delta * kc->to;
 		if (now >= kc->next)	/* overflow */
 			kc->next = now + kc->to;
 		KNOTE_ACTIVATE(kn, 0);	/* XXX - handle locking */