diff options
author | Christoph Hellwig <hch@lst.de> | 2017-05-27 06:07:19 -0400 |
---|---|---|
committer | Jeff Layton <jlayton@redhat.com> | 2017-05-27 06:07:19 -0400 |
commit | a75d30c772078546ac00399a94ecdc82df1a4d72 (patch) | |
tree | c3e90e52f03092b6d3c59a949c7a2fceed8380af /fs/fcntl.c | |
parent | 80b79dd0e2f29f06a6a54a5755c718f1c7ebb136 (diff) |
fs/locks: pass kernel struct flock to fcntl_getlk/setlk
This will make it easier to implement a sane compat fcntl syscall.
[ jlayton: fix undeclared identifiers in 32-bit fcntl64 syscall handler ]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/fcntl.c')
-rw-r--r-- | fs/fcntl.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/fs/fcntl.c b/fs/fcntl.c index f4e7267d117f..ed4283d500a3 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -246,6 +246,8 @@ static int f_getowner_uids(struct file *filp, unsigned long arg) | |||
246 | static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, | 246 | static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, |
247 | struct file *filp) | 247 | struct file *filp) |
248 | { | 248 | { |
249 | void __user *argp = (void __user *)arg; | ||
250 | struct flock flock; | ||
249 | long err = -EINVAL; | 251 | long err = -EINVAL; |
250 | 252 | ||
251 | switch (cmd) { | 253 | switch (cmd) { |
@@ -273,7 +275,11 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, | |||
273 | case F_OFD_GETLK: | 275 | case F_OFD_GETLK: |
274 | #endif | 276 | #endif |
275 | case F_GETLK: | 277 | case F_GETLK: |
276 | err = fcntl_getlk(filp, cmd, (struct flock __user *) arg); | 278 | if (copy_from_user(&flock, argp, sizeof(flock))) |
279 | return -EFAULT; | ||
280 | err = fcntl_getlk(filp, cmd, &flock); | ||
281 | if (!err && copy_to_user(argp, &flock, sizeof(flock))) | ||
282 | return -EFAULT; | ||
277 | break; | 283 | break; |
278 | #if BITS_PER_LONG != 32 | 284 | #if BITS_PER_LONG != 32 |
279 | /* 32-bit arches must use fcntl64() */ | 285 | /* 32-bit arches must use fcntl64() */ |
@@ -283,7 +289,9 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, | |||
283 | /* Fallthrough */ | 289 | /* Fallthrough */ |
284 | case F_SETLK: | 290 | case F_SETLK: |
285 | case F_SETLKW: | 291 | case F_SETLKW: |
286 | err = fcntl_setlk(fd, filp, cmd, (struct flock __user *) arg); | 292 | if (copy_from_user(&flock, argp, sizeof(flock))) |
293 | return -EFAULT; | ||
294 | err = fcntl_setlk(fd, filp, cmd, &flock); | ||
287 | break; | 295 | break; |
288 | case F_GETOWN: | 296 | case F_GETOWN: |
289 | /* | 297 | /* |
@@ -383,7 +391,9 @@ out: | |||
383 | SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, | 391 | SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, |
384 | unsigned long, arg) | 392 | unsigned long, arg) |
385 | { | 393 | { |
394 | void __user *argp = (void __user *)arg; | ||
386 | struct fd f = fdget_raw(fd); | 395 | struct fd f = fdget_raw(fd); |
396 | struct flock64 flock; | ||
387 | long err = -EBADF; | 397 | long err = -EBADF; |
388 | 398 | ||
389 | if (!f.file) | 399 | if (!f.file) |
@@ -401,14 +411,21 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, | |||
401 | switch (cmd) { | 411 | switch (cmd) { |
402 | case F_GETLK64: | 412 | case F_GETLK64: |
403 | case F_OFD_GETLK: | 413 | case F_OFD_GETLK: |
404 | err = fcntl_getlk64(f.file, cmd, (struct flock64 __user *) arg); | 414 | err = -EFAULT; |
415 | if (copy_from_user(&flock, argp, sizeof(flock))) | ||
416 | break; | ||
417 | err = fcntl_getlk64(f.file, cmd, &flock); | ||
418 | if (!err && copy_to_user(argp, &flock, sizeof(flock))) | ||
419 | err = -EFAULT; | ||
405 | break; | 420 | break; |
406 | case F_SETLK64: | 421 | case F_SETLK64: |
407 | case F_SETLKW64: | 422 | case F_SETLKW64: |
408 | case F_OFD_SETLK: | 423 | case F_OFD_SETLK: |
409 | case F_OFD_SETLKW: | 424 | case F_OFD_SETLKW: |
410 | err = fcntl_setlk64(fd, f.file, cmd, | 425 | err = -EFAULT; |
411 | (struct flock64 __user *) arg); | 426 | if (copy_from_user(&flock, argp, sizeof(flock))) |
427 | break; | ||
428 | err = fcntl_setlk64(fd, f.file, cmd, &flock); | ||
412 | break; | 429 | break; |
413 | default: | 430 | default: |
414 | err = do_fcntl(fd, cmd, arg, f.file); | 431 | err = do_fcntl(fd, cmd, arg, f.file); |