summaryrefslogtreecommitdiffstats
path: root/fs/fcntl.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2017-05-27 06:07:19 -0400
committerJeff Layton <jlayton@redhat.com>2017-05-27 06:07:19 -0400
commita75d30c772078546ac00399a94ecdc82df1a4d72 (patch)
treec3e90e52f03092b6d3c59a949c7a2fceed8380af /fs/fcntl.c
parent80b79dd0e2f29f06a6a54a5755c718f1c7ebb136 (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.c27
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)
246static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, 246static 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:
383SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, 391SYSCALL_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);