summaryrefslogtreecommitdiff
path: root/kernel/time/posix-timers.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2024-10-01 10:42:00 +0200
committerThomas Gleixner <tglx@linutronix.de>2024-10-29 11:43:18 +0100
commit68f99be287a59d50a9ad231d523f7e578f8bd28a (patch)
treeccd6b69aa68725390557779e19ea1fbad12dd212 /kernel/time/posix-timers.c
parent92b043fd995a63a57aae29ff85a39b6f30cd440c (diff)
signal: Confine POSIX_TIMERS properly
Move the itimer rearming out of the signal code and consolidate all posix timer related functions in the signal code under one ifdef. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Frederic Weisbecker <frederic@kernel.org> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/all/20241001083835.314100569@linutronix.de
Diffstat (limited to 'kernel/time/posix-timers.c')
-rw-r--r--kernel/time/posix-timers.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index fc40dacabe78..d461a32b7260 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -251,7 +251,7 @@ static void common_hrtimer_rearm(struct k_itimer *timr)
/*
* This function is called from the signal delivery code if
- * info->si_sys_private is not zero, which indicates that the timer has to
+ * info::si_sys_private is not zero, which indicates that the timer has to
* be rearmed. Restart the timer and update info::si_overrun.
*/
void posixtimer_rearm(struct kernel_siginfo *info)
@@ -259,9 +259,15 @@ void posixtimer_rearm(struct kernel_siginfo *info)
struct k_itimer *timr;
unsigned long flags;
+ /*
+ * Release siglock to ensure proper locking order versus
+ * timr::it_lock. Keep interrupts disabled.
+ */
+ spin_unlock(&current->sighand->siglock);
+
timr = lock_timer(info->si_tid, &flags);
if (!timr)
- return;
+ goto out;
if (timr->it_interval && timr->it_requeue_pending == info->si_sys_private) {
timr->kclock->timer_rearm(timr);
@@ -275,6 +281,11 @@ void posixtimer_rearm(struct kernel_siginfo *info)
}
unlock_timer(timr, flags);
+out:
+ spin_lock(&current->sighand->siglock);
+
+ /* Don't expose the si_sys_private value to userspace */
+ info->si_sys_private = 0;
}
int posix_timer_queue_signal(struct k_itimer *timr)