The scheduled -EINVAL for invalid timevals in setitimer
As scheduled, do_setitimer() now returns -EINVAL for invalid timeval. Signed-off-by: Adrian Bunk <bunk@stusta.de> Acked-by: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
b3561ea946
commit
35bab756b4
2 changed files with 3 additions and 68 deletions
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue