From 86541b39d3b2d119ee647659c2a77749088f344c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Tue, 22 Jun 2021 15:28:31 +0200 Subject: [PATCH 1/3] Use minimal-sized caches for non-recursive views Currently the implicit default for the "max-cache-size" option is "90%". As this option is inherited by all configured views, using multiple views can lead to memory exhaustion over time due to overcommitment. The "max-cache-size 90%;" default also causes cache RBT hash tables to be preallocated for every configured view, which does not really make sense for views which do not allow recursion. To limit this problem's potential for causing operational issues, use a minimal-sized cache for views which do not allow recursion and do not have "max-cache-size" explicitly set (either in global configuration or in view configuration). For configurations which include multiple views allowing recursion, adjusting "max-cache-size" appropriately is still left to the operator. --- bin/named/server.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/bin/named/server.c b/bin/named/server.c index ba0757348e..b426c94be2 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -3971,6 +3971,42 @@ register_one_plugin(const cfg_obj_t *config, const cfg_obj_t *obj, return (result); } +/* + * Determine if a minimal-sized cache can be used for a given view, according + * to 'maps' (implicit defaults, global options, view options) and 'optionmaps' + * (global options, view options). This is only allowed for views which have + * recursion disabled and do not have "max-cache-size" set explicitly. Using + * minimal-sized caches prevents a situation in which all explicitly configured + * and built-in views inherit the default "max-cache-size 90%;" setting, which + * could lead to memory exhaustion with multiple views configured. + */ +static bool +minimal_cache_allowed(const cfg_obj_t *maps[4], + const cfg_obj_t *optionmaps[3]) { + const cfg_obj_t *obj; + + /* + * Do not use a minimal-sized cache for a view with recursion enabled. + */ + obj = NULL; + (void)named_config_get(maps, "recursion", &obj); + INSIST(obj != NULL); + if (cfg_obj_asboolean(obj)) { + return (false); + } + + /* + * Do not use a minimal-sized cache if a specific size was requested. + */ + obj = NULL; + (void)named_config_get(optionmaps, "max-cache-size", &obj); + if (obj != NULL) { + return (false); + } + + return (true); +} + /* * Configure 'view' according to 'vconfig', taking defaults from * 'config' where values are missing in 'vconfig'. @@ -4236,6 +4272,12 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config, */ if (named_g_maxcachesize != 0) { max_cache_size = named_g_maxcachesize; + } else if (minimal_cache_allowed(maps, optionmaps)) { + /* + * dns_cache_setcachesize() will adjust this to the smallest + * allowed value. + */ + max_cache_size = 1; } else if (cfg_obj_isstring(obj)) { str = cfg_obj_asstring(obj); INSIST(strcasecmp(str, "unlimited") == 0); From 86698ded32515710b5b8734b4ed8ac4d2be62b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Tue, 22 Jun 2021 15:28:31 +0200 Subject: [PATCH 2/3] Hardcode "max-cache-size" for the "_bind" view The built-in "_bind" view does not allow recursion and therefore does not need a large cache database. However, as "max-cache-size" is not explicitly set for that view in the default configuration, it inherits that setting from global options. Set "max-cache-size" for the built-in "_bind" view to a fixed value (2 MB, i.e. the smallest allowed value) to prevent needlessly preallocating memory for its cache RBT hash table. --- bin/named/config.c | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/named/config.c b/bin/named/config.c index 7e4757a4fe..10087b47f3 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -263,6 +263,7 @@ view \"_bind\" chaos {\n\ recursion no;\n\ notify no;\n\ allow-new-zones no;\n\ + max-cache-size 2M;\n\ \n\ # Prevent use of this zone in DNS amplified reflection DoS attacks\n\ rate-limit {\n\ From f9500f824dd2b422b127b87f8c6d35c014ee3740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Tue, 22 Jun 2021 15:28:31 +0200 Subject: [PATCH 3/3] Add CHANGES entry --- CHANGES | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index 0f7ed65ff9..5a036e684b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +5662. [bug] Views with recursion disabled are now configured with a + default cache size of 2 MB, unless "max-cache-size" is + explicitly set. This prevents cache RBT hash tables from + being needlessly preallocated for such views. [GL #2777] + 5661. [bug] A deadlock was introduced when fixing [GL #1875] because when locking the key file mutex for each zone structure that is in a different view, "in-view" logic was not