Commit 35bab756 authored by Adrian Bunk's avatar Adrian Bunk Committed by Linus Torvalds

The scheduled -EINVAL for invalid timevals in setitimer

As scheduled, do_setitimer() now returns -EINVAL for invalid timeval.
Signed-off-by: default avatarAdrian Bunk <bunk@stusta.de>
Acked-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent b3561ea9
......@@ -117,18 +117,6 @@ Who: Adrian Bunk <bunk@stusta.de>
---------------------------
What: Usage of invalid timevals in setitimer
When: March 2007
Why: POSIX requires to validate timevals in the setitimer call. This
was never done by Linux. The invalid (e.g. negative timevals) were
silently converted to more or less random timeouts and intervals.
Until the removal a per boot limited number of warnings is printed
and the timevals are sanitized.
Who: Thomas Gleixner <tglx@linutronix.de>
---------------------------
What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports
(temporary transition config option provided until then)
The transition config option will also be removed at the same time.
......
......@@ -137,60 +137,12 @@ enum hrtimer_restart it_real_fn(struct hrtimer *timer)
return HRTIMER_NORESTART;
}
/*
* We do not care about correctness. We just sanitize the values so
* the ktime_t operations which expect normalized values do not
* break. This converts negative values to long timeouts similar to
* the code in kernel versions < 2.6.16
*
* Print a limited number of warning messages when an invalid timeval
* is detected.
*/
static void fixup_timeval(struct timeval *tv, int interval)
{
static int warnlimit = 10;
unsigned long tmp;
if (warnlimit > 0) {
warnlimit--;
printk(KERN_WARNING
"setitimer: %s (pid = %d) provided "
"invalid timeval %s: tv_sec = %ld tv_usec = %ld\n",
current->comm, current->pid,
interval ? "it_interval" : "it_value",
tv->tv_sec, (long) tv->tv_usec);
}
tmp = tv->tv_usec;
if (tmp >= USEC_PER_SEC) {
tv->tv_usec = tmp % USEC_PER_SEC;
tv->tv_sec += tmp / USEC_PER_SEC;
}
tmp = tv->tv_sec;
if (tmp > LONG_MAX)
tv->tv_sec = LONG_MAX;
}
/*
* Returns true if the timeval is in canonical form
*/
#define timeval_valid(t) \
(((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC))
/*
* Check for invalid timevals, sanitize them and print a limited
* number of warnings.
*/
static void check_itimerval(struct itimerval *value) {
if (unlikely(!timeval_valid(&value->it_value)))
fixup_timeval(&value->it_value, 0);
if (unlikely(!timeval_valid(&value->it_interval)))
fixup_timeval(&value->it_interval, 1);
}
int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
{
struct task_struct *tsk = current;
......@@ -200,15 +152,10 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
/*
* Validate the timevals in value.
*
* Note: Although the spec requires that invalid values shall
* return -EINVAL, we just fixup the value and print a limited
* number of warnings in order not to break users of this
* historical misfeature.
*
* Scheduled for replacement in March 2007
*/
check_itimerval(value);
if (!timeval_valid(&value->it_value) ||
!timeval_valid(&value->it_interval))
return -EINVAL;
switch (which) {
case ITIMER_REAL:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment