@@ -907,7 +907,11 @@ struct io_kiocb {
907907
908908 u64 user_data ;
909909 u32 result ;
910- u32 cflags ;
910+ /* fd initially, then cflags for completion */
911+ union {
912+ u32 cflags ;
913+ int fd ;
914+ };
911915
912916 struct io_ring_ctx * ctx ;
913917 struct task_struct * task ;
@@ -916,8 +920,12 @@ struct io_kiocb {
916920 /* store used ubuf, so we can prevent reloading */
917921 struct io_mapped_ubuf * imu ;
918922
919- /* used by request caches, completion batching and iopoll */
920- struct io_wq_work_node comp_list ;
923+ union {
924+ /* used by request caches, completion batching and iopoll */
925+ struct io_wq_work_node comp_list ;
926+ /* cache ->apoll->events */
927+ int apoll_events ;
928+ };
921929 atomic_t refs ;
922930 atomic_t poll_refs ;
923931 struct io_task_work io_task_work ;
@@ -3183,19 +3191,18 @@ static inline void io_rw_done(struct kiocb *kiocb, ssize_t ret)
31833191static inline loff_t * io_kiocb_update_pos (struct io_kiocb * req )
31843192{
31853193 struct kiocb * kiocb = & req -> rw .kiocb ;
3186- bool is_stream = req -> file -> f_mode & FMODE_STREAM ;
31873194
3188- if (kiocb -> ki_pos == -1 ) {
3189- if (!is_stream ) {
3190- req -> flags |= REQ_F_CUR_POS ;
3191- kiocb -> ki_pos = req -> file -> f_pos ;
3192- return & kiocb -> ki_pos ;
3193- } else {
3194- kiocb -> ki_pos = 0 ;
3195- return NULL ;
3196- }
3195+ if (kiocb -> ki_pos != -1 )
3196+ return & kiocb -> ki_pos ;
3197+
3198+ if (!(req -> file -> f_mode & FMODE_STREAM )) {
3199+ req -> flags |= REQ_F_CUR_POS ;
3200+ kiocb -> ki_pos = req -> file -> f_pos ;
3201+ return & kiocb -> ki_pos ;
31973202 }
3198- return is_stream ? NULL : & kiocb -> ki_pos ;
3203+
3204+ kiocb -> ki_pos = 0 ;
3205+ return NULL ;
31993206}
32003207
32013208static void kiocb_done (struct io_kiocb * req , ssize_t ret ,
@@ -4351,7 +4358,7 @@ static int io_tee(struct io_kiocb *req, unsigned int issue_flags)
43514358 return - EAGAIN ;
43524359
43534360 if (sp -> flags & SPLICE_F_FD_IN_FIXED )
4354- in = io_file_get_fixed (req , sp -> splice_fd_in , IO_URING_F_UNLOCKED );
4361+ in = io_file_get_fixed (req , sp -> splice_fd_in , issue_flags );
43554362 else
43564363 in = io_file_get_normal (req , sp -> splice_fd_in );
43574364 if (!in ) {
@@ -4393,7 +4400,7 @@ static int io_splice(struct io_kiocb *req, unsigned int issue_flags)
43934400 return - EAGAIN ;
43944401
43954402 if (sp -> flags & SPLICE_F_FD_IN_FIXED )
4396- in = io_file_get_fixed (req , sp -> splice_fd_in , IO_URING_F_UNLOCKED );
4403+ in = io_file_get_fixed (req , sp -> splice_fd_in , issue_flags );
43974404 else
43984405 in = io_file_get_normal (req , sp -> splice_fd_in );
43994406 if (!in ) {
@@ -5834,7 +5841,6 @@ static void io_poll_remove_entries(struct io_kiocb *req)
58345841static int io_poll_check_events (struct io_kiocb * req , bool locked )
58355842{
58365843 struct io_ring_ctx * ctx = req -> ctx ;
5837- struct io_poll_iocb * poll = io_poll_get_single (req );
58385844 int v ;
58395845
58405846 /* req->task == current here, checking PF_EXITING is safe */
@@ -5851,17 +5857,17 @@ static int io_poll_check_events(struct io_kiocb *req, bool locked)
58515857 return - ECANCELED ;
58525858
58535859 if (!req -> result ) {
5854- struct poll_table_struct pt = { ._key = req -> cflags };
5860+ struct poll_table_struct pt = { ._key = req -> apoll_events };
5861+ unsigned flags = locked ? 0 : IO_URING_F_UNLOCKED ;
58555862
5856- if (unlikely (!io_assign_file (req , IO_URING_F_UNLOCKED )))
5857- req -> result = - EBADF ;
5858- else
5859- req -> result = vfs_poll (req -> file , & pt ) & req -> cflags ;
5863+ if (unlikely (!io_assign_file (req , flags )))
5864+ return - EBADF ;
5865+ req -> result = vfs_poll (req -> file , & pt ) & req -> apoll_events ;
58605866 }
58615867
58625868 /* multishot, just fill an CQE and proceed */
5863- if (req -> result && !(req -> cflags & EPOLLONESHOT )) {
5864- __poll_t mask = mangle_poll (req -> result & poll -> events );
5869+ if (req -> result && !(req -> apoll_events & EPOLLONESHOT )) {
5870+ __poll_t mask = mangle_poll (req -> result & req -> apoll_events );
58655871 bool filled ;
58665872
58675873 spin_lock (& ctx -> completion_lock );
@@ -5939,7 +5945,7 @@ static void __io_poll_execute(struct io_kiocb *req, int mask, int events)
59395945 * CPU. We want to avoid pulling in req->apoll->events for that
59405946 * case.
59415947 */
5942- req -> cflags = events ;
5948+ req -> apoll_events = events ;
59435949 if (req -> opcode == IORING_OP_POLL_ADD )
59445950 req -> io_task_work .func = io_poll_task_func ;
59455951 else
@@ -6331,7 +6337,7 @@ static int io_poll_add_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe
63316337 return - EINVAL ;
63326338
63336339 io_req_set_refcount (req );
6334- req -> cflags = poll -> events = io_poll_parse_events (sqe , flags );
6340+ req -> apoll_events = poll -> events = io_poll_parse_events (sqe , flags );
63356341 return 0 ;
63366342}
63376343
@@ -6833,6 +6839,7 @@ static int io_files_update(struct io_kiocb *req, unsigned int issue_flags)
68336839 up .nr = 0 ;
68346840 up .tags = 0 ;
68356841 up .resv = 0 ;
6842+ up .resv2 = 0 ;
68366843
68376844 io_ring_submit_lock (ctx , needs_lock );
68386845 ret = __io_register_rsrc_update (ctx , IORING_RSRC_FILE ,
@@ -7088,9 +7095,9 @@ static bool io_assign_file(struct io_kiocb *req, unsigned int issue_flags)
70887095 return true;
70897096
70907097 if (req -> flags & REQ_F_FIXED_FILE )
7091- req -> file = io_file_get_fixed (req , req -> work . fd , issue_flags );
7098+ req -> file = io_file_get_fixed (req , req -> fd , issue_flags );
70927099 else
7093- req -> file = io_file_get_normal (req , req -> work . fd );
7100+ req -> file = io_file_get_normal (req , req -> fd );
70947101 if (req -> file )
70957102 return true;
70967103
@@ -7104,13 +7111,14 @@ static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags)
71047111 const struct cred * creds = NULL ;
71057112 int ret ;
71067113
7114+ if (unlikely (!io_assign_file (req , issue_flags )))
7115+ return - EBADF ;
7116+
71077117 if (unlikely ((req -> flags & REQ_F_CREDS ) && req -> creds != current_cred ()))
71087118 creds = override_creds (req -> creds );
71097119
71107120 if (!io_op_defs [req -> opcode ].audit_skip )
71117121 audit_uring_entry (req -> opcode );
7112- if (unlikely (!io_assign_file (req , issue_flags )))
7113- return - EBADF ;
71147122
71157123 switch (req -> opcode ) {
71167124 case IORING_OP_NOP :
@@ -7271,16 +7279,18 @@ static void io_wq_submit_work(struct io_wq_work *work)
72717279 if (timeout )
72727280 io_queue_linked_timeout (timeout );
72737281
7274- if (!io_assign_file (req , issue_flags )) {
7275- err = - EBADF ;
7276- work -> flags |= IO_WQ_WORK_CANCEL ;
7277- }
72787282
72797283 /* either cancelled or io-wq is dying, so don't touch tctx->iowq */
72807284 if (work -> flags & IO_WQ_WORK_CANCEL ) {
7285+ fail :
72817286 io_req_task_queue_fail (req , err );
72827287 return ;
72837288 }
7289+ if (!io_assign_file (req , issue_flags )) {
7290+ err = - EBADF ;
7291+ work -> flags |= IO_WQ_WORK_CANCEL ;
7292+ goto fail ;
7293+ }
72847294
72857295 if (req -> flags & REQ_F_FORCE_ASYNC ) {
72867296 bool opcode_poll = def -> pollin || def -> pollout ;
@@ -7628,7 +7638,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
76287638 if (io_op_defs [opcode ].needs_file ) {
76297639 struct io_submit_state * state = & ctx -> submit_state ;
76307640
7631- req -> work . fd = READ_ONCE (sqe -> fd );
7641+ req -> fd = READ_ONCE (sqe -> fd );
76327642
76337643 /*
76347644 * Plug now if we have more than 2 IO left after this, and the
@@ -10524,6 +10534,11 @@ static int io_ringfd_register(struct io_ring_ctx *ctx, void __user *__arg,
1052410534 break ;
1052510535 }
1052610536
10537+ if (reg .resv ) {
10538+ ret = - EINVAL ;
10539+ break ;
10540+ }
10541+
1052710542 if (reg .offset == -1U ) {
1052810543 start = 0 ;
1052910544 end = IO_RINGFD_REG_MAX ;
@@ -10570,7 +10585,7 @@ static int io_ringfd_unregister(struct io_ring_ctx *ctx, void __user *__arg,
1057010585 ret = - EFAULT ;
1057110586 break ;
1057210587 }
10573- if (reg .offset >= IO_RINGFD_REG_MAX ) {
10588+ if (reg .resv || reg . offset >= IO_RINGFD_REG_MAX ) {
1057410589 ret = - EINVAL ;
1057510590 break ;
1057610591 }
@@ -10697,6 +10712,8 @@ static int io_get_ext_arg(unsigned flags, const void __user *argp, size_t *argsz
1069710712 return - EINVAL ;
1069810713 if (copy_from_user (& arg , argp , sizeof (arg )))
1069910714 return - EFAULT ;
10715+ if (arg .pad )
10716+ return - EINVAL ;
1070010717 * sig = u64_to_user_ptr (arg .sigmask );
1070110718 * argsz = arg .sigmask_sz ;
1070210719 * ts = u64_to_user_ptr (arg .ts );
@@ -11178,7 +11195,8 @@ static __cold int io_uring_create(unsigned entries, struct io_uring_params *p,
1117811195 IORING_FEAT_CUR_PERSONALITY | IORING_FEAT_FAST_POLL |
1117911196 IORING_FEAT_POLL_32BITS | IORING_FEAT_SQPOLL_NONFIXED |
1118011197 IORING_FEAT_EXT_ARG | IORING_FEAT_NATIVE_WORKERS |
11181- IORING_FEAT_RSRC_TAGS | IORING_FEAT_CQE_SKIP ;
11198+ IORING_FEAT_RSRC_TAGS | IORING_FEAT_CQE_SKIP |
11199+ IORING_FEAT_LINKED_FILE ;
1118211200
1118311201 if (copy_to_user (params , p , sizeof (* p ))) {
1118411202 ret = - EFAULT ;
@@ -11389,8 +11407,6 @@ static int __io_register_rsrc_update(struct io_ring_ctx *ctx, unsigned type,
1138911407 __u32 tmp ;
1139011408 int err ;
1139111409
11392- if (up -> resv )
11393- return - EINVAL ;
1139411410 if (check_add_overflow (up -> offset , nr_args , & tmp ))
1139511411 return - EOVERFLOW ;
1139611412 err = io_rsrc_node_switch_start (ctx );
@@ -11416,6 +11432,8 @@ static int io_register_files_update(struct io_ring_ctx *ctx, void __user *arg,
1141611432 memset (& up , 0 , sizeof (up ));
1141711433 if (copy_from_user (& up , arg , sizeof (struct io_uring_rsrc_update )))
1141811434 return - EFAULT ;
11435+ if (up .resv || up .resv2 )
11436+ return - EINVAL ;
1141911437 return __io_register_rsrc_update (ctx , IORING_RSRC_FILE , & up , nr_args );
1142011438}
1142111439
@@ -11428,7 +11446,7 @@ static int io_register_rsrc_update(struct io_ring_ctx *ctx, void __user *arg,
1142811446 return - EINVAL ;
1142911447 if (copy_from_user (& up , arg , sizeof (up )))
1143011448 return - EFAULT ;
11431- if (!up .nr || up .resv )
11449+ if (!up .nr || up .resv || up . resv2 )
1143211450 return - EINVAL ;
1143311451 return __io_register_rsrc_update (ctx , type , & up , up .nr );
1143411452}
0 commit comments