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
|
@ -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
|
What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports
|
||||||
(temporary transition config option provided until then)
|
(temporary transition config option provided until then)
|
||||||
The transition config option will also be removed at the same time.
|
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;
|
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
|
* Returns true if the timeval is in canonical form
|
||||||
*/
|
*/
|
||||||
#define timeval_valid(t) \
|
#define timeval_valid(t) \
|
||||||
(((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC))
|
(((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)
|
int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
|
||||||
{
|
{
|
||||||
struct task_struct *tsk = current;
|
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.
|
* 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) {
|
switch (which) {
|
||||||
case ITIMER_REAL:
|
case ITIMER_REAL:
|
||||||
|
|
Loading…
Reference in New Issue