@@ -474,6 +474,65 @@ static int test(struct args *args)
474474 return ret ;
475475}
476476
477+ static int test_recvmsg_validate (void )
478+ {
479+ struct io_uring_recvmsg_out * o ;
480+ unsigned char buf [64 ];
481+ struct msghdr msgh ;
482+ unsigned int len ;
483+
484+ memset (buf , 0 , sizeof (buf ));
485+ memset (& msgh , 0 , sizeof (msgh ));
486+ o = (struct io_uring_recvmsg_out * )buf ;
487+
488+ msgh .msg_namelen = 4 ;
489+ msgh .msg_controllen = 8 ;
490+ if (!io_uring_recvmsg_validate (buf , 64 , & msgh ))
491+ return -1 ;
492+
493+ /* exact fit */
494+ if (!io_uring_recvmsg_validate (buf , 28 , & msgh ))
495+ return -1 ;
496+
497+ /* one byte short */
498+ if (io_uring_recvmsg_validate (buf , 27 , & msgh ))
499+ return -1 ;
500+
501+ /* negative buf_len */
502+ if (io_uring_recvmsg_validate (buf , -1 , & msgh ))
503+ return -1 ;
504+
505+ /* buf smaller than header alone */
506+ msgh .msg_namelen = 0 ;
507+ msgh .msg_controllen = 0 ;
508+ if (io_uring_recvmsg_validate (buf , 15 , & msgh ))
509+ return -1 ;
510+
511+ /* controllen overflow must be rejected */
512+ msgh .msg_controllen = (socklen_t )(~(socklen_t )0 - sizeof (struct io_uring_recvmsg_out ));
513+ msgh .msg_namelen = 4 ;
514+ if (io_uring_recvmsg_validate (buf , 64 , & msgh ))
515+ return -1 ;
516+
517+ msgh .msg_namelen = 4 ;
518+ msgh .msg_controllen = 8 ;
519+ len = io_uring_recvmsg_payload_length (o , 64 , & msgh );
520+ if (len != 36 )
521+ return -1 ;
522+
523+ /* negative buf_len */
524+ if (io_uring_recvmsg_payload_length (o , -1 , & msgh ) != 0 )
525+ return -1 ;
526+
527+ /* name+ctrl > buf_len must return 0, not wrap around */
528+ msgh .msg_namelen = 40 ;
529+ msgh .msg_controllen = 30 ;
530+ if (io_uring_recvmsg_payload_length (o , 64 , & msgh ) != 0 )
531+ return -1 ;
532+
533+ return 0 ;
534+ }
535+
477536static int test_enobuf (void )
478537{
479538 struct io_uring ring ;
@@ -564,6 +623,12 @@ int main(int argc, char *argv[])
564623
565624 has_defer = t_probe_defer_taskrun ();
566625
626+ ret = test_recvmsg_validate ();
627+ if (ret ) {
628+ fprintf (stderr , "test_recvmsg_validate() failed: %d\n" , ret );
629+ return T_EXIT_FAIL ;
630+ }
631+
567632 for (loop = 0 ; loop < 16 ; loop ++ ) {
568633 struct args a = {
569634 .stream = loop & 0x01 ,
0 commit comments