From patchwork Sat Jul 25 16:39:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias Fischer X-Patchwork-Id: 10067 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519) (Client CN "mail01.haj.ipfire.org", Issuer "YR2" (not verified)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 4h6rF45kfjz3wkB for ; Sat, 25 Jul 2026 16:40:08 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [IPv6:2001:678:b28::201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519) (Client CN "mail02.haj.ipfire.org", Issuer "YE1" (not verified)) by mail01.ipfire.org (Postfix) with ESMTPS id 4h6rF44yW9z44D for ; Sat, 25 Jul 2026 16:40:08 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [IPv6:::1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4h6rF440V6z34ml for ; Sat, 25 Jul 2026 16:40:08 +0000 (UTC) X-Original-To: development@lists.ipfire.org Received: from mail01.ipfire.org (mail01.haj.ipfire.org [IPv6:2001:678:b28::25]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519) (Client CN "mail01.haj.ipfire.org", Issuer "YR2" (not verified)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4h6rF171BGz2xJk for ; Sat, 25 Jul 2026 16:40:05 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mail01.ipfire.org (Postfix) with ESMTPSA id 4h6rF13JPpz1xs; Sat, 25 Jul 2026 16:40:05 +0000 (UTC) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003ed25519; t=1784997605; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=dUWZx77lusNUyOxAzecTqNTqX/Na2XJwtD91q1Hlyec=; b=htUE7tCz/o7EH4re6ZZ5ycGPf65e0BtbIHB8ZnGwUUJkmwn2I5AngY3nM7WhGgVcF4qnXn OtQuUtYNBD8Xt8Dw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003rsa; t=1784997605; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=dUWZx77lusNUyOxAzecTqNTqX/Na2XJwtD91q1Hlyec=; b=rZD2OOiIAj9bDeGdtB5rr+plJ1TjmiT/dlvBhmYk4UUzF0bBU6rkkK9X7YzzbjZhhnFhZR aKX26i1Lxe6x9yVeXgHQfMoylujCxJPlW6TMSpnj6wSHouG+JYyz4gsMixA8NtuitIK+Dw D2WagLg0fd/nyd+zobj2XNulp/K42OoGAlk48hkGq3WEFhvomut2nvXqbx7v36c2PmehIv 4szgxyMYEvpoUwm1R+UMNj6MBSk+u0tyxU5wpUe/aVrJlSvveo6wRtz/U5DG+JZMKWBMqh KOjosZa5oDCk3Pf4es9bHuvQca9BVVtaKVqFyLywoywoW7/WXbUSn+B8gmAQDw== From: Matthias Fischer To: development@lists.ipfire.org Cc: Matthias Fischer Subject: [PATCH] knot-resolver: Update to 6.4.1 Date: Sat, 25 Jul 2026 18:39:55 +0200 Message-ID: <20260725163957.3363172-1-matthias.fischer@ipfire.org> Precedence: list List-Id: List-Subscribe: , List-Unsubscribe: , List-Post: List-Help: Sender: Mail-Followup-To: MIME-Version: 1.0 - Commented some unnecessary lines in rootfile. - Removed no longer needed patchfile. For details see: https://www.knot-resolver.cz/2026-07-22-knot-resolver-6.4.1.html "Security DNS-over-QUIC (DoQ) had severe issues, allowing even RCE Many people reported (some of) these issues to us. DNSSEC correctness issues, acting mainly through the aggressive cache: * dealing with Labels field in RRSIGs being smaller than the signer's * dealing with NSEC's next-name pointing outside of the zone Special thanks to Qifan Zhang from Palo Alto Networks. Improvements docker: upgrade to Debian 13 (!1856) update IANA's certificate for root trust anchor bootstrapping (!1845) Bugfixes /local-data/addresses*: make multiple addresses work (#808, #954) views: fix protocol-based matching for DoQ" Signed-off-by: Matthias Fischer --- config/rootfiles/common/knot-resolver | 18 +- lfs/knot-resolver | 7 +- src/patches/knot-resolver-6.4.0-1854.patch | 251 --------------------- 3 files changed, 12 insertions(+), 264 deletions(-) delete mode 100644 src/patches/knot-resolver-6.4.0-1854.patch diff --git a/config/rootfiles/common/knot-resolver b/config/rootfiles/common/knot-resolver index 9d5a83460..80d82d34b 100644 --- a/config/rootfiles/common/knot-resolver +++ b/config/rootfiles/common/knot-resolver @@ -43,7 +43,7 @@ usr/lib/knot-resolver/distro-preconfig.lua usr/lib/knot-resolver/kluautil.lua usr/lib/knot-resolver/kres-gen.lua usr/lib/knot-resolver/kres.lua -usr/lib/knot-resolver/kres_modules +#usr/lib/knot-resolver/kres_modules usr/lib/knot-resolver/kres_modules/bogus_log.so #usr/lib/knot-resolver/kres_modules/daf usr/lib/knot-resolver/kres_modules/daf.lua @@ -109,13 +109,13 @@ usr/lib/knot-resolver/zonefile.lua usr/lib/libkres.so.9 #usr/lib/pkgconfig/libkres.pc usr/lib/python3.10/site-packages/knot_resolver -usr/lib/python3.10/site-packages/knot_resolver-6.4.0-py3.10.egg-info -usr/lib/python3.10/site-packages/knot_resolver-6.4.0-py3.10.egg-info/PKG-INFO -usr/lib/python3.10/site-packages/knot_resolver-6.4.0-py3.10.egg-info/SOURCES.txt -usr/lib/python3.10/site-packages/knot_resolver-6.4.0-py3.10.egg-info/dependency_links.txt -usr/lib/python3.10/site-packages/knot_resolver-6.4.0-py3.10.egg-info/entry_points.txt -usr/lib/python3.10/site-packages/knot_resolver-6.4.0-py3.10.egg-info/requires.txt -usr/lib/python3.10/site-packages/knot_resolver-6.4.0-py3.10.egg-info/top_level.txt +#usr/lib/python3.10/site-packages/knot_resolver-6.4.1-py3.10.egg-info +usr/lib/python3.10/site-packages/knot_resolver-6.4.1-py3.10.egg-info/PKG-INFO +usr/lib/python3.10/site-packages/knot_resolver-6.4.1-py3.10.egg-info/SOURCES.txt +usr/lib/python3.10/site-packages/knot_resolver-6.4.1-py3.10.egg-info/dependency_links.txt +usr/lib/python3.10/site-packages/knot_resolver-6.4.1-py3.10.egg-info/entry_points.txt +usr/lib/python3.10/site-packages/knot_resolver-6.4.1-py3.10.egg-info/requires.txt +usr/lib/python3.10/site-packages/knot_resolver-6.4.1-py3.10.egg-info/top_level.txt #usr/lib/python3.10/site-packages/knot_resolver/__init__.py #usr/lib/python3.10/site-packages/knot_resolver/client #usr/lib/python3.10/site-packages/knot_resolver/client/__init__.py @@ -269,7 +269,7 @@ usr/sbin/kresd #usr/share/man/man8/kresctl.8 #usr/share/man/man8/kresd.8 var/cache/knot-resolver -var/lib/knot-resolver +#var/lib/knot-resolver var/lib/knot-resolver/leases.db var/lib/knot-resolver/root.keys var/lib/knot-resolver/zones diff --git a/lfs/knot-resolver b/lfs/knot-resolver index 3d49a3bc7..daeea4159 100644 --- a/lfs/knot-resolver +++ b/lfs/knot-resolver @@ -1,7 +1,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2024 IPFire Team # +# Copyright (C) 2007-2026 IPFire Team # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -24,7 +24,7 @@ include Config -VER = 6.4.0 +VER = 6.4.1 THISAPP = knot-resolver-$(VER) DL_FILE = $(THISAPP).tar.xz @@ -40,7 +40,7 @@ objects = $(DL_FILE) $(DL_FILE) = $(DL_FROM)/$(DL_FILE) -$(DL_FILE)_BLAKE2 = dbe67ea0ad3484aba912406f960568c2c92630910863eaf33aeba9b15dce0279810a7df8844aa7d5617f1055de957445042a80c7479972f185bbfff457e96e1d +$(DL_FILE)_BLAKE2 = cd755323a3e6decf36bacf2508f8f3cf02a4538d1909e17689d1e2d7821e8b9d8e463a1426d6ea765bbfd7cc9aa11894fe8a0ad5e8b51ad9f970c44735fb3a3e install : $(TARGET) @@ -70,7 +70,6 @@ $(subst %,%_BLAKE2,$(objects)) : $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @$(PREBUILD) @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/knot-resolver-6.4.0-1854.patch cd $(DIR_APP) && meson setup \ --prefix=/usr \ -Duser=knot-resolver \ diff --git a/src/patches/knot-resolver-6.4.0-1854.patch b/src/patches/knot-resolver-6.4.0-1854.patch deleted file mode 100644 index 94267c2a4..000000000 --- a/src/patches/knot-resolver-6.4.0-1854.patch +++ /dev/null @@ -1,251 +0,0 @@ -diff --git a/lib/cache/cdb_api.h b/lib/cache/cdb_api.h -index 9e8a34d58..b589b564a 100644 ---- a/lib/cache/cdb_api.h -+++ b/lib/cache/cdb_api.h -@@ -65,11 +65,15 @@ struct kr_cdb_api { - * \return error code - accepting RW transactions can fail with LMDB. - */ - int (*commit)(kr_cdb_pt db, struct kr_cdb_stats *stat, bool accept_rw, bool reset_ro); -+ /** Run before a row of operations to ensure they happen in a single RW transaction, -+ * at least in case of successes. */ -+ int (*txn_open_rw)(kr_cdb_pt db, struct kr_cdb_stats *stat/*unused*/); - - /* Data access */ - - int (*read)(kr_cdb_pt db, struct kr_cdb_stats *stat, - const knot_db_val_t *key, knot_db_val_t *val, int maxcount); -+ /* TODO: the behavior of write() around transactions is a bit complex. */ - int (*write)(kr_cdb_pt db, struct kr_cdb_stats *stat, const knot_db_val_t *key, - knot_db_val_t *val, int maxcount); - -@@ -111,13 +115,19 @@ struct kr_cdb_api { - int (*check_health)(kr_cdb_pt db, struct kr_cdb_stats *stat); - - -- /** Start iterating; return the first *val with *key. -+ /** Start iterating: get the first *val with *key + return error code. - * -- * This only makes sense if !is_cache. -- * TODO: it only works inside RO transactions for now. -+ * - in cache: ensures a RO transaction (and commits the RW txn if any) -+ * - in ruledb: transaction is preserved if exists, otherwise RO txn gets opened - */ - int (*it_first)(kr_cdb_pt db, struct kr_cdb_stats *stat, - const knot_db_val_t *key, knot_db_val_t *val); -- /** Advance to the next *val with the same key. */ -+ /** Advance to the next *val with the same key. Return error code. */ - int (*it_next)(kr_cdb_pt db, struct kr_cdb_stats *stat, knot_db_val_t *val); -+ /** Delete the current *val + return error code. -+ * -+ * You can it_next() to continue. -+ * This assumed that you got it_first() in a RW txn. -+ */ -+ int (*it_del)(kr_cdb_pt db, struct kr_cdb_stats *stat); - }; -diff --git a/lib/cache/cdb_lmdb.c b/lib/cache/cdb_lmdb.c -index 0319b5cbb..6221c9492 100644 ---- a/lib/cache/cdb_lmdb.c -+++ b/lib/cache/cdb_lmdb.c -@@ -38,12 +38,13 @@ struct lmdb_env - * - * - only one of (ro,rw) may be active at once - * - non-NULL .ro may be active or reset -- * - non-NULL .rw is always active -+ * - ro_curs can survive an RW transaction and renewed later in an RO txn -+ * - non-NULL .rw is always active, non-NULL rw_curs is always active - */ - struct { - bool ro_active, ro_curs_active; - MDB_txn *ro, *rw; -- MDB_cursor *ro_curs; -+ MDB_cursor *ro_curs, *rw_curs; - } txn; - - bool is_cache; /**< cache vs. rules; from struct kr_cdb_opts::is_cache */ -@@ -236,6 +237,7 @@ static int cdb_commit(kr_cdb_pt db, struct kr_cdb_stats *stats, bool accept_rw, - mdb_txn_abort(env->txn.rw); - } - env->txn.rw = NULL; /* the transaction got freed even in case of errors */ -+ env->txn.rw_curs = NULL; /* auto-closed with txn if existed */ - } else if (reset_ro && env->txn.ro && env->txn.ro_active) { - mdb_txn_reset(env->txn.ro); - env->txn.ro_active = false; -@@ -244,21 +246,39 @@ static int cdb_commit(kr_cdb_pt db, struct kr_cdb_stats *stats, bool accept_rw, - return ret; - } - --/** Obtain a read-only cursor (and a read-only transaction). -- * TODO: allow RW transaction (for ruledb iterator) */ -+static int cdb_txn_open_rw(kr_cdb_pt db, struct kr_cdb_stats *stat/*unused*/) -+{ -+ struct lmdb_env *env = db2env(db); -+ MDB_txn *txn = NULL; -+ return txn_get(env, &txn, false); -+} -+ -+/** Obtain a cursor (and a transaction). -+ * -+ * - for cache these are read only -+ * - for policy the RW transaction gets preserved if open */ - static int txn_curs_get(struct lmdb_env *env, MDB_cursor **curs, struct kr_cdb_stats *stats) - { - if (kr_fails_assert(env && curs)) - return kr_error(EINVAL); - if (env->txn.ro_curs_active) -- goto success; -- /* Only in a read-only txn; TODO: it's a bit messy/coupled -- * At least for rules we don't do the auto-commit feature. */ -- if (env->txn.rw) { -- if (!env->is_cache) return kr_error(EINPROGRESS); -+ goto success_ro; -+ /* Only in a read-only txn if for cache; TODO: it's a bit messy/coupled */ -+ if (env->txn.rw && env->is_cache) { - int ret = cdb_commit(env2db(env), stats, true, false); - if (ret) return ret; - } -+ if (env->txn.rw && !env->is_cache) { -+ if (!env->txn.rw_curs) { -+ MDB_txn *txn = env->txn.rw; -+ int ret = mdb_cursor_open(txn, env->dbi, &env->txn.rw_curs); -+ if (ret) return lmdb_error(env, ret); -+ } -+ if (kr_fails_assert(env->txn.rw_curs)) -+ return kr_error(EINVAL); -+ *curs = env->txn.rw_curs; -+ return kr_ok(); -+ } - MDB_txn *txn = NULL; - int ret = txn_get(env, &txn, true); - if (ret) return ret; -@@ -270,7 +290,7 @@ static int txn_curs_get(struct lmdb_env *env, MDB_cursor **curs, struct kr_cdb_s - } - if (ret) return lmdb_error(env, ret); - env->txn.ro_curs_active = true; --success: -+success_ro: - kr_assert(env->txn.ro_curs_active && env->txn.ro && env->txn.ro_active - && !env->txn.rw); - *curs = env->txn.ro_curs; -@@ -301,6 +321,7 @@ static void txn_abort(struct lmdb_env *env) - if (env->txn.rw) { - mdb_txn_abort(env->txn.rw); - env->txn.rw = NULL; /* the transaction got freed even in case of errors */ -+ env->txn.rw_curs = NULL; /* auto-closed with txn if existed */ - } - } - -@@ -940,7 +961,7 @@ static int cdb_it_next(kr_cdb_pt db, struct kr_cdb_stats *stats, knot_db_val_t * - if (kr_fails_assert(db && val)) - return kr_error(EINVAL); - struct lmdb_env *env = db2env(db); -- if (kr_fails_assert(!env->is_cache && env->txn.ro_curs_active)) -+ if (kr_fails_assert(!env->is_cache && (env->txn.ro_curs_active || env->txn.rw_curs))) - return kr_error(EINVAL); - - MDB_cursor *curs = NULL; -@@ -952,19 +973,35 @@ static int cdb_it_next(kr_cdb_pt db, struct kr_cdb_stats *stats, knot_db_val_t * - *val = val_mdb2knot(val2_m); - return kr_ok(); - } -+static int cdb_it_del(kr_cdb_pt db, struct kr_cdb_stats *stats) -+{ -+ if (kr_fails_assert(db)) -+ return kr_error(EINVAL); -+ struct lmdb_env *env = db2env(db); -+ if (kr_fails_assert(!env->is_cache && env->txn.rw_curs)) -+ return kr_error(EINVAL); -+ -+ MDB_cursor *curs = NULL; -+ int ret = txn_curs_get(env, &curs, stats); -+ if (ret) return ret; -+ ret = mdb_cursor_del(curs, 0); -+ if (ret) return lmdb_error(env, ret); -+ return kr_ok(); -+} - - - const struct kr_cdb_api *kr_cdb_lmdb(void) - { - static const struct kr_cdb_api api = { - "lmdb", -- cdb_init, cdb_deinit, cdb_count, cdb_clear, cdb_commit, -+ cdb_init, cdb_deinit, cdb_count, cdb_clear, -+ cdb_commit, cdb_txn_open_rw, - cdb_readv, cdb_writev, cdb_remove, - cdb_match, - cdb_read_leq, cdb_read_less, - cdb_usage_percent, cdb_get_maxsize, - cdb_check_health, -- cdb_it_first, cdb_it_next, -+ cdb_it_first, cdb_it_next, cdb_it_del, - }; - return &api; - } -diff --git a/lib/rules/api.c b/lib/rules/api.c -index d9dbfcf1f..4c213d6f5 100644 ---- a/lib/rules/api.c -+++ b/lib/rules/api.c -@@ -663,21 +663,27 @@ int kr_rule_local_data_merge(const knot_rrset_t *rrs, const kr_rule_tags_t tags, - uint8_t key_data[KEY_MAXLEN]; - knot_db_val_t key = local_data_key(rrs, key_data, RULESET_DEFAULT); - knot_db_val_t val; -+ int ret = ruledb_op(txn_open_rw); -+ if (ret) -+ return kr_error(ret); - // Transaction: we assume that we're in a RW transaction already, - // so that here we already "have a lock" on the last version. -- // FIXME: iterate over multiple tags, once iterator supports RW TXN -- int ret = ruledb_op(read, &key, &val, 1); -+ // Multiple variants are possible, with different tags. -+ for (ret = ruledb_op(it_first, &key, &val); ret == 0; ret = ruledb_op(it_next, &val)) { -+ // we're looking for the same tag-set -+ kr_rule_tags_t tags_old; -+ if (deserialize_fails_assert(&val, &tags_old) || tags_old != tags) -+ continue; -+ kr_rule_opts_t opts_old; -+ if (deserialize_fails_assert(&val, &opts_old)) -+ continue; -+ break; -+ } - if (abs(ret) == abs(ENOENT)) - goto fallback; - if (ret) - return kr_error(ret); -- // check tags -- kr_rule_tags_t tags_old; -- if (deserialize_fails_assert(&val, &tags_old) || tags_old != tags) -- goto fallback; -- kr_rule_opts_t opts_old; -- if (deserialize_fails_assert(&val, &opts_old)) -- goto fallback; -+ - // merge TTLs - uint32_t ttl; - if (deserialize_fails_assert(&val, &ttl)) -@@ -700,6 +706,10 @@ int kr_rule_local_data_merge(const knot_rrset_t *rrs, const kr_rule_tags_t tags, - mm_ctx_delete(mm); - return kr_error(ret); - } -+ // ATM ruledb does not overwrite, so we `remove` before `write`. -+ ret = ruledb_op(it_del); -+ if (ret) -+ return kr_error(ret); - // everything is ready to insert the merged RRset - ret = local_data_ins(key, &rrs_new, NULL, tags, opts); - mm_ctx_delete(mm); -diff --git a/lib/rules/api.h b/lib/rules/api.h -index feea98e09..c3af5901b 100644 ---- a/lib/rules/api.h -+++ b/lib/rules/api.h -@@ -144,10 +144,8 @@ const uint32_t KR_RULE_TTL_DEFAULT; - KR_EXPORT - int kr_rule_local_data_ins(const knot_rrset_t *rrs, const knot_rdataset_t *sig_rds, - kr_rule_tags_t tags, kr_rule_opts_t opts); --/** Merge RRs into a local data rule. -+/** Merge RRs into a local data rule with the same set of tags. - * -- * - FIXME: with multiple tags variants for the same name-type pair, -- * you typically end up with a single RR per RRset - * - RRSIGs get dropped, if any were attached. - * - We assume that this is called with a RW transaction open already, - * which is always true in normal usage (long RW txn covering whole config).