dnsmasq: version 2.90
Bump to 2.90 to get upstream's fix for DNSSEC KeyTrap (CVE-2023-50387, CVE-2023-50868) among many other goodies and fixes (notably, upstream 568fb024... fixes a UAF in cache_remove_uid that was routinely crashing dnsmasq in my deployment). Catch up our 200-ubus_dns.patch, too. Signed-off-by: Nathaniel Wesley Filardo <nwfilardo@gmail.com>
This commit is contained in:
		 Nathaniel Wesley Filardo
					Nathaniel Wesley Filardo
				
			
				
					committed by
					
						 Robert Marko
						Robert Marko
					
				
			
			
				
	
			
			
			 Robert Marko
						Robert Marko
					
				
			
						parent
						
							3561015efd
						
					
				
				
					commit
					838a27f64f
				
			| @@ -8,13 +8,13 @@ | |||||||
| include $(TOPDIR)/rules.mk | include $(TOPDIR)/rules.mk | ||||||
|  |  | ||||||
| PKG_NAME:=dnsmasq | PKG_NAME:=dnsmasq | ||||||
| PKG_UPSTREAM_VERSION:=2.89 | PKG_UPSTREAM_VERSION:=2.90 | ||||||
| PKG_VERSION:=$(subst test,~~test,$(subst rc,~rc,$(PKG_UPSTREAM_VERSION))) | PKG_VERSION:=$(subst test,~~test,$(subst rc,~rc,$(PKG_UPSTREAM_VERSION))) | ||||||
| PKG_RELEASE:=8 | PKG_RELEASE:=8 | ||||||
|  |  | ||||||
| PKG_SOURCE:=$(PKG_NAME)-$(PKG_UPSTREAM_VERSION).tar.xz | PKG_SOURCE:=$(PKG_NAME)-$(PKG_UPSTREAM_VERSION).tar.xz | ||||||
| PKG_SOURCE_URL:=https://thekelleys.org.uk/dnsmasq/ | PKG_SOURCE_URL:=https://thekelleys.org.uk/dnsmasq/ | ||||||
| PKG_HASH:=02bd230346cf0b9d5909f5e151df168b2707103785eb616b56685855adebb609 | PKG_HASH:=8e50309bd837bfec9649a812e066c09b6988b73d749b7d293c06c57d46a109e4 | ||||||
|  |  | ||||||
| PKG_LICENSE:=GPL-2.0 | PKG_LICENSE:=GPL-2.0 | ||||||
| PKG_LICENSE_FILES:=COPYING | PKG_LICENSE_FILES:=COPYING | ||||||
|   | |||||||
| @@ -1,6 +1,23 @@ | |||||||
|  | diff --git a/src/dnsmasq.c b/src/dnsmasq.c | ||||||
|  | index 30fb419..776351a 100644 | ||||||
|  | --- a/src/dnsmasq.c | ||||||
|  | +++ b/src/dnsmasq.c | ||||||
|  | @@ -2025,6 +2025,10 @@ static void check_dns_listeners(time_t now) | ||||||
|  |  		  daemon->pipe_to_parent = pipefd[1]; | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  | +#ifdef HAVE_UBUS | ||||||
|  | +	      drop_ubus_listeners(); | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  	      /* start with no upstream connections. */ | ||||||
|  |  	      for (s = daemon->servers; s; s = s->next) | ||||||
|  |  		 s->tcpfd = -1;  | ||||||
|  | diff --git a/src/dnsmasq.h b/src/dnsmasq.h | ||||||
|  | index e455c3f..c84ba48 100644 | ||||||
| --- a/src/dnsmasq.h | --- a/src/dnsmasq.h | ||||||
| +++ b/src/dnsmasq.h | +++ b/src/dnsmasq.h | ||||||
| @@ -1631,14 +1631,26 @@ void emit_dbus_signal(int action, struct | @@ -1673,14 +1673,26 @@ void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname); | ||||||
|   |   | ||||||
|  /* ubus.c */ |  /* ubus.c */ | ||||||
|  #ifdef HAVE_UBUS |  #ifdef HAVE_UBUS | ||||||
| @@ -11,6 +28,7 @@ | |||||||
|  void set_ubus_listeners(void); |  void set_ubus_listeners(void); | ||||||
|  void check_ubus_listeners(void); |  void check_ubus_listeners(void); | ||||||
| +void drop_ubus_listeners(void); | +void drop_ubus_listeners(void); | ||||||
|  | +int ubus_dns_notify_has_subscribers(void); | ||||||
| +struct blob_buf *ubus_dns_notify_prepare(void); | +struct blob_buf *ubus_dns_notify_prepare(void); | ||||||
| +int ubus_dns_notify(const char *type, ubus_dns_notify_cb cb, void *priv); | +int ubus_dns_notify(const char *type, ubus_dns_notify_cb cb, void *priv); | ||||||
|  void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface); |  void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface); | ||||||
| @@ -19,14 +37,28 @@ | |||||||
|  void ubus_event_bcast_connmark_allowlist_resolved(u32 mark, const char *pattern, const char *ip, u32 ttl); |  void ubus_event_bcast_connmark_allowlist_resolved(u32 mark, const char *pattern, const char *ip, u32 ttl); | ||||||
|  #  endif |  #  endif | ||||||
| +#else | +#else | ||||||
| +struct blob_buf; | +static inline int ubus_dns_notify_has_subscribers(void) | ||||||
| +static inline struct blob_buf *ubus_dns_notify_prepare(void) |  | ||||||
| +{ | +{ | ||||||
| +	return NULL; | +	return 0; | ||||||
| +} | +} | ||||||
|  #endif |  #endif | ||||||
|   |   | ||||||
|  /* ipset.c */ |  /* ipset.c */ | ||||||
|  | diff --git a/src/forward.c b/src/forward.c | ||||||
|  | index 32f37e4..3d28963 100644 | ||||||
|  | --- a/src/forward.c | ||||||
|  | +++ b/src/forward.c | ||||||
|  | @@ -803,7 +803,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server | ||||||
|  |  	  cache_secure = 0; | ||||||
|  |  	} | ||||||
|  |         | ||||||
|  | -      if (daemon->doctors && do_doctor(header, n, daemon->namebuff)) | ||||||
|  | +      if ((daemon->doctors || ubus_dns_notify_has_subscribers()) && do_doctor(header, n, daemon->namebuff)) | ||||||
|  |  	cache_secure = 0; | ||||||
|  |         | ||||||
|  |        /* check_for_bogus_wildcard() does it's own caching, so | ||||||
|  | diff --git a/src/rfc1035.c b/src/rfc1035.c | ||||||
|  | index 387d894..7bf7967 100644 | ||||||
| --- a/src/rfc1035.c | --- a/src/rfc1035.c | ||||||
| +++ b/src/rfc1035.c | +++ b/src/rfc1035.c | ||||||
| @@ -13,8 +13,10 @@ | @@ -13,8 +13,10 @@ | ||||||
| @@ -41,7 +73,7 @@ | |||||||
|   |   | ||||||
|  int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,  |  int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,  | ||||||
|  		 char *name, int isExtract, int extrabytes) |  		 char *name, int isExtract, int extrabytes) | ||||||
| @@ -394,9 +396,64 @@ static int private_net6(struct in6_addr | @@ -384,10 +386,65 @@ static int private_net6(struct in6_addr *a, int ban_localhost) | ||||||
|      ((u32 *)a)[0] == htonl(0x20010db8); /* RFC 6303 4.6 */ |      ((u32 *)a)[0] == htonl(0x20010db8); /* RFC 6303 4.6 */ | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -100,14 +132,15 @@ | |||||||
| +} | +} | ||||||
| +#endif | +#endif | ||||||
| + | + | ||||||
|  static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *header, size_t qlen, int *doctored) |  int do_doctor(struct dns_header *header, size_t qlen, char *namebuff) | ||||||
|  { |  { | ||||||
|  |    unsigned char *p; | ||||||
| -  int i, qtype, qclass, rdlen; | -  int i, qtype, qclass, rdlen; | ||||||
| +  int i, qtype, qclass, rdlen, ttl; | +  int i, qtype, qclass, rdlen, ttl; | ||||||
|  |    int done = 0; | ||||||
|     |     | ||||||
|    for (i = count; i != 0; i--) |    if (!(p = skip_questions(header, qlen))) | ||||||
|      { | @@ -404,7 +461,7 @@ int do_doctor(struct dns_header *header, size_t qlen, char *namebuff) | ||||||
| @@ -405,7 +462,7 @@ static unsigned char *do_doctor(unsigned |  | ||||||
|         |         | ||||||
|        GETSHORT(qtype, p);  |        GETSHORT(qtype, p);  | ||||||
|        GETSHORT(qclass, p); |        GETSHORT(qclass, p); | ||||||
| @@ -116,53 +149,36 @@ | |||||||
|        GETSHORT(rdlen, p); |        GETSHORT(rdlen, p); | ||||||
|         |         | ||||||
|        if (qclass == C_IN && qtype == T_A) |        if (qclass == C_IN && qtype == T_A) | ||||||
| @@ -416,6 +473,9 @@ static unsigned char *do_doctor(unsigned | @@ -415,6 +472,9 @@ int do_doctor(struct dns_header *header, size_t qlen, char *namebuff) | ||||||
|  	  if (!CHECK_LEN(header, p, qlen, INADDRSZ)) |  	  if (!CHECK_LEN(header, p, qlen, INADDRSZ)) | ||||||
|  	    return 0; |  	    return done; | ||||||
|  	   |  	   | ||||||
| +	  if (ubus_dns_doctor(daemon->namebuff, ttl, p, AF_INET)) | +	  if (ubus_dns_doctor(daemon->namebuff, ttl, p, AF_INET)) | ||||||
| +	    *doctored = 1; | +	    header->hb3 &= ~HB3_AA; | ||||||
| + | + | ||||||
|  	  /* alignment */ |  	  /* alignment */ | ||||||
|  	  memcpy(&addr, p, INADDRSZ); |  	  memcpy(&addr.addr4, p, INADDRSZ); | ||||||
|  	   |  	   | ||||||
| @@ -433,13 +493,22 @@ static unsigned char *do_doctor(unsigned | @@ -444,6 +504,14 @@ int do_doctor(struct dns_header *header, size_t qlen, char *namebuff) | ||||||
|  	      addr.s_addr &= ~doctor->mask.s_addr; |  | ||||||
|  	      addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr); |  | ||||||
|  	      /* Since we munged the data, the server it came from is no longer authoritative */ |  | ||||||
| -	      header->hb3 &= ~HB3_AA; |  | ||||||
|  	      *doctored = 1; |  | ||||||
|  	      memcpy(p, &addr, INADDRSZ); |  | ||||||
|  	      break; |  	      break; | ||||||
|  	    } |  	    } | ||||||
|  	} |  	} | ||||||
| -       |  | ||||||
| +      else if (qclass == C_IN && qtype == T_AAAA) | +      else if (qclass == C_IN && qtype == T_AAAA) | ||||||
| +        { | +        { | ||||||
| +	  if (!CHECK_LEN(header, p, qlen, IN6ADDRSZ)) | +	  if (!CHECK_LEN(header, p, qlen, IN6ADDRSZ)) | ||||||
| +	    return 0; | +	    return 0; | ||||||
| + | + | ||||||
| +	  if (ubus_dns_doctor(daemon->namebuff, ttl, p, AF_INET6)) | +	  if (ubus_dns_doctor(daemon->namebuff, ttl, p, AF_INET6)) | ||||||
| +	    *doctored = 1; |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
| +      if (*doctored) |  | ||||||
| +	    header->hb3 &= ~HB3_AA; | +	    header->hb3 &= ~HB3_AA; | ||||||
|        if (!ADD_RDLEN(header, p, qlen, rdlen)) | +	} | ||||||
|  	 return 0; /* bad packet */ |  | ||||||
|      } |  | ||||||
| @@ -570,7 +639,7 @@ int extract_addresses(struct dns_header |  | ||||||
|    cache_start_insert(); |  | ||||||
|         |         | ||||||
|    /* find_soa is needed for dns_doctor side effects, so don't call it lazily if there are any. */ |        if (!ADD_RDLEN(header, p, qlen, rdlen)) | ||||||
| -  if (daemon->doctors || option_bool(OPT_DNSSEC_VALID)) |  	 return done; /* bad packet */ | ||||||
| +  if (daemon->doctors || option_bool(OPT_DNSSEC_VALID) || ubus_dns_notify_prepare()) | diff --git a/src/ubus.c b/src/ubus.c | ||||||
|      { | index a5758e7..f2a75a8 100644 | ||||||
|        searched_soa = 1; |  | ||||||
|        ttl = find_soa(header, qlen, doctored); |  | ||||||
| --- a/src/ubus.c | --- a/src/ubus.c | ||||||
| +++ b/src/ubus.c | +++ b/src/ubus.c | ||||||
| @@ -72,6 +72,13 @@ static struct ubus_object ubus_object = | @@ -72,6 +72,13 @@ static struct ubus_object ubus_object = { | ||||||
|    .subscribe_cb = ubus_subscribe_cb, |    .subscribe_cb = ubus_subscribe_cb, | ||||||
|  }; |  }; | ||||||
|   |   | ||||||
| @@ -176,7 +192,7 @@ | |||||||
|  static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj) |  static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj) | ||||||
|  { |  { | ||||||
|    (void)ctx; |    (void)ctx; | ||||||
| @@ -105,13 +112,21 @@ static void ubus_disconnect_cb(struct ub | @@ -105,13 +112,21 @@ static void ubus_disconnect_cb(struct ubus_context *ubus) | ||||||
|  char *ubus_init() |  char *ubus_init() | ||||||
|  { |  { | ||||||
|    struct ubus_context *ubus = NULL; |    struct ubus_context *ubus = NULL; | ||||||
| @@ -216,15 +232,18 @@ | |||||||
|  static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj, |  static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj, | ||||||
|  			       struct ubus_request_data *req, const char *method, |  			       struct ubus_request_data *req, const char *method, | ||||||
|  			       struct blob_attr *msg) |  			       struct blob_attr *msg) | ||||||
| @@ -328,6 +354,50 @@ fail: | @@ -328,6 +354,53 @@ fail: | ||||||
|        } \ |        } \ | ||||||
|    } while (0) |    } while (0) | ||||||
|   |   | ||||||
|  | +int ubus_dns_notify_has_subscribers(void) | ||||||
|  | +{ | ||||||
|  | +	return (daemon->ubus && ubus_dns_object.has_subscribers); | ||||||
|  | +} | ||||||
|  | + | ||||||
| +struct blob_buf *ubus_dns_notify_prepare(void) | +struct blob_buf *ubus_dns_notify_prepare(void) | ||||||
| +{ | +{ | ||||||
| +  struct ubus_context *ubus = (struct ubus_context *)daemon->ubus; | +	if (!ubus_dns_notify_has_subscribers()) | ||||||
| + |  | ||||||
| +	if (!ubus || !ubus_dns_object.has_subscribers) |  | ||||||
| +		return NULL; | +		return NULL; | ||||||
| + | + | ||||||
| +	blob_buf_init(&b, 0); | +	blob_buf_init(&b, 0); | ||||||
| @@ -267,16 +286,3 @@ | |||||||
|  void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface) |  void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface) | ||||||
|  { |  { | ||||||
|    struct ubus_context *ubus = (struct ubus_context *)daemon->ubus; |    struct ubus_context *ubus = (struct ubus_context *)daemon->ubus; | ||||||
| --- a/src/dnsmasq.c |  | ||||||
| +++ b/src/dnsmasq.c |  | ||||||
| @@ -2003,6 +2003,10 @@ static void check_dns_listeners(time_t n |  | ||||||
|  		  daemon->pipe_to_parent = pipefd[1]; |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
| +#ifdef HAVE_UBUS |  | ||||||
| +	      drop_ubus_listeners(); |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
|  	      /* start with no upstream connections. */ |  | ||||||
|  	      for (s = daemon->servers; s; s = s->next) |  | ||||||
|  		 s->tcpfd = -1;  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user