diff --git a/src/tools/miri/src/shims/unix/socket.rs b/src/tools/miri/src/shims/unix/socket.rs index c553cd1f70e8..e2bdd459c100 100644 --- a/src/tools/miri/src/shims/unix/socket.rs +++ b/src/tools/miri/src/shims/unix/socket.rs @@ -316,10 +316,10 @@ fn socket( flags ); } - if protocol != 0 { + if protocol != 0 && protocol != this.eval_libc_i32("IPPROTO_TCP") { throw_unsup_format!( "socket: socket protocol {protocol} is unsupported, \ - only 0 is allowed" + only IPPROTO_TCP and 0 are allowed" ); } diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socket.rs b/src/tools/miri/tests/pass-dep/libc/libc-socket.rs index c87677a756a0..6f3bd22b42e6 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-socket.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-socket.rs @@ -16,6 +16,7 @@ fn main() { test_create_close(); + test_create_close_tcp(); test_bind_ipv4(); test_bind_ipv4_reuseaddr(); test_set_reuseaddr_invalid_len(); @@ -59,6 +60,21 @@ fn test_create_close() { unsafe { errno_check(libc::close(sockfd)) }; } +/// Test creating a socket and then closing it afterwards but we explicitly +/// specify that the TCP protocol should be used. +fn test_create_close_tcp() { + let sockfd = unsafe { + errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, libc::IPPROTO_TCP)).unwrap() + }; + + let flags = unsafe { errno_result(libc::fcntl(sockfd, libc::F_GETFL, 0)).unwrap() }; + + // Ensure that socket is initially blocking. + assert_eq!(flags & libc::O_NONBLOCK, 0); + + unsafe { errno_check(libc::close(sockfd)) }; +} + fn test_bind_ipv4() { let sockfd = unsafe { errno_result(libc::socket(libc::AF_INET, libc::SOCK_STREAM, 0)).unwrap() };