mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 03:40:52 +07:00
io_uring-5.6-20200320
-----BEGIN PGP SIGNATURE----- iQJEBAABCAAuFiEEwPw5LcreJtl1+l5K99NY+ylx4KYFAl51dbQQHGF4Ym9lQGtl cm5lbC5kawAKCRD301j7KXHgpiV3EADJHB2r2hTTEym5u1PbrEEVkjvdL6InU8lD lFM7m2g6yZUncwm+aSZynHqAFY6Rd5Jk+gmYMuioi3ZxC2rs7jG1AOTpaeJYmhle lzkjqSLtl+gdPMA9ydivk1UwILFjtZKG1JNc++tnCn3q7+eCkgnWAlq5b7idG2eF BS0AEZP6Yz1zStTHLbHSB0StY8ovMIw0VaVQvguHLL9EBpbHmrs0cq3tipWkAyPR 2YwnXbxsJySukkwmBKxEWrGUYDze56jqJIqdFsOE0+WtGV+nk7OScPseXAaP4/+G Vl23VNfryuZcsBUwI9tY1SzCFEXIwdXVGpCAYwQ/kU5WfvFpYaei+fXVNnL4kjR0 PfpA6XnMsZ3DzqgepmUd92sAA56ZtBxuGjqcSYlg/JwjvUHdpaZDkE2WLqkAMeUN 8A7cUw+R6XWQ2/y6ob7QvKiT/ZDR8GrYUl3EdGE3LhB1ZsvLXJDZpWipwQBzuk9R vJJOkGst38rjsWnb+nfeLh3AsgjF14wo+2vQL4mKs24xKTIvadHsFAZjKLXZ93Wf Vn58FaPOYIkjBidYLWb3dlO1ZR8S0803gohLkLV6adH8bCNCWxGTOR51DZLomAsb nAUCEAJaZrOqaQAuJAFNNpS8+/da3AIF4HVd2EdZ1yFXU15y0+zIxtROjKzg+OxO M3jC/Aet1Q== =IMcu -----END PGP SIGNATURE----- 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}
This commit is contained in:
commit
1ab7ea1f83
@ -540,9 +540,14 @@ static int alloc_fd(unsigned start, unsigned flags)
|
||||
return __alloc_fd(current->files, start, rlimit(RLIMIT_NOFILE), flags);
|
||||
}
|
||||
|
||||
int __get_unused_fd_flags(unsigned flags, unsigned long nofile)
|
||||
{
|
||||
return __alloc_fd(current->files, 0, nofile, flags);
|
||||
}
|
||||
|
||||
int get_unused_fd_flags(unsigned flags)
|
||||
{
|
||||
return __alloc_fd(current->files, 0, rlimit(RLIMIT_NOFILE), flags);
|
||||
return __get_unused_fd_flags(flags, rlimit(RLIMIT_NOFILE));
|
||||
}
|
||||
EXPORT_SYMBOL(get_unused_fd_flags);
|
||||
|
||||
|
@ -343,6 +343,7 @@ struct io_accept {
|
||||
struct sockaddr __user *addr;
|
||||
int __user *addr_len;
|
||||
int flags;
|
||||
unsigned long nofile;
|
||||
};
|
||||
|
||||
struct io_sync {
|
||||
@ -397,6 +398,7 @@ struct io_open {
|
||||
struct filename *filename;
|
||||
struct statx __user *buffer;
|
||||
struct open_how how;
|
||||
unsigned long nofile;
|
||||
};
|
||||
|
||||
struct io_files_update {
|
||||
@ -2577,6 +2579,7 @@ static int io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
return ret;
|
||||
}
|
||||
|
||||
req->open.nofile = rlimit(RLIMIT_NOFILE);
|
||||
req->flags |= REQ_F_NEED_CLEANUP;
|
||||
return 0;
|
||||
}
|
||||
@ -2618,6 +2621,7 @@ static int io_openat2_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
return ret;
|
||||
}
|
||||
|
||||
req->open.nofile = rlimit(RLIMIT_NOFILE);
|
||||
req->flags |= REQ_F_NEED_CLEANUP;
|
||||
return 0;
|
||||
}
|
||||
@ -2636,7 +2640,7 @@ static int io_openat2(struct io_kiocb *req, struct io_kiocb **nxt,
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = get_unused_fd_flags(req->open.how.flags);
|
||||
ret = __get_unused_fd_flags(req->open.how.flags, req->open.nofile);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
@ -3321,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;
|
||||
@ -3337,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)
|
||||
@ -4131,6 +4137,9 @@ static int io_req_defer_prep(struct io_kiocb *req,
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
|
||||
if (!sqe)
|
||||
return 0;
|
||||
|
||||
if (io_op_defs[req->opcode].file_table) {
|
||||
ret = io_grab_files(req);
|
||||
if (unlikely(ret))
|
||||
@ -4907,6 +4916,11 @@ static bool io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
|
||||
if (sqe_flags & (IOSQE_IO_LINK|IOSQE_IO_HARDLINK)) {
|
||||
req->flags |= REQ_F_LINK;
|
||||
INIT_LIST_HEAD(&req->link_list);
|
||||
|
||||
if (io_alloc_async_ctx(req)) {
|
||||
ret = -EAGAIN;
|
||||
goto err_req;
|
||||
}
|
||||
ret = io_req_defer_prep(req, sqe);
|
||||
if (ret)
|
||||
req->flags |= REQ_F_FAIL_LINK;
|
||||
|
@ -85,6 +85,7 @@ extern int f_dupfd(unsigned int from, struct file *file, unsigned flags);
|
||||
extern int replace_fd(unsigned fd, struct file *file, unsigned flags);
|
||||
extern void set_close_on_exec(unsigned int fd, int flag);
|
||||
extern bool get_close_on_exec(unsigned int fd);
|
||||
extern int __get_unused_fd_flags(unsigned flags, unsigned long nofile);
|
||||
extern int get_unused_fd_flags(unsigned flags);
|
||||
extern void put_unused_fd(unsigned int fd);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user