@@ -576,6 +576,16 @@ struct io_accept {
576576 unsigned long nofile ;
577577};
578578
579+ struct io_socket {
580+ struct file * file ;
581+ int domain ;
582+ int type ;
583+ int protocol ;
584+ int flags ;
585+ u32 file_slot ;
586+ unsigned long nofile ;
587+ };
588+
579589struct io_sync {
580590 struct file * file ;
581591 loff_t len ;
@@ -951,6 +961,7 @@ struct io_kiocb {
951961 struct io_hardlink hardlink ;
952962 struct io_msg msg ;
953963 struct io_xattr xattr ;
964+ struct io_socket sock ;
954965 };
955966
956967 u8 opcode ;
@@ -1227,6 +1238,9 @@ static const struct io_op_def io_op_defs[] = {
12271238 .needs_file = 1
12281239 },
12291240 [IORING_OP_GETXATTR ] = {},
1241+ [IORING_OP_SOCKET ] = {
1242+ .audit_skip = 1 ,
1243+ },
12301244};
12311245
12321246/* requests with any of those set should undergo io_disarm_next() */
@@ -6017,6 +6031,62 @@ static int io_accept(struct io_kiocb *req, unsigned int issue_flags)
60176031 return 0 ;
60186032}
60196033
6034+ static int io_socket_prep (struct io_kiocb * req , const struct io_uring_sqe * sqe )
6035+ {
6036+ struct io_socket * sock = & req -> sock ;
6037+
6038+ if (unlikely (req -> ctx -> flags & IORING_SETUP_IOPOLL ))
6039+ return - EINVAL ;
6040+ if (sqe -> ioprio || sqe -> addr || sqe -> rw_flags || sqe -> buf_index )
6041+ return - EINVAL ;
6042+
6043+ sock -> domain = READ_ONCE (sqe -> fd );
6044+ sock -> type = READ_ONCE (sqe -> off );
6045+ sock -> protocol = READ_ONCE (sqe -> len );
6046+ sock -> file_slot = READ_ONCE (sqe -> file_index );
6047+ sock -> nofile = rlimit (RLIMIT_NOFILE );
6048+
6049+ sock -> flags = sock -> type & ~SOCK_TYPE_MASK ;
6050+ if (sock -> file_slot && (sock -> flags & SOCK_CLOEXEC ))
6051+ return - EINVAL ;
6052+ if (sock -> flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK ))
6053+ return - EINVAL ;
6054+ return 0 ;
6055+ }
6056+
6057+ static int io_socket (struct io_kiocb * req , unsigned int issue_flags )
6058+ {
6059+ struct io_socket * sock = & req -> sock ;
6060+ bool fixed = !!sock -> file_slot ;
6061+ struct file * file ;
6062+ int ret , fd ;
6063+
6064+ if (!fixed ) {
6065+ fd = __get_unused_fd_flags (sock -> flags , sock -> nofile );
6066+ if (unlikely (fd < 0 ))
6067+ return fd ;
6068+ }
6069+ file = __sys_socket_file (sock -> domain , sock -> type , sock -> protocol );
6070+ if (IS_ERR (file )) {
6071+ if (!fixed )
6072+ put_unused_fd (fd );
6073+ ret = PTR_ERR (file );
6074+ if (ret == - EAGAIN && (issue_flags & IO_URING_F_NONBLOCK ))
6075+ return - EAGAIN ;
6076+ if (ret == - ERESTARTSYS )
6077+ ret = - EINTR ;
6078+ req_set_fail (req );
6079+ } else if (!fixed ) {
6080+ fd_install (fd , file );
6081+ ret = fd ;
6082+ } else {
6083+ ret = io_install_fixed_file (req , file , issue_flags ,
6084+ sock -> file_slot - 1 );
6085+ }
6086+ __io_req_complete (req , issue_flags , ret , 0 );
6087+ return 0 ;
6088+ }
6089+
60206090static int io_connect_prep_async (struct io_kiocb * req )
60216091{
60226092 struct io_async_connect * io = req -> async_data ;
@@ -6105,6 +6175,7 @@ IO_NETOP_PREP_ASYNC(sendmsg);
61056175IO_NETOP_PREP_ASYNC (recvmsg );
61066176IO_NETOP_PREP_ASYNC (connect );
61076177IO_NETOP_PREP (accept );
6178+ IO_NETOP_PREP (socket );
61086179IO_NETOP_FN (send );
61096180IO_NETOP_FN (recv );
61106181#endif /* CONFIG_NET */
@@ -7426,6 +7497,8 @@ static int io_req_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
74267497 return io_fgetxattr_prep (req , sqe );
74277498 case IORING_OP_GETXATTR :
74287499 return io_getxattr_prep (req , sqe );
7500+ case IORING_OP_SOCKET :
7501+ return io_socket_prep (req , sqe );
74297502 }
74307503
74317504 printk_once (KERN_WARNING "io_uring: unhandled opcode %d\n" ,
@@ -7744,6 +7817,9 @@ static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags)
77447817 case IORING_OP_GETXATTR :
77457818 ret = io_getxattr (req , issue_flags );
77467819 break ;
7820+ case IORING_OP_SOCKET :
7821+ ret = io_socket (req , issue_flags );
7822+ break ;
77477823 default :
77487824 ret = - EINVAL ;
77497825 break ;
0 commit comments