@@ -204,46 +204,26 @@ static int io_setup_async_msg(struct io_kiocb *req,
204204 return - EAGAIN ;
205205}
206206
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-
222207#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 )
226211{
227212 struct io_sr_msg * sr = io_kiocb_to_cmd (req , struct io_sr_msg );
228- struct compat_msghdr msg ;
229213 struct compat_iovec __user * uiov ;
230214 int ret ;
231215
232- if (copy_from_user (& msg , sr -> umsg_compat , sizeof (msg )))
216+ if (copy_from_user (msg , sr -> umsg_compat , sizeof (* msg )))
233217 return - EFAULT ;
234218
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 );
240220 if (req -> flags & REQ_F_BUFFER_SELECT ) {
241221 compat_ssize_t clen ;
242222
243223 iomsg -> free_iov = NULL ;
244- if (msg . msg_iovlen == 0 ) {
224+ if (msg -> msg_iovlen == 0 ) {
245225 sr -> len = 0 ;
246- } else if (msg . msg_iovlen > 1 ) {
226+ } else if (msg -> msg_iovlen > 1 ) {
247227 return - EINVAL ;
248228 } else {
249229 if (!access_ok (uiov , sizeof (* uiov )))
@@ -255,18 +235,11 @@ static int __io_compat_msg_copy_hdr(struct io_kiocb *req,
255235 sr -> len = clen ;
256236 }
257237
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-
265238 return 0 ;
266239 }
267240
268241 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 ,
270243 UIO_FASTIOV , & iomsg -> free_iov ,
271244 & iomsg -> msg .msg_iter , true);
272245 if (unlikely (ret < 0 ))
@@ -276,78 +249,70 @@ static int __io_compat_msg_copy_hdr(struct io_kiocb *req,
276249}
277250#endif
278251
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 )
281254{
282255 struct io_sr_msg * sr = io_kiocb_to_cmd (req , struct io_sr_msg );
283- struct user_msghdr msg ;
284256 int ret ;
285257
286- if (copy_from_user (& msg , sr -> umsg , sizeof (* sr -> umsg )))
258+ if (copy_from_user (msg , sr -> umsg , sizeof (* sr -> umsg )))
287259 return - EFAULT ;
288260
289- ret = __copy_msghdr (& iomsg -> msg , & msg , addr );
290- if (ret )
291- return ret ;
292-
293261 if (req -> flags & REQ_F_BUFFER_SELECT ) {
294- if (msg . msg_iovlen == 0 ) {
262+ if (msg -> msg_iovlen == 0 ) {
295263 sr -> len = iomsg -> fast_iov [0 ].iov_len = 0 ;
296264 iomsg -> fast_iov [0 ].iov_base = NULL ;
297265 iomsg -> free_iov = NULL ;
298- } else if (msg . msg_iovlen > 1 ) {
266+ } else if (msg -> msg_iovlen > 1 ) {
299267 return - EINVAL ;
300268 } 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 )))
303271 return - EFAULT ;
304272 sr -> len = iomsg -> fast_iov [0 ].iov_len ;
305273 iomsg -> free_iov = NULL ;
306274 }
307275
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-
315276 return 0 ;
316277 }
317278
318279 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 ,
320281 & iomsg -> free_iov , & iomsg -> msg .msg_iter , false);
321282 if (unlikely (ret < 0 ))
322283 return ret ;
323284
324285 return 0 ;
325286}
326287
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 )
329290{
291+ struct io_sr_msg * sr = io_kiocb_to_cmd (req , struct io_sr_msg );
292+ struct user_msghdr msg ;
293+ int ret ;
294+
330295 iomsg -> msg .msg_name = & iomsg -> addr ;
331296 iomsg -> msg .msg_iter .nr_segs = 0 ;
332297
333298#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 ;
337301
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 ;
340305
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
346309
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 ) )
349312 return ret ;
350313
314+ ret = __copy_msghdr (& iomsg -> msg , & msg , NULL );
315+
351316 /* save msg_control as sys_sendmsg() overwrites it */
352317 sr -> msg_control = iomsg -> msg .msg_control_user ;
353318 return ret ;
@@ -569,10 +534,66 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags)
569534 return IOU_OK ;
570535}
571536
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+
572561static int io_recvmsg_copy_hdr (struct io_kiocb * req ,
573562 struct io_async_msghdr * iomsg )
574563{
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 );
576597}
577598
578599int io_recvmsg_prep_async (struct io_kiocb * req )
0 commit comments