diff options
-rw-r--r-- | Documentation/feature-removal-schedule.txt | 12 | ||||
-rw-r--r-- | kernel/itimer.c | 66 |
2 files changed, 78 insertions, 0 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 21272e4b4a5c..495858b236b6 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -176,6 +176,18 @@ Who: Richard Knutsson <ricknu-0@student.ltu.se> and Greg Kroah-Hartman <gregkh@s | |||
176 | 176 | ||
177 | --------------------------- | 177 | --------------------------- |
178 | 178 | ||
179 | What: Usage of invalid timevals in setitimer | ||
180 | When: March 2007 | ||
181 | Why: POSIX requires to validate timevals in the setitimer call. This | ||
182 | was never done by Linux. The invalid (e.g. negative timevals) were | ||
183 | silently converted to more or less random timeouts and intervals. | ||
184 | Until the removal a per boot limited number of warnings is printed | ||
185 | and the timevals are sanitized. | ||
186 | |||
187 | Who: Thomas Gleixner <tglx@linutronix.de> | ||
188 | |||
189 | --------------------------- | ||
190 | |||
179 | What: I2C interface of the it87 driver | 191 | What: I2C interface of the it87 driver |
180 | When: January 2007 | 192 | When: January 2007 |
181 | Why: The ISA interface is faster and should be always available. The I2C | 193 | Why: The ISA interface is faster and should be always available. The I2C |
diff --git a/kernel/itimer.c b/kernel/itimer.c index a2dc375927d8..680e6b70c872 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c | |||
@@ -143,6 +143,60 @@ int it_real_fn(void *data) | |||
143 | return HRTIMER_NORESTART; | 143 | return HRTIMER_NORESTART; |
144 | } | 144 | } |
145 | 145 | ||
146 | /* | ||
147 | * We do not care about correctness. We just sanitize the values so | ||
148 | * the ktime_t operations which expect normalized values do not | ||
149 | * break. This converts negative values to long timeouts similar to | ||
150 | * the code in kernel versions < 2.6.16 | ||
151 | * | ||
152 | * Print a limited number of warning messages when an invalid timeval | ||
153 | * is detected. | ||
154 | */ | ||
155 | static void fixup_timeval(struct timeval *tv, int interval) | ||
156 | { | ||
157 | static int warnlimit = 10; | ||
158 | unsigned long tmp; | ||
159 | |||
160 | if (warnlimit > 0) { | ||
161 | warnlimit--; | ||
162 | printk(KERN_WARNING | ||
163 | "setitimer: %s (pid = %d) provided " | ||
164 | "invalid timeval %s: tv_sec = %ld tv_usec = %ld\n", | ||
165 | current->comm, current->pid, | ||
166 | interval ? "it_interval" : "it_value", | ||
167 | tv->tv_sec, (long) tv->tv_usec); | ||
168 | } | ||
169 | |||
170 | tmp = tv->tv_usec; | ||
171 | if (tmp >= USEC_PER_SEC) { | ||
172 | tv->tv_usec = tmp % USEC_PER_SEC; | ||
173 | tv->tv_sec += tmp / USEC_PER_SEC; | ||
174 | } | ||
175 | |||
176 | tmp = tv->tv_sec; | ||
177 | if (tmp > LONG_MAX) | ||
178 | tv->tv_sec = LONG_MAX; | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * Returns true if the timeval is in canonical form | ||
183 | */ | ||
184 | #define timeval_valid(t) \ | ||
185 | (((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC)) | ||
186 | |||
187 | /* | ||
188 | * Check for invalid timevals, sanitize them and print a limited | ||
189 | * number of warnings. | ||
190 | */ | ||
191 | static void check_itimerval(struct itimerval *value) { | ||
192 | |||
193 | if (unlikely(!timeval_valid(&value->it_value))) | ||
194 | fixup_timeval(&value->it_value, 0); | ||
195 | |||
196 | if (unlikely(!timeval_valid(&value->it_interval))) | ||
197 | fixup_timeval(&value->it_interval, 1); | ||
198 | } | ||
199 | |||
146 | int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) | 200 | int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) |
147 | { | 201 | { |
148 | struct task_struct *tsk = current; | 202 | struct task_struct *tsk = current; |
@@ -150,6 +204,18 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) | |||
150 | ktime_t expires; | 204 | ktime_t expires; |
151 | cputime_t cval, cinterval, nval, ninterval; | 205 | cputime_t cval, cinterval, nval, ninterval; |
152 | 206 | ||
207 | /* | ||
208 | * Validate the timevals in value. | ||
209 | * | ||
210 | * Note: Although the spec requires that invalid values shall | ||
211 | * return -EINVAL, we just fixup the value and print a limited | ||
212 | * number of warnings in order not to break users of this | ||
213 | * historical misfeature. | ||
214 | * | ||
215 | * Scheduled for replacement in March 2007 | ||
216 | */ | ||
217 | check_itimerval(value); | ||
218 | |||
153 | switch (which) { | 219 | switch (which) { |
154 | case ITIMER_REAL: | 220 | case ITIMER_REAL: |
155 | again: | 221 | again: |