diff options
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 192 |
1 files changed, 106 insertions, 86 deletions
diff --git a/net/socket.c b/net/socket.c index 74283610db15..510ae18d220a 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -426,6 +426,28 @@ int sock_map_fd(struct socket *sock) | |||
426 | return fd; | 426 | return fd; |
427 | } | 427 | } |
428 | 428 | ||
429 | static struct socket *sock_from_file(struct file *file, int *err) | ||
430 | { | ||
431 | struct inode *inode; | ||
432 | struct socket *sock; | ||
433 | |||
434 | if (file->f_op == &socket_file_ops) | ||
435 | return file->private_data; /* set in sock_map_fd */ | ||
436 | |||
437 | inode = file->f_dentry->d_inode; | ||
438 | if (!S_ISSOCK(inode->i_mode)) { | ||
439 | *err = -ENOTSOCK; | ||
440 | return NULL; | ||
441 | } | ||
442 | |||
443 | sock = SOCKET_I(inode); | ||
444 | if (sock->file != file) { | ||
445 | printk(KERN_ERR "socki_lookup: socket file changed!\n"); | ||
446 | sock->file = file; | ||
447 | } | ||
448 | return sock; | ||
449 | } | ||
450 | |||
429 | /** | 451 | /** |
430 | * sockfd_lookup - Go from a file number to its socket slot | 452 | * sockfd_lookup - Go from a file number to its socket slot |
431 | * @fd: file handle | 453 | * @fd: file handle |
@@ -442,31 +464,31 @@ int sock_map_fd(struct socket *sock) | |||
442 | struct socket *sockfd_lookup(int fd, int *err) | 464 | struct socket *sockfd_lookup(int fd, int *err) |
443 | { | 465 | { |
444 | struct file *file; | 466 | struct file *file; |
445 | struct inode *inode; | ||
446 | struct socket *sock; | 467 | struct socket *sock; |
447 | 468 | ||
448 | if (!(file = fget(fd))) | 469 | if (!(file = fget(fd))) { |
449 | { | ||
450 | *err = -EBADF; | 470 | *err = -EBADF; |
451 | return NULL; | 471 | return NULL; |
452 | } | 472 | } |
453 | 473 | sock = sock_from_file(file, err); | |
454 | if (file->f_op == &socket_file_ops) | 474 | if (!sock) |
455 | return file->private_data; /* set in sock_map_fd */ | ||
456 | |||
457 | inode = file->f_dentry->d_inode; | ||
458 | if (!S_ISSOCK(inode->i_mode)) { | ||
459 | *err = -ENOTSOCK; | ||
460 | fput(file); | 475 | fput(file); |
461 | return NULL; | 476 | return sock; |
462 | } | 477 | } |
463 | 478 | ||
464 | sock = SOCKET_I(inode); | 479 | static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed) |
465 | if (sock->file != file) { | 480 | { |
466 | printk(KERN_ERR "socki_lookup: socket file changed!\n"); | 481 | struct file *file; |
467 | sock->file = file; | 482 | struct socket *sock; |
483 | |||
484 | file = fget_light(fd, fput_needed); | ||
485 | if (file) { | ||
486 | sock = sock_from_file(file, err); | ||
487 | if (sock) | ||
488 | return sock; | ||
489 | fput_light(file, *fput_needed); | ||
468 | } | 490 | } |
469 | return sock; | 491 | return NULL; |
470 | } | 492 | } |
471 | 493 | ||
472 | /** | 494 | /** |
@@ -1301,19 +1323,17 @@ asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen) | |||
1301 | { | 1323 | { |
1302 | struct socket *sock; | 1324 | struct socket *sock; |
1303 | char address[MAX_SOCK_ADDR]; | 1325 | char address[MAX_SOCK_ADDR]; |
1304 | int err; | 1326 | int err, fput_needed; |
1305 | 1327 | ||
1306 | if((sock = sockfd_lookup(fd,&err))!=NULL) | 1328 | if((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL) |
1307 | { | 1329 | { |
1308 | if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) { | 1330 | if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) { |
1309 | err = security_socket_bind(sock, (struct sockaddr *)address, addrlen); | 1331 | err = security_socket_bind(sock, (struct sockaddr *)address, addrlen); |
1310 | if (err) { | 1332 | if (!err) |
1311 | sockfd_put(sock); | 1333 | err = sock->ops->bind(sock, |
1312 | return err; | 1334 | (struct sockaddr *)address, addrlen); |
1313 | } | ||
1314 | err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen); | ||
1315 | } | 1335 | } |
1316 | sockfd_put(sock); | 1336 | fput_light(sock->file, fput_needed); |
1317 | } | 1337 | } |
1318 | return err; | 1338 | return err; |
1319 | } | 1339 | } |
@@ -1330,20 +1350,17 @@ int sysctl_somaxconn = SOMAXCONN; | |||
1330 | asmlinkage long sys_listen(int fd, int backlog) | 1350 | asmlinkage long sys_listen(int fd, int backlog) |
1331 | { | 1351 | { |
1332 | struct socket *sock; | 1352 | struct socket *sock; |
1333 | int err; | 1353 | int err, fput_needed; |
1334 | 1354 | ||
1335 | if ((sock = sockfd_lookup(fd, &err)) != NULL) { | 1355 | if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) { |
1336 | if ((unsigned) backlog > sysctl_somaxconn) | 1356 | if ((unsigned) backlog > sysctl_somaxconn) |
1337 | backlog = sysctl_somaxconn; | 1357 | backlog = sysctl_somaxconn; |
1338 | 1358 | ||
1339 | err = security_socket_listen(sock, backlog); | 1359 | err = security_socket_listen(sock, backlog); |
1340 | if (err) { | 1360 | if (!err) |
1341 | sockfd_put(sock); | 1361 | err = sock->ops->listen(sock, backlog); |
1342 | return err; | ||
1343 | } | ||
1344 | 1362 | ||
1345 | err=sock->ops->listen(sock, backlog); | 1363 | fput_light(sock->file, fput_needed); |
1346 | sockfd_put(sock); | ||
1347 | } | 1364 | } |
1348 | return err; | 1365 | return err; |
1349 | } | 1366 | } |
@@ -1365,10 +1382,10 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _ | |||
1365 | { | 1382 | { |
1366 | struct socket *sock, *newsock; | 1383 | struct socket *sock, *newsock; |
1367 | struct file *newfile; | 1384 | struct file *newfile; |
1368 | int err, len, newfd; | 1385 | int err, len, newfd, fput_needed; |
1369 | char address[MAX_SOCK_ADDR]; | 1386 | char address[MAX_SOCK_ADDR]; |
1370 | 1387 | ||
1371 | sock = sockfd_lookup(fd, &err); | 1388 | sock = sockfd_lookup_light(fd, &err, &fput_needed); |
1372 | if (!sock) | 1389 | if (!sock) |
1373 | goto out; | 1390 | goto out; |
1374 | 1391 | ||
@@ -1421,7 +1438,7 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _ | |||
1421 | security_socket_post_accept(sock, newsock); | 1438 | security_socket_post_accept(sock, newsock); |
1422 | 1439 | ||
1423 | out_put: | 1440 | out_put: |
1424 | sockfd_put(sock); | 1441 | fput_light(sock->file, fput_needed); |
1425 | out: | 1442 | out: |
1426 | return err; | 1443 | return err; |
1427 | out_fd: | 1444 | out_fd: |
@@ -1449,9 +1466,9 @@ asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrl | |||
1449 | { | 1466 | { |
1450 | struct socket *sock; | 1467 | struct socket *sock; |
1451 | char address[MAX_SOCK_ADDR]; | 1468 | char address[MAX_SOCK_ADDR]; |
1452 | int err; | 1469 | int err, fput_needed; |
1453 | 1470 | ||
1454 | sock = sockfd_lookup(fd, &err); | 1471 | sock = sockfd_lookup_light(fd, &err, &fput_needed); |
1455 | if (!sock) | 1472 | if (!sock) |
1456 | goto out; | 1473 | goto out; |
1457 | err = move_addr_to_kernel(uservaddr, addrlen, address); | 1474 | err = move_addr_to_kernel(uservaddr, addrlen, address); |
@@ -1465,7 +1482,7 @@ asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrl | |||
1465 | err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen, | 1482 | err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen, |
1466 | sock->file->f_flags); | 1483 | sock->file->f_flags); |
1467 | out_put: | 1484 | out_put: |
1468 | sockfd_put(sock); | 1485 | fput_light(sock->file, fput_needed); |
1469 | out: | 1486 | out: |
1470 | return err; | 1487 | return err; |
1471 | } | 1488 | } |
@@ -1479,9 +1496,9 @@ asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int _ | |||
1479 | { | 1496 | { |
1480 | struct socket *sock; | 1497 | struct socket *sock; |
1481 | char address[MAX_SOCK_ADDR]; | 1498 | char address[MAX_SOCK_ADDR]; |
1482 | int len, err; | 1499 | int len, err, fput_needed; |
1483 | 1500 | ||
1484 | sock = sockfd_lookup(fd, &err); | 1501 | sock = sockfd_lookup_light(fd, &err, &fput_needed); |
1485 | if (!sock) | 1502 | if (!sock) |
1486 | goto out; | 1503 | goto out; |
1487 | 1504 | ||
@@ -1495,7 +1512,7 @@ asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int _ | |||
1495 | err = move_addr_to_user(address, len, usockaddr, usockaddr_len); | 1512 | err = move_addr_to_user(address, len, usockaddr, usockaddr_len); |
1496 | 1513 | ||
1497 | out_put: | 1514 | out_put: |
1498 | sockfd_put(sock); | 1515 | fput_light(sock->file, fput_needed); |
1499 | out: | 1516 | out: |
1500 | return err; | 1517 | return err; |
1501 | } | 1518 | } |
@@ -1509,20 +1526,19 @@ asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int _ | |||
1509 | { | 1526 | { |
1510 | struct socket *sock; | 1527 | struct socket *sock; |
1511 | char address[MAX_SOCK_ADDR]; | 1528 | char address[MAX_SOCK_ADDR]; |
1512 | int len, err; | 1529 | int len, err, fput_needed; |
1513 | 1530 | ||
1514 | if ((sock = sockfd_lookup(fd, &err))!=NULL) | 1531 | if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) { |
1515 | { | ||
1516 | err = security_socket_getpeername(sock); | 1532 | err = security_socket_getpeername(sock); |
1517 | if (err) { | 1533 | if (err) { |
1518 | sockfd_put(sock); | 1534 | fput_light(sock->file, fput_needed); |
1519 | return err; | 1535 | return err; |
1520 | } | 1536 | } |
1521 | 1537 | ||
1522 | err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1); | 1538 | err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1); |
1523 | if (!err) | 1539 | if (!err) |
1524 | err=move_addr_to_user(address,len, usockaddr, usockaddr_len); | 1540 | err=move_addr_to_user(address,len, usockaddr, usockaddr_len); |
1525 | sockfd_put(sock); | 1541 | fput_light(sock->file, fput_needed); |
1526 | } | 1542 | } |
1527 | return err; | 1543 | return err; |
1528 | } | 1544 | } |
@@ -1541,10 +1557,16 @@ asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flag | |||
1541 | int err; | 1557 | int err; |
1542 | struct msghdr msg; | 1558 | struct msghdr msg; |
1543 | struct iovec iov; | 1559 | struct iovec iov; |
1544 | 1560 | int fput_needed; | |
1545 | sock = sockfd_lookup(fd, &err); | 1561 | struct file *sock_file; |
1562 | |||
1563 | sock_file = fget_light(fd, &fput_needed); | ||
1564 | if (!sock_file) | ||
1565 | return -EBADF; | ||
1566 | |||
1567 | sock = sock_from_file(sock_file, &err); | ||
1546 | if (!sock) | 1568 | if (!sock) |
1547 | goto out; | 1569 | goto out_put; |
1548 | iov.iov_base=buff; | 1570 | iov.iov_base=buff; |
1549 | iov.iov_len=len; | 1571 | iov.iov_len=len; |
1550 | msg.msg_name=NULL; | 1572 | msg.msg_name=NULL; |
@@ -1553,8 +1575,7 @@ asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flag | |||
1553 | msg.msg_control=NULL; | 1575 | msg.msg_control=NULL; |
1554 | msg.msg_controllen=0; | 1576 | msg.msg_controllen=0; |
1555 | msg.msg_namelen=0; | 1577 | msg.msg_namelen=0; |
1556 | if(addr) | 1578 | if (addr) { |
1557 | { | ||
1558 | err = move_addr_to_kernel(addr, addr_len, address); | 1579 | err = move_addr_to_kernel(addr, addr_len, address); |
1559 | if (err < 0) | 1580 | if (err < 0) |
1560 | goto out_put; | 1581 | goto out_put; |
@@ -1567,8 +1588,7 @@ asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flag | |||
1567 | err = sock_sendmsg(sock, &msg, len); | 1588 | err = sock_sendmsg(sock, &msg, len); |
1568 | 1589 | ||
1569 | out_put: | 1590 | out_put: |
1570 | sockfd_put(sock); | 1591 | fput_light(sock_file, fput_needed); |
1571 | out: | ||
1572 | return err; | 1592 | return err; |
1573 | } | 1593 | } |
1574 | 1594 | ||
@@ -1595,8 +1615,14 @@ asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned f | |||
1595 | struct msghdr msg; | 1615 | struct msghdr msg; |
1596 | char address[MAX_SOCK_ADDR]; | 1616 | char address[MAX_SOCK_ADDR]; |
1597 | int err,err2; | 1617 | int err,err2; |
1618 | struct file *sock_file; | ||
1619 | int fput_needed; | ||
1620 | |||
1621 | sock_file = fget_light(fd, &fput_needed); | ||
1622 | if (!sock_file) | ||
1623 | return -EBADF; | ||
1598 | 1624 | ||
1599 | sock = sockfd_lookup(fd, &err); | 1625 | sock = sock_from_file(sock_file, &err); |
1600 | if (!sock) | 1626 | if (!sock) |
1601 | goto out; | 1627 | goto out; |
1602 | 1628 | ||
@@ -1618,8 +1644,8 @@ asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned f | |||
1618 | if(err2<0) | 1644 | if(err2<0) |
1619 | err=err2; | 1645 | err=err2; |
1620 | } | 1646 | } |
1621 | sockfd_put(sock); | ||
1622 | out: | 1647 | out: |
1648 | fput_light(sock_file, fput_needed); | ||
1623 | return err; | 1649 | return err; |
1624 | } | 1650 | } |
1625 | 1651 | ||
@@ -1639,25 +1665,24 @@ asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags | |||
1639 | 1665 | ||
1640 | asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen) | 1666 | asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen) |
1641 | { | 1667 | { |
1642 | int err; | 1668 | int err, fput_needed; |
1643 | struct socket *sock; | 1669 | struct socket *sock; |
1644 | 1670 | ||
1645 | if (optlen < 0) | 1671 | if (optlen < 0) |
1646 | return -EINVAL; | 1672 | return -EINVAL; |
1647 | 1673 | ||
1648 | if ((sock = sockfd_lookup(fd, &err))!=NULL) | 1674 | if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) |
1649 | { | 1675 | { |
1650 | err = security_socket_setsockopt(sock,level,optname); | 1676 | err = security_socket_setsockopt(sock,level,optname); |
1651 | if (err) { | 1677 | if (err) |
1652 | sockfd_put(sock); | 1678 | goto out_put; |
1653 | return err; | ||
1654 | } | ||
1655 | 1679 | ||
1656 | if (level == SOL_SOCKET) | 1680 | if (level == SOL_SOCKET) |
1657 | err=sock_setsockopt(sock,level,optname,optval,optlen); | 1681 | err=sock_setsockopt(sock,level,optname,optval,optlen); |
1658 | else | 1682 | else |
1659 | err=sock->ops->setsockopt(sock, level, optname, optval, optlen); | 1683 | err=sock->ops->setsockopt(sock, level, optname, optval, optlen); |
1660 | sockfd_put(sock); | 1684 | out_put: |
1685 | fput_light(sock->file, fput_needed); | ||
1661 | } | 1686 | } |
1662 | return err; | 1687 | return err; |
1663 | } | 1688 | } |
@@ -1669,23 +1694,20 @@ asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optv | |||
1669 | 1694 | ||
1670 | asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen) | 1695 | asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen) |
1671 | { | 1696 | { |
1672 | int err; | 1697 | int err, fput_needed; |
1673 | struct socket *sock; | 1698 | struct socket *sock; |
1674 | 1699 | ||
1675 | if ((sock = sockfd_lookup(fd, &err))!=NULL) | 1700 | if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) { |
1676 | { | 1701 | err = security_socket_getsockopt(sock, level, optname); |
1677 | err = security_socket_getsockopt(sock, level, | 1702 | if (err) |
1678 | optname); | 1703 | goto out_put; |
1679 | if (err) { | ||
1680 | sockfd_put(sock); | ||
1681 | return err; | ||
1682 | } | ||
1683 | 1704 | ||
1684 | if (level == SOL_SOCKET) | 1705 | if (level == SOL_SOCKET) |
1685 | err=sock_getsockopt(sock,level,optname,optval,optlen); | 1706 | err=sock_getsockopt(sock,level,optname,optval,optlen); |
1686 | else | 1707 | else |
1687 | err=sock->ops->getsockopt(sock, level, optname, optval, optlen); | 1708 | err=sock->ops->getsockopt(sock, level, optname, optval, optlen); |
1688 | sockfd_put(sock); | 1709 | out_put: |
1710 | fput_light(sock->file, fput_needed); | ||
1689 | } | 1711 | } |
1690 | return err; | 1712 | return err; |
1691 | } | 1713 | } |
@@ -1697,19 +1719,15 @@ asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optv | |||
1697 | 1719 | ||
1698 | asmlinkage long sys_shutdown(int fd, int how) | 1720 | asmlinkage long sys_shutdown(int fd, int how) |
1699 | { | 1721 | { |
1700 | int err; | 1722 | int err, fput_needed; |
1701 | struct socket *sock; | 1723 | struct socket *sock; |
1702 | 1724 | ||
1703 | if ((sock = sockfd_lookup(fd, &err))!=NULL) | 1725 | if ((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL) |
1704 | { | 1726 | { |
1705 | err = security_socket_shutdown(sock, how); | 1727 | err = security_socket_shutdown(sock, how); |
1706 | if (err) { | 1728 | if (!err) |
1707 | sockfd_put(sock); | 1729 | err = sock->ops->shutdown(sock, how); |
1708 | return err; | 1730 | fput_light(sock->file, fput_needed); |
1709 | } | ||
1710 | |||
1711 | err=sock->ops->shutdown(sock, how); | ||
1712 | sockfd_put(sock); | ||
1713 | } | 1731 | } |
1714 | return err; | 1732 | return err; |
1715 | } | 1733 | } |
@@ -1738,6 +1756,7 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) | |||
1738 | unsigned char *ctl_buf = ctl; | 1756 | unsigned char *ctl_buf = ctl; |
1739 | struct msghdr msg_sys; | 1757 | struct msghdr msg_sys; |
1740 | int err, ctl_len, iov_size, total_len; | 1758 | int err, ctl_len, iov_size, total_len; |
1759 | int fput_needed; | ||
1741 | 1760 | ||
1742 | err = -EFAULT; | 1761 | err = -EFAULT; |
1743 | if (MSG_CMSG_COMPAT & flags) { | 1762 | if (MSG_CMSG_COMPAT & flags) { |
@@ -1746,7 +1765,7 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) | |||
1746 | } else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr))) | 1765 | } else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr))) |
1747 | return -EFAULT; | 1766 | return -EFAULT; |
1748 | 1767 | ||
1749 | sock = sockfd_lookup(fd, &err); | 1768 | sock = sockfd_lookup_light(fd, &err, &fput_needed); |
1750 | if (!sock) | 1769 | if (!sock) |
1751 | goto out; | 1770 | goto out; |
1752 | 1771 | ||
@@ -1814,7 +1833,7 @@ out_freeiov: | |||
1814 | if (iov != iovstack) | 1833 | if (iov != iovstack) |
1815 | sock_kfree_s(sock->sk, iov, iov_size); | 1834 | sock_kfree_s(sock->sk, iov, iov_size); |
1816 | out_put: | 1835 | out_put: |
1817 | sockfd_put(sock); | 1836 | fput_light(sock->file, fput_needed); |
1818 | out: | 1837 | out: |
1819 | return err; | 1838 | return err; |
1820 | } | 1839 | } |
@@ -1832,6 +1851,7 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flag | |||
1832 | struct msghdr msg_sys; | 1851 | struct msghdr msg_sys; |
1833 | unsigned long cmsg_ptr; | 1852 | unsigned long cmsg_ptr; |
1834 | int err, iov_size, total_len, len; | 1853 | int err, iov_size, total_len, len; |
1854 | int fput_needed; | ||
1835 | 1855 | ||
1836 | /* kernel mode address */ | 1856 | /* kernel mode address */ |
1837 | char addr[MAX_SOCK_ADDR]; | 1857 | char addr[MAX_SOCK_ADDR]; |
@@ -1847,7 +1867,7 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flag | |||
1847 | if (copy_from_user(&msg_sys,msg,sizeof(struct msghdr))) | 1867 | if (copy_from_user(&msg_sys,msg,sizeof(struct msghdr))) |
1848 | return -EFAULT; | 1868 | return -EFAULT; |
1849 | 1869 | ||
1850 | sock = sockfd_lookup(fd, &err); | 1870 | sock = sockfd_lookup_light(fd, &err, &fput_needed); |
1851 | if (!sock) | 1871 | if (!sock) |
1852 | goto out; | 1872 | goto out; |
1853 | 1873 | ||
@@ -1914,7 +1934,7 @@ out_freeiov: | |||
1914 | if (iov != iovstack) | 1934 | if (iov != iovstack) |
1915 | sock_kfree_s(sock->sk, iov, iov_size); | 1935 | sock_kfree_s(sock->sk, iov, iov_size); |
1916 | out_put: | 1936 | out_put: |
1917 | sockfd_put(sock); | 1937 | fput_light(sock->file, fput_needed); |
1918 | out: | 1938 | out: |
1919 | return err; | 1939 | return err; |
1920 | } | 1940 | } |