From f8710bdc8b29ee1176fe3bfaeabebbda1b7a79f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= Date: Mon, 11 Nov 2024 00:56:09 +0100 Subject: [PATCH] Properly randomize query id of DNS packets --- avahi-core/wide-area.c | 36 ++++++++++++++++++++++++++++-------- configure.ac | 3 ++- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/avahi-core/wide-area.c b/avahi-core/wide-area.c index 971f5e7..00a1505 100644 --- a/avahi-core/wide-area.c +++ b/avahi-core/wide-area.c @@ -40,6 +40,13 @@ #include "addr-util.h" #include "rr-util.h" +#ifdef HAVE_SYS_RANDOM_H +#include +#endif +#ifndef HAVE_GETRANDOM +# define getrandom(d, len, flags) (-1) +#endif + #define CACHE_ENTRIES_MAX 500 typedef struct AvahiWideAreaCacheEntry AvahiWideAreaCacheEntry; @@ -84,8 +91,6 @@ struct AvahiWideAreaLookupEngine { int fd_ipv4, fd_ipv6; AvahiWatch *watch_ipv4, *watch_ipv6; - uint16_t next_id; - /* Cache */ AVAHI_LLIST_HEAD(AvahiWideAreaCacheEntry, cache); AvahiHashmap *cache_by_key; @@ -201,6 +206,26 @@ static void sender_timeout_callback(AvahiTimeEvent *e, void *userdata) { avahi_time_event_update(e, avahi_elapse_time(&tv, 1000, 0)); } +static uint16_t get_random_uint16(void) { + uint16_t next_id; + + if (getrandom(&next_id, sizeof(next_id), 0) == -1) + next_id = (uint16_t) rand(); + return next_id; +} + +static uint16_t avahi_wide_area_next_id(AvahiWideAreaLookupEngine *e) { + uint16_t next_id; + + next_id = get_random_uint16(); + while (find_lookup(e, next_id)) { + /* This ID is already used, get new. */ + next_id = get_random_uint16(); + } + return next_id; +} + + AvahiWideAreaLookup *avahi_wide_area_lookup_new( AvahiWideAreaLookupEngine *e, AvahiKey *key, @@ -227,11 +252,7 @@ AvahiWideAreaLookup *avahi_wide_area_lookup_new( /* If more than 65K wide area quries are issued simultaneously, * this will break. This should be limited by some higher level */ - for (;; e->next_id++) - if (!find_lookup(e, e->next_id)) - break; /* This ID is not yet used. */ - - l->id = e->next_id++; + l->id = avahi_wide_area_next_id(e); /* We keep the packet around in case we need to repeat our query */ l->packet = avahi_dns_packet_new(0); @@ -604,7 +625,6 @@ AvahiWideAreaLookupEngine *avahi_wide_area_engine_new(AvahiServer *s) { 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; - e->next_id = (uint16_t) rand(); /* Initialize cache */ AVAHI_LLIST_HEAD_INIT(AvahiWideAreaCacheEntry, e->cache); diff --git a/configure.ac b/configure.ac index a3211b8..31bce3d 100644 --- a/configure.ac +++ b/configure.ac @@ -367,7 +367,8 @@ AC_FUNC_SELECT_ARGTYPES # whether libc's malloc does too. (Same for realloc.) #AC_FUNC_MALLOC #AC_FUNC_REALLOC -AC_CHECK_FUNCS([gethostname memchr memmove memset mkdir select socket strchr strcspn strdup strerror strrchr strspn strstr uname setresuid setreuid setresgid setregid strcasecmp gettimeofday putenv strncasecmp strlcpy gethostbyname seteuid setegid setproctitle getprogname]) +AC_CHECK_FUNCS([gethostname memchr memmove memset mkdir select socket strchr strcspn strdup strerror strrchr strspn strstr uname setresuid setreuid setresgid setregid strcasecmp gettimeofday putenv strncasecmp strlcpy gethostbyname seteuid setegid setproctitle getprogname getrandom]) +AC_CHECK_HEADERS([sys/random.h]) AC_FUNC_CHOWN AC_FUNC_STAT -- 2.44.0