Commit 610d18f4128ebbd88845d0fc60cce67b49af881e

Authored by Davide Libenzi
Committed by Linus Torvalds
1 parent ef35ce231b

timerfd: add flags check

As requested by Michael, add a missing check for valid flags in
timerfd_settime(), and make it return EINVAL in case some extra bits are
set.

Michael said:
If this is to be any use to userland apps that want to check flag
support (perhaps it is too late already), then the sooner we get it
into the kernel the better: 2.6.29 would be good; earlier stables as
well would be even better.

[akpm@linux-foundation.org: remove unused TFD_FLAGS_SET]
Acked-by: Michael Kerrisk <mtk.manpages@gmail.com>
Signed-off-by: Davide Libenzi <davidel@xmailserver.org>
Cc: <stable@kernel.org>		[2.6.27.x, 2.6.28.x]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 18 additions and 10 deletions Side-by-side Diff

... ... @@ -186,11 +186,10 @@
186 186 BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC);
187 187 BUILD_BUG_ON(TFD_NONBLOCK != O_NONBLOCK);
188 188  
189   - if (flags & ~(TFD_CLOEXEC | TFD_NONBLOCK))
  189 + if ((flags & ~TFD_CREATE_FLAGS) ||
  190 + (clockid != CLOCK_MONOTONIC &&
  191 + clockid != CLOCK_REALTIME))
190 192 return -EINVAL;
191   - if (clockid != CLOCK_MONOTONIC &&
192   - clockid != CLOCK_REALTIME)
193   - return -EINVAL;
194 193  
195 194 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
196 195 if (!ctx)
... ... @@ -201,7 +200,7 @@
201 200 hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS);
202 201  
203 202 ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx,
204   - flags & (O_CLOEXEC | O_NONBLOCK));
  203 + flags & TFD_SHARED_FCNTL_FLAGS);
205 204 if (ufd < 0)
206 205 kfree(ctx);
207 206  
... ... @@ -219,7 +218,8 @@
219 218 if (copy_from_user(&ktmr, utmr, sizeof(ktmr)))
220 219 return -EFAULT;
221 220  
222   - if (!timespec_valid(&ktmr.it_value) ||
  221 + if ((flags & ~TFD_SETTIME_FLAGS) ||
  222 + !timespec_valid(&ktmr.it_value) ||
223 223 !timespec_valid(&ktmr.it_interval))
224 224 return -EINVAL;
225 225  
include/linux/timerfd.h
... ... @@ -11,13 +11,22 @@
11 11 /* For O_CLOEXEC and O_NONBLOCK */
12 12 #include <linux/fcntl.h>
13 13  
14   -/* Flags for timerfd_settime. */
  14 +/*
  15 + * CAREFUL: Check include/asm-generic/fcntl.h when defining
  16 + * new flags, since they might collide with O_* ones. We want
  17 + * to re-use O_* flags that couldn't possibly have a meaning
  18 + * from eventfd, in order to leave a free define-space for
  19 + * shared O_* flags.
  20 + */
15 21 #define TFD_TIMER_ABSTIME (1 << 0)
16   -
17   -/* Flags for timerfd_create. */
18 22 #define TFD_CLOEXEC O_CLOEXEC
19 23 #define TFD_NONBLOCK O_NONBLOCK
20 24  
  25 +#define TFD_SHARED_FCNTL_FLAGS (TFD_CLOEXEC | TFD_NONBLOCK)
  26 +/* Flags for timerfd_create. */
  27 +#define TFD_CREATE_FLAGS TFD_SHARED_FCNTL_FLAGS
  28 +/* Flags for timerfd_settime. */
  29 +#define TFD_SETTIME_FLAGS TFD_TIMER_ABSTIME
21 30  
22 31 #endif /* _LINUX_TIMERFD_H */