Commit 09952e3e authored by Jens Axboe's avatar Jens Axboe
Browse files

io_uring: make sure accept honor rlimit nofile



Just like commit 4022e7af, this fixes the fact that
IORING_OP_ACCEPT ends up using get_unused_fd_flags(), which checks
current->signal->rlim[] for limits.

Add an extra argument to __sys_accept4_file() that allows us to pass
in the proper nofile limit, and grab it at request prep time.

Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 4022e7af
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -343,6 +343,7 @@ struct io_accept {
	struct sockaddr __user		*addr;
	int __user			*addr_len;
	int				flags;
	unsigned long			nofile;
};

struct io_sync {
@@ -3324,6 +3325,7 @@ static int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
	accept->addr = u64_to_user_ptr(READ_ONCE(sqe->addr));
	accept->addr_len = u64_to_user_ptr(READ_ONCE(sqe->addr2));
	accept->flags = READ_ONCE(sqe->accept_flags);
	accept->nofile = rlimit(RLIMIT_NOFILE);
	return 0;
#else
	return -EOPNOTSUPP;
@@ -3340,7 +3342,8 @@ static int __io_accept(struct io_kiocb *req, struct io_kiocb **nxt,

	file_flags = force_nonblock ? O_NONBLOCK : 0;
	ret = __sys_accept4_file(req->file, file_flags, accept->addr,
					accept->addr_len, accept->flags);
					accept->addr_len, accept->flags,
					accept->nofile);
	if (ret == -EAGAIN && force_nonblock)
		return -EAGAIN;
	if (ret == -ERESTARTSYS)
+2 −1
Original line number Diff line number Diff line
@@ -401,7 +401,8 @@ extern int __sys_sendto(int fd, void __user *buff, size_t len,
			int addr_len);
extern int __sys_accept4_file(struct file *file, unsigned file_flags,
			struct sockaddr __user *upeer_sockaddr,
			 int __user *upeer_addrlen, int flags);
			 int __user *upeer_addrlen, int flags,
			 unsigned long nofile);
extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
			 int __user *upeer_addrlen, int flags);
extern int __sys_socket(int family, int type, int protocol);
+5 −3
Original line number Diff line number Diff line
@@ -1707,7 +1707,8 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog)

int __sys_accept4_file(struct file *file, unsigned file_flags,
		       struct sockaddr __user *upeer_sockaddr,
		       int __user *upeer_addrlen, int flags)
		       int __user *upeer_addrlen, int flags,
		       unsigned long nofile)
{
	struct socket *sock, *newsock;
	struct file *newfile;
@@ -1738,7 +1739,7 @@ int __sys_accept4_file(struct file *file, unsigned file_flags,
	 */
	__module_get(newsock->ops->owner);

	newfd = get_unused_fd_flags(flags);
	newfd = __get_unused_fd_flags(flags, nofile);
	if (unlikely(newfd < 0)) {
		err = newfd;
		sock_release(newsock);
@@ -1807,7 +1808,8 @@ int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
	f = fdget(fd);
	if (f.file) {
		ret = __sys_accept4_file(f.file, 0, upeer_sockaddr,
						upeer_addrlen, flags);
						upeer_addrlen, flags,
						rlimit(RLIMIT_NOFILE));
		if (f.flags)
			fput(f.file);
	}