History

net: add __sys_accept4_file() helper

This is identical to __sys_accept4(), except it takes a struct file instead of an fd, and it also allows passing in extra file->f_flags flags. The latter is done to support masking in O_NONBLOCK without manipulating the original file flags. No functional changes in this patch.

Jens Axboe committed 7 years ago

Commit de2ea4b1 parent fcb323c2 files · +44 −24Browse files

Unified · Split

2 files
  1. include/linux/socket.h +3 −0
  2. net/socket.c +41 −24
include/linux/socket.h+3−0
@@ -392,6 +392,9 @@ extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size, · 391 unmodified lines
392extern int __sys_sendto(int fd, void __user *buff, size_t len,392extern int __sys_sendto(int fd, void __user *buff, size_t len,
393 unsigned int flags, struct sockaddr __user *addr,393 unsigned int flags, struct sockaddr __user *addr,
394 int addr_len);394 int addr_len);
395extern int __sys_accept4_file(struct file *file, unsigned file_flags,
396 struct sockaddr __user *upeer_sockaddr,
397 int __user *upeer_addrlen, int flags);
395extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,398extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
396 int __user *upeer_addrlen, int flags);399 int __user *upeer_addrlen, int flags);
397extern int __sys_socket(int family, int type, int protocol);400extern int __sys_socket(int family, int type, int protocol);
net/socket.c+41−24
@@ -1690,24 +1690,13 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog) · 1689 unmodified lines
1690 return __sys_listen(fd, backlog);1690 return __sys_listen(fd, backlog);
1691}1691}
1692 1692
1693/*1693int __sys_accept4_file(struct file *file, unsigned file_flags,
1694 * For accept, we attempt to create a new socket, set up the link1694 struct sockaddr __user *upeer_sockaddr,
1695 * with the client, wake up the client, then return the new1695 int __user *upeer_addrlen, int flags)
1696 * connected fd. We collect the address of the connector in kernel
1697 * space and move it to user at the very end. This is unclean because
1698 * we open the socket then return an error.
1699 *
1700 * 1003.1g adds the ability to recvmsg() to query connection pending
1701 * status to recvmsg. We need to add that support in a way thats
1702 * clean when we restructure accept also.
1703 */
1704
1705int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
1706 int __user *upeer_addrlen, int flags)
1707{1696{
1708 struct socket *sock, *newsock;1697 struct socket *sock, *newsock;
1709 struct file *newfile;1698 struct file *newfile;
1710 int err, len, newfd, fput_needed;1699 int err, len, newfd;
1711 struct sockaddr_storage address;1700 struct sockaddr_storage address;
1712 1701
1713 if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))1702 if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
@@ -1716,14 +1705,14 @@ int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, · 2 unmodified lines
1716 if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))1705 if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
1717 flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;1706 flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1718 1707
1719 sock = sockfd_lookup_light(fd, &err, &fput_needed);1708 sock = sock_from_file(file, &err);
1720 if (!sock)1709 if (!sock)
1721 goto out;1710 goto out;
1722 1711
1723 err = -ENFILE;1712 err = -ENFILE;
1724 newsock = sock_alloc();1713 newsock = sock_alloc();
1725 if (!newsock)1714 if (!newsock)
1726 goto out_put;1715 goto out;
1727 1716
1728 newsock->type = sock->type;1717 newsock->type = sock->type;
1729 newsock->ops = sock->ops;1718 newsock->ops = sock->ops;
@@ -1738,20 +1727,21 @@ int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, · 8 unmodified lines
1738 if (unlikely(newfd < 0)) {1727 if (unlikely(newfd < 0)) {
1739 err = newfd;1728 err = newfd;
1740 sock_release(newsock);1729 sock_release(newsock);
1741 goto out_put;1730 goto out;
1742 }1731 }
1743 newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);1732 newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);
1744 if (IS_ERR(newfile)) {1733 if (IS_ERR(newfile)) {
1745 err = PTR_ERR(newfile);1734 err = PTR_ERR(newfile);
1746 put_unused_fd(newfd);1735 put_unused_fd(newfd);
1747 goto out_put;1736 goto out;
1748 }1737 }
1749 1738
1750 err = security_socket_accept(sock, newsock);1739 err = security_socket_accept(sock, newsock);
1751 if (err)1740 if (err)
1752 goto out_fd;1741 goto out_fd;
1753 1742
1754 err = sock->ops->accept(sock, newsock, sock->file->f_flags, false);1743 err = sock->ops->accept(sock, newsock, sock->file->f_flags | file_flags,
1744 false);
1755 if (err < 0)1745 if (err < 0)
1756 goto out_fd;1746 goto out_fd;
1757 1747
@@ -1772,15 +1762,42 @@ int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, · 14 unmodified lines
1772 1762
1773 fd_install(newfd, newfile);1763 fd_install(newfd, newfile);
1774 err = newfd;1764 err = newfd;
1775
1776out_put:
1777 fput_light(sock->file, fput_needed);
1778out:1765out:
1779 return err;1766 return err;
1780out_fd:1767out_fd:
1781 fput(newfile);1768 fput(newfile);
1782 put_unused_fd(newfd);1769 put_unused_fd(newfd);
1783 goto out_put;1770 goto out;
1771
1772}
1773
1774/*
1775 * For accept, we attempt to create a new socket, set up the link
1776 * with the client, wake up the client, then return the new
1777 * connected fd. We collect the address of the connector in kernel
1778 * space and move it to user at the very end. This is unclean because
1779 * we open the socket then return an error.
1780 *
1781 * 1003.1g adds the ability to recvmsg() to query connection pending
1782 * status to recvmsg. We need to add that support in a way thats
1783 * clean when we restructure accept also.
1784 */
1785
1786int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
1787 int __user *upeer_addrlen, int flags)
1788{
1789 int ret = -EBADF;
1790 struct fd f;
1791
1792 f = fdget(fd);
1793 if (f.file) {
1794 ret = __sys_accept4_file(f.file, 0, upeer_sockaddr,
1795 upeer_addrlen, flags);
1796 if (f.flags)
1797 fput(f.file);
1798 }
1799
1800 return ret;
1784}1801}
1785 1802
1786SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,1803SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t