aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-05 16:13:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-05 16:13:32 -0400
commit3bad2f1c676581d01e7645eb03e9b27e28b0a92e (patch)
tree7e946eb2c7dab8c08e473ee1249be9a814728158
parentb4b8cbf679c4866a523a35d1454884a31bd5d8dc (diff)
parent8c6657cb50cb037ff58b3f6a547c6569568f3527 (diff)
Merge branch 'work.misc-set_fs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc user access cleanups from Al Viro: "The first pile is assorted getting rid of cargo-culted access_ok(), cargo-culted set_fs() and field-by-field copyouts. The same description applies to a lot of stuff in other branches - this is just the stuff that didn't fit into a more specific topical branch" * 'work.misc-set_fs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: Switch flock copyin/copyout primitives to copy_{from,to}_user() fs/fcntl: return -ESRCH in f_setown when pid/pgid can't be found fs/fcntl: f_setown, avoid undefined behaviour fs/fcntl: f_setown, allow returning error lpfc debugfs: get rid of pointless access_ok() adb: get rid of pointless access_ok() isdn: get rid of pointless access_ok() compat statfs: switch to copy_to_user() fs/locks: don't mess with the address limit in compat_fcntl64 nfsd_readlink(): switch to vfs_get_link() drbd: ->sendpage() never needed set_fs() fs/locks: pass kernel struct flock to fcntl_getlk/setlk fs: locks: Fix some troubles at kernel-doc comments
-rw-r--r--drivers/block/drbd/drbd_main.c3
-rw-r--r--drivers/isdn/i4l/isdn_common.c18
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c6
-rw-r--r--drivers/isdn/isdnloop/isdnloop.c2
-rw-r--r--drivers/macintosh/adb.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c20
-rw-r--r--fs/fcntl.c231
-rw-r--r--fs/locks.c97
-rw-r--r--fs/nfsd/vfs.c39
-rw-r--r--fs/statfs.c58
-rw-r--r--include/linux/fs.h10
-rw-r--r--net/socket.c3
12 files changed, 220 insertions, 271 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 5fb99e06ebe4..e2ed28d45ce1 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1551,7 +1551,6 @@ static int _drbd_send_page(struct drbd_peer_device *peer_device, struct page *pa
1551 int offset, size_t size, unsigned msg_flags) 1551 int offset, size_t size, unsigned msg_flags)
1552{ 1552{
1553 struct socket *socket = peer_device->connection->data.socket; 1553 struct socket *socket = peer_device->connection->data.socket;
1554 mm_segment_t oldfs = get_fs();
1555 int len = size; 1554 int len = size;
1556 int err = -EIO; 1555 int err = -EIO;
1557 1556
@@ -1566,7 +1565,6 @@ static int _drbd_send_page(struct drbd_peer_device *peer_device, struct page *pa
1566 1565
1567 msg_flags |= MSG_NOSIGNAL; 1566 msg_flags |= MSG_NOSIGNAL;
1568 drbd_update_congested(peer_device->connection); 1567 drbd_update_congested(peer_device->connection);
1569 set_fs(KERNEL_DS);
1570 do { 1568 do {
1571 int sent; 1569 int sent;
1572 1570
@@ -1586,7 +1584,6 @@ static int _drbd_send_page(struct drbd_peer_device *peer_device, struct page *pa
1586 len -= sent; 1584 len -= sent;
1587 offset += sent; 1585 offset += sent;
1588 } while (len > 0 /* THINK && device->cstate >= C_CONNECTED*/); 1586 } while (len > 0 /* THINK && device->cstate >= C_CONNECTED*/);
1589 set_fs(oldfs);
1590 clear_bit(NET_CONGESTED, &peer_device->connection->flags); 1587 clear_bit(NET_CONGESTED, &peer_device->connection->flags);
1591 1588
1592 if (len == 0) { 1589 if (len == 0) {
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 9b856e1890d1..89b09c51ab7c 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -1304,9 +1304,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
1304 if (arg) { 1304 if (arg) {
1305 ulong __user *p = argp; 1305 ulong __user *p = argp;
1306 int i; 1306 int i;
1307 if (!access_ok(VERIFY_WRITE, p,
1308 sizeof(ulong) * ISDN_MAX_CHANNELS * 2))
1309 return -EFAULT;
1310 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1307 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
1311 put_user(dev->ibytes[i], p++); 1308 put_user(dev->ibytes[i], p++);
1312 put_user(dev->obytes[i], p++); 1309 put_user(dev->obytes[i], p++);
@@ -1540,11 +1537,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
1540 char __user *p = argp; 1537 char __user *p = argp;
1541 int i; 1538 int i;
1542 1539
1543 if (!access_ok(VERIFY_WRITE, argp,
1544 (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN)
1545 * ISDN_MAX_CHANNELS))
1546 return -EFAULT;
1547
1548 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1540 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
1549 if (copy_to_user(p, dev->mdm.info[i].emu.profile, 1541 if (copy_to_user(p, dev->mdm.info[i].emu.profile,
1550 ISDN_MODEM_NUMREG)) 1542 ISDN_MODEM_NUMREG))
@@ -1567,11 +1559,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
1567 char __user *p = argp; 1559 char __user *p = argp;
1568 int i; 1560 int i;
1569 1561
1570 if (!access_ok(VERIFY_READ, argp,
1571 (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN)
1572 * ISDN_MAX_CHANNELS))
1573 return -EFAULT;
1574
1575 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1562 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
1576 if (copy_from_user(dev->mdm.info[i].emu.profile, p, 1563 if (copy_from_user(dev->mdm.info[i].emu.profile, p,
1577 ISDN_MODEM_NUMREG)) 1564 ISDN_MODEM_NUMREG))
@@ -1617,8 +1604,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
1617 int j = 0; 1604 int j = 0;
1618 1605
1619 while (1) { 1606 while (1) {
1620 if (!access_ok(VERIFY_READ, p, 1))
1621 return -EFAULT;
1622 get_user(bname[j], p++); 1607 get_user(bname[j], p++);
1623 switch (bname[j]) { 1608 switch (bname[j]) {
1624 case '\0': 1609 case '\0':
@@ -1685,9 +1670,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
1685 drvidx = 0; 1670 drvidx = 0;
1686 if (drvidx == -1) 1671 if (drvidx == -1)
1687 return -ENODEV; 1672 return -ENODEV;
1688 if (!access_ok(VERIFY_WRITE, argp,
1689 sizeof(isdn_ioctl_struct)))
1690 return -EFAULT;
1691 c.driver = drvidx; 1673 c.driver = drvidx;
1692 c.command = ISDN_CMD_IOCTL; 1674 c.command = ISDN_CMD_IOCTL;
1693 c.arg = cmd; 1675 c.arg = cmd;
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 88e5a025cea7..6c44609fd83a 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -795,9 +795,6 @@ isdn_ppp_read(int min, struct file *file, char __user *buf, int count)
795 if (!(is->state & IPPP_OPEN)) 795 if (!(is->state & IPPP_OPEN))
796 return 0; 796 return 0;
797 797
798 if (!access_ok(VERIFY_WRITE, buf, count))
799 return -EFAULT;
800
801 spin_lock_irqsave(&is->buflock, flags); 798 spin_lock_irqsave(&is->buflock, flags);
802 b = is->first->next; 799 b = is->first->next;
803 save_buf = b->buf; 800 save_buf = b->buf;
@@ -2014,9 +2011,6 @@ isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct net_device *dev)
2014 struct ppp_stats t; 2011 struct ppp_stats t;
2015 isdn_net_local *lp = netdev_priv(dev); 2012 isdn_net_local *lp = netdev_priv(dev);
2016 2013
2017 if (!access_ok(VERIFY_WRITE, res, sizeof(struct ppp_stats)))
2018 return -EFAULT;
2019
2020 /* build a temporary stat struct and copy it to user space */ 2014 /* build a temporary stat struct and copy it to user space */
2021 2015
2022 memset(&t, 0, sizeof(struct ppp_stats)); 2016 memset(&t, 0, sizeof(struct ppp_stats));
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index 7ac7badb8f55..6ffd13466b8c 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -1142,8 +1142,6 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card)
1142 case ISDNLOOP_IOCTL_DEBUGVAR: 1142 case ISDNLOOP_IOCTL_DEBUGVAR:
1143 return (ulong) card; 1143 return (ulong) card;
1144 case ISDNLOOP_IOCTL_STARTUP: 1144 case ISDNLOOP_IOCTL_STARTUP:
1145 if (!access_ok(VERIFY_READ, (void *) a, sizeof(isdnloop_sdef)))
1146 return -EFAULT;
1147 return isdnloop_start(card, (isdnloop_sdef *) a); 1145 return isdnloop_start(card, (isdnloop_sdef *) a);
1148 break; 1146 break;
1149 case ISDNLOOP_IOCTL_ADDCARD: 1147 case ISDNLOOP_IOCTL_ADDCARD:
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index fee939efc4fc..039dc8285fc5 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -723,8 +723,6 @@ static ssize_t adb_read(struct file *file, char __user *buf,
723 return -EINVAL; 723 return -EINVAL;
724 if (count > sizeof(req->reply)) 724 if (count > sizeof(req->reply))
725 count = sizeof(req->reply); 725 count = sizeof(req->reply);
726 if (!access_ok(VERIFY_WRITE, buf, count))
727 return -EFAULT;
728 726
729 req = NULL; 727 req = NULL;
730 spin_lock_irqsave(&state->lock, flags); 728 spin_lock_irqsave(&state->lock, flags);
@@ -781,8 +779,6 @@ static ssize_t adb_write(struct file *file, const char __user *buf,
781 return -EINVAL; 779 return -EINVAL;
782 if (adb_controller == NULL) 780 if (adb_controller == NULL)
783 return -ENXIO; 781 return -ENXIO;
784 if (!access_ok(VERIFY_READ, buf, count))
785 return -EFAULT;
786 782
787 req = kmalloc(sizeof(struct adb_request), 783 req = kmalloc(sizeof(struct adb_request),
788 GFP_KERNEL); 784 GFP_KERNEL);
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 4bcb92c844ca..89afa7813e5a 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -1949,10 +1949,6 @@ lpfc_debugfs_nvmestat_write(struct file *file, const char __user *buf,
1949 if (nbytes > 64) 1949 if (nbytes > 64)
1950 nbytes = 64; 1950 nbytes = 64;
1951 1951
1952 /* Protect copy from user */
1953 if (!access_ok(VERIFY_READ, buf, nbytes))
1954 return -EFAULT;
1955
1956 memset(mybuf, 0, sizeof(mybuf)); 1952 memset(mybuf, 0, sizeof(mybuf));
1957 1953
1958 if (copy_from_user(mybuf, buf, nbytes)) 1954 if (copy_from_user(mybuf, buf, nbytes))
@@ -2037,10 +2033,6 @@ lpfc_debugfs_nvmektime_write(struct file *file, const char __user *buf,
2037 if (nbytes > 64) 2033 if (nbytes > 64)
2038 nbytes = 64; 2034 nbytes = 64;
2039 2035
2040 /* Protect copy from user */
2041 if (!access_ok(VERIFY_READ, buf, nbytes))
2042 return -EFAULT;
2043
2044 memset(mybuf, 0, sizeof(mybuf)); 2036 memset(mybuf, 0, sizeof(mybuf));
2045 2037
2046 if (copy_from_user(mybuf, buf, nbytes)) 2038 if (copy_from_user(mybuf, buf, nbytes))
@@ -2169,10 +2161,6 @@ lpfc_debugfs_nvmeio_trc_write(struct file *file, const char __user *buf,
2169 if (nbytes > 64) 2161 if (nbytes > 64)
2170 nbytes = 64; 2162 nbytes = 64;
2171 2163
2172 /* Protect copy from user */
2173 if (!access_ok(VERIFY_READ, buf, nbytes))
2174 return -EFAULT;
2175
2176 memset(mybuf, 0, sizeof(mybuf)); 2164 memset(mybuf, 0, sizeof(mybuf));
2177 2165
2178 if (copy_from_user(mybuf, buf, nbytes)) 2166 if (copy_from_user(mybuf, buf, nbytes))
@@ -2280,10 +2268,6 @@ lpfc_debugfs_cpucheck_write(struct file *file, const char __user *buf,
2280 if (nbytes > 64) 2268 if (nbytes > 64)
2281 nbytes = 64; 2269 nbytes = 64;
2282 2270
2283 /* Protect copy from user */
2284 if (!access_ok(VERIFY_READ, buf, nbytes))
2285 return -EFAULT;
2286
2287 memset(mybuf, 0, sizeof(mybuf)); 2271 memset(mybuf, 0, sizeof(mybuf));
2288 2272
2289 if (copy_from_user(mybuf, buf, nbytes)) 2273 if (copy_from_user(mybuf, buf, nbytes))
@@ -2354,10 +2338,6 @@ static int lpfc_idiag_cmd_get(const char __user *buf, size_t nbytes,
2354 int i; 2338 int i;
2355 size_t bsize; 2339 size_t bsize;
2356 2340
2357 /* Protect copy from user */
2358 if (!access_ok(VERIFY_READ, buf, nbytes))
2359 return -EFAULT;
2360
2361 memset(mybuf, 0, sizeof(mybuf)); 2341 memset(mybuf, 0, sizeof(mybuf));
2362 memset(idiag_cmd, 0, sizeof(*idiag_cmd)); 2342 memset(idiag_cmd, 0, sizeof(*idiag_cmd));
2363 bsize = min(nbytes, (sizeof(mybuf)-1)); 2343 bsize = min(nbytes, (sizeof(mybuf)-1));
diff --git a/fs/fcntl.c b/fs/fcntl.c
index ed051f825bad..b6bd89628025 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -109,20 +109,34 @@ void __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
109} 109}
110EXPORT_SYMBOL(__f_setown); 110EXPORT_SYMBOL(__f_setown);
111 111
112void f_setown(struct file *filp, unsigned long arg, int force) 112int f_setown(struct file *filp, unsigned long arg, int force)
113{ 113{
114 enum pid_type type; 114 enum pid_type type;
115 struct pid *pid; 115 struct pid *pid = NULL;
116 int who = arg; 116 int who = arg, ret = 0;
117
117 type = PIDTYPE_PID; 118 type = PIDTYPE_PID;
118 if (who < 0) { 119 if (who < 0) {
120 /* avoid overflow below */
121 if (who == INT_MIN)
122 return -EINVAL;
123
119 type = PIDTYPE_PGID; 124 type = PIDTYPE_PGID;
120 who = -who; 125 who = -who;
121 } 126 }
127
122 rcu_read_lock(); 128 rcu_read_lock();
123 pid = find_vpid(who); 129 if (who) {
124 __f_setown(filp, pid, type, force); 130 pid = find_vpid(who);
131 if (!pid)
132 ret = -ESRCH;
133 }
134
135 if (!ret)
136 __f_setown(filp, pid, type, force);
125 rcu_read_unlock(); 137 rcu_read_unlock();
138
139 return ret;
126} 140}
127EXPORT_SYMBOL(f_setown); 141EXPORT_SYMBOL(f_setown);
128 142
@@ -307,6 +321,8 @@ static long fcntl_rw_hint(struct file *file, unsigned int cmd,
307static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, 321static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
308 struct file *filp) 322 struct file *filp)
309{ 323{
324 void __user *argp = (void __user *)arg;
325 struct flock flock;
310 long err = -EINVAL; 326 long err = -EINVAL;
311 327
312 switch (cmd) { 328 switch (cmd) {
@@ -334,7 +350,11 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
334 case F_OFD_GETLK: 350 case F_OFD_GETLK:
335#endif 351#endif
336 case F_GETLK: 352 case F_GETLK:
337 err = fcntl_getlk(filp, cmd, (struct flock __user *) arg); 353 if (copy_from_user(&flock, argp, sizeof(flock)))
354 return -EFAULT;
355 err = fcntl_getlk(filp, cmd, &flock);
356 if (!err && copy_to_user(argp, &flock, sizeof(flock)))
357 return -EFAULT;
338 break; 358 break;
339#if BITS_PER_LONG != 32 359#if BITS_PER_LONG != 32
340 /* 32-bit arches must use fcntl64() */ 360 /* 32-bit arches must use fcntl64() */
@@ -344,7 +364,9 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
344 /* Fallthrough */ 364 /* Fallthrough */
345 case F_SETLK: 365 case F_SETLK:
346 case F_SETLKW: 366 case F_SETLKW:
347 err = fcntl_setlk(fd, filp, cmd, (struct flock __user *) arg); 367 if (copy_from_user(&flock, argp, sizeof(flock)))
368 return -EFAULT;
369 err = fcntl_setlk(fd, filp, cmd, &flock);
348 break; 370 break;
349 case F_GETOWN: 371 case F_GETOWN:
350 /* 372 /*
@@ -358,8 +380,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
358 force_successful_syscall_return(); 380 force_successful_syscall_return();
359 break; 381 break;
360 case F_SETOWN: 382 case F_SETOWN:
361 f_setown(filp, arg, 1); 383 err = f_setown(filp, arg, 1);
362 err = 0;
363 break; 384 break;
364 case F_GETOWN_EX: 385 case F_GETOWN_EX:
365 err = f_getown_ex(filp, arg); 386 err = f_getown_ex(filp, arg);
@@ -450,7 +471,9 @@ out:
450SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, 471SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
451 unsigned long, arg) 472 unsigned long, arg)
452{ 473{
474 void __user *argp = (void __user *)arg;
453 struct fd f = fdget_raw(fd); 475 struct fd f = fdget_raw(fd);
476 struct flock64 flock;
454 long err = -EBADF; 477 long err = -EBADF;
455 478
456 if (!f.file) 479 if (!f.file)
@@ -468,14 +491,21 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
468 switch (cmd) { 491 switch (cmd) {
469 case F_GETLK64: 492 case F_GETLK64:
470 case F_OFD_GETLK: 493 case F_OFD_GETLK:
471 err = fcntl_getlk64(f.file, cmd, (struct flock64 __user *) arg); 494 err = -EFAULT;
495 if (copy_from_user(&flock, argp, sizeof(flock)))
496 break;
497 err = fcntl_getlk64(f.file, cmd, &flock);
498 if (!err && copy_to_user(argp, &flock, sizeof(flock)))
499 err = -EFAULT;
472 break; 500 break;
473 case F_SETLK64: 501 case F_SETLK64:
474 case F_SETLKW64: 502 case F_SETLKW64:
475 case F_OFD_SETLK: 503 case F_OFD_SETLK:
476 case F_OFD_SETLKW: 504 case F_OFD_SETLKW:
477 err = fcntl_setlk64(fd, f.file, cmd, 505 err = -EFAULT;
478 (struct flock64 __user *) arg); 506 if (copy_from_user(&flock, argp, sizeof(flock)))
507 break;
508 err = fcntl_setlk64(fd, f.file, cmd, &flock);
479 break; 509 break;
480 default: 510 default:
481 err = do_fcntl(fd, cmd, arg, f.file); 511 err = do_fcntl(fd, cmd, arg, f.file);
@@ -489,57 +519,56 @@ out:
489#endif 519#endif
490 520
491#ifdef CONFIG_COMPAT 521#ifdef CONFIG_COMPAT
522/* careful - don't use anywhere else */
523#define copy_flock_fields(from, to) \
524 (to).l_type = (from).l_type; \
525 (to).l_whence = (from).l_whence; \
526 (to).l_start = (from).l_start; \
527 (to).l_len = (from).l_len; \
528 (to).l_pid = (from).l_pid;
529
492static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) 530static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl)
493{ 531{
494 if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || 532 struct compat_flock fl;
495 __get_user(kfl->l_type, &ufl->l_type) || 533
496 __get_user(kfl->l_whence, &ufl->l_whence) || 534 if (copy_from_user(&fl, ufl, sizeof(struct compat_flock)))
497 __get_user(kfl->l_start, &ufl->l_start) ||
498 __get_user(kfl->l_len, &ufl->l_len) ||
499 __get_user(kfl->l_pid, &ufl->l_pid))
500 return -EFAULT; 535 return -EFAULT;
536 copy_flock_fields(*kfl, fl);
501 return 0; 537 return 0;
502} 538}
503 539
504static int put_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) 540static int get_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl)
505{ 541{
506 if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)) || 542 struct compat_flock64 fl;
507 __put_user(kfl->l_type, &ufl->l_type) || 543
508 __put_user(kfl->l_whence, &ufl->l_whence) || 544 if (copy_from_user(&fl, ufl, sizeof(struct compat_flock64)))
509 __put_user(kfl->l_start, &ufl->l_start) ||
510 __put_user(kfl->l_len, &ufl->l_len) ||
511 __put_user(kfl->l_pid, &ufl->l_pid))
512 return -EFAULT; 545 return -EFAULT;
546 copy_flock_fields(*kfl, fl);
513 return 0; 547 return 0;
514} 548}
515 549
516#ifndef HAVE_ARCH_GET_COMPAT_FLOCK64 550static int put_compat_flock(struct flock *kfl, struct compat_flock __user *ufl)
517static int get_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl)
518{ 551{
519 if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || 552 struct compat_flock fl;
520 __get_user(kfl->l_type, &ufl->l_type) || 553
521 __get_user(kfl->l_whence, &ufl->l_whence) || 554 memset(&fl, 0, sizeof(struct compat_flock));
522 __get_user(kfl->l_start, &ufl->l_start) || 555 copy_flock_fields(fl, *kfl);
523 __get_user(kfl->l_len, &ufl->l_len) || 556 if (copy_to_user(ufl, &fl, sizeof(struct compat_flock)))
524 __get_user(kfl->l_pid, &ufl->l_pid))
525 return -EFAULT; 557 return -EFAULT;
526 return 0; 558 return 0;
527} 559}
528#endif
529 560
530#ifndef HAVE_ARCH_PUT_COMPAT_FLOCK64
531static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl) 561static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl)
532{ 562{
533 if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)) || 563 struct compat_flock64 fl;
534 __put_user(kfl->l_type, &ufl->l_type) || 564
535 __put_user(kfl->l_whence, &ufl->l_whence) || 565 memset(&fl, 0, sizeof(struct compat_flock64));
536 __put_user(kfl->l_start, &ufl->l_start) || 566 copy_flock_fields(fl, *kfl);
537 __put_user(kfl->l_len, &ufl->l_len) || 567 if (copy_to_user(ufl, &fl, sizeof(struct compat_flock64)))
538 __put_user(kfl->l_pid, &ufl->l_pid))
539 return -EFAULT; 568 return -EFAULT;
540 return 0; 569 return 0;
541} 570}
542#endif 571#undef copy_flock_fields
543 572
544static unsigned int 573static unsigned int
545convert_fcntl_cmd(unsigned int cmd) 574convert_fcntl_cmd(unsigned int cmd)
@@ -556,76 +585,92 @@ convert_fcntl_cmd(unsigned int cmd)
556 return cmd; 585 return cmd;
557} 586}
558 587
588/*
589 * GETLK was successful and we need to return the data, but it needs to fit in
590 * the compat structure.
591 * l_start shouldn't be too big, unless the original start + end is greater than
592 * COMPAT_OFF_T_MAX, in which case the app was asking for trouble, so we return
593 * -EOVERFLOW in that case. l_len could be too big, in which case we just
594 * truncate it, and only allow the app to see that part of the conflicting lock
595 * that might make sense to it anyway
596 */
597static int fixup_compat_flock(struct flock *flock)
598{
599 if (flock->l_start > COMPAT_OFF_T_MAX)
600 return -EOVERFLOW;
601 if (flock->l_len > COMPAT_OFF_T_MAX)
602 flock->l_len = COMPAT_OFF_T_MAX;
603 return 0;
604}
605
559COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, 606COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
560 compat_ulong_t, arg) 607 compat_ulong_t, arg)
561{ 608{
562 mm_segment_t old_fs; 609 struct fd f = fdget_raw(fd);
563 struct flock f; 610 struct flock flock;
564 long ret; 611 long err = -EBADF;
565 unsigned int conv_cmd; 612
613 if (!f.file)
614 return err;
615
616 if (unlikely(f.file->f_mode & FMODE_PATH)) {
617 if (!check_fcntl_cmd(cmd))
618 goto out_put;
619 }
620
621 err = security_file_fcntl(f.file, cmd, arg);
622 if (err)
623 goto out_put;
566 624
567 switch (cmd) { 625 switch (cmd) {
568 case F_GETLK: 626 case F_GETLK:
627 err = get_compat_flock(&flock, compat_ptr(arg));
628 if (err)
629 break;
630 err = fcntl_getlk(f.file, convert_fcntl_cmd(cmd), &flock);
631 if (err)
632 break;
633 err = fixup_compat_flock(&flock);
634 if (err)
635 return err;
636 err = put_compat_flock(&flock, compat_ptr(arg));
637 break;
638 case F_GETLK64:
639 case F_OFD_GETLK:
640 err = get_compat_flock64(&flock, compat_ptr(arg));
641 if (err)
642 break;
643 err = fcntl_getlk(f.file, convert_fcntl_cmd(cmd), &flock);
644 if (err)
645 break;
646 err = fixup_compat_flock(&flock);
647 if (err)
648 return err;
649 err = put_compat_flock64(&flock, compat_ptr(arg));
650 break;
569 case F_SETLK: 651 case F_SETLK:
570 case F_SETLKW: 652 case F_SETLKW:
571 ret = get_compat_flock(&f, compat_ptr(arg)); 653 err = get_compat_flock(&flock, compat_ptr(arg));
572 if (ret != 0) 654 if (err)
573 break; 655 break;
574 old_fs = get_fs(); 656 err = fcntl_setlk(fd, f.file, convert_fcntl_cmd(cmd), &flock);
575 set_fs(KERNEL_DS);
576 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
577 set_fs(old_fs);
578 if (cmd == F_GETLK && ret == 0) {
579 /* GETLK was successful and we need to return the data...
580 * but it needs to fit in the compat structure.
581 * l_start shouldn't be too big, unless the original
582 * start + end is greater than COMPAT_OFF_T_MAX, in which
583 * case the app was asking for trouble, so we return
584 * -EOVERFLOW in that case.
585 * l_len could be too big, in which case we just truncate it,
586 * and only allow the app to see that part of the conflicting
587 * lock that might make sense to it anyway
588 */
589
590 if (f.l_start > COMPAT_OFF_T_MAX)
591 ret = -EOVERFLOW;
592 if (f.l_len > COMPAT_OFF_T_MAX)
593 f.l_len = COMPAT_OFF_T_MAX;
594 if (ret == 0)
595 ret = put_compat_flock(&f, compat_ptr(arg));
596 }
597 break; 657 break;
598
599 case F_GETLK64:
600 case F_SETLK64: 658 case F_SETLK64:
601 case F_SETLKW64: 659 case F_SETLKW64:
602 case F_OFD_GETLK:
603 case F_OFD_SETLK: 660 case F_OFD_SETLK:
604 case F_OFD_SETLKW: 661 case F_OFD_SETLKW:
605 ret = get_compat_flock64(&f, compat_ptr(arg)); 662 err = get_compat_flock64(&flock, compat_ptr(arg));
606 if (ret != 0) 663 if (err)
607 break; 664 break;
608 old_fs = get_fs(); 665 err = fcntl_setlk(fd, f.file, convert_fcntl_cmd(cmd), &flock);
609 set_fs(KERNEL_DS);
610 conv_cmd = convert_fcntl_cmd(cmd);
611 ret = sys_fcntl(fd, conv_cmd, (unsigned long)&f);
612 set_fs(old_fs);
613 if ((conv_cmd == F_GETLK || conv_cmd == F_OFD_GETLK) && ret == 0) {
614 /* need to return lock information - see above for commentary */
615 if (f.l_start > COMPAT_LOFF_T_MAX)
616 ret = -EOVERFLOW;
617 if (f.l_len > COMPAT_LOFF_T_MAX)
618 f.l_len = COMPAT_LOFF_T_MAX;
619 if (ret == 0)
620 ret = put_compat_flock64(&f, compat_ptr(arg));
621 }
622 break; 666 break;
623
624 default: 667 default:
625 ret = sys_fcntl(fd, cmd, arg); 668 err = do_fcntl(fd, cmd, arg, f.file);
626 break; 669 break;
627 } 670 }
628 return ret; 671out_put:
672 fdput(f);
673 return err;
629} 674}
630 675
631COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, 676COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd,
diff --git a/fs/locks.c b/fs/locks.c
index af2031a1fcff..afefeb4ad6de 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1858,8 +1858,8 @@ EXPORT_SYMBOL(generic_setlease);
1858 * 1858 *
1859 * Call this to establish a lease on the file. The "lease" argument is not 1859 * Call this to establish a lease on the file. The "lease" argument is not
1860 * used for F_UNLCK requests and may be NULL. For commands that set or alter 1860 * used for F_UNLCK requests and may be NULL. For commands that set or alter
1861 * an existing lease, the (*lease)->fl_lmops->lm_break operation must be set; 1861 * an existing lease, the ``(*lease)->fl_lmops->lm_break`` operation must be
1862 * if not, this function will return -ENOLCK (and generate a scary-looking 1862 * set; if not, this function will return -ENOLCK (and generate a scary-looking
1863 * stack trace). 1863 * stack trace).
1864 * 1864 *
1865 * The "priv" pointer is passed directly to the lm_setup function as-is. It 1865 * The "priv" pointer is passed directly to the lm_setup function as-is. It
@@ -1972,15 +1972,13 @@ EXPORT_SYMBOL(locks_lock_inode_wait);
1972 * @cmd: the type of lock to apply. 1972 * @cmd: the type of lock to apply.
1973 * 1973 *
1974 * Apply a %FL_FLOCK style lock to an open file descriptor. 1974 * Apply a %FL_FLOCK style lock to an open file descriptor.
1975 * The @cmd can be one of 1975 * The @cmd can be one of:
1976 * 1976 *
1977 * %LOCK_SH -- a shared lock. 1977 * - %LOCK_SH -- a shared lock.
1978 * 1978 * - %LOCK_EX -- an exclusive lock.
1979 * %LOCK_EX -- an exclusive lock. 1979 * - %LOCK_UN -- remove an existing lock.
1980 * 1980 * - %LOCK_MAND -- a 'mandatory' flock.
1981 * %LOCK_UN -- remove an existing lock. 1981 * This exists to emulate Windows Share Modes.
1982 *
1983 * %LOCK_MAND -- a `mandatory' flock. This exists to emulate Windows Share Modes.
1984 * 1982 *
1985 * %LOCK_MAND can be combined with %LOCK_READ or %LOCK_WRITE to allow other 1983 * %LOCK_MAND can be combined with %LOCK_READ or %LOCK_WRITE to allow other
1986 * processes read and write access respectively. 1984 * processes read and write access respectively.
@@ -2086,26 +2084,22 @@ static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
2086/* Report the first existing lock that would conflict with l. 2084/* Report the first existing lock that would conflict with l.
2087 * This implements the F_GETLK command of fcntl(). 2085 * This implements the F_GETLK command of fcntl().
2088 */ 2086 */
2089int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l) 2087int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock)
2090{ 2088{
2091 struct file_lock file_lock; 2089 struct file_lock file_lock;
2092 struct flock flock;
2093 int error; 2090 int error;
2094 2091
2095 error = -EFAULT;
2096 if (copy_from_user(&flock, l, sizeof(flock)))
2097 goto out;
2098 error = -EINVAL; 2092 error = -EINVAL;
2099 if ((flock.l_type != F_RDLCK) && (flock.l_type != F_WRLCK)) 2093 if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK)
2100 goto out; 2094 goto out;
2101 2095
2102 error = flock_to_posix_lock(filp, &file_lock, &flock); 2096 error = flock_to_posix_lock(filp, &file_lock, flock);
2103 if (error) 2097 if (error)
2104 goto out; 2098 goto out;
2105 2099
2106 if (cmd == F_OFD_GETLK) { 2100 if (cmd == F_OFD_GETLK) {
2107 error = -EINVAL; 2101 error = -EINVAL;
2108 if (flock.l_pid != 0) 2102 if (flock->l_pid != 0)
2109 goto out; 2103 goto out;
2110 2104
2111 cmd = F_GETLK; 2105 cmd = F_GETLK;
@@ -2117,15 +2111,12 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l)
2117 if (error) 2111 if (error)
2118 goto out; 2112 goto out;
2119 2113
2120 flock.l_type = file_lock.fl_type; 2114 flock->l_type = file_lock.fl_type;
2121 if (file_lock.fl_type != F_UNLCK) { 2115 if (file_lock.fl_type != F_UNLCK) {
2122 error = posix_lock_to_flock(&flock, &file_lock); 2116 error = posix_lock_to_flock(flock, &file_lock);
2123 if (error) 2117 if (error)
2124 goto rel_priv; 2118 goto rel_priv;
2125 } 2119 }
2126 error = -EFAULT;
2127 if (!copy_to_user(l, &flock, sizeof(flock)))
2128 error = 0;
2129rel_priv: 2120rel_priv:
2130 locks_release_private(&file_lock); 2121 locks_release_private(&file_lock);
2131out: 2122out:
@@ -2218,26 +2209,16 @@ check_fmode_for_setlk(struct file_lock *fl)
2218 * This implements both the F_SETLK and F_SETLKW commands of fcntl(). 2209 * This implements both the F_SETLK and F_SETLKW commands of fcntl().
2219 */ 2210 */
2220int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, 2211int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
2221 struct flock __user *l) 2212 struct flock *flock)
2222{ 2213{
2223 struct file_lock *file_lock = locks_alloc_lock(); 2214 struct file_lock *file_lock = locks_alloc_lock();
2224 struct flock flock; 2215 struct inode *inode = locks_inode(filp);
2225 struct inode *inode;
2226 struct file *f; 2216 struct file *f;
2227 int error; 2217 int error;
2228 2218
2229 if (file_lock == NULL) 2219 if (file_lock == NULL)
2230 return -ENOLCK; 2220 return -ENOLCK;
2231 2221
2232 inode = locks_inode(filp);
2233
2234 /*
2235 * This might block, so we do it before checking the inode.
2236 */
2237 error = -EFAULT;
2238 if (copy_from_user(&flock, l, sizeof(flock)))
2239 goto out;
2240
2241 /* Don't allow mandatory locks on files that may be memory mapped 2222 /* Don't allow mandatory locks on files that may be memory mapped
2242 * and shared. 2223 * and shared.
2243 */ 2224 */
@@ -2246,7 +2227,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
2246 goto out; 2227 goto out;
2247 } 2228 }
2248 2229
2249 error = flock_to_posix_lock(filp, file_lock, &flock); 2230 error = flock_to_posix_lock(filp, file_lock, flock);
2250 if (error) 2231 if (error)
2251 goto out; 2232 goto out;
2252 2233
@@ -2261,7 +2242,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
2261 switch (cmd) { 2242 switch (cmd) {
2262 case F_OFD_SETLK: 2243 case F_OFD_SETLK:
2263 error = -EINVAL; 2244 error = -EINVAL;
2264 if (flock.l_pid != 0) 2245 if (flock->l_pid != 0)
2265 goto out; 2246 goto out;
2266 2247
2267 cmd = F_SETLK; 2248 cmd = F_SETLK;
@@ -2270,7 +2251,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
2270 break; 2251 break;
2271 case F_OFD_SETLKW: 2252 case F_OFD_SETLKW:
2272 error = -EINVAL; 2253 error = -EINVAL;
2273 if (flock.l_pid != 0) 2254 if (flock->l_pid != 0)
2274 goto out; 2255 goto out;
2275 2256
2276 cmd = F_SETLKW; 2257 cmd = F_SETLKW;
@@ -2315,26 +2296,22 @@ out:
2315/* Report the first existing lock that would conflict with l. 2296/* Report the first existing lock that would conflict with l.
2316 * This implements the F_GETLK command of fcntl(). 2297 * This implements the F_GETLK command of fcntl().
2317 */ 2298 */
2318int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) 2299int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock)
2319{ 2300{
2320 struct file_lock file_lock; 2301 struct file_lock file_lock;
2321 struct flock64 flock;
2322 int error; 2302 int error;
2323 2303
2324 error = -EFAULT;
2325 if (copy_from_user(&flock, l, sizeof(flock)))
2326 goto out;
2327 error = -EINVAL; 2304 error = -EINVAL;
2328 if ((flock.l_type != F_RDLCK) && (flock.l_type != F_WRLCK)) 2305 if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK)
2329 goto out; 2306 goto out;
2330 2307
2331 error = flock64_to_posix_lock(filp, &file_lock, &flock); 2308 error = flock64_to_posix_lock(filp, &file_lock, flock);
2332 if (error) 2309 if (error)
2333 goto out; 2310 goto out;
2334 2311
2335 if (cmd == F_OFD_GETLK) { 2312 if (cmd == F_OFD_GETLK) {
2336 error = -EINVAL; 2313 error = -EINVAL;
2337 if (flock.l_pid != 0) 2314 if (flock->l_pid != 0)
2338 goto out; 2315 goto out;
2339 2316
2340 cmd = F_GETLK64; 2317 cmd = F_GETLK64;
@@ -2346,13 +2323,9 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l)
2346 if (error) 2323 if (error)
2347 goto out; 2324 goto out;
2348 2325
2349 flock.l_type = file_lock.fl_type; 2326 flock->l_type = file_lock.fl_type;
2350 if (file_lock.fl_type != F_UNLCK) 2327 if (file_lock.fl_type != F_UNLCK)
2351 posix_lock_to_flock64(&flock, &file_lock); 2328 posix_lock_to_flock64(flock, &file_lock);
2352
2353 error = -EFAULT;
2354 if (!copy_to_user(l, &flock, sizeof(flock)))
2355 error = 0;
2356 2329
2357 locks_release_private(&file_lock); 2330 locks_release_private(&file_lock);
2358out: 2331out:
@@ -2363,26 +2336,16 @@ out:
2363 * This implements both the F_SETLK and F_SETLKW commands of fcntl(). 2336 * This implements both the F_SETLK and F_SETLKW commands of fcntl().
2364 */ 2337 */
2365int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, 2338int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
2366 struct flock64 __user *l) 2339 struct flock64 *flock)
2367{ 2340{
2368 struct file_lock *file_lock = locks_alloc_lock(); 2341 struct file_lock *file_lock = locks_alloc_lock();
2369 struct flock64 flock; 2342 struct inode *inode = locks_inode(filp);
2370 struct inode *inode;
2371 struct file *f; 2343 struct file *f;
2372 int error; 2344 int error;
2373 2345
2374 if (file_lock == NULL) 2346 if (file_lock == NULL)
2375 return -ENOLCK; 2347 return -ENOLCK;
2376 2348
2377 /*
2378 * This might block, so we do it before checking the inode.
2379 */
2380 error = -EFAULT;
2381 if (copy_from_user(&flock, l, sizeof(flock)))
2382 goto out;
2383
2384 inode = locks_inode(filp);
2385
2386 /* Don't allow mandatory locks on files that may be memory mapped 2349 /* Don't allow mandatory locks on files that may be memory mapped
2387 * and shared. 2350 * and shared.
2388 */ 2351 */
@@ -2391,7 +2354,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
2391 goto out; 2354 goto out;
2392 } 2355 }
2393 2356
2394 error = flock64_to_posix_lock(filp, file_lock, &flock); 2357 error = flock64_to_posix_lock(filp, file_lock, flock);
2395 if (error) 2358 if (error)
2396 goto out; 2359 goto out;
2397 2360
@@ -2406,7 +2369,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
2406 switch (cmd) { 2369 switch (cmd) {
2407 case F_OFD_SETLK: 2370 case F_OFD_SETLK:
2408 error = -EINVAL; 2371 error = -EINVAL;
2409 if (flock.l_pid != 0) 2372 if (flock->l_pid != 0)
2410 goto out; 2373 goto out;
2411 2374
2412 cmd = F_SETLK64; 2375 cmd = F_SETLK64;
@@ -2415,7 +2378,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
2415 break; 2378 break;
2416 case F_OFD_SETLKW: 2379 case F_OFD_SETLKW:
2417 error = -EINVAL; 2380 error = -EINVAL;
2418 if (flock.l_pid != 0) 2381 if (flock->l_pid != 0)
2419 goto out; 2382 goto out;
2420 2383
2421 cmd = F_SETLKW64; 2384 cmd = F_SETLKW64;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 2be32955d7f2..6eef95c585e3 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1464,41 +1464,34 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1464__be32 1464__be32
1465nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp) 1465nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
1466{ 1466{
1467 mm_segment_t oldfs;
1468 __be32 err; 1467 __be32 err;
1469 int host_err; 1468 const char *link;
1470 struct path path; 1469 struct path path;
1470 DEFINE_DELAYED_CALL(done);
1471 int len;
1471 1472
1472 err = fh_verify(rqstp, fhp, S_IFLNK, NFSD_MAY_NOP); 1473 err = fh_verify(rqstp, fhp, S_IFLNK, NFSD_MAY_NOP);
1473 if (err) 1474 if (unlikely(err))
1474 goto out; 1475 return err;
1475 1476
1476 path.mnt = fhp->fh_export->ex_path.mnt; 1477 path.mnt = fhp->fh_export->ex_path.mnt;
1477 path.dentry = fhp->fh_dentry; 1478 path.dentry = fhp->fh_dentry;
1478 1479
1479 err = nfserr_inval; 1480 if (unlikely(!d_is_symlink(path.dentry)))
1480 if (!d_is_symlink(path.dentry)) 1481 return nfserr_inval;
1481 goto out;
1482 1482
1483 touch_atime(&path); 1483 touch_atime(&path);
1484 /* N.B. Why does this call need a get_fs()??
1485 * Remove the set_fs and watch the fireworks:-) --okir
1486 */
1487 1484
1488 oldfs = get_fs(); set_fs(KERNEL_DS); 1485 link = vfs_get_link(path.dentry, &done);
1489 host_err = vfs_readlink(path.dentry, (char __user *)buf, *lenp); 1486 if (IS_ERR(link))
1490 set_fs(oldfs); 1487 return nfserrno(PTR_ERR(link));
1491 1488
1492 if (host_err < 0) 1489 len = strlen(link);
1493 goto out_nfserr; 1490 if (len < *lenp)
1494 *lenp = host_err; 1491 *lenp = len;
1495 err = 0; 1492 memcpy(buf, link, *lenp);
1496out: 1493 do_delayed_call(&done);
1497 return err; 1494 return 0;
1498
1499out_nfserr:
1500 err = nfserrno(host_err);
1501 goto out;
1502} 1495}
1503 1496
1504/* 1497/*
diff --git a/fs/statfs.c b/fs/statfs.c
index 4e4623c7a126..41a6a82da5e2 100644
--- a/fs/statfs.c
+++ b/fs/statfs.c
@@ -244,6 +244,7 @@ SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf)
244#ifdef CONFIG_COMPAT 244#ifdef CONFIG_COMPAT
245static int put_compat_statfs(struct compat_statfs __user *ubuf, struct kstatfs *kbuf) 245static int put_compat_statfs(struct compat_statfs __user *ubuf, struct kstatfs *kbuf)
246{ 246{
247 struct compat_statfs buf;
247 if (sizeof ubuf->f_blocks == 4) { 248 if (sizeof ubuf->f_blocks == 4) {
248 if ((kbuf->f_blocks | kbuf->f_bfree | kbuf->f_bavail | 249 if ((kbuf->f_blocks | kbuf->f_bfree | kbuf->f_bavail |
249 kbuf->f_bsize | kbuf->f_frsize) & 0xffffffff00000000ULL) 250 kbuf->f_bsize | kbuf->f_frsize) & 0xffffffff00000000ULL)
@@ -257,20 +258,20 @@ static int put_compat_statfs(struct compat_statfs __user *ubuf, struct kstatfs *
257 && (kbuf->f_ffree & 0xffffffff00000000ULL)) 258 && (kbuf->f_ffree & 0xffffffff00000000ULL))
258 return -EOVERFLOW; 259 return -EOVERFLOW;
259 } 260 }
260 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) || 261 memset(&buf, 0, sizeof(struct compat_statfs));
261 __put_user(kbuf->f_type, &ubuf->f_type) || 262 buf.f_type = kbuf->f_type;
262 __put_user(kbuf->f_bsize, &ubuf->f_bsize) || 263 buf.f_bsize = kbuf->f_bsize;
263 __put_user(kbuf->f_blocks, &ubuf->f_blocks) || 264 buf.f_blocks = kbuf->f_blocks;
264 __put_user(kbuf->f_bfree, &ubuf->f_bfree) || 265 buf.f_bfree = kbuf->f_bfree;
265 __put_user(kbuf->f_bavail, &ubuf->f_bavail) || 266 buf.f_bavail = kbuf->f_bavail;
266 __put_user(kbuf->f_files, &ubuf->f_files) || 267 buf.f_files = kbuf->f_files;
267 __put_user(kbuf->f_ffree, &ubuf->f_ffree) || 268 buf.f_ffree = kbuf->f_ffree;
268 __put_user(kbuf->f_namelen, &ubuf->f_namelen) || 269 buf.f_namelen = kbuf->f_namelen;
269 __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || 270 buf.f_fsid.val[0] = kbuf->f_fsid.val[0];
270 __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) || 271 buf.f_fsid.val[1] = kbuf->f_fsid.val[1];
271 __put_user(kbuf->f_frsize, &ubuf->f_frsize) || 272 buf.f_frsize = kbuf->f_frsize;
272 __put_user(kbuf->f_flags, &ubuf->f_flags) || 273 buf.f_flags = kbuf->f_flags;
273 __clear_user(ubuf->f_spare, sizeof(ubuf->f_spare))) 274 if (copy_to_user(ubuf, &buf, sizeof(struct compat_statfs)))
274 return -EFAULT; 275 return -EFAULT;
275 return 0; 276 return 0;
276} 277}
@@ -299,6 +300,7 @@ COMPAT_SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct compat_statfs __user *,
299 300
300static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstatfs *kbuf) 301static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstatfs *kbuf)
301{ 302{
303 struct compat_statfs64 buf;
302 if (sizeof(ubuf->f_bsize) == 4) { 304 if (sizeof(ubuf->f_bsize) == 4) {
303 if ((kbuf->f_type | kbuf->f_bsize | kbuf->f_namelen | 305 if ((kbuf->f_type | kbuf->f_bsize | kbuf->f_namelen |
304 kbuf->f_frsize | kbuf->f_flags) & 0xffffffff00000000ULL) 306 kbuf->f_frsize | kbuf->f_flags) & 0xffffffff00000000ULL)
@@ -312,20 +314,20 @@ static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstat
312 && (kbuf->f_ffree & 0xffffffff00000000ULL)) 314 && (kbuf->f_ffree & 0xffffffff00000000ULL))
313 return -EOVERFLOW; 315 return -EOVERFLOW;
314 } 316 }
315 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) || 317 memset(&buf, 0, sizeof(struct compat_statfs64));
316 __put_user(kbuf->f_type, &ubuf->f_type) || 318 buf.f_type = kbuf->f_type;
317 __put_user(kbuf->f_bsize, &ubuf->f_bsize) || 319 buf.f_bsize = kbuf->f_bsize;
318 __put_user(kbuf->f_blocks, &ubuf->f_blocks) || 320 buf.f_blocks = kbuf->f_blocks;
319 __put_user(kbuf->f_bfree, &ubuf->f_bfree) || 321 buf.f_bfree = kbuf->f_bfree;
320 __put_user(kbuf->f_bavail, &ubuf->f_bavail) || 322 buf.f_bavail = kbuf->f_bavail;
321 __put_user(kbuf->f_files, &ubuf->f_files) || 323 buf.f_files = kbuf->f_files;
322 __put_user(kbuf->f_ffree, &ubuf->f_ffree) || 324 buf.f_ffree = kbuf->f_ffree;
323 __put_user(kbuf->f_namelen, &ubuf->f_namelen) || 325 buf.f_namelen = kbuf->f_namelen;
324 __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || 326 buf.f_fsid.val[0] = kbuf->f_fsid.val[0];
325 __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) || 327 buf.f_fsid.val[1] = kbuf->f_fsid.val[1];
326 __put_user(kbuf->f_frsize, &ubuf->f_frsize) || 328 buf.f_frsize = kbuf->f_frsize;
327 __put_user(kbuf->f_flags, &ubuf->f_flags) || 329 buf.f_flags = kbuf->f_flags;
328 __clear_user(ubuf->f_spare, sizeof(ubuf->f_spare))) 330 if (copy_to_user(ubuf, &buf, sizeof(struct compat_statfs64)))
329 return -EFAULT; 331 return -EFAULT;
330 return 0; 332 return 0;
331} 333}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 771fe1131467..9a540d399d1b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1047,14 +1047,14 @@ static inline struct inode *locks_inode(const struct file *f)
1047} 1047}
1048 1048
1049#ifdef CONFIG_FILE_LOCKING 1049#ifdef CONFIG_FILE_LOCKING
1050extern int fcntl_getlk(struct file *, unsigned int, struct flock __user *); 1050extern int fcntl_getlk(struct file *, unsigned int, struct flock *);
1051extern int fcntl_setlk(unsigned int, struct file *, unsigned int, 1051extern int fcntl_setlk(unsigned int, struct file *, unsigned int,
1052 struct flock __user *); 1052 struct flock *);
1053 1053
1054#if BITS_PER_LONG == 32 1054#if BITS_PER_LONG == 32
1055extern int fcntl_getlk64(struct file *, unsigned int, struct flock64 __user *); 1055extern int fcntl_getlk64(struct file *, unsigned int, struct flock64 *);
1056extern int fcntl_setlk64(unsigned int, struct file *, unsigned int, 1056extern int fcntl_setlk64(unsigned int, struct file *, unsigned int,
1057 struct flock64 __user *); 1057 struct flock64 *);
1058#endif 1058#endif
1059 1059
1060extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg); 1060extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg);
@@ -1258,7 +1258,7 @@ extern void fasync_free(struct fasync_struct *);
1258extern void kill_fasync(struct fasync_struct **, int, int); 1258extern void kill_fasync(struct fasync_struct **, int, int);
1259 1259
1260extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); 1260extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
1261extern void f_setown(struct file *filp, unsigned long arg, int force); 1261extern int f_setown(struct file *filp, unsigned long arg, int force);
1262extern void f_delown(struct file *filp); 1262extern void f_delown(struct file *filp);
1263extern pid_t f_getown(struct file *filp); 1263extern pid_t f_getown(struct file *filp);
1264extern int send_sigurg(struct fown_struct *fown); 1264extern int send_sigurg(struct fown_struct *fown);
diff --git a/net/socket.c b/net/socket.c
index 8f9dab330d57..59e902b9df09 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -991,8 +991,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
991 err = -EFAULT; 991 err = -EFAULT;
992 if (get_user(pid, (int __user *)argp)) 992 if (get_user(pid, (int __user *)argp))
993 break; 993 break;
994 f_setown(sock->file, pid, 1); 994 err = f_setown(sock->file, pid, 1);
995 err = 0;
996 break; 995 break;
997 case FIOGETOWN: 996 case FIOGETOWN:
998 case SIOCGPGRP: 997 case SIOCGPGRP: