diff options
Diffstat (limited to 'kernel/time/alarmtimer.c')
| -rw-r--r-- | kernel/time/alarmtimer.c | 14 | 
1 files changed, 11 insertions, 3 deletions
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 5cb5b0008d97..ee2f4202d82a 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -387,7 +387,7 @@ void alarm_start_relative(struct alarm *alarm, ktime_t start)  {  	struct alarm_base *base = &alarm_bases[alarm->type]; -	start = ktime_add(start, base->gettime()); +	start = ktime_add_safe(start, base->gettime());  	alarm_start(alarm, start);  }  EXPORT_SYMBOL_GPL(alarm_start_relative); @@ -475,7 +475,7 @@ u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval)  		overrun++;  	} -	alarm->node.expires = ktime_add(alarm->node.expires, interval); +	alarm->node.expires = ktime_add_safe(alarm->node.expires, interval);  	return overrun;  }  EXPORT_SYMBOL_GPL(alarm_forward); @@ -660,13 +660,21 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,  	/* start the timer */  	timr->it.alarm.interval = timespec64_to_ktime(new_setting->it_interval); + +	/* +	 * Rate limit to the tick as a hot fix to prevent DOS. Will be +	 * mopped up later. +	 */ +	if (timr->it.alarm.interval < TICK_NSEC) +		timr->it.alarm.interval = TICK_NSEC; +  	exp = timespec64_to_ktime(new_setting->it_value);  	/* Convert (if necessary) to absolute time */  	if (flags != TIMER_ABSTIME) {  		ktime_t now;  		now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime(); -		exp = ktime_add(now, exp); +		exp = ktime_add_safe(now, exp);  	}  	alarm_start(&timr->it.alarm.alarmtimer, exp);  | 
