mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-03 18:05:06 -05:00
socket: drop messages from unterminated Unix paths
On some systems (e.g. FreeBSD) the source Unix domain socket path provided by recvmsg() as msg_name is not always null-terminated even if more space than required for sockaddr_un is provided due to the padding in the sockaddr_all union, and the returned msg_namelen value does not indicate it is missing the termination. If a cmdmon client bound its socket to a maximum-length path (chronyc doesn't allow that), the path would be overread when printing a debug message and trying to send a response. Drop messages from paths not shorter than sun_path to avoid working with un-printf()able and/or unreachable addresses. The clients are expected to not use the maximum-length paths.
This commit is contained in:
15
socket.c
15
socket.c
@@ -877,8 +877,10 @@ static int
|
||||
process_header(struct msghdr *msg, int msg_length, int sock_fd, int flags,
|
||||
SCK_Message *message)
|
||||
{
|
||||
int r = 1, path_len, max_path_len;
|
||||
struct cmsghdr *cmsg;
|
||||
int r = 1;
|
||||
|
||||
init_message_addresses(message, SCK_ADDR_UNSPEC);
|
||||
|
||||
if (msg->msg_namelen <= sizeof (union sockaddr_all) &&
|
||||
msg->msg_namelen > sizeof (((struct sockaddr *)msg->msg_name)->sa_family)) {
|
||||
@@ -891,18 +893,23 @@ process_header(struct msghdr *msg, int msg_length, int sock_fd, int flags,
|
||||
SCK_SockaddrToIPSockAddr(msg->msg_name, msg->msg_namelen, &message->remote_addr.ip);
|
||||
break;
|
||||
case AF_UNIX:
|
||||
/* Make sure the path is terminated by '\0' */
|
||||
max_path_len = sizeof (((struct sockaddr_un *)msg->msg_name)->sun_path);
|
||||
path_len = strnlen(((struct sockaddr_un *)msg->msg_name)->sun_path, max_path_len);
|
||||
if (path_len >= max_path_len) {
|
||||
DEBUG_LOG("Unterminated path");
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
init_message_addresses(message, SCK_ADDR_UNIX);
|
||||
message->remote_addr.path = ((struct sockaddr_un *)msg->msg_name)->sun_path;
|
||||
break;
|
||||
default:
|
||||
init_message_addresses(message, SCK_ADDR_UNSPEC);
|
||||
DEBUG_LOG("Unexpected address");
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
init_message_addresses(message, SCK_ADDR_UNSPEC);
|
||||
|
||||
if (msg->msg_namelen > sizeof (union sockaddr_all)) {
|
||||
DEBUG_LOG("Truncated source address");
|
||||
r = 0;
|
||||
|
||||
Reference in New Issue
Block a user