aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/itimer.c
diff options
context:
space:
mode:
authorAdrian Bunk <bunk@stusta.de>2007-05-08 03:30:49 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 14:15:13 -0400
commit35bab756b49bd148760a3bbd3c907cd74754dbb4 (patch)
tree8572b353c595a026931fe04e4bc20d1e50516e3f /kernel/itimer.c
parentb3561ea9462b33a0bf824b4ca19a1ae84db81210 (diff)
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>
Diffstat (limited to 'kernel/itimer.c')
-rw-r--r--kernel/itimer.c59
1 files changed, 3 insertions, 56 deletions
diff --git a/kernel/itimer.c b/kernel/itimer.c
index 4523f3396f23..3205e8e114fa 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -138,59 +138,11 @@ enum hrtimer_restart it_real_fn(struct hrtimer *timer)
138} 138}
139 139
140/* 140/*
141 * We do not care about correctness. We just sanitize the values so
142 * the ktime_t operations which expect normalized values do not
143 * break. This converts negative values to long timeouts similar to
144 * the code in kernel versions < 2.6.16
145 *
146 * Print a limited number of warning messages when an invalid timeval
147 * is detected.
148 */
149static void fixup_timeval(struct timeval *tv, int interval)
150{
151 static int warnlimit = 10;
152 unsigned long tmp;
153
154 if (warnlimit > 0) {
155 warnlimit--;
156 printk(KERN_WARNING
157 "setitimer: %s (pid = %d) provided "
158 "invalid timeval %s: tv_sec = %ld tv_usec = %ld\n",
159 current->comm, current->pid,
160 interval ? "it_interval" : "it_value",
161 tv->tv_sec, (long) tv->tv_usec);
162 }
163
164 tmp = tv->tv_usec;
165 if (tmp >= USEC_PER_SEC) {
166 tv->tv_usec = tmp % USEC_PER_SEC;
167 tv->tv_sec += tmp / USEC_PER_SEC;
168 }
169
170 tmp = tv->tv_sec;
171 if (tmp > LONG_MAX)
172 tv->tv_sec = LONG_MAX;
173}
174
175/*
176 * Returns true if the timeval is in canonical form 141 * Returns true if the timeval is in canonical form
177 */ 142 */
178#define timeval_valid(t) \ 143#define timeval_valid(t) \
179 (((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC)) 144 (((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC))
180 145
181/*
182 * Check for invalid timevals, sanitize them and print a limited
183 * number of warnings.
184 */
185static void check_itimerval(struct itimerval *value) {
186
187 if (unlikely(!timeval_valid(&value->it_value)))
188 fixup_timeval(&value->it_value, 0);
189
190 if (unlikely(!timeval_valid(&value->it_interval)))
191 fixup_timeval(&value->it_interval, 1);
192}
193
194int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) 146int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
195{ 147{
196 struct task_struct *tsk = current; 148 struct task_struct *tsk = current;
@@ -200,15 +152,10 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
200 152
201 /* 153 /*
202 * Validate the timevals in value. 154 * Validate the timevals in value.
203 *
204 * Note: Although the spec requires that invalid values shall
205 * return -EINVAL, we just fixup the value and print a limited
206 * number of warnings in order not to break users of this
207 * historical misfeature.
208 *
209 * Scheduled for replacement in March 2007
210 */ 155 */
211 check_itimerval(value); 156 if (!timeval_valid(&value->it_value) ||
157 !timeval_valid(&value->it_interval))
158 return -EINVAL;
212 159
213 switch (which) { 160 switch (which) {
214 case ITIMER_REAL: 161 case ITIMER_REAL: