diff --git a/src/base/ctrl_socket.c b/src/base/ctrl_socket.c index c0d328e0..031f96fc 100644 --- a/src/base/ctrl_socket.c +++ b/src/base/ctrl_socket.c @@ -144,7 +144,7 @@ static void handle_command(HANDLE h, const char *line) retval = xdebug_xml_node_init("ctrl-response"); xdebug_xml_add_attribute(retval, "xmlns:xdebug-ctrl", "https://xdebug.org/ctrl/xdebug"); - command = lookup_cmd(cmd); + command = cmd ? lookup_cmd(cmd) : NULL; if (command) { command->handler(&retval, args); } else { @@ -280,6 +280,8 @@ static void xdebug_control_socket_handle(void) } if (FD_ISSET(XG_BASE(control_socket_fd), &working_set)) { + struct ucred peer_cred; + socklen_t peer_cred_len = sizeof(peer_cred); int new_sd = accept(XG_BASE(control_socket_fd), NULL, NULL); if (new_sd < 0) { if (errno != EWOULDBLOCK) { @@ -288,11 +290,24 @@ static void xdebug_control_socket_handle(void) return; } + if (getsockopt(new_sd, SOL_SOCKET, SO_PEERCRED, &peer_cred, &peer_cred_len) != 0) { + xdebug_log_ex(XLOG_CHAN_CONFIG, XLOG_WARN, "CTRL-AUTH", "Can't get peer credentials: %s", strerror(errno)); + close(new_sd); + return; + } + if (peer_cred.uid != geteuid()) { + xdebug_log_ex(XLOG_CHAN_CONFIG, XLOG_WARN, "CTRL-AUTH", "Rejected peer with UID %lu (expected %lu)", + (unsigned long) peer_cred.uid, (unsigned long) geteuid()); + close(new_sd); + return; + } + memset(buffer, 0, sizeof(buffer)); - bytes_read = read(new_sd, buffer, sizeof(buffer)); + bytes_read = read(new_sd, buffer, sizeof(buffer) - 1); if (bytes_read == -1) { xdebug_log_ex(XLOG_CHAN_CONFIG, XLOG_WARN, "CTRL-HANDLE", "Can't receive from socket: %s", strerror(errno)); - } else { + } else if (bytes_read > 0) { + buffer[bytes_read] = '\0'; xdebug_log_ex(XLOG_CHAN_CONFIG, XLOG_INFO, "CTRL-HANDLE", "Received: '%s'", buffer); handle_command(new_sd, buffer); } @@ -353,7 +368,7 @@ static void xdebug_control_socket_handle(void) if (!ReadFile( XG_BASE(control_socket_h), buffer, - sizeof(buffer), + sizeof(buffer) - 1, &bytes_read, &XG_BASE(control_socket_ov) )) { @@ -371,8 +386,11 @@ static void xdebug_control_socket_handle(void) } } - xdebug_log_ex(XLOG_CHAN_CONFIG, XLOG_INFO, "CTRL-HANDLE", "Received: '%s'", buffer); - handle_command(XG_BASE(control_socket_h), buffer); + if (bytes_read > 0) { + buffer[bytes_read] = '\0'; + xdebug_log_ex(XLOG_CHAN_CONFIG, XLOG_INFO, "CTRL-HANDLE", "Received: '%s'", buffer); + handle_command(XG_BASE(control_socket_h), buffer); + } WaitForSingleObject(XG_BASE(control_socket_ov).hEvent, INFINITY); GetOverlappedResult(XG_BASE(control_socket_h), &XG_BASE(control_socket_ov), &bytes_read, FALSE);