From 3bbe0d065fa0fe185ea381cd2b7ee3fa85658db3 Mon Sep 17 00:00:00 2001 From: Michal Sekletar Date: Wed, 9 Jul 2025 14:57:22 +0200 Subject: [PATCH] Fix CVE-2024-52615 Resolves: RHEL-94846 --- ...e-data-member-as-big-as-IPv6-address.patch | 33 +++ ...ore-wide-area-fix-for-CVE-2024-52615.patch | 227 ++++++++++++++++++ avahi.spec | 7 +- 3 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 0001-Make-data-member-as-big-as-IPv6-address.patch create mode 100644 0001-core-wide-area-fix-for-CVE-2024-52615.patch diff --git a/0001-Make-data-member-as-big-as-IPv6-address.patch b/0001-Make-data-member-as-big-as-IPv6-address.patch new file mode 100644 index 0000000..2921858 --- /dev/null +++ b/0001-Make-data-member-as-big-as-IPv6-address.patch @@ -0,0 +1,33 @@ +From 358e5a3b0122b418614e2ac0fc71f6aad1de06f8 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 23 Jun 2025 16:27:40 +0200 +Subject: [PATCH] Make data member as big as IPv6 address + +Unfortunately, recent FORTIFY_SOURCE hardening for inet_pton() can't +deal with our type independent "data[1]" union member trick. + +Fixes #699 +--- + avahi-common/address.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/avahi-common/address.h b/avahi-common/address.h +index a14104f..013fa97 100644 +--- a/avahi-common/address.h ++++ b/avahi-common/address.h +@@ -71,9 +71,9 @@ typedef struct AvahiAddress { + AvahiProtocol proto; /**< Address family */ + + union { +- AvahiIPv6Address ipv6; /**< Address when IPv6 */ +- AvahiIPv4Address ipv4; /**< Address when IPv4 */ +- uint8_t data[1]; /**< Type-independent data field */ ++ AvahiIPv6Address ipv6; /**< Address when IPv6 */ ++ AvahiIPv4Address ipv4; /**< Address when IPv4 */ ++ uint8_t data[sizeof(AvahiIPv6Address)]; /**< Type-independent data field */ + } data; + } AvahiAddress; + +-- +2.49.0 + diff --git a/0001-core-wide-area-fix-for-CVE-2024-52615.patch b/0001-core-wide-area-fix-for-CVE-2024-52615.patch new file mode 100644 index 0000000..ed2f491 --- /dev/null +++ b/0001-core-wide-area-fix-for-CVE-2024-52615.patch @@ -0,0 +1,227 @@ +From 4e2e1ea0908d7e6ad7f38ae04fdcdf2411f8b942 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 27 Nov 2024 18:07:32 +0100 +Subject: [PATCH] core/wide-area: fix for CVE-2024-52615 + +--- + avahi-core/wide-area.c | 128 ++++++++++++++++++++++------------------- + 1 file changed, 69 insertions(+), 59 deletions(-) + +diff --git a/avahi-core/wide-area.c b/avahi-core/wide-area.c +index 00a1505..06df7af 100644 +--- a/avahi-core/wide-area.c ++++ b/avahi-core/wide-area.c +@@ -81,6 +81,10 @@ struct AvahiWideAreaLookup { + + AvahiAddress dns_server_used; + ++ int fd; ++ AvahiWatch *watch; ++ AvahiProtocol proto; ++ + AVAHI_LLIST_FIELDS(AvahiWideAreaLookup, lookups); + AVAHI_LLIST_FIELDS(AvahiWideAreaLookup, by_key); + }; +@@ -88,9 +92,6 @@ struct AvahiWideAreaLookup { + struct AvahiWideAreaLookupEngine { + AvahiServer *server; + +- int fd_ipv4, fd_ipv6; +- AvahiWatch *watch_ipv4, *watch_ipv6; +- + /* Cache */ + AVAHI_LLIST_HEAD(AvahiWideAreaCacheEntry, cache); + AvahiHashmap *cache_by_key; +@@ -125,35 +126,67 @@ static AvahiWideAreaLookup* find_lookup(AvahiWideAreaLookupEngine *e, uint16_t i + return l; + } + ++static void socket_event(AVAHI_GCC_UNUSED AvahiWatch *w, int fd, AVAHI_GCC_UNUSED AvahiWatchEvent events, void *userdata); ++ + static int send_to_dns_server(AvahiWideAreaLookup *l, AvahiDnsPacket *p) { ++ AvahiWideAreaLookupEngine *e; + AvahiAddress *a; ++ AvahiServer *s; ++ AvahiWatch *w; ++ int r; + + assert(l); + assert(p); + +- if (l->engine->n_dns_servers <= 0) ++ e = l->engine; ++ assert(e); ++ ++ s = e->server; ++ assert(s); ++ ++ if (e->n_dns_servers <= 0) + return -1; + +- assert(l->engine->current_dns_server < l->engine->n_dns_servers); ++ assert(e->current_dns_server < e->n_dns_servers); + +- a = &l->engine->dns_servers[l->engine->current_dns_server]; ++ a = &e->dns_servers[e->current_dns_server]; + l->dns_server_used = *a; + +- if (a->proto == AVAHI_PROTO_INET) { ++ if (l->fd >= 0) { ++ /* We are reusing lookup object and sending packet to another server so let's cleanup before we establish connection to new server. */ ++ s->poll_api->watch_free(l->watch); ++ l->watch = NULL; + +- if (l->engine->fd_ipv4 < 0) +- return -1; ++ close(l->fd); ++ l->fd = -EBADF; ++ } + +- return avahi_send_dns_packet_ipv4(l->engine->fd_ipv4, AVAHI_IF_UNSPEC, p, NULL, &a->data.ipv4, AVAHI_DNS_PORT); ++ assert(a->proto == AVAHI_PROTO_INET || a->proto == AVAHI_PROTO_INET6); + +- } else { +- assert(a->proto == AVAHI_PROTO_INET6); ++ if (a->proto == AVAHI_PROTO_INET) ++ r = s->config.use_ipv4 ? avahi_open_unicast_socket_ipv4() : -1; ++ else ++ r = s->config.use_ipv6 ? avahi_open_unicast_socket_ipv6() : -1; + +- if (l->engine->fd_ipv6 < 0) +- return -1; ++ if (r < 0) { ++ avahi_log_error(__FILE__ ": Failed to create socket for wide area lookup"); ++ return -1; ++ } + +- return avahi_send_dns_packet_ipv6(l->engine->fd_ipv6, AVAHI_IF_UNSPEC, p, NULL, &a->data.ipv6, AVAHI_DNS_PORT); ++ w = s->poll_api->watch_new(s->poll_api, r, AVAHI_WATCH_IN, socket_event, l); ++ if (!w) { ++ close(r); ++ avahi_log_error(__FILE__ ": Failed to create socket watch for wide area lookup"); ++ return -1; + } ++ ++ l->fd = r; ++ l->watch = w; ++ l->proto = a->proto; ++ ++ return a->proto == AVAHI_PROTO_INET ? ++ avahi_send_dns_packet_ipv4(l->fd, AVAHI_IF_UNSPEC, p, NULL, &a->data.ipv4, AVAHI_DNS_PORT): ++ avahi_send_dns_packet_ipv6(l->fd, AVAHI_IF_UNSPEC, p, NULL, &a->data.ipv6, AVAHI_DNS_PORT); + } + + static void next_dns_server(AvahiWideAreaLookupEngine *e) { +@@ -246,6 +279,9 @@ AvahiWideAreaLookup *avahi_wide_area_lookup_new( + l->dead = 0; + l->key = avahi_key_ref(key); + l->cname_key = avahi_key_new_cname(l->key); ++ l->fd = -EBADF; ++ l->watch = NULL; ++ l->proto = AVAHI_PROTO_UNSPEC; + l->callback = callback; + l->userdata = userdata; + +@@ -314,6 +350,12 @@ static void lookup_destroy(AvahiWideAreaLookup *l) { + if (l->cname_key) + avahi_key_unref(l->cname_key); + ++ if (l->watch) ++ l->engine->server->poll_api->watch_free(l->watch); ++ ++ if (l->fd >= 0) ++ close(l->fd); ++ + avahi_free(l); + } + +@@ -572,14 +614,20 @@ finish: + } + + static void socket_event(AVAHI_GCC_UNUSED AvahiWatch *w, int fd, AVAHI_GCC_UNUSED AvahiWatchEvent events, void *userdata) { +- AvahiWideAreaLookupEngine *e = userdata; ++ AvahiWideAreaLookup *l = userdata; ++ AvahiWideAreaLookupEngine *e = l->engine; + AvahiDnsPacket *p = NULL; + +- if (fd == e->fd_ipv4) +- p = avahi_recv_dns_packet_ipv4(e->fd_ipv4, NULL, NULL, NULL, NULL, NULL); ++ assert(l); ++ assert(e); ++ assert(l->fd == fd); ++ ++ if (l->proto == AVAHI_PROTO_INET) ++ p = avahi_recv_dns_packet_ipv4(l->fd, NULL, NULL, NULL, NULL, NULL); + else { +- assert(fd == e->fd_ipv6); +- p = avahi_recv_dns_packet_ipv6(e->fd_ipv6, NULL, NULL, NULL, NULL, NULL); ++ assert(l->proto == AVAHI_PROTO_INET6); ++ ++ p = avahi_recv_dns_packet_ipv6(l->fd, NULL, NULL, NULL, NULL, NULL); + } + + if (p) { +@@ -598,32 +646,6 @@ AvahiWideAreaLookupEngine *avahi_wide_area_engine_new(AvahiServer *s) { + e->server = s; + e->cleanup_dead = 0; + +- /* Create sockets */ +- e->fd_ipv4 = s->config.use_ipv4 ? avahi_open_unicast_socket_ipv4() : -1; +- e->fd_ipv6 = s->config.use_ipv6 ? avahi_open_unicast_socket_ipv6() : -1; +- +- if (e->fd_ipv4 < 0 && e->fd_ipv6 < 0) { +- avahi_log_error(__FILE__": Failed to create wide area sockets: %s", strerror(errno)); +- +- if (e->fd_ipv6 >= 0) +- close(e->fd_ipv6); +- +- if (e->fd_ipv4 >= 0) +- close(e->fd_ipv4); +- +- avahi_free(e); +- return NULL; +- } +- +- /* Create watches */ +- +- e->watch_ipv4 = e->watch_ipv6 = NULL; +- +- if (e->fd_ipv4 >= 0) +- e->watch_ipv4 = s->poll_api->watch_new(e->server->poll_api, e->fd_ipv4, AVAHI_WATCH_IN, socket_event, e); +- if (e->fd_ipv6 >= 0) +- e->watch_ipv6 = s->poll_api->watch_new(e->server->poll_api, e->fd_ipv6, AVAHI_WATCH_IN, socket_event, e); +- + e->n_dns_servers = e->current_dns_server = 0; + + /* Initialize cache */ +@@ -651,18 +673,6 @@ void avahi_wide_area_engine_free(AvahiWideAreaLookupEngine *e) { + avahi_hashmap_free(e->lookups_by_id); + avahi_hashmap_free(e->lookups_by_key); + +- if (e->watch_ipv4) +- e->server->poll_api->watch_free(e->watch_ipv4); +- +- if (e->watch_ipv6) +- e->server->poll_api->watch_free(e->watch_ipv6); +- +- if (e->fd_ipv6 >= 0) +- close(e->fd_ipv6); +- +- if (e->fd_ipv4 >= 0) +- close(e->fd_ipv4); +- + avahi_free(e); + } + +@@ -680,7 +690,7 @@ void avahi_wide_area_set_servers(AvahiWideAreaLookupEngine *e, const AvahiAddres + + if (a) { + for (e->n_dns_servers = 0; n > 0 && e->n_dns_servers < AVAHI_WIDE_AREA_SERVERS_MAX; a++, n--) +- if ((a->proto == AVAHI_PROTO_INET && e->fd_ipv4 >= 0) || (a->proto == AVAHI_PROTO_INET6 && e->fd_ipv6 >= 0)) ++ if (a->proto == AVAHI_PROTO_INET || a->proto == AVAHI_PROTO_INET6) + e->dns_servers[e->n_dns_servers++] = *a; + } else { + assert(n == 0); +-- +2.49.0 + diff --git a/avahi.spec b/avahi.spec index 068e168..b883f6d 100644 --- a/avahi.spec +++ b/avahi.spec @@ -48,7 +48,7 @@ Name: avahi Version: 0.8 -Release: 22%{?dist} +Release: 23%{?dist} Summary: Local network service discovery License: LGPLv2+ URL: http://avahi.org @@ -145,6 +145,8 @@ Patch21: 0001-core-reject-overly-long-TXT-resource-records.patch Patch22: 0001-avahi-client-fix-resource-leak.patch Patch23: 0001-avahi-core-rearrange-deallocations-in-avahi_time_eve.patch Patch24: 0001-Properly-randomize-query-id-of-DNS-packets.patch +Patch25: 0001-core-wide-area-fix-for-CVE-2024-52615.patch +Patch26: 0001-Make-data-member-as-big-as-IPv6-address.patch ## downstream patches Patch100: avahi-0.6.30-mono-libdir.patch @@ -840,6 +842,9 @@ exit 0 %changelog +* Wed Jul 09 2025 Michal Sekletar - 0.8-23 +- Fix CVE-2024-52615 (RHEL-94846) + * Mon Jan 06 2025 Michal Sekletar - 0.8-22 - Fix CVE-2024-52616 (RHEL-67722)