From: Giang Nguyen <nen24t@gmail.com> Two defensive fixes on top of the AF_UNIX patchset: 1. sun_path is 108 bytes, but base_name was copied with strlen() and no bound check into a stack union. Not reachable through the Windows API, since SOCKADDR_UN.sun_path already caps the input, but the server should not trust request data for a fixed-size buffer. Now rejected with WSAEINVAL. 2. The connect() failure path returned without fchdir(server_dir_fd), leaving the server's working directory in the socket directory. Not observable in practice because open_fd() restores it on the next file operation, but the state is better cleaned up where it is created. Neither is a triggerable bug -- both were verified as not reachable, and ws2_32:sock test_afunix is unchanged at 32 failing assertions. Signed-off-by: Giang Nguyen <nen24t@gmail.com> --- server/sock.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/server/sock.c b/server/sock.c index 42cc6f82a34..c53f55533bc 100644 --- a/server/sock.c +++ b/server/sock.c @@ -2801,6 +2801,13 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) else base_name = unix_path; + if (strlen( base_name ) >= sizeof(unix_addr.un.sun_path)) + { + free( unix_path ); + set_win32_error( WSAEINVAL ); + return; + } + if (chdir( unix_path ) == -1) { set_error( sock_get_ntstatus( errno ) ); @@ -2872,15 +2879,15 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) } } + if (sock->family == WS_AF_UNIX && *addr->sa_data) + fchdir(server_dir_fd); + if (ret < 0 && errno != EINPROGRESS) { set_error( sock_get_ntstatus( errno ) ); return; } - if (sock->family == WS_AF_UNIX && *addr->sa_data) - fchdir(server_dir_fd); - /* a connected or connecting socket can no longer be accepted into */ allow_fd_caching( sock->fd ); @@ -3184,6 +3191,13 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) else base_name = unix_path; + if (strlen( base_name ) >= sizeof(unix_addr.un.sun_path)) + { + free( unix_path ); + set_win32_error( WSAEINVAL ); + return; + } + if (chdir( unix_path ) == -1) { free( unix_path ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7650