Merge tag 'io_uring-5.6-20200320' of git://git.kernel.dk/linux-block

Pull io_uring fixes from Jens Axboe:
"Two different fixes in here:

- Fix for a potential NULL pointer deref for links with async or
drain marked (Pavel)

- Fix for not properly checking RLIMIT_NOFILE for async punted
operations.

This affects openat/openat2, which were added this cycle, and
accept4. I did a full audit of other cases where we might check
current->signal->rlim[] and found only RLIMIT_FSIZE for buffered
writes and fallocate. That one is fixed and queued for 5.7 and
marked stable"

* tag 'io_uring-5.6-20200320' of git://git.kernel.dk/linux-block:
io_uring: make sure accept honor rlimit nofile
io_uring: make sure openat/openat2 honor rlimit nofile
io_uring: NULL-deref for IOSQE_{ASYNC,DRAIN}

Changed files
+30 -7
fs
include
net
+6 -1
fs/file.c
··· 540 540 return __alloc_fd(current->files, start, rlimit(RLIMIT_NOFILE), flags); 541 541 } 542 542 543 + int __get_unused_fd_flags(unsigned flags, unsigned long nofile) 544 + { 545 + return __alloc_fd(current->files, 0, nofile, flags); 546 + } 547 + 543 548 int get_unused_fd_flags(unsigned flags) 544 549 { 545 - return __alloc_fd(current->files, 0, rlimit(RLIMIT_NOFILE), flags); 550 + return __get_unused_fd_flags(flags, rlimit(RLIMIT_NOFILE)); 546 551 } 547 552 EXPORT_SYMBOL(get_unused_fd_flags); 548 553
+16 -2
fs/io_uring.c
··· 343 343 struct sockaddr __user *addr; 344 344 int __user *addr_len; 345 345 int flags; 346 + unsigned long nofile; 346 347 }; 347 348 348 349 struct io_sync { ··· 398 397 struct filename *filename; 399 398 struct statx __user *buffer; 400 399 struct open_how how; 400 + unsigned long nofile; 401 401 }; 402 402 403 403 struct io_files_update { ··· 2579 2577 return ret; 2580 2578 } 2581 2579 2580 + req->open.nofile = rlimit(RLIMIT_NOFILE); 2582 2581 req->flags |= REQ_F_NEED_CLEANUP; 2583 2582 return 0; 2584 2583 } ··· 2621 2618 return ret; 2622 2619 } 2623 2620 2621 + req->open.nofile = rlimit(RLIMIT_NOFILE); 2624 2622 req->flags |= REQ_F_NEED_CLEANUP; 2625 2623 return 0; 2626 2624 } ··· 2640 2636 if (ret) 2641 2637 goto err; 2642 2638 2643 - ret = get_unused_fd_flags(req->open.how.flags); 2639 + ret = __get_unused_fd_flags(req->open.how.flags, req->open.nofile); 2644 2640 if (ret < 0) 2645 2641 goto err; 2646 2642 ··· 3325 3321 accept->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); 3326 3322 accept->addr_len = u64_to_user_ptr(READ_ONCE(sqe->addr2)); 3327 3323 accept->flags = READ_ONCE(sqe->accept_flags); 3324 + accept->nofile = rlimit(RLIMIT_NOFILE); 3328 3325 return 0; 3329 3326 #else 3330 3327 return -EOPNOTSUPP; ··· 3342 3337 3343 3338 file_flags = force_nonblock ? O_NONBLOCK : 0; 3344 3339 ret = __sys_accept4_file(req->file, file_flags, accept->addr, 3345 - accept->addr_len, accept->flags); 3340 + accept->addr_len, accept->flags, 3341 + accept->nofile); 3346 3342 if (ret == -EAGAIN && force_nonblock) 3347 3343 return -EAGAIN; 3348 3344 if (ret == -ERESTARTSYS) ··· 4137 4131 { 4138 4132 ssize_t ret = 0; 4139 4133 4134 + if (!sqe) 4135 + return 0; 4136 + 4140 4137 if (io_op_defs[req->opcode].file_table) { 4141 4138 ret = io_grab_files(req); 4142 4139 if (unlikely(ret)) ··· 4916 4907 if (sqe_flags & (IOSQE_IO_LINK|IOSQE_IO_HARDLINK)) { 4917 4908 req->flags |= REQ_F_LINK; 4918 4909 INIT_LIST_HEAD(&req->link_list); 4910 + 4911 + if (io_alloc_async_ctx(req)) { 4912 + ret = -EAGAIN; 4913 + goto err_req; 4914 + } 4919 4915 ret = io_req_defer_prep(req, sqe); 4920 4916 if (ret) 4921 4917 req->flags |= REQ_F_FAIL_LINK;
+1
include/linux/file.h
··· 85 85 extern int replace_fd(unsigned fd, struct file *file, unsigned flags); 86 86 extern void set_close_on_exec(unsigned int fd, int flag); 87 87 extern bool get_close_on_exec(unsigned int fd); 88 + extern int __get_unused_fd_flags(unsigned flags, unsigned long nofile); 88 89 extern int get_unused_fd_flags(unsigned flags); 89 90 extern void put_unused_fd(unsigned int fd); 90 91
+2 -1
include/linux/socket.h
··· 401 401 int addr_len); 402 402 extern int __sys_accept4_file(struct file *file, unsigned file_flags, 403 403 struct sockaddr __user *upeer_sockaddr, 404 - int __user *upeer_addrlen, int flags); 404 + int __user *upeer_addrlen, int flags, 405 + unsigned long nofile); 405 406 extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, 406 407 int __user *upeer_addrlen, int flags); 407 408 extern int __sys_socket(int family, int type, int protocol);
+5 -3
net/socket.c
··· 1707 1707 1708 1708 int __sys_accept4_file(struct file *file, unsigned file_flags, 1709 1709 struct sockaddr __user *upeer_sockaddr, 1710 - int __user *upeer_addrlen, int flags) 1710 + int __user *upeer_addrlen, int flags, 1711 + unsigned long nofile) 1711 1712 { 1712 1713 struct socket *sock, *newsock; 1713 1714 struct file *newfile; ··· 1739 1738 */ 1740 1739 __module_get(newsock->ops->owner); 1741 1740 1742 - newfd = get_unused_fd_flags(flags); 1741 + newfd = __get_unused_fd_flags(flags, nofile); 1743 1742 if (unlikely(newfd < 0)) { 1744 1743 err = newfd; 1745 1744 sock_release(newsock); ··· 1808 1807 f = fdget(fd); 1809 1808 if (f.file) { 1810 1809 ret = __sys_accept4_file(f.file, 0, upeer_sockaddr, 1811 - upeer_addrlen, flags); 1810 + upeer_addrlen, flags, 1811 + rlimit(RLIMIT_NOFILE)); 1812 1812 if (f.flags) 1813 1813 fput(f.file); 1814 1814 }