Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 23501
b: refs/heads/master
c: 7d99b7d
h: refs/heads/master
i:
  23499: 6b7e8b1
v: v3
  • Loading branch information
Thomas Gleixner authored and Linus Torvalds committed Mar 25, 2006
1 parent b998105 commit 3281e0e
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c08b8a49100715b20e6f7c997e992428b5e06078
refs/heads/master: 7d99b7d634d81bb372e03e4561c80430aa4cfac2
12 changes: 12 additions & 0 deletions trunk/Documentation/feature-removal-schedule.txt
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,18 @@ Who: Richard Knutsson <ricknu-0@student.ltu.se> and Greg Kroah-Hartman <gregkh@s

---------------------------

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: I2C interface of the it87 driver
When: January 2007
Why: The ISA interface is faster and should be always available. The I2C
Expand Down
66 changes: 66 additions & 0 deletions trunk/kernel/itimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,79 @@ int it_real_fn(void *data)
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;
struct hrtimer *timer;
ktime_t expires;
cputime_t cval, cinterval, nval, ninterval;

/*
* 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);

switch (which) {
case ITIMER_REAL:
again:
Expand Down

0 comments on commit 3281e0e

Please sign in to comment.