@@ -204,46 +204,26 @@ static int io_setup_async_msg(struct io_kiocb *req,
204
204
return - EAGAIN ;
205
205
}
206
206
207
- static bool io_recvmsg_multishot_overflow (struct io_async_msghdr * iomsg )
208
- {
209
- int hdr ;
210
-
211
- if (iomsg -> namelen < 0 )
212
- return true;
213
- if (check_add_overflow ((int )sizeof (struct io_uring_recvmsg_out ),
214
- iomsg -> namelen , & hdr ))
215
- return true;
216
- if (check_add_overflow (hdr , (int )iomsg -> controllen , & hdr ))
217
- return true;
218
-
219
- return false;
220
- }
221
-
222
207
#ifdef CONFIG_COMPAT
223
- static int __io_compat_msg_copy_hdr (struct io_kiocb * req ,
224
- struct io_async_msghdr * iomsg ,
225
- struct sockaddr __user * * addr , int ddir )
208
+ static int io_compat_msg_copy_hdr (struct io_kiocb * req ,
209
+ struct io_async_msghdr * iomsg ,
210
+ struct compat_msghdr * msg , int ddir )
226
211
{
227
212
struct io_sr_msg * sr = io_kiocb_to_cmd (req , struct io_sr_msg );
228
- struct compat_msghdr msg ;
229
213
struct compat_iovec __user * uiov ;
230
214
int ret ;
231
215
232
- if (copy_from_user (& msg , sr -> umsg_compat , sizeof (msg )))
216
+ if (copy_from_user (msg , sr -> umsg_compat , sizeof (* msg )))
233
217
return - EFAULT ;
234
218
235
- ret = __get_compat_msghdr (& iomsg -> msg , & msg , addr );
236
- if (ret )
237
- return ret ;
238
-
239
- uiov = compat_ptr (msg .msg_iov );
219
+ uiov = compat_ptr (msg -> msg_iov );
240
220
if (req -> flags & REQ_F_BUFFER_SELECT ) {
241
221
compat_ssize_t clen ;
242
222
243
223
iomsg -> free_iov = NULL ;
244
- if (msg . msg_iovlen == 0 ) {
224
+ if (msg -> msg_iovlen == 0 ) {
245
225
sr -> len = 0 ;
246
- } else if (msg . msg_iovlen > 1 ) {
226
+ } else if (msg -> msg_iovlen > 1 ) {
247
227
return - EINVAL ;
248
228
} else {
249
229
if (!access_ok (uiov , sizeof (* uiov )))
@@ -255,18 +235,11 @@ static int __io_compat_msg_copy_hdr(struct io_kiocb *req,
255
235
sr -> len = clen ;
256
236
}
257
237
258
- if (ddir == ITER_DEST && req -> flags & REQ_F_APOLL_MULTISHOT ) {
259
- iomsg -> namelen = msg .msg_namelen ;
260
- iomsg -> controllen = msg .msg_controllen ;
261
- if (io_recvmsg_multishot_overflow (iomsg ))
262
- return - EOVERFLOW ;
263
- }
264
-
265
238
return 0 ;
266
239
}
267
240
268
241
iomsg -> free_iov = iomsg -> fast_iov ;
269
- ret = __import_iovec (ddir , (struct iovec __user * )uiov , msg . msg_iovlen ,
242
+ ret = __import_iovec (ddir , (struct iovec __user * )uiov , msg -> msg_iovlen ,
270
243
UIO_FASTIOV , & iomsg -> free_iov ,
271
244
& iomsg -> msg .msg_iter , true);
272
245
if (unlikely (ret < 0 ))
@@ -276,78 +249,70 @@ static int __io_compat_msg_copy_hdr(struct io_kiocb *req,
276
249
}
277
250
#endif
278
251
279
- static int __io_msg_copy_hdr (struct io_kiocb * req , struct io_async_msghdr * iomsg ,
280
- struct sockaddr __user * * addr , int ddir )
252
+ static int io_msg_copy_hdr (struct io_kiocb * req , struct io_async_msghdr * iomsg ,
253
+ struct user_msghdr * msg , int ddir )
281
254
{
282
255
struct io_sr_msg * sr = io_kiocb_to_cmd (req , struct io_sr_msg );
283
- struct user_msghdr msg ;
284
256
int ret ;
285
257
286
- if (copy_from_user (& msg , sr -> umsg , sizeof (* sr -> umsg )))
258
+ if (copy_from_user (msg , sr -> umsg , sizeof (* sr -> umsg )))
287
259
return - EFAULT ;
288
260
289
- ret = __copy_msghdr (& iomsg -> msg , & msg , addr );
290
- if (ret )
291
- return ret ;
292
-
293
261
if (req -> flags & REQ_F_BUFFER_SELECT ) {
294
- if (msg . msg_iovlen == 0 ) {
262
+ if (msg -> msg_iovlen == 0 ) {
295
263
sr -> len = iomsg -> fast_iov [0 ].iov_len = 0 ;
296
264
iomsg -> fast_iov [0 ].iov_base = NULL ;
297
265
iomsg -> free_iov = NULL ;
298
- } else if (msg . msg_iovlen > 1 ) {
266
+ } else if (msg -> msg_iovlen > 1 ) {
299
267
return - EINVAL ;
300
268
} else {
301
- if (copy_from_user (iomsg -> fast_iov , msg . msg_iov ,
302
- sizeof (* msg . msg_iov )))
269
+ if (copy_from_user (iomsg -> fast_iov , msg -> msg_iov ,
270
+ sizeof (* msg -> msg_iov )))
303
271
return - EFAULT ;
304
272
sr -> len = iomsg -> fast_iov [0 ].iov_len ;
305
273
iomsg -> free_iov = NULL ;
306
274
}
307
275
308
- if (ddir == ITER_DEST && req -> flags & REQ_F_APOLL_MULTISHOT ) {
309
- iomsg -> namelen = msg .msg_namelen ;
310
- iomsg -> controllen = msg .msg_controllen ;
311
- if (io_recvmsg_multishot_overflow (iomsg ))
312
- return - EOVERFLOW ;
313
- }
314
-
315
276
return 0 ;
316
277
}
317
278
318
279
iomsg -> free_iov = iomsg -> fast_iov ;
319
- ret = __import_iovec (ddir , msg . msg_iov , msg . msg_iovlen , UIO_FASTIOV ,
280
+ ret = __import_iovec (ddir , msg -> msg_iov , msg -> msg_iovlen , UIO_FASTIOV ,
320
281
& iomsg -> free_iov , & iomsg -> msg .msg_iter , false);
321
282
if (unlikely (ret < 0 ))
322
283
return ret ;
323
284
324
285
return 0 ;
325
286
}
326
287
327
- static int io_msg_copy_hdr (struct io_kiocb * req , struct io_async_msghdr * iomsg ,
328
- struct sockaddr __user * * addr , int ddir )
288
+ static int io_sendmsg_copy_hdr (struct io_kiocb * req ,
289
+ struct io_async_msghdr * iomsg )
329
290
{
291
+ struct io_sr_msg * sr = io_kiocb_to_cmd (req , struct io_sr_msg );
292
+ struct user_msghdr msg ;
293
+ int ret ;
294
+
330
295
iomsg -> msg .msg_name = & iomsg -> addr ;
331
296
iomsg -> msg .msg_iter .nr_segs = 0 ;
332
297
333
298
#ifdef CONFIG_COMPAT
334
- if (req -> ctx -> compat )
335
- return __io_compat_msg_copy_hdr (req , iomsg , addr , ddir );
336
- #endif
299
+ if (unlikely (req -> ctx -> compat )) {
300
+ struct compat_msghdr cmsg ;
337
301
338
- return __io_msg_copy_hdr (req , iomsg , addr , ddir );
339
- }
302
+ ret = io_compat_msg_copy_hdr (req , iomsg , & cmsg , ITER_SOURCE );
303
+ if (unlikely (ret ))
304
+ return ret ;
340
305
341
- static int io_sendmsg_copy_hdr (struct io_kiocb * req ,
342
- struct io_async_msghdr * iomsg )
343
- {
344
- struct io_sr_msg * sr = io_kiocb_to_cmd (req , struct io_sr_msg );
345
- int ret ;
306
+ return __get_compat_msghdr (& iomsg -> msg , & cmsg , NULL );
307
+ }
308
+ #endif
346
309
347
- ret = io_msg_copy_hdr (req , iomsg , NULL , ITER_SOURCE );
348
- if (ret )
310
+ ret = io_msg_copy_hdr (req , iomsg , & msg , ITER_SOURCE );
311
+ if (unlikely ( ret ) )
349
312
return ret ;
350
313
314
+ ret = __copy_msghdr (& iomsg -> msg , & msg , NULL );
315
+
351
316
/* save msg_control as sys_sendmsg() overwrites it */
352
317
sr -> msg_control = iomsg -> msg .msg_control_user ;
353
318
return ret ;
@@ -569,10 +534,66 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags)
569
534
return IOU_OK ;
570
535
}
571
536
537
+ static int io_recvmsg_mshot_prep (struct io_kiocb * req ,
538
+ struct io_async_msghdr * iomsg ,
539
+ size_t namelen , size_t controllen )
540
+ {
541
+ if ((req -> flags & (REQ_F_APOLL_MULTISHOT |REQ_F_BUFFER_SELECT )) ==
542
+ (REQ_F_APOLL_MULTISHOT |REQ_F_BUFFER_SELECT )) {
543
+ int hdr ;
544
+
545
+ if (unlikely (namelen < 0 ))
546
+ return - EOVERFLOW ;
547
+ if (check_add_overflow ((int )sizeof (struct io_uring_recvmsg_out ),
548
+ namelen , & hdr ))
549
+ return - EOVERFLOW ;
550
+ if (check_add_overflow (hdr , (int )controllen , & hdr ))
551
+ return - EOVERFLOW ;
552
+
553
+ iomsg -> namelen = namelen ;
554
+ iomsg -> controllen = controllen ;
555
+ return 0 ;
556
+ }
557
+
558
+ return 0 ;
559
+ }
560
+
572
561
static int io_recvmsg_copy_hdr (struct io_kiocb * req ,
573
562
struct io_async_msghdr * iomsg )
574
563
{
575
- return io_msg_copy_hdr (req , iomsg , & iomsg -> uaddr , ITER_DEST );
564
+ struct user_msghdr msg ;
565
+ int ret ;
566
+
567
+ iomsg -> msg .msg_name = & iomsg -> addr ;
568
+ iomsg -> msg .msg_iter .nr_segs = 0 ;
569
+
570
+ #ifdef CONFIG_COMPAT
571
+ if (unlikely (req -> ctx -> compat )) {
572
+ struct compat_msghdr cmsg ;
573
+
574
+ ret = io_compat_msg_copy_hdr (req , iomsg , & cmsg , ITER_DEST );
575
+ if (unlikely (ret ))
576
+ return ret ;
577
+
578
+ ret = __get_compat_msghdr (& iomsg -> msg , & cmsg , & iomsg -> uaddr );
579
+ if (unlikely (ret ))
580
+ return ret ;
581
+
582
+ return io_recvmsg_mshot_prep (req , iomsg , cmsg .msg_namelen ,
583
+ cmsg .msg_controllen );
584
+ }
585
+ #endif
586
+
587
+ ret = io_msg_copy_hdr (req , iomsg , & msg , ITER_DEST );
588
+ if (unlikely (ret ))
589
+ return ret ;
590
+
591
+ ret = __copy_msghdr (& iomsg -> msg , & msg , & iomsg -> uaddr );
592
+ if (unlikely (ret ))
593
+ return ret ;
594
+
595
+ return io_recvmsg_mshot_prep (req , iomsg , msg .msg_namelen ,
596
+ msg .msg_controllen );
576
597
}
577
598
578
599
int io_recvmsg_prep_async (struct io_kiocb * req )
0 commit comments