Skip to content

Commit 09952e3

Browse files
committed
io_uring: make sure accept honor rlimit nofile
Just like commit 4022e7a, 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: David S. Miller <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 4022e7a commit 09952e3

File tree

3 files changed

+11
-5
lines changed

3 files changed

+11
-5
lines changed

fs/io_uring.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ struct io_accept {
343343
struct sockaddr __user *addr;
344344
int __user *addr_len;
345345
int flags;
346+
unsigned long nofile;
346347
};
347348

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

33413343
file_flags = force_nonblock ? O_NONBLOCK : 0;
33423344
ret = __sys_accept4_file(req->file, file_flags, accept->addr,
3343-
accept->addr_len, accept->flags);
3345+
accept->addr_len, accept->flags,
3346+
accept->nofile);
33443347
if (ret == -EAGAIN && force_nonblock)
33453348
return -EAGAIN;
33463349
if (ret == -ERESTARTSYS)

include/linux/socket.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,8 @@ extern int __sys_sendto(int fd, void __user *buff, size_t len,
401401
int addr_len);
402402
extern int __sys_accept4_file(struct file *file, unsigned file_flags,
403403
struct sockaddr __user *upeer_sockaddr,
404-
int __user *upeer_addrlen, int flags);
404+
int __user *upeer_addrlen, int flags,
405+
unsigned long nofile);
405406
extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
406407
int __user *upeer_addrlen, int flags);
407408
extern int __sys_socket(int family, int type, int protocol);

net/socket.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,7 +1707,8 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog)
17071707

17081708
int __sys_accept4_file(struct file *file, unsigned file_flags,
17091709
struct sockaddr __user *upeer_sockaddr,
1710-
int __user *upeer_addrlen, int flags)
1710+
int __user *upeer_addrlen, int flags,
1711+
unsigned long nofile)
17111712
{
17121713
struct socket *sock, *newsock;
17131714
struct file *newfile;
@@ -1738,7 +1739,7 @@ int __sys_accept4_file(struct file *file, unsigned file_flags,
17381739
*/
17391740
__module_get(newsock->ops->owner);
17401741

1741-
newfd = get_unused_fd_flags(flags);
1742+
newfd = __get_unused_fd_flags(flags, nofile);
17421743
if (unlikely(newfd < 0)) {
17431744
err = newfd;
17441745
sock_release(newsock);
@@ -1807,7 +1808,8 @@ int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
18071808
f = fdget(fd);
18081809
if (f.file) {
18091810
ret = __sys_accept4_file(f.file, 0, upeer_sockaddr,
1810-
upeer_addrlen, flags);
1811+
upeer_addrlen, flags,
1812+
rlimit(RLIMIT_NOFILE));
18111813
if (f.flags)
18121814
fput(f.file);
18131815
}

0 commit comments

Comments
 (0)