@@ -1111,7 +1111,8 @@ void Machine::setup_linux_system_calls(bool unsafe_syscalls)
11111111 {
11121112 cpu.machine ().copy_from_guest (&addr, g_addr, addrlen);
11131113 // Validate the address
1114- if (UNLIKELY (!cpu.machine ().fds ().validate_socket_address (fd, addr)))
1114+ if (auto & callback = cpu.machine ().fds ().bind_socket_callback ;
1115+ UNLIKELY (callback == nullptr || !callback (fd, addr)))
11151116 {
11161117 regs.rax = -EPERM ;
11171118 } else {
@@ -1138,20 +1139,18 @@ void Machine::setup_linux_system_calls(bool unsafe_syscalls)
11381139 const int vfd = regs.rdi ;
11391140 const int fd = cpu.machine ().fds ().translate_writable_vfd (vfd);
11401141 const int backlog = regs.rsi ;
1141- if (UNLIKELY (listen (fd, backlog) < 0 ))
1142+ if (auto & callback = cpu.machine ().fds ().listening_socket_callback ;
1143+ UNLIKELY (callback == nullptr || !callback (vfd, fd)))
1144+ {
1145+ regs.rax = -EPERM ;
1146+ }
1147+ else if (UNLIKELY (listen (fd, backlog) < 0 ))
11421148 {
11431149 regs.rax = -errno;
11441150 }
11451151 else
11461152 {
1147- if (auto & callback = cpu.machine ().fds ().listening_socket_callback ;
1148- callback != nullptr )
1149- {
1150- const bool allowed = callback (vfd, fd);
1151- regs.rax = allowed ? 0 : -EPERM ;
1152- } else {
1153- regs.rax = 0 ;
1154- }
1153+ regs.rax = 0 ;
11551154 }
11561155 cpu.set_registers (regs);
11571156 SYSPRINT (" listen(fd=%d (%d), backlog=%d) = %lld\n " ,
@@ -1333,7 +1332,7 @@ void Machine::setup_linux_system_calls(bool unsafe_syscalls)
13331332 // Ignore too large buffers
13341333 regs.rax = -ENOMEM ;
13351334 }
1336- else if (UNLIKELY (addrlen > sizeof (struct sockaddr )))
1335+ else if (UNLIKELY (addrlen > sizeof (struct sockaddr_storage )))
13371336 {
13381337 regs.rax = -EINVAL ;
13391338 }
@@ -1345,7 +1344,7 @@ void Machine::setup_linux_system_calls(bool unsafe_syscalls)
13451344 const auto bufcount =
13461345 cpu.machine ().gather_buffers_from_range (buffers.size (), buffers.data (), g_buf, bytes);
13471346
1348- struct sockaddr addr;
1347+ struct sockaddr_storage addr {} ;
13491348 struct msghdr msg {};
13501349 msg.msg_name = nullptr ;
13511350 msg.msg_namelen = 0 ;
@@ -1360,13 +1359,20 @@ void Machine::setup_linux_system_calls(bool unsafe_syscalls)
13601359 msg.msg_name = &addr;
13611360 msg.msg_namelen = addrlen;
13621361 }
1363-
1364- ssize_t result = sendmsg (fd, &msg, flags);
1365- if (UNLIKELY (result < 0 )) {
1366- regs.rax = -errno;
1367- }
1368- else {
1369- regs.rax = result;
1362+ // Validate the address
1363+ if (UNLIKELY (addrlen > 0 && g_addr != 0x0 &&
1364+ !cpu.machine ().fds ().validate_socket_address (fd, addr)))
1365+ {
1366+ regs.rax = -EPERM ;
1367+ } else
1368+ {
1369+ ssize_t result = sendmsg (fd, &msg, flags);
1370+ if (UNLIKELY (result < 0 )) {
1371+ regs.rax = -errno;
1372+ }
1373+ else {
1374+ regs.rax = result;
1375+ }
13701376 }
13711377 }
13721378 } catch (...) {
@@ -1540,21 +1546,36 @@ void Machine::setup_linux_system_calls(bool unsafe_syscalls)
15401546 g_base, g_len);
15411547 bufcount += this_bufcount;
15421548 }
1543- struct sockaddr addr {};
1549+ struct sockaddr_storage addr {};
15441550 struct msghdr msg_send {};
1545- msg_send.msg_name = &addr ;
1546- msg_send.msg_namelen = sizeof (addr) ;
1551+ msg_send.msg_name = nullptr ;
1552+ msg_send.msg_namelen = 0 ;
15471553 msg_send.msg_iov = (struct iovec *)&buffers[0 ];
15481554 msg_send.msg_iovlen = bufcount;
15491555 msg_send.msg_control = nullptr ;
15501556 msg_send.msg_controllen = 0 ;
15511557 msg_send.msg_flags = MSG_NOSIGNAL ; // Ignore SIGPIPE
1552- // Perform the sendmsg
1553- ssize_t result = sendmsg (fd, &msg_send, flags);
1554- if (UNLIKELY (result < 0 )) {
1555- regs.rax = -errno;
1556- } else {
1557- regs.rax = result;
1558+
1559+ if (msg.msg_namelen > 0 && msg.msg_name != 0x0 ) {
1560+ cpu.machine ().copy_from_guest (&addr, reinterpret_cast <uint64_t >(msg.msg_name ), msg.msg_namelen );
1561+ msg_send.msg_name = &addr;
1562+ msg_send.msg_namelen = msg.msg_namelen ;
1563+ }
1564+ // Validate the address
1565+ if (UNLIKELY (msg.msg_namelen > 0 && msg.msg_name != 0x0 &&
1566+ !cpu.machine ().fds ().validate_socket_address (fd, addr)))
1567+ {
1568+ regs.rax = -EPERM ;
1569+ }
1570+ else
1571+ {
1572+ // Perform the sendmsg
1573+ ssize_t result = sendmsg (fd, &msg_send, flags);
1574+ if (UNLIKELY (result < 0 )) {
1575+ regs.rax = -errno;
1576+ } else {
1577+ regs.rax = result;
1578+ }
15581579 }
15591580 } catch (...) {
15601581 regs.rax = -EBADF ;
0 commit comments