Compare commits
10 Commits
581547dd10
...
82d10ec565
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82d10ec565 | ||
|
|
c7d1ca9d80 | ||
|
|
65e08b50f9 | ||
|
|
ee3064f5b9 | ||
|
|
a7ddf12e8e | ||
|
|
3ce4ec9926 | ||
|
|
f17935f74f | ||
|
|
c99587841c | ||
|
|
05af015a7e | ||
|
|
9fcb57dd53 |
28
backport-001-CVE-2024-43168.patch
Normal file
28
backport-001-CVE-2024-43168.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 193401e7543a1e561dd634a3eaae932fa462a2b9 Mon Sep 17 00:00:00 2001
|
||||
From: zhailiangliang <zhailiangliang@loongson.cn>
|
||||
Date: Wed, 3 Apr 2024 15:40:58 +0800
|
||||
Subject: [PATCH] fix heap-buffer-overflow issue in function cfg_mark_ports of
|
||||
file util/config_file.c
|
||||
|
||||
---
|
||||
util/config_file.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/util/config_file.c b/util/config_file.c
|
||||
index 26185da0..e7b2f195 100644
|
||||
--- a/util/config_file.c
|
||||
+++ b/util/config_file.c
|
||||
@@ -1761,6 +1761,10 @@ cfg_mark_ports(const char* str, int allow, int* avail, int num)
|
||||
#endif
|
||||
if(!mid) {
|
||||
int port = atoi(str);
|
||||
+ if(port < 0) {
|
||||
+ log_err("Prevent out-of-bounds access to array avail");
|
||||
+ return 0;
|
||||
+ }
|
||||
if(port == 0 && strcmp(str, "0") != 0) {
|
||||
log_err("cannot parse port number '%s'", str);
|
||||
return 0;
|
||||
--
|
||||
2.33.0
|
||||
|
||||
56
backport-002-CVE-2024-43168.patch
Normal file
56
backport-002-CVE-2024-43168.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From dfff8d23cf4145c58e5c1e99d4159d3a91a70ab7 Mon Sep 17 00:00:00 2001
|
||||
From: "W.C.A. Wijngaards" <wouter@nlnetlabs.nl>
|
||||
Date: Wed, 3 Apr 2024 10:16:18 +0200
|
||||
Subject: [PATCH] - For #1040: adjust error text and disallow negative ports in
|
||||
other parts of cfg_mark_ports.
|
||||
|
||||
---
|
||||
util/config_file.c | 14 +++++++++++++-
|
||||
1 files changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/util/config_file.c b/util/config_file.c
|
||||
index e7b2f195..74554286 100644
|
||||
--- a/util/config_file.c
|
||||
+++ b/util/config_file.c
|
||||
@@ -1762,7 +1762,7 @@ cfg_mark_ports(const char* str, int allow, int* avail, int num)
|
||||
if(!mid) {
|
||||
int port = atoi(str);
|
||||
if(port < 0) {
|
||||
- log_err("Prevent out-of-bounds access to array avail");
|
||||
+ log_err("port number is negative: %d", port);
|
||||
return 0;
|
||||
}
|
||||
if(port == 0 && strcmp(str, "0") != 0) {
|
||||
@@ -1774,6 +1774,10 @@ cfg_mark_ports(const char* str, int allow, int* avail, int num)
|
||||
} else {
|
||||
int i, low, high = atoi(mid+1);
|
||||
char buf[16];
|
||||
+ if(high < 0) {
|
||||
+ log_err("port number is negative: %d", high);
|
||||
+ return 0;
|
||||
+ }
|
||||
if(high == 0 && strcmp(mid+1, "0") != 0) {
|
||||
log_err("cannot parse port number '%s'", mid+1);
|
||||
return 0;
|
||||
@@ -1786,10 +1790,18 @@ cfg_mark_ports(const char* str, int allow, int* avail, int num)
|
||||
memcpy(buf, str, (size_t)(mid-str));
|
||||
buf[mid-str] = 0;
|
||||
low = atoi(buf);
|
||||
+ if(low < 0) {
|
||||
+ log_err("port number is negative: %d", low);
|
||||
+ return 0;
|
||||
+ }
|
||||
if(low == 0 && strcmp(buf, "0") != 0) {
|
||||
log_err("cannot parse port number '%s'", buf);
|
||||
return 0;
|
||||
}
|
||||
+ if(high > num) {
|
||||
+ /* Stop very high values from taking a long time. */
|
||||
+ high = num;
|
||||
+ }
|
||||
for(i=low; i<=high; i++) {
|
||||
if(i < num)
|
||||
avail[i] = (allow?i:0);
|
||||
--
|
||||
2.33.0
|
||||
|
||||
135
backport-003-CVE-2024-43168.patch
Normal file
135
backport-003-CVE-2024-43168.patch
Normal file
@ -0,0 +1,135 @@
|
||||
From 4497e8a154f53cd5947a6ee5aa65cf99be57152e Mon Sep 17 00:00:00 2001
|
||||
From: zhailiangliang <zhailiangliang@loongson.cn>
|
||||
Date: Tue, 7 May 2024 11:35:52 +0000
|
||||
Subject: [PATCH] Fix potential overflow bug while parsing port in function
|
||||
cfg_mark_ports
|
||||
|
||||
---
|
||||
util/config_file.c | 76 ++++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 50 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/util/config_file.c b/util/config_file.c
|
||||
index 2b67d4c1..4a3b7d77 100644
|
||||
--- a/util/config_file.c
|
||||
+++ b/util/config_file.c
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "config.h"
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
+#include <errno.h>
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
@@ -1772,6 +1773,38 @@ init_outgoing_availports(int* a, int num)
|
||||
}
|
||||
}
|
||||
|
||||
+static int
|
||||
+extract_port_from_str(const char* str, int max_port) {
|
||||
+ char* endptr;
|
||||
+ if (str == NULL || *str == '\0') {
|
||||
+ log_err("str: '%s' is invalid", str);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ long int value = strtol(str, &endptr, 10);
|
||||
+ if ((endptr == str) || (*endptr != '\0')) {
|
||||
+ log_err("cannot parse port number '%s'", str);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (errno == ERANGE) {
|
||||
+ log_err("overflow occurred when parsing '%s'", str);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (value == 0 && strcmp(str, "0") != 0) {
|
||||
+ log_err("cannot parse port number '%s'", str);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (value < 0 || value >= max_port) {
|
||||
+ log_err(" '%s' is out of bounds [0, %d)", str, max_port);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return (int)value;
|
||||
+}
|
||||
+
|
||||
int
|
||||
cfg_mark_ports(const char* str, int allow, int* avail, int num)
|
||||
{
|
||||
@@ -1782,53 +1815,44 @@ cfg_mark_ports(const char* str, int allow, int* avail, int num)
|
||||
"options");
|
||||
#endif
|
||||
if(!mid) {
|
||||
- int port = atoi(str);
|
||||
- if(port < 0) {
|
||||
- log_err("port number is negative: %d", port);
|
||||
+ int port = extract_port_from_str(str, num);
|
||||
+ if (port < 0) {
|
||||
+ log_err("Failed to parse the port number");
|
||||
return 0;
|
||||
}
|
||||
- if(port == 0 && strcmp(str, "0") != 0) {
|
||||
- log_err("cannot parse port number '%s'", str);
|
||||
- return 0;
|
||||
- }
|
||||
- if(port < num)
|
||||
- avail[port] = (allow?port:0);
|
||||
+ avail[port] = (allow?port:0);
|
||||
} else {
|
||||
- int i, low, high = atoi(mid+1);
|
||||
char buf[16];
|
||||
- if(high < 0) {
|
||||
- log_err("port number is negative: %d", high);
|
||||
- return 0;
|
||||
- }
|
||||
- if(high == 0 && strcmp(mid+1, "0") != 0) {
|
||||
- log_err("cannot parse port number '%s'", mid+1);
|
||||
+ int i, low;
|
||||
+ int high = extract_port_from_str(mid+1, num);
|
||||
+ if (high < 0) {
|
||||
+ log_err("Failed to parse the port number");
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
if( (int)(mid-str)+1 >= (int)sizeof(buf) ) {
|
||||
log_err("cannot parse port number '%s'", str);
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
if(mid > str)
|
||||
memcpy(buf, str, (size_t)(mid-str));
|
||||
buf[mid-str] = 0;
|
||||
- low = atoi(buf);
|
||||
- if(low < 0) {
|
||||
- log_err("port number is negative: %d", low);
|
||||
+ low = extract_port_from_str(buf, num);
|
||||
+ if (low < 0) {
|
||||
+ log_err("Failed to parse the port number");
|
||||
return 0;
|
||||
}
|
||||
- if(low == 0 && strcmp(buf, "0") != 0) {
|
||||
- log_err("cannot parse port number '%s'", buf);
|
||||
+
|
||||
+ if (low > high) {
|
||||
+ log_err("Low value is greater than high value");
|
||||
return 0;
|
||||
}
|
||||
- if(high > num) {
|
||||
- /* Stop very high values from taking a long time. */
|
||||
- high = num;
|
||||
- }
|
||||
+
|
||||
for(i=low; i<=high; i++) {
|
||||
if(i < num)
|
||||
avail[i] = (allow?i:0);
|
||||
}
|
||||
- return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
44
backport-004-CVE-2024-43168.patch
Normal file
44
backport-004-CVE-2024-43168.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From c085a53268940dfbb907cbaa7a690740b6c8210c Mon Sep 17 00:00:00 2001
|
||||
From: "W.C.A. Wijngaards" <wouter@nlnetlabs.nl>
|
||||
Date: Tue, 7 May 2024 14:05:21 +0200
|
||||
Subject: [PATCH] - Fix for #1062: declaration before statement, avoid print of
|
||||
null, and redundant check for array size. And changelog note for merge of
|
||||
#1062.
|
||||
|
||||
---
|
||||
util/config_file.c | 8 +++++---
|
||||
1 files changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/util/config_file.c b/util/config_file.c
|
||||
index 4a3b7d77..2ac6c468 100644
|
||||
--- a/util/config_file.c
|
||||
+++ b/util/config_file.c
|
||||
@@ -1776,12 +1776,13 @@ init_outgoing_availports(int* a, int num)
|
||||
static int
|
||||
extract_port_from_str(const char* str, int max_port) {
|
||||
char* endptr;
|
||||
+ long int value;
|
||||
if (str == NULL || *str == '\0') {
|
||||
- log_err("str: '%s' is invalid", str);
|
||||
+ log_err("str: '%s' is invalid", (str?str:"NULL"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
- long int value = strtol(str, &endptr, 10);
|
||||
+ value = strtol(str, &endptr, 10);
|
||||
if ((endptr == str) || (*endptr != '\0')) {
|
||||
log_err("cannot parse port number '%s'", str);
|
||||
return -1;
|
||||
@@ -1820,7 +1821,8 @@ cfg_mark_ports(const char* str, int allow, int* avail, int num)
|
||||
log_err("Failed to parse the port number");
|
||||
return 0;
|
||||
}
|
||||
- avail[port] = (allow?port:0);
|
||||
+ if(port < num)
|
||||
+ avail[port] = (allow?port:0);
|
||||
} else {
|
||||
char buf[16];
|
||||
int i, low;
|
||||
--
|
||||
2.33.0
|
||||
|
||||
717
backport-CVE-2024-33655.patch
Normal file
717
backport-CVE-2024-33655.patch
Normal file
@ -0,0 +1,717 @@
|
||||
From c3206f4568f60c486be6d165b1f2b5b254fea3de Mon Sep 17 00:00:00 2001
|
||||
From: "W.C.A. Wijngaards" <wouter@nlnetlabs.nl>
|
||||
Date: Wed, 1 May 2024 10:10:58 +0200
|
||||
Subject: [PATCH] - Fix for the DNSBomb vulnerability CVE-2024-33655. Thanks to
|
||||
Xiang Li from the Network and Information Security Lab of Tsinghua
|
||||
University for reporting it.
|
||||
|
||||
debian:https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/unbound/1.13.1-1ubuntu5.5/unbound_1.13.1-1ubuntu5.5.debian.tar.xz
|
||||
Conflict:NA
|
||||
Reference:https://github.com/NLnetLabs/unbound/commit/c3206f4568f60c486be6d165b1f2b5b254fea3de
|
||||
---
|
||||
doc/Changelog | 5 +
|
||||
doc/example.conf.in | 15 ++
|
||||
doc/unbound.conf.5.in | 30 ++++
|
||||
services/cache/infra.c | 170 +++++++++++++++++-
|
||||
services/cache/infra.h | 28 +++
|
||||
services/mesh.c | 65 +++++++
|
||||
testdata/cachedb_expired_client_timeout.crpl | 1 +
|
||||
testdata/cachedb_subnet_expired.crpl | 1 +
|
||||
.../doh_downstream.tdir/doh_downstream.conf | 1 +
|
||||
.../doh_downstream_notls.conf | 1 +
|
||||
.../doh_downstream_post.conf | 1 +
|
||||
.../fwd_three_service.conf | 1 +
|
||||
testdata/iter_ghost_timewindow.rpl | 1 +
|
||||
.../ssl_req_order.tdir/ssl_req_order.conf | 1 +
|
||||
.../tcp_req_order.tdir/tcp_req_order.conf | 1 +
|
||||
testdata/tcp_sigpipe.tdir/tcp_sigpipe.conf | 3 +-
|
||||
util/config_file.c | 15 ++
|
||||
util/config_file.h | 15 ++
|
||||
util/configlexer.lex | 5 +
|
||||
util/configparser.y | 55 ++++++
|
||||
20 files changed, 412 insertions(+), 3 deletions(-)
|
||||
|
||||
#diff --git a/doc/Changelog b/doc/Changelog
|
||||
#index dab04633d..24fbb42c7 100644
|
||||
#--- a/doc/Changelog
|
||||
#+++ b/doc/Changelog
|
||||
#@@ -1,3 +1,8 @@
|
||||
#+1 May 2024: Wouter
|
||||
#+ - Fix for the DNSBomb vulnerability CVE-2024-33655. Thanks to Xiang Li
|
||||
#+ from the Network and Information Security Lab of Tsinghua University
|
||||
#+ for reporting it.
|
||||
#+
|
||||
# 29 April 2024: Yorgos
|
||||
# - Cleanup unnecessary strdup calls for EDE strings.
|
||||
#
|
||||
--- a/doc/example.conf.in
|
||||
+++ b/doc/example.conf.in
|
||||
@@ -168,6 +168,15 @@ server:
|
||||
# are behind a slow satellite link, to eg. 1128.
|
||||
# unknown-server-time-limit: 376
|
||||
|
||||
+ # msec before recursion replies are dropped. The work item continues.
|
||||
+ # discard-timeout: 1900
|
||||
+
|
||||
+ # Max number of replies waiting for recursion per IP address.
|
||||
+ # wait-limit: 1000
|
||||
+
|
||||
+ # Apart from the default, the wait limit can be set for a netblock.
|
||||
+ # wait-limit-netblock: 192.0.2.0/24 50000
|
||||
+
|
||||
# the amount of memory to use for the RRset cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# rrset-cache-size: 4m
|
||||
--- a/doc/unbound.conf.5.in
|
||||
+++ b/doc/unbound.conf.5.in
|
||||
@@ -284,6 +284,26 @@ Increase this if you are behind a slow s
|
||||
That would then avoid re\-querying every initial query because it times out.
|
||||
Default is 376 msec.
|
||||
.TP
|
||||
+.B discard\-timeout: \fI<msec>
|
||||
+The wait time in msec where recursion requests are dropped. This is
|
||||
+to stop a large number of replies from accumulating. They receive
|
||||
+no reply, the work item continues to recurse. It is nice to be a bit
|
||||
+larger than serve\-expired\-client\-timeout if that is enabled.
|
||||
+A value of 1900 msec is suggested. The value 0 disables it.
|
||||
+Default 1900 msec.
|
||||
+.TP
|
||||
+.B wait\-limit: \fI<number>
|
||||
+The number of replies that can wait for recursion, for an IP address.
|
||||
+This makes a ratelimit per IP address of waiting replies for recursion.
|
||||
+It stops very large amounts of queries waiting to be returned to one
|
||||
+destination. The value 0 disables wait limits. Default is 1000.
|
||||
+.TP
|
||||
+.B wait\-limit\-netblock: \fI<netblock> <number>
|
||||
+The wait limit for the netblock. If not given the wait\-limit value is
|
||||
+used. The most specific netblock is used to determine the limit. Useful for
|
||||
+overriding the default for a specific, group or individual, server.
|
||||
+The value -1 disables wait limits for the netblock.
|
||||
+.TP
|
||||
.B so\-rcvbuf: \fI<number>
|
||||
If not 0, then set the SO_RCVBUF socket option to get more buffer
|
||||
space on UDP port 53 incoming queries. So that short spikes on busy
|
||||
--- a/services/cache/infra.c
|
||||
+++ b/services/cache/infra.c
|
||||
@@ -229,6 +229,69 @@ setup_domain_limits(struct infra_cache*
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/** find or create element in wait limit netblock tree */
|
||||
+static struct wait_limit_netblock_info*
|
||||
+wait_limit_netblock_findcreate(struct infra_cache* infra, char* str)
|
||||
+{
|
||||
+ rbtree_type* tree;
|
||||
+ struct sockaddr_storage addr;
|
||||
+ int net;
|
||||
+ socklen_t addrlen;
|
||||
+ struct wait_limit_netblock_info* d;
|
||||
+
|
||||
+ if(!netblockstrtoaddr(str, 0, &addr, &addrlen, &net)) {
|
||||
+ log_err("cannot parse wait limit netblock '%s'", str);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* can we find it? */
|
||||
+ tree = &infra->wait_limits_netblock;
|
||||
+ d = (struct wait_limit_netblock_info*)addr_tree_find(tree, &addr,
|
||||
+ addrlen, net);
|
||||
+ if(d)
|
||||
+ return d;
|
||||
+
|
||||
+ /* create it */
|
||||
+ d = (struct wait_limit_netblock_info*)calloc(1, sizeof(*d));
|
||||
+ if(!d)
|
||||
+ return NULL;
|
||||
+ d->limit = -1;
|
||||
+ if(!addr_tree_insert(tree, &d->node, &addr, addrlen, net)) {
|
||||
+ log_err("duplicate element in domainlimit tree");
|
||||
+ free(d);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ return d;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/** insert wait limit information into lookup tree */
|
||||
+static int
|
||||
+infra_wait_limit_netblock_insert(struct infra_cache* infra,
|
||||
+ struct config_file* cfg)
|
||||
+{
|
||||
+ struct config_str2list* p;
|
||||
+ struct wait_limit_netblock_info* d;
|
||||
+ for(p = cfg->wait_limit_netblock; p; p = p->next) {
|
||||
+ d = wait_limit_netblock_findcreate(infra, p->str);
|
||||
+ if(!d)
|
||||
+ return 0;
|
||||
+ d->limit = atoi(p->str2);
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+/** setup wait limits tree (0 on failure) */
|
||||
+static int
|
||||
+setup_wait_limits(struct infra_cache* infra, struct config_file* cfg)
|
||||
+{
|
||||
+ addr_tree_init(&infra->wait_limits_netblock);
|
||||
+ if(!infra_wait_limit_netblock_insert(infra, cfg))
|
||||
+ return 0;
|
||||
+ addr_tree_init_parents(&infra->wait_limits_netblock);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
struct infra_cache*
|
||||
infra_create(struct config_file* cfg)
|
||||
{
|
||||
@@ -259,6 +322,10 @@ infra_create(struct config_file* cfg)
|
||||
infra_delete(infra);
|
||||
return NULL;
|
||||
}
|
||||
+ if(!setup_wait_limits(infra, cfg)) {
|
||||
+ infra_delete(infra);
|
||||
+ return NULL;
|
||||
+ }
|
||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||
infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
|
||||
INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
|
||||
@@ -279,6 +346,12 @@ static void domain_limit_free(rbnode_typ
|
||||
}
|
||||
}
|
||||
|
||||
+/** delete wait_limit_netblock_info entries */
|
||||
+static void wait_limit_netblock_del(rbnode_type* n, void* ATTR_UNUSED(arg))
|
||||
+{
|
||||
+ free(n);
|
||||
+}
|
||||
+
|
||||
void
|
||||
infra_delete(struct infra_cache* infra)
|
||||
{
|
||||
@@ -288,6 +361,8 @@ infra_delete(struct infra_cache* infra)
|
||||
slabhash_delete(infra->domain_rates);
|
||||
traverse_postorder(&infra->domain_limits, domain_limit_free, NULL);
|
||||
slabhash_delete(infra->client_ip_rates);
|
||||
+ traverse_postorder(&infra->wait_limits_netblock,
|
||||
+ wait_limit_netblock_del, NULL);
|
||||
free(infra);
|
||||
}
|
||||
|
||||
@@ -873,7 +948,7 @@ static void infra_create_ratedata(struct
|
||||
|
||||
/** create rate data item for ip address */
|
||||
static void infra_ip_create_ratedata(struct infra_cache* infra,
|
||||
- struct comm_reply* repinfo, time_t timenow)
|
||||
+ struct comm_reply* repinfo, time_t timenow, int mesh_wait)
|
||||
{
|
||||
hashvalue_type h = hash_addr(&(repinfo->addr),
|
||||
repinfo->addrlen, 0);
|
||||
@@ -892,6 +967,7 @@ static void infra_ip_create_ratedata(str
|
||||
k->entry.data = d;
|
||||
d->qps[0] = 1;
|
||||
d->timestamp[0] = timenow;
|
||||
+ d->mesh_wait = mesh_wait;
|
||||
slabhash_insert(infra->client_ip_rates, h, &k->entry, d, NULL);
|
||||
}
|
||||
|
||||
@@ -1070,6 +1146,74 @@ int infra_ip_ratelimit_inc(struct infra_
|
||||
}
|
||||
|
||||
/* create */
|
||||
- infra_ip_create_ratedata(infra, repinfo, timenow);
|
||||
+ infra_ip_create_ratedata(infra, repinfo, timenow, 0);
|
||||
return 1;
|
||||
}
|
||||
+
|
||||
+int infra_wait_limit_allowed(struct infra_cache* infra, struct comm_reply* rep,
|
||||
+ struct config_file* cfg)
|
||||
+{
|
||||
+ struct lruhash_entry* entry;
|
||||
+ if(cfg->wait_limit == 0)
|
||||
+ return 1;
|
||||
+
|
||||
+ entry = infra_find_ip_ratedata(infra, rep, 0);
|
||||
+ if(entry) {
|
||||
+ rbtree_type* tree;
|
||||
+ struct wait_limit_netblock_info* w;
|
||||
+ struct rate_data* d = (struct rate_data*)entry->data;
|
||||
+ int mesh_wait = d->mesh_wait;
|
||||
+ lock_rw_unlock(&entry->lock);
|
||||
+
|
||||
+ /* have the wait amount, check how much is allowed */
|
||||
+ tree = &infra->wait_limits_netblock;
|
||||
+ w = (struct wait_limit_netblock_info*)addr_tree_lookup(tree,
|
||||
+ &rep->addr, rep->addrlen);
|
||||
+ if(w) {
|
||||
+ if(w->limit != -1 && mesh_wait > w->limit)
|
||||
+ return 0;
|
||||
+ } else {
|
||||
+ /* if there is no IP netblock specific information,
|
||||
+ * use the configured value. */
|
||||
+ if(mesh_wait > cfg->wait_limit)
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+void infra_wait_limit_inc(struct infra_cache* infra, struct comm_reply* rep,
|
||||
+ time_t timenow, struct config_file* cfg)
|
||||
+{
|
||||
+ struct lruhash_entry* entry;
|
||||
+ if(cfg->wait_limit == 0)
|
||||
+ return;
|
||||
+
|
||||
+ /* Find it */
|
||||
+ entry = infra_find_ip_ratedata(infra, rep, 1);
|
||||
+ if(entry) {
|
||||
+ struct rate_data* d = (struct rate_data*)entry->data;
|
||||
+ d->mesh_wait++;
|
||||
+ lock_rw_unlock(&entry->lock);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Create it */
|
||||
+ infra_ip_create_ratedata(infra, rep, timenow, 1);
|
||||
+}
|
||||
+
|
||||
+void infra_wait_limit_dec(struct infra_cache* infra, struct comm_reply* rep,
|
||||
+ struct config_file* cfg)
|
||||
+{
|
||||
+ struct lruhash_entry* entry;
|
||||
+ if(cfg->wait_limit == 0)
|
||||
+ return;
|
||||
+
|
||||
+ entry = infra_find_ip_ratedata(infra, rep, 1);
|
||||
+ if(entry) {
|
||||
+ struct rate_data* d = (struct rate_data*)entry->data;
|
||||
+ if(d->mesh_wait > 0)
|
||||
+ d->mesh_wait--;
|
||||
+ lock_rw_unlock(&entry->lock);
|
||||
+ }
|
||||
+}
|
||||
--- a/services/cache/infra.h
|
||||
+++ b/services/cache/infra.h
|
||||
@@ -122,6 +122,8 @@ struct infra_cache {
|
||||
rbtree_type domain_limits;
|
||||
/** hash table with query rates per client ip: ip_rate_key, ip_rate_data */
|
||||
struct slabhash* client_ip_rates;
|
||||
+ /** tree of addr_tree_node, with wait_limit_netblock_info information */
|
||||
+ rbtree_type wait_limits_netblock;
|
||||
};
|
||||
|
||||
/** ratelimit, unless overridden by domain_limits, 0 is off */
|
||||
@@ -182,10 +184,22 @@ struct rate_data {
|
||||
/** what the timestamp is of the qps array members, counter is
|
||||
* valid for that timestamp. Usually now and now-1. */
|
||||
time_t timestamp[RATE_WINDOW];
|
||||
+ /** the number of queries waiting in the mesh */
|
||||
+ int mesh_wait;
|
||||
};
|
||||
|
||||
#define ip_rate_data rate_data
|
||||
|
||||
+/**
|
||||
+ * Data to store the configuration per netblock for the wait limit
|
||||
+ */
|
||||
+struct wait_limit_netblock_info {
|
||||
+ /** The addr tree node, this must be first. */
|
||||
+ struct addr_tree_node node;
|
||||
+ /** the limit on the amount */
|
||||
+ int limit;
|
||||
+};
|
||||
+
|
||||
/** infra host cache default hash lookup size */
|
||||
#define INFRA_HOST_STARTSIZE 32
|
||||
/** bytes per zonename reserved in the hostcache, dnamelen(zonename.com.) */
|
||||
@@ -466,4 +480,16 @@ void ip_rate_delkeyfunc(void* d, void* a
|
||||
/* delete data */
|
||||
#define ip_rate_deldatafunc rate_deldatafunc
|
||||
|
||||
+/** See if the IP address can have another reply in the wait limit */
|
||||
+int infra_wait_limit_allowed(struct infra_cache* infra, struct comm_reply* rep,
|
||||
+ struct config_file* cfg);
|
||||
+
|
||||
+/** Increment number of waiting replies for IP */
|
||||
+void infra_wait_limit_inc(struct infra_cache* infra, struct comm_reply* rep,
|
||||
+ time_t timenow, struct config_file* cfg);
|
||||
+
|
||||
+/** Decrement number of waiting replies for IP */
|
||||
+void infra_wait_limit_dec(struct infra_cache* infra, struct comm_reply* rep,
|
||||
+ struct config_file* cfg);
|
||||
+
|
||||
#endif /* SERVICES_CACHE_INFRA_H */
|
||||
--- a/services/mesh.c
|
||||
+++ b/services/mesh.c
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "services/outbound_list.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "services/cache/rrset.h"
|
||||
+#include "services/cache/infra.h"
|
||||
#include "util/log.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/module.h"
|
||||
@@ -465,6 +466,14 @@ void mesh_new_client(struct mesh_area* m
|
||||
if(rep->c->tcp_req_info) {
|
||||
r_buffer = rep->c->tcp_req_info->spool_buffer;
|
||||
}
|
||||
+ if(!infra_wait_limit_allowed(mesh->env->infra_cache, rep,
|
||||
+ mesh->env->cfg)) {
|
||||
+ verbose(VERB_ALGO, "Too many queries waiting from the IP. "
|
||||
+ "dropping incoming query.");
|
||||
+ comm_point_drop_reply(rep);
|
||||
+ mesh->stats_dropped++;
|
||||
+ return;
|
||||
+ }
|
||||
if(!unique)
|
||||
s = mesh_area_find(mesh, cinfo, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
/* does this create a new reply state? */
|
||||
@@ -559,6 +568,8 @@ void mesh_new_client(struct mesh_area* m
|
||||
log_err("mesh_new_client: out of memory initializing serve expired");
|
||||
goto servfail_mem;
|
||||
}
|
||||
+ infra_wait_limit_inc(mesh->env->infra_cache, rep, *mesh->env->now,
|
||||
+ mesh->env->cfg);
|
||||
/* update statistics */
|
||||
if(was_detached) {
|
||||
log_assert(mesh->num_detached_states > 0);
|
||||
@@ -883,6 +894,8 @@ mesh_state_cleanup(struct mesh_state* ms
|
||||
* takes no time and also it does not do the mesh accounting */
|
||||
mstate->reply_list = NULL;
|
||||
for(; rep; rep=rep->next) {
|
||||
+ infra_wait_limit_dec(mesh->env->infra_cache,
|
||||
+ &rep->query_reply, mesh->env->cfg);
|
||||
comm_point_drop_reply(&rep->query_reply);
|
||||
log_assert(mesh->num_reply_addrs > 0);
|
||||
mesh->num_reply_addrs--;
|
||||
@@ -1300,6 +1313,8 @@ mesh_send_reply(struct mesh_state* m, in
|
||||
comm_point_send_reply(&r->query_reply);
|
||||
m->reply_list = rlist;
|
||||
}
|
||||
+ infra_wait_limit_dec(m->s.env->infra_cache, &r->query_reply,
|
||||
+ m->s.env->cfg);
|
||||
/* account */
|
||||
log_assert(m->s.env->mesh->num_reply_addrs > 0);
|
||||
m->s.env->mesh->num_reply_addrs--;
|
||||
@@ -1353,6 +1368,28 @@ void mesh_query_done(struct mesh_state*
|
||||
}
|
||||
}
|
||||
for(r = mstate->reply_list; r; r = r->next) {
|
||||
+ struct timeval old;
|
||||
+ timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time);
|
||||
+ if(mstate->s.env->cfg->discard_timeout != 0 &&
|
||||
+ ((int)old.tv_sec)*1000+((int)old.tv_usec)/1000 >
|
||||
+ mstate->s.env->cfg->discard_timeout) {
|
||||
+ /* Drop the reply, it is too old */
|
||||
+ /* briefly set the reply_list to NULL, so that the
|
||||
+ * tcp req info cleanup routine that calls the mesh
|
||||
+ * to deregister the meshstate for it is not done
|
||||
+ * because the list is NULL and also accounting is not
|
||||
+ * done there, but instead we do that here. */
|
||||
+ struct mesh_reply* reply_list = mstate->reply_list;
|
||||
+ verbose(VERB_ALGO, "drop reply, it is older than discard-timeout");
|
||||
+ infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
+ &r->query_reply, mstate->s.env->cfg);
|
||||
+ mstate->reply_list = NULL;
|
||||
+ comm_point_drop_reply(&r->query_reply);
|
||||
+ mstate->reply_list = reply_list;
|
||||
+ mstate->s.env->mesh->stats_dropped++;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
tv = r->start_time;
|
||||
|
||||
/* if a response-ip address block has been stored the
|
||||
@@ -1384,6 +1421,8 @@ void mesh_query_done(struct mesh_state*
|
||||
* because the list is NULL and also accounting is not
|
||||
* done there, but instead we do that here. */
|
||||
struct mesh_reply* reply_list = mstate->reply_list;
|
||||
+ infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
+ &r->query_reply, mstate->s.env->cfg);
|
||||
mstate->reply_list = NULL;
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
@@ -1858,6 +1897,8 @@ void mesh_state_remove_reply(struct mesh
|
||||
/* delete it, but allocated in m region */
|
||||
log_assert(mesh->num_reply_addrs > 0);
|
||||
mesh->num_reply_addrs--;
|
||||
+ infra_wait_limit_dec(mesh->env->infra_cache,
|
||||
+ &n->query_reply, mesh->env->cfg);
|
||||
|
||||
/* prev = prev; */
|
||||
n = n->next;
|
||||
@@ -1997,6 +2038,28 @@ mesh_serve_expired_callback(void* arg)
|
||||
log_dns_msg("Serve expired lookup", &qstate->qinfo, msg->rep);
|
||||
|
||||
for(r = mstate->reply_list; r; r = r->next) {
|
||||
+ struct timeval old;
|
||||
+ timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time);
|
||||
+ if(mstate->s.env->cfg->discard_timeout != 0 &&
|
||||
+ ((int)old.tv_sec)*1000+((int)old.tv_usec)/1000 >
|
||||
+ mstate->s.env->cfg->discard_timeout) {
|
||||
+ /* Drop the reply, it is too old */
|
||||
+ /* briefly set the reply_list to NULL, so that the
|
||||
+ * tcp req info cleanup routine that calls the mesh
|
||||
+ * to deregister the meshstate for it is not done
|
||||
+ * because the list is NULL and also accounting is not
|
||||
+ * done there, but instead we do that here. */
|
||||
+ struct mesh_reply* reply_list = mstate->reply_list;
|
||||
+ verbose(VERB_ALGO, "drop reply, it is older than discard-timeout");
|
||||
+ infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
+ &r->query_reply, mstate->s.env->cfg);
|
||||
+ mstate->reply_list = NULL;
|
||||
+ comm_point_drop_reply(&r->query_reply);
|
||||
+ mstate->reply_list = reply_list;
|
||||
+ mstate->s.env->mesh->stats_dropped++;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
tv = r->start_time;
|
||||
|
||||
/* If address info is returned, it means the action should be an
|
||||
@@ -2024,6 +2087,8 @@ mesh_serve_expired_callback(void* arg)
|
||||
r, r_buffer, prev, prev_buffer);
|
||||
if(r->query_reply.c->tcp_req_info)
|
||||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||
+ infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
+ &r->query_reply, mstate->s.env->cfg);
|
||||
prev = r;
|
||||
prev_buffer = r_buffer;
|
||||
|
||||
--- a/testdata/doh_downstream.tdir/doh_downstream.conf
|
||||
+++ b/testdata/doh_downstream.tdir/doh_downstream.conf
|
||||
@@ -11,6 +11,7 @@ server:
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
+ discard-timeout: 3000 # testns uses sleep=2
|
||||
http-query-buffer-size: 1G
|
||||
http-response-buffer-size: 1G
|
||||
http-max-streams: 200
|
||||
--- a/testdata/doh_downstream_notls.tdir/doh_downstream_notls.conf
|
||||
+++ b/testdata/doh_downstream_notls.tdir/doh_downstream_notls.conf
|
||||
@@ -11,6 +11,7 @@ server:
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
+ discard-timeout: 3000 # testns uses sleep=2
|
||||
http-query-buffer-size: 1G
|
||||
http-response-buffer-size: 1G
|
||||
http-max-streams: 200
|
||||
--- a/testdata/doh_downstream_post.tdir/doh_downstream_post.conf
|
||||
+++ b/testdata/doh_downstream_post.tdir/doh_downstream_post.conf
|
||||
@@ -11,6 +11,7 @@ server:
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
+ discard-timeout: 3000 # testns uses sleep=2
|
||||
http-query-buffer-size: 1G
|
||||
http-response-buffer-size: 1G
|
||||
http-max-streams: 200
|
||||
--- a/testdata/fwd_three_service.tdir/fwd_three_service.conf
|
||||
+++ b/testdata/fwd_three_service.tdir/fwd_three_service.conf
|
||||
@@ -11,6 +11,7 @@ server:
|
||||
num-queries-per-thread: 1024
|
||||
use-syslog: no
|
||||
do-not-query-localhost: no
|
||||
+ discard-timeout: 3000 # testns uses sleep=2
|
||||
forward-zone:
|
||||
name: "."
|
||||
forward-addr: "127.0.0.1@@TOPORT@"
|
||||
--- a/testdata/ssl_req_order.tdir/ssl_req_order.conf
|
||||
+++ b/testdata/ssl_req_order.tdir/ssl_req_order.conf
|
||||
@@ -9,6 +9,7 @@ server:
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
+ discard-timeout: 3000 # testns uses sleep=2
|
||||
ssl-port: @PORT@
|
||||
ssl-service-key: "unbound_server.key"
|
||||
ssl-service-pem: "unbound_server.pem"
|
||||
--- a/testdata/tcp_req_order.tdir/tcp_req_order.conf
|
||||
+++ b/testdata/tcp_req_order.tdir/tcp_req_order.conf
|
||||
@@ -9,6 +9,7 @@ server:
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
+ discard-timeout: 3000 # testns uses sleep=2
|
||||
|
||||
local-zone: "example.net" static
|
||||
local-data: "www1.example.net. IN A 1.2.3.1"
|
||||
--- a/testdata/tcp_sigpipe.tdir/tcp_sigpipe.conf
|
||||
+++ b/testdata/tcp_sigpipe.tdir/tcp_sigpipe.conf
|
||||
@@ -1,5 +1,5 @@
|
||||
server:
|
||||
- verbosity: 2
|
||||
+ verbosity: 4
|
||||
# num-threads: 1
|
||||
interface: 127.0.0.1
|
||||
port: @PORT@
|
||||
@@ -9,6 +9,7 @@ server:
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
+ discard-timeout: 3000 # testns uses sleep=2
|
||||
|
||||
forward-zone:
|
||||
name: "."
|
||||
--- a/util/config_file.c
|
||||
+++ b/util/config_file.c
|
||||
@@ -289,6 +289,11 @@ config_create(void)
|
||||
cfg->minimal_responses = 1;
|
||||
cfg->rrset_roundrobin = 1;
|
||||
cfg->unknown_server_time_limit = 376;
|
||||
+ cfg->discard_timeout = 1900; /* msec */
|
||||
+ cfg->wait_limit = 1000;
|
||||
+ cfg->wait_limit_cookie = 10000;
|
||||
+ cfg->wait_limit_netblock = NULL;
|
||||
+ cfg->wait_limit_cookie_netblock = NULL;
|
||||
cfg->max_udp_size = 4096;
|
||||
if(!(cfg->server_key_file = strdup(RUN_DIR"/unbound_server.key")))
|
||||
goto error_exit;
|
||||
@@ -661,6 +666,9 @@ int config_set_option(struct config_file
|
||||
else S_YNO("minimal-responses:", minimal_responses)
|
||||
else S_YNO("rrset-roundrobin:", rrset_roundrobin)
|
||||
else S_NUMBER_OR_ZERO("unknown-server-time-limit:", unknown_server_time_limit)
|
||||
+ else S_NUMBER_OR_ZERO("discard-timeout:", discard_timeout)
|
||||
+ else S_NUMBER_OR_ZERO("wait-limit:", wait_limit)
|
||||
+ else S_NUMBER_OR_ZERO("wait-limit-cookie:", wait_limit_cookie)
|
||||
else S_STRLIST("local-data:", local_data)
|
||||
else S_YNO("unblock-lan-zones:", unblock_lan_zones)
|
||||
else S_YNO("insecure-lan-zones:", insecure_lan_zones)
|
||||
@@ -1101,6 +1109,11 @@ config_get_option(struct config_file* cf
|
||||
else O_YNO(opt, "minimal-responses", minimal_responses)
|
||||
else O_YNO(opt, "rrset-roundrobin", rrset_roundrobin)
|
||||
else O_DEC(opt, "unknown-server-time-limit", unknown_server_time_limit)
|
||||
+ else O_DEC(opt, "discard-timeout", discard_timeout)
|
||||
+ else O_DEC(opt, "wait-limit", wait_limit)
|
||||
+ else O_DEC(opt, "wait-limit-cookie", wait_limit_cookie)
|
||||
+ else O_LS2(opt, "wait-limit-netblock", wait_limit_netblock)
|
||||
+ else O_LS2(opt, "wait-limit-cookie-netblock", wait_limit_cookie_netblock)
|
||||
#ifdef CLIENT_SUBNET
|
||||
else O_LST(opt, "send-client-subnet", client_subnet)
|
||||
else O_LST(opt, "client-subnet-zone", client_subnet_zone)
|
||||
@@ -1545,6 +1558,8 @@ config_delete(struct config_file* cfg)
|
||||
config_deltrplstrlist(cfg->acl_tag_actions);
|
||||
config_deltrplstrlist(cfg->acl_tag_datas);
|
||||
config_delstrlist(cfg->control_ifs.first);
|
||||
+ config_deldblstrlist(cfg->wait_limit_netblock);
|
||||
+ config_deldblstrlist(cfg->wait_limit_cookie_netblock);
|
||||
free(cfg->server_key_file);
|
||||
free(cfg->server_cert_file);
|
||||
free(cfg->control_key_file);
|
||||
--- a/util/config_file.h
|
||||
+++ b/util/config_file.h
|
||||
@@ -489,6 +489,21 @@ struct config_file {
|
||||
/* wait time for unknown server in msec */
|
||||
int unknown_server_time_limit;
|
||||
|
||||
+ /** Wait time to drop recursion replies */
|
||||
+ int discard_timeout;
|
||||
+
|
||||
+ /** Wait limit for number of replies per IP address */
|
||||
+ int wait_limit;
|
||||
+
|
||||
+ /** Wait limit for number of replies per IP address with cookie */
|
||||
+ int wait_limit_cookie;
|
||||
+
|
||||
+ /** wait limit per netblock */
|
||||
+ struct config_str2list* wait_limit_netblock;
|
||||
+
|
||||
+ /** wait limit with cookie per netblock */
|
||||
+ struct config_str2list* wait_limit_cookie_netblock;
|
||||
+
|
||||
/* maximum UDP response size */
|
||||
size_t max_udp_size;
|
||||
|
||||
--- a/util/configlexer.lex
|
||||
+++ b/util/configlexer.lex
|
||||
@@ -440,6 +440,11 @@ domain-insecure{COLON} { YDVAR(1, VAR_D
|
||||
minimal-responses{COLON} { YDVAR(1, VAR_MINIMAL_RESPONSES) }
|
||||
rrset-roundrobin{COLON} { YDVAR(1, VAR_RRSET_ROUNDROBIN) }
|
||||
unknown-server-time-limit{COLON} { YDVAR(1, VAR_UNKNOWN_SERVER_TIME_LIMIT) }
|
||||
+discard-timeout{COLON} { YDVAR(1, VAR_DISCARD_TIMEOUT) }
|
||||
+wait-limit{COLON} { YDVAR(1, VAR_WAIT_LIMIT) }
|
||||
+wait-limit-cookie{COLON} { YDVAR(1, VAR_WAIT_LIMIT_COOKIE) }
|
||||
+wait-limit-netblock{COLON} { YDVAR(1, VAR_WAIT_LIMIT_NETBLOCK) }
|
||||
+wait-limit-cookie-netblock{COLON} { YDVAR(1, VAR_WAIT_LIMIT_COOKIE_NETBLOCK) }
|
||||
max-udp-size{COLON} { YDVAR(1, VAR_MAX_UDP_SIZE) }
|
||||
dns64-prefix{COLON} { YDVAR(1, VAR_DNS64_PREFIX) }
|
||||
dns64-synthall{COLON} { YDVAR(1, VAR_DNS64_SYNTHALL) }
|
||||
--- a/util/configparser.y
|
||||
+++ b/util/configparser.y
|
||||
@@ -176,6 +176,8 @@ extern struct config_parser_state* cfg_p
|
||||
%token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
|
||||
%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY
|
||||
%token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY
|
||||
+%token VAR_DISCARD_TIMEOUT VAR_WAIT_LIMIT VAR_WAIT_LIMIT_COOKIE
|
||||
+%token VAR_WAIT_LIMIT_NETBLOCK VAR_WAIT_LIMIT_COOKIE_NETBLOCK
|
||||
%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES VAR_TLS_USE_SNI
|
||||
%token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6
|
||||
%token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE
|
||||
@@ -296,6 +298,8 @@ content_server: server_num_threads | ser
|
||||
server_fast_server_permil | server_fast_server_num | server_tls_win_cert |
|
||||
server_tcp_connection_limit | server_log_servfail | server_deny_any |
|
||||
server_unknown_server_time_limit | server_log_tag_queryreply |
|
||||
+ server_discard_timeout | server_wait_limit | server_wait_limit_cookie |
|
||||
+ server_wait_limit_netblock | server_wait_limit_cookie_netblock |
|
||||
server_stream_wait_size | server_tls_ciphers |
|
||||
server_tls_ciphersuites | server_tls_session_ticket_keys |
|
||||
server_tls_use_sni | server_edns_client_string |
|
||||
@@ -2145,6 +2149,57 @@ server_unknown_server_time_limit: VAR_UN
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
+server_discard_timeout: VAR_DISCARD_TIMEOUT STRING_ARG
|
||||
+ {
|
||||
+ OUTYY(("P(server_discard_timeout:%s)\n", $2));
|
||||
+ cfg_parser->cfg->discard_timeout = atoi($2);
|
||||
+ free($2);
|
||||
+ }
|
||||
+ ;
|
||||
+server_wait_limit: VAR_WAIT_LIMIT STRING_ARG
|
||||
+ {
|
||||
+ OUTYY(("P(server_wait_limit:%s)\n", $2));
|
||||
+ cfg_parser->cfg->wait_limit = atoi($2);
|
||||
+ free($2);
|
||||
+ }
|
||||
+ ;
|
||||
+server_wait_limit_cookie: VAR_WAIT_LIMIT_COOKIE STRING_ARG
|
||||
+ {
|
||||
+ OUTYY(("P(server_wait_limit_cookie:%s)\n", $2));
|
||||
+ cfg_parser->cfg->wait_limit_cookie = atoi($2);
|
||||
+ free($2);
|
||||
+ }
|
||||
+ ;
|
||||
+server_wait_limit_netblock: VAR_WAIT_LIMIT_NETBLOCK STRING_ARG STRING_ARG
|
||||
+ {
|
||||
+ OUTYY(("P(server_wait_limit_netblock:%s %s)\n", $2, $3));
|
||||
+ if(atoi($3) == 0 && strcmp($3, "0") != 0) {
|
||||
+ yyerror("number expected");
|
||||
+ free($2);
|
||||
+ free($3);
|
||||
+ } else {
|
||||
+ if(!cfg_str2list_insert(&cfg_parser->cfg->
|
||||
+ wait_limit_netblock, $2, $3))
|
||||
+ fatal_exit("out of memory adding "
|
||||
+ "wait-limit-netblock");
|
||||
+ }
|
||||
+ }
|
||||
+ ;
|
||||
+server_wait_limit_cookie_netblock: VAR_WAIT_LIMIT_COOKIE_NETBLOCK STRING_ARG STRING_ARG
|
||||
+ {
|
||||
+ OUTYY(("P(server_wait_limit_cookie_netblock:%s %s)\n", $2, $3));
|
||||
+ if(atoi($3) == 0 && strcmp($3, "0") != 0) {
|
||||
+ yyerror("number expected");
|
||||
+ free($2);
|
||||
+ free($3);
|
||||
+ } else {
|
||||
+ if(!cfg_str2list_insert(&cfg_parser->cfg->
|
||||
+ wait_limit_cookie_netblock, $2, $3))
|
||||
+ fatal_exit("out of memory adding "
|
||||
+ "wait-limit-cookie-netblock");
|
||||
+ }
|
||||
+ }
|
||||
+ ;
|
||||
server_max_udp_size: VAR_MAX_UDP_SIZE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_max_udp_size:%s)\n", $2));
|
||||
45
backport-CVE-2024-43167.patch
Normal file
45
backport-CVE-2024-43167.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From 8e43e2574c4e02f79c562a061581cdcefe136912 Mon Sep 17 00:00:00 2001
|
||||
From: zhailiangliang <zhailiangliang@loongson.cn>
|
||||
Date: Tue, 21 May 2024 08:40:16 +0000
|
||||
Subject: [PATCH] fix null pointer dereference issue in function ub_ctx_set_fwd
|
||||
of file libunbound/libunbound.c
|
||||
|
||||
---
|
||||
libunbound/libunbound.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libunbound/libunbound.c b/libunbound/libunbound.c
|
||||
index 17057ec6..3c895514 100644
|
||||
--- a/libunbound/libunbound.c
|
||||
+++ b/libunbound/libunbound.c
|
||||
@@ -981,7 +981,8 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
|
||||
if(!addr) {
|
||||
/* disable fwd mode - the root stub should be first. */
|
||||
if(ctx->env->cfg->forwards &&
|
||||
- strcmp(ctx->env->cfg->forwards->name, ".") == 0) {
|
||||
+ (ctx->env->cfg->forwards->name &&
|
||||
+ strcmp(ctx->env->cfg->forwards->name, ".") == 0)) {
|
||||
s = ctx->env->cfg->forwards;
|
||||
ctx->env->cfg->forwards = s->next;
|
||||
s->next = NULL;
|
||||
@@ -1001,7 +1002,8 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
|
||||
/* it parses, add root stub in front of list */
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(!ctx->env->cfg->forwards ||
|
||||
- strcmp(ctx->env->cfg->forwards->name, ".") != 0) {
|
||||
+ (ctx->env->cfg->forwards->name &&
|
||||
+ strcmp(ctx->env->cfg->forwards->name, ".") != 0)) {
|
||||
s = calloc(1, sizeof(*s));
|
||||
if(!s) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
@@ -1019,6 +1021,7 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
|
||||
ctx->env->cfg->forwards = s;
|
||||
} else {
|
||||
log_assert(ctx->env->cfg->forwards);
|
||||
+ log_assert(ctx->env->cfg->forwards->name);
|
||||
s = ctx->env->cfg->forwards;
|
||||
}
|
||||
dupl = strdup(addr);
|
||||
--
|
||||
2.33.0
|
||||
|
||||
246
backport-CVE-2024-8508.patch
Normal file
246
backport-CVE-2024-8508.patch
Normal file
@ -0,0 +1,246 @@
|
||||
From b7c61d7cc256d6a174e6179622c7fa968272c259 Mon Sep 17 00:00:00 2001
|
||||
From: Yorgos Thessalonikefs <yorgos@nlnetlabs.nl>
|
||||
Date: Thu, 3 Oct 2024 14:46:57 +0200
|
||||
Subject: [PATCH] - Fix CVE-2024-8508, unbounded name compression could lead to
|
||||
denial of service.
|
||||
|
||||
---
|
||||
util/data/msgencode.c | 77 ++++++++++++++++++++++++++-----------------
|
||||
1 file changed, 46 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/util/data/msgencode.c b/util/data/msgencode.c
|
||||
index 898ff8412..6d116fb52 100644
|
||||
--- a/util/data/msgencode.c
|
||||
+++ b/util/data/msgencode.c
|
||||
@@ -62,6 +62,10 @@
|
||||
#define RETVAL_TRUNC -4
|
||||
/** return code that means all is peachy keen. Equal to DNS rcode NOERROR */
|
||||
#define RETVAL_OK 0
|
||||
+/** Max compressions we are willing to perform; more than that will result
|
||||
+ * in semi-compressed messages, or truncated even on TCP for huge messages, to
|
||||
+ * avoid locking the CPU for long */
|
||||
+#define MAX_COMPRESSION_PER_MESSAGE 120
|
||||
|
||||
/**
|
||||
* Data structure to help domain name compression in outgoing messages.
|
||||
@@ -284,15 +288,17 @@ write_compressed_dname(sldns_buffer* pkt, uint8_t* dname, int labs,
|
||||
|
||||
/** compress owner name of RR, return RETVAL_OUTMEM RETVAL_TRUNC */
|
||||
static int
|
||||
-compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
- struct regional* region, struct compress_tree_node** tree,
|
||||
- size_t owner_pos, uint16_t* owner_ptr, int owner_labs)
|
||||
+compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
+ struct regional* region, struct compress_tree_node** tree,
|
||||
+ size_t owner_pos, uint16_t* owner_ptr, int owner_labs,
|
||||
+ size_t* compress_count)
|
||||
{
|
||||
struct compress_tree_node* p;
|
||||
struct compress_tree_node** insertpt = NULL;
|
||||
if(!*owner_ptr) {
|
||||
/* compress first time dname */
|
||||
- if((p = compress_tree_lookup(tree, key->rk.dname,
|
||||
+ if(*compress_count < MAX_COMPRESSION_PER_MESSAGE &&
|
||||
+ (p = compress_tree_lookup(tree, key->rk.dname,
|
||||
owner_labs, &insertpt))) {
|
||||
if(p->labs == owner_labs)
|
||||
/* avoid ptr chains, since some software is
|
||||
@@ -301,6 +307,7 @@ compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
if(!write_compressed_dname(pkt, key->rk.dname,
|
||||
owner_labs, p))
|
||||
return RETVAL_TRUNC;
|
||||
+ (*compress_count)++;
|
||||
/* check if typeclass+4 ttl + rdatalen is available */
|
||||
if(sldns_buffer_remaining(pkt) < 4+4+2)
|
||||
return RETVAL_TRUNC;
|
||||
@@ -313,7 +320,8 @@ compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
if(owner_pos <= PTR_MAX_OFFSET)
|
||||
*owner_ptr = htons(PTR_CREATE(owner_pos));
|
||||
}
|
||||
- if(!compress_tree_store(key->rk.dname, owner_labs,
|
||||
+ if(*compress_count < MAX_COMPRESSION_PER_MESSAGE &&
|
||||
+ !compress_tree_store(key->rk.dname, owner_labs,
|
||||
owner_pos, region, p, insertpt))
|
||||
return RETVAL_OUTMEM;
|
||||
} else {
|
||||
@@ -333,20 +341,24 @@ compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
|
||||
/** compress any domain name to the packet, return RETVAL_* */
|
||||
static int
|
||||
-compress_any_dname(uint8_t* dname, sldns_buffer* pkt, int labs,
|
||||
- struct regional* region, struct compress_tree_node** tree)
|
||||
+compress_any_dname(uint8_t* dname, sldns_buffer* pkt, int labs,
|
||||
+ struct regional* region, struct compress_tree_node** tree,
|
||||
+ size_t* compress_count)
|
||||
{
|
||||
struct compress_tree_node* p;
|
||||
struct compress_tree_node** insertpt = NULL;
|
||||
size_t pos = sldns_buffer_position(pkt);
|
||||
- if((p = compress_tree_lookup(tree, dname, labs, &insertpt))) {
|
||||
+ if(*compress_count < MAX_COMPRESSION_PER_MESSAGE &&
|
||||
+ (p = compress_tree_lookup(tree, dname, labs, &insertpt))) {
|
||||
if(!write_compressed_dname(pkt, dname, labs, p))
|
||||
return RETVAL_TRUNC;
|
||||
+ (*compress_count)++;
|
||||
} else {
|
||||
if(!dname_buffer_write(pkt, dname))
|
||||
return RETVAL_TRUNC;
|
||||
}
|
||||
- if(!compress_tree_store(dname, labs, pos, region, p, insertpt))
|
||||
+ if(*compress_count < MAX_COMPRESSION_PER_MESSAGE &&
|
||||
+ !compress_tree_store(dname, labs, pos, region, p, insertpt))
|
||||
return RETVAL_OUTMEM;
|
||||
return RETVAL_OK;
|
||||
}
|
||||
@@ -364,9 +376,9 @@ type_rdata_compressable(struct ub_packed_rrset_key* key)
|
||||
|
||||
/** compress domain names in rdata, return RETVAL_* */
|
||||
static int
|
||||
-compress_rdata(sldns_buffer* pkt, uint8_t* rdata, size_t todolen,
|
||||
- struct regional* region, struct compress_tree_node** tree,
|
||||
- const sldns_rr_descriptor* desc)
|
||||
+compress_rdata(sldns_buffer* pkt, uint8_t* rdata, size_t todolen,
|
||||
+ struct regional* region, struct compress_tree_node** tree,
|
||||
+ const sldns_rr_descriptor* desc, size_t* compress_count)
|
||||
{
|
||||
int labs, r, rdf = 0;
|
||||
size_t dname_len, len, pos = sldns_buffer_position(pkt);
|
||||
@@ -380,8 +392,8 @@ compress_rdata(sldns_buffer* pkt, uint8_t* rdata, size_t todolen,
|
||||
switch(desc->_wireformat[rdf]) {
|
||||
case LDNS_RDF_TYPE_DNAME:
|
||||
labs = dname_count_size_labels(rdata, &dname_len);
|
||||
- if((r=compress_any_dname(rdata, pkt, labs, region,
|
||||
- tree)) != RETVAL_OK)
|
||||
+ if((r=compress_any_dname(rdata, pkt, labs, region,
|
||||
+ tree, compress_count)) != RETVAL_OK)
|
||||
return r;
|
||||
rdata += dname_len;
|
||||
todolen -= dname_len;
|
||||
@@ -449,7 +461,8 @@ static int
|
||||
packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
uint16_t* num_rrs, time_t timenow, struct regional* region,
|
||||
int do_data, int do_sig, struct compress_tree_node** tree,
|
||||
- sldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset)
|
||||
+ sldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset,
|
||||
+ size_t* compress_count)
|
||||
{
|
||||
size_t i, j, owner_pos;
|
||||
int r, owner_labs;
|
||||
@@ -477,9 +490,9 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
for(i=0; i<data->count; i++) {
|
||||
/* rrset roundrobin */
|
||||
j = (i + rr_offset) % data->count;
|
||||
- if((r=compress_owner(key, pkt, region, tree,
|
||||
- owner_pos, &owner_ptr, owner_labs))
|
||||
- != RETVAL_OK)
|
||||
+ if((r=compress_owner(key, pkt, region, tree,
|
||||
+ owner_pos, &owner_ptr, owner_labs,
|
||||
+ compress_count)) != RETVAL_OK)
|
||||
return r;
|
||||
sldns_buffer_write(pkt, &key->rk.type, 2);
|
||||
sldns_buffer_write(pkt, &key->rk.rrset_class, 2);
|
||||
@@ -489,8 +502,8 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
else sldns_buffer_write_u32(pkt, data->rr_ttl[j]-adjust);
|
||||
if(c) {
|
||||
if((r=compress_rdata(pkt, data->rr_data[j],
|
||||
- data->rr_len[j], region, tree, c))
|
||||
- != RETVAL_OK)
|
||||
+ data->rr_len[j], region, tree, c,
|
||||
+ compress_count)) != RETVAL_OK)
|
||||
return r;
|
||||
} else {
|
||||
if(sldns_buffer_remaining(pkt) < data->rr_len[j])
|
||||
@@ -510,9 +523,9 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
return RETVAL_TRUNC;
|
||||
sldns_buffer_write(pkt, &owner_ptr, 2);
|
||||
} else {
|
||||
- if((r=compress_any_dname(key->rk.dname,
|
||||
- pkt, owner_labs, region, tree))
|
||||
- != RETVAL_OK)
|
||||
+ if((r=compress_any_dname(key->rk.dname,
|
||||
+ pkt, owner_labs, region, tree,
|
||||
+ compress_count)) != RETVAL_OK)
|
||||
return r;
|
||||
if(sldns_buffer_remaining(pkt) <
|
||||
4+4+data->rr_len[i])
|
||||
@@ -544,7 +557,8 @@ static int
|
||||
insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||
sldns_buffer* pkt, size_t rrsets_before, time_t timenow,
|
||||
struct regional* region, struct compress_tree_node** tree,
|
||||
- sldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset)
|
||||
+ sldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset,
|
||||
+ size_t* compress_count)
|
||||
{
|
||||
int r;
|
||||
size_t i, setstart;
|
||||
@@ -560,7 +574,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||
setstart = sldns_buffer_position(pkt);
|
||||
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
|
||||
pkt, num_rrs, timenow, region, 1, 1, tree,
|
||||
- s, qtype, dnssec, rr_offset))
|
||||
+ s, qtype, dnssec, rr_offset, compress_count))
|
||||
!= RETVAL_OK) {
|
||||
/* Bad, but if due to size must set TC bit */
|
||||
/* trim off the rrset neatly. */
|
||||
@@ -573,7 +587,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||
setstart = sldns_buffer_position(pkt);
|
||||
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
|
||||
pkt, num_rrs, timenow, region, 1, 0, tree,
|
||||
- s, qtype, dnssec, rr_offset))
|
||||
+ s, qtype, dnssec, rr_offset, compress_count))
|
||||
!= RETVAL_OK) {
|
||||
sldns_buffer_set_position(pkt, setstart);
|
||||
return r;
|
||||
@@ -584,7 +598,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||
setstart = sldns_buffer_position(pkt);
|
||||
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
|
||||
pkt, num_rrs, timenow, region, 0, 1, tree,
|
||||
- s, qtype, dnssec, rr_offset))
|
||||
+ s, qtype, dnssec, rr_offset, compress_count))
|
||||
!= RETVAL_OK) {
|
||||
sldns_buffer_set_position(pkt, setstart);
|
||||
return r;
|
||||
@@ -677,6 +691,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
struct compress_tree_node* tree = 0;
|
||||
int r;
|
||||
size_t rr_offset;
|
||||
+ size_t compress_count=0;
|
||||
|
||||
sldns_buffer_clear(buffer);
|
||||
if(udpsize < sldns_buffer_limit(buffer))
|
||||
@@ -723,7 +738,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
arep.rrsets = &qinfo->local_alias->rrset;
|
||||
if((r=insert_section(&arep, 1, &ancount, buffer, 0,
|
||||
timezero, region, &tree, LDNS_SECTION_ANSWER,
|
||||
- qinfo->qtype, dnssec, rr_offset)) != RETVAL_OK) {
|
||||
+ qinfo->qtype, dnssec, rr_offset, &compress_count)) != RETVAL_OK) {
|
||||
if(r == RETVAL_TRUNC) {
|
||||
/* create truncated message */
|
||||
sldns_buffer_write_u16_at(buffer, 6, ancount);
|
||||
@@ -738,7 +753,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
/* insert answer section */
|
||||
if((r=insert_section(rep, rep->an_numrrsets, &ancount, buffer,
|
||||
0, timenow, region, &tree, LDNS_SECTION_ANSWER, qinfo->qtype,
|
||||
- dnssec, rr_offset)) != RETVAL_OK) {
|
||||
+ dnssec, rr_offset, &compress_count)) != RETVAL_OK) {
|
||||
if(r == RETVAL_TRUNC) {
|
||||
/* create truncated message */
|
||||
sldns_buffer_write_u16_at(buffer, 6, ancount);
|
||||
@@ -756,7 +771,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer,
|
||||
rep->an_numrrsets, timenow, region, &tree,
|
||||
LDNS_SECTION_AUTHORITY, qinfo->qtype,
|
||||
- dnssec, rr_offset)) != RETVAL_OK) {
|
||||
+ dnssec, rr_offset, &compress_count)) != RETVAL_OK) {
|
||||
if(r == RETVAL_TRUNC) {
|
||||
/* create truncated message */
|
||||
sldns_buffer_write_u16_at(buffer, 8, nscount);
|
||||
@@ -773,7 +788,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer,
|
||||
rep->an_numrrsets + rep->ns_numrrsets, timenow, region,
|
||||
&tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype,
|
||||
- dnssec, rr_offset)) != RETVAL_OK) {
|
||||
+ dnssec, rr_offset, &compress_count)) != RETVAL_OK) {
|
||||
if(r == RETVAL_TRUNC) {
|
||||
/* no need to set TC bit, this is the additional */
|
||||
sldns_buffer_write_u16_at(buffer, 10, arcount);
|
||||
27
backport-check-before-use-daemon-shm_info.patch
Normal file
27
backport-check-before-use-daemon-shm_info.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 073c7301ebdf7511320ec817ad7ecacf6b45c4be Mon Sep 17 00:00:00 2001
|
||||
From: eaglegai <31752768+eaglegai@users.noreply.github.com>
|
||||
Date: Tue, 21 Jan 2025 22:47:51 +0800
|
||||
Subject: [PATCH] check before use daemon->shm_info (#1229)
|
||||
|
||||
fix core after the command `unbound-control stop unbound`
|
||||
|
||||
fix:https://github.com/NLnetLabs/unbound/issues/1228
|
||||
|
||||
Signed-off-by: eaglegai <eaglegai@163.com>
|
||||
---
|
||||
util/shm_side/shm_main.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/util/shm_side/shm_main.c b/util/shm_side/shm_main.c
|
||||
index 6fd1f5ea6..751d6d649 100644
|
||||
--- a/util/shm_side/shm_main.c
|
||||
+++ b/util/shm_side/shm_main.c
|
||||
@@ -195,7 +195,7 @@ void shm_main_shutdown(struct daemon* daemon)
|
||||
{
|
||||
#ifdef HAVE_SHMGET
|
||||
/* web are OK, just disabled */
|
||||
- if(!daemon->cfg->shm_enable)
|
||||
+ if(!daemon->cfg->shm_enable || !daemon->shm_info)
|
||||
return;
|
||||
|
||||
verbose(VERB_DETAIL, "SHM shutdown - KEY [%d] - ID CTL [%d] ARR [%d] - PTR CTL [%p] ARR [%p]",
|
||||
@ -166,6 +166,15 @@ server:
|
||||
# msec to wait before close of port on timeout UDP. 0 disables.
|
||||
# delay-close: 0
|
||||
|
||||
# msec before recursion replies are dropped. The work item continues.
|
||||
# discard-timeout: 1900
|
||||
|
||||
# Max number of replies waiting for recursion per IP address.
|
||||
# wait-limit: 1000
|
||||
|
||||
# Apart from the default, the wait limit can be set for a netblock.
|
||||
# wait-limit-netblock: 192.0.2.0/24 50000
|
||||
|
||||
# the amount of memory to use for the RRset cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# rrset-cache-size: 4m
|
||||
|
||||
42
unbound.spec
42
unbound.spec
@ -2,7 +2,7 @@
|
||||
|
||||
Name: unbound
|
||||
Version: 1.13.2
|
||||
Release: 12
|
||||
Release: 17
|
||||
Summary: Unbound is a validating, recursive, caching DNS resolver
|
||||
License: BSD
|
||||
Url: https://nlnetlabs.nl/projects/unbound/about/
|
||||
@ -28,10 +28,18 @@ Patch3: backport-CVE-2022-3204.patch
|
||||
Patch4: backport-Undefine-shift-in-sldns_str2wire_hip_buf.patch
|
||||
Patch5: backport-Integer-overflow-in-sldns_wire2str_pkt_scan.patch
|
||||
Patch6: backport-CVE-2023-50387_CVE-2023-50868.patch
|
||||
Patch7: backport-CVE-2024-43167.patch
|
||||
Patch8: backport-001-CVE-2024-43168.patch
|
||||
Patch9: backport-002-CVE-2024-43168.patch
|
||||
Patch10: backport-003-CVE-2024-43168.patch
|
||||
Patch11: backport-004-CVE-2024-43168.patch
|
||||
Patch12: backport-CVE-2024-33655.patch
|
||||
Patch13: backport-CVE-2024-8508.patch
|
||||
Patch14: backport-check-before-use-daemon-shm_info.patch
|
||||
|
||||
BuildRequires: make flex swig pkgconfig systemd
|
||||
BuildRequires: libevent-devel expat-devel openssl-devel python3-devel
|
||||
BuildRequires: gcc
|
||||
BuildRequires: gcc byacc
|
||||
|
||||
%{?systemd_requires}
|
||||
Requires: %{name}-libs = %{version}-%{release}
|
||||
@ -252,6 +260,36 @@ popd
|
||||
%{_mandir}/man*
|
||||
|
||||
%changelog
|
||||
* Thu Jan 23 2025 gaihuiying <eaglegai@163.com> - 1.13.2-17
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
- SUG:NA
|
||||
- DESC:backport upstream to add check to fix coredump
|
||||
|
||||
* Wed Oct 16 2024 gaihuiying <eaglegai@163.com> - 1.13.2-16
|
||||
- Type:cves
|
||||
- CVE:CVE-2024-8508
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2024-8508
|
||||
|
||||
* Thu Sep 26 2024 gaihuiying <eaglegai@163.com> - 1.13.2-15
|
||||
- Type:CVE
|
||||
- CVE:CVE-2024-33655
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2024-33655
|
||||
|
||||
* Mon Aug 26 2024 gaihuiying <eaglegai@163.com> - 1.13.2-14
|
||||
- Type:cves
|
||||
- CVE:CVE-2024-43168
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2024-43168 better
|
||||
|
||||
* Mon Aug 19 2024 gaihuiying <eaglegai@163.com> - 1.13.2-13
|
||||
- Type:cves
|
||||
- CVE:CVE-2024-43167 CVE-2024-43168
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2024-43167 CVE-2024-43168
|
||||
|
||||
* Tue Jun 25 2024 gaihuiying <eaglegai@163.com> - 1.13.2-12
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user