diff options
author | Xavi Hernandez <xhernandez@redhat.com> | 2020-01-14 13:28:47 +0100 |
---|---|---|
committer | Xavi Hernandez <xhernandez@redhat.com> | 2020-02-28 09:00:27 +0100 |
commit | b9940cb47dc91e6a7711f2626f5877e00177a0c2 (patch) | |
tree | 2fabb5160aafcb0c52f377d910f2a5dca5bd5e62 | |
parent | 0bfb22c7d7e6a41c920cb3556c6a55474c66b6cf (diff) |
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:
> Change-Id: I5864a0c6e6f1b405bd85988529570140cf23b250
> Fixes: bz#1790870
> Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
Change-Id: I5864a0c6e6f1b405bd85988529570140cf23b250
Fixes: bz#1792857
Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
-rw-r--r-- | libglusterfs/src/events.c | 56 |
1 files changed, 15 insertions, 41 deletions
diff --git a/libglusterfs/src/events.c b/libglusterfs/src/events.c index 4e2f8f93a00..6d1e3836477 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); |