Skip to content

Commit 2ffb448

Browse files
committed
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer fix from Thomas Gleixner: "A single bugfix which prevents arbitrary sigev_notify values in posix-timers" * 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: posix-timer: Properly check sigevent->sigev_notify
2 parents c437279 + cef31d9 commit 2ffb448

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

kernel/time/posix-timers.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -434,17 +434,22 @@ static struct pid *good_sigevent(sigevent_t * event)
434434
{
435435
struct task_struct *rtn = current->group_leader;
436436

437-
if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
438-
(!(rtn = find_task_by_vpid(event->sigev_notify_thread_id)) ||
439-
!same_thread_group(rtn, current) ||
440-
(event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
437+
switch (event->sigev_notify) {
438+
case SIGEV_SIGNAL | SIGEV_THREAD_ID:
439+
rtn = find_task_by_vpid(event->sigev_notify_thread_id);
440+
if (!rtn || !same_thread_group(rtn, current))
441+
return NULL;
442+
/* FALLTHRU */
443+
case SIGEV_SIGNAL:
444+
case SIGEV_THREAD:
445+
if (event->sigev_signo <= 0 || event->sigev_signo > SIGRTMAX)
446+
return NULL;
447+
/* FALLTHRU */
448+
case SIGEV_NONE:
449+
return task_pid(rtn);
450+
default:
441451
return NULL;
442-
443-
if (((event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) &&
444-
((event->sigev_signo <= 0) || (event->sigev_signo > SIGRTMAX)))
445-
return NULL;
446-
447-
return task_pid(rtn);
452+
}
448453
}
449454

450455
static struct k_itimer * alloc_posix_timer(void)
@@ -669,7 +674,7 @@ void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
669674
struct timespec64 ts64;
670675
bool sig_none;
671676

672-
sig_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE;
677+
sig_none = timr->it_sigev_notify == SIGEV_NONE;
673678
iv = timr->it_interval;
674679

675680
/* interval timer ? */
@@ -856,7 +861,7 @@ int common_timer_set(struct k_itimer *timr, int flags,
856861

857862
timr->it_interval = timespec64_to_ktime(new_setting->it_interval);
858863
expires = timespec64_to_ktime(new_setting->it_value);
859-
sigev_none = (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE;
864+
sigev_none = timr->it_sigev_notify == SIGEV_NONE;
860865

861866
kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none);
862867
timr->it_active = !sigev_none;

0 commit comments

Comments
 (0)