diff options
Diffstat (limited to 'fs/timerfd.c')
| -rw-r--r-- | fs/timerfd.c | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/fs/timerfd.c b/fs/timerfd.c index dffeb3795af1..d03822bbf190 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c | |||
| @@ -234,19 +234,17 @@ static const struct file_operations timerfd_fops = { | |||
| 234 | .llseek = noop_llseek, | 234 | .llseek = noop_llseek, |
| 235 | }; | 235 | }; |
| 236 | 236 | ||
| 237 | static struct file *timerfd_fget(int fd) | 237 | static int timerfd_fget(int fd, struct fd *p) |
| 238 | { | 238 | { |
| 239 | struct file *file; | 239 | struct fd f = fdget(fd); |
| 240 | 240 | if (!f.file) | |
| 241 | file = fget(fd); | 241 | return -EBADF; |
| 242 | if (!file) | 242 | if (f.file->f_op != &timerfd_fops) { |
| 243 | return ERR_PTR(-EBADF); | 243 | fdput(f); |
| 244 | if (file->f_op != &timerfd_fops) { | 244 | return -EINVAL; |
| 245 | fput(file); | ||
| 246 | return ERR_PTR(-EINVAL); | ||
| 247 | } | 245 | } |
| 248 | 246 | *p = f; | |
| 249 | return file; | 247 | return 0; |
| 250 | } | 248 | } |
| 251 | 249 | ||
| 252 | SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) | 250 | SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) |
| @@ -284,7 +282,7 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
| 284 | const struct itimerspec __user *, utmr, | 282 | const struct itimerspec __user *, utmr, |
| 285 | struct itimerspec __user *, otmr) | 283 | struct itimerspec __user *, otmr) |
| 286 | { | 284 | { |
| 287 | struct file *file; | 285 | struct fd f; |
| 288 | struct timerfd_ctx *ctx; | 286 | struct timerfd_ctx *ctx; |
| 289 | struct itimerspec ktmr, kotmr; | 287 | struct itimerspec ktmr, kotmr; |
| 290 | int ret; | 288 | int ret; |
| @@ -297,10 +295,10 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
| 297 | !timespec_valid(&ktmr.it_interval)) | 295 | !timespec_valid(&ktmr.it_interval)) |
| 298 | return -EINVAL; | 296 | return -EINVAL; |
| 299 | 297 | ||
| 300 | file = timerfd_fget(ufd); | 298 | ret = timerfd_fget(ufd, &f); |
| 301 | if (IS_ERR(file)) | 299 | if (ret) |
| 302 | return PTR_ERR(file); | 300 | return ret; |
| 303 | ctx = file->private_data; | 301 | ctx = f.file->private_data; |
| 304 | 302 | ||
| 305 | timerfd_setup_cancel(ctx, flags); | 303 | timerfd_setup_cancel(ctx, flags); |
| 306 | 304 | ||
| @@ -334,7 +332,7 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
| 334 | ret = timerfd_setup(ctx, flags, &ktmr); | 332 | ret = timerfd_setup(ctx, flags, &ktmr); |
| 335 | 333 | ||
| 336 | spin_unlock_irq(&ctx->wqh.lock); | 334 | spin_unlock_irq(&ctx->wqh.lock); |
| 337 | fput(file); | 335 | fdput(f); |
| 338 | if (otmr && copy_to_user(otmr, &kotmr, sizeof(kotmr))) | 336 | if (otmr && copy_to_user(otmr, &kotmr, sizeof(kotmr))) |
| 339 | return -EFAULT; | 337 | return -EFAULT; |
| 340 | 338 | ||
| @@ -343,14 +341,13 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
| 343 | 341 | ||
| 344 | SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) | 342 | SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) |
| 345 | { | 343 | { |
| 346 | struct file *file; | 344 | struct fd f; |
| 347 | struct timerfd_ctx *ctx; | 345 | struct timerfd_ctx *ctx; |
| 348 | struct itimerspec kotmr; | 346 | struct itimerspec kotmr; |
| 349 | 347 | int ret = timerfd_fget(ufd, &f); | |
| 350 | file = timerfd_fget(ufd); | 348 | if (ret) |
| 351 | if (IS_ERR(file)) | 349 | return ret; |
| 352 | return PTR_ERR(file); | 350 | ctx = f.file->private_data; |
| 353 | ctx = file->private_data; | ||
| 354 | 351 | ||
| 355 | spin_lock_irq(&ctx->wqh.lock); | 352 | spin_lock_irq(&ctx->wqh.lock); |
| 356 | if (ctx->expired && ctx->tintv.tv64) { | 353 | if (ctx->expired && ctx->tintv.tv64) { |
| @@ -362,7 +359,7 @@ SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) | |||
| 362 | kotmr.it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | 359 | kotmr.it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); |
| 363 | kotmr.it_interval = ktime_to_timespec(ctx->tintv); | 360 | kotmr.it_interval = ktime_to_timespec(ctx->tintv); |
| 364 | spin_unlock_irq(&ctx->wqh.lock); | 361 | spin_unlock_irq(&ctx->wqh.lock); |
| 365 | fput(file); | 362 | fdput(f); |
| 366 | 363 | ||
| 367 | return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0; | 364 | return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0; |
| 368 | } | 365 | } |
