From 5e231ceb35bb763d6fafc7c3efe1c3c582929cc2 Mon Sep 17 00:00:00 2001 From: Xavi Hernandez Date: Tue, 14 Jan 2020 13:28:47 +0100 Subject: [PATCH 417/449] events: fix IPv6 memory corruption When an event was generated and the target host was resolved to an IPv6 address, there was a memory overflow when that address was copied to a fixed IPv4 structure (IPv6 addresses are longer than IPv4 ones). This fix correctly handles IPv4 and IPv6 addresses returned by getaddrinfo() Backport of: > Upstream-patch-link: https://review.gluster.org/24014 > Change-Id: I5864a0c6e6f1b405bd85988529570140cf23b250 > Fixes: bz#1790870 > Signed-off-by: Xavi Hernandez BUG: 1792873 Change-Id: I5864a0c6e6f1b405bd85988529570140cf23b250 Signed-off-by: Xavi Hernandez Reviewed-on: https://code.engineering.redhat.com/gerrit/202486 Tested-by: RHGS Build Bot Reviewed-by: Sunil Kumar Heggodu Gopala Acharya --- libglusterfs/src/events.c | 56 +++++++++++++---------------------------------- 1 file changed, 15 insertions(+), 41 deletions(-) diff --git a/libglusterfs/src/events.c b/libglusterfs/src/events.c index 4e2f8f9..6d1e383 100644 --- a/libglusterfs/src/events.c +++ b/libglusterfs/src/events.c @@ -34,7 +34,6 @@ _gf_event(eventtypes_t event, const char *fmt, ...) int ret = 0; int sock = -1; char *eventstr = NULL; - struct sockaddr_in server; va_list arguments; char *msg = NULL; glusterfs_ctx_t *ctx = NULL; @@ -42,11 +41,10 @@ _gf_event(eventtypes_t event, const char *fmt, ...) struct addrinfo hints; struct addrinfo *result = NULL; xlator_t *this = THIS; - int sin_family = AF_INET; char *volfile_server_transport = NULL; /* Global context */ - ctx = THIS->ctx; + ctx = this->ctx; if (event < 0 || event >= EVENT_LAST) { ret = EVENT_ERROR_INVALID_INPUTS; @@ -60,48 +58,31 @@ _gf_event(eventtypes_t event, const char *fmt, ...) goto out; } - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - if (ctx) { volfile_server_transport = ctx->cmd_args.volfile_server_transport; } - if (!volfile_server_transport) { volfile_server_transport = "tcp"; } - /* Get Host name to send message */ + + /* host = NULL returns localhost */ + host = NULL; if (ctx && ctx->cmd_args.volfile_server && (strcmp(volfile_server_transport, "unix"))) { /* If it is client code then volfile_server is set use that information to push the events. */ - if ((getaddrinfo(ctx->cmd_args.volfile_server, NULL, &hints, - &result)) != 0) { - ret = EVENT_ERROR_RESOLVE; - goto out; - } - - if (get_ip_from_addrinfo(result, &host) == NULL) { - ret = EVENT_ERROR_RESOLVE; - goto out; - } - - sin_family = result->ai_family; - } else { - /* Localhost, Use the defined IP for localhost */ - host = gf_strdup(EVENT_HOST); + host = ctx->cmd_args.volfile_server; } - /* Socket Configurations */ - server.sin_family = sin_family; - server.sin_port = htons(EVENT_PORT); - ret = inet_pton(server.sin_family, host, &server.sin_addr); - if (ret <= 0) { - gf_msg(this->name, GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, - "inet_pton failed with return code %d", ret); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_ADDRCONFIG; + + if ((getaddrinfo(host, TOSTRING(EVENT_PORT), &hints, &result)) != 0) { + ret = EVENT_ERROR_RESOLVE; goto out; } - memset(&server.sin_zero, '\0', sizeof(server.sin_zero)); va_start(arguments, fmt); ret = gf_vasprintf(&msg, fmt, arguments); @@ -113,15 +94,15 @@ _gf_event(eventtypes_t event, const char *fmt, ...) } ret = gf_asprintf(&eventstr, "%u %d %s", (unsigned)time(NULL), event, msg); - + GF_FREE(msg); if (ret <= 0) { ret = EVENT_ERROR_MSG_FORMAT; goto out; } /* Send Message */ - if (sendto(sock, eventstr, strlen(eventstr), 0, (struct sockaddr *)&server, - sizeof(server)) <= 0) { + if (sendto(sock, eventstr, strlen(eventstr), 0, result->ai_addr, + result->ai_addrlen) <= 0) { ret = EVENT_ERROR_SEND; goto out; } @@ -133,17 +114,10 @@ out: sys_close(sock); } - /* Allocated by gf_vasprintf */ - if (msg) - GF_FREE(msg); - /* Allocated by gf_asprintf */ if (eventstr) GF_FREE(eventstr); - if (host) - GF_FREE(host); - if (result) freeaddrinfo(result); -- 1.8.3.1