Disable the shared cache between resolvers for now.
authorflorian <florian@openbsd.org>
Sat, 29 Jun 2024 17:25:56 +0000 (17:25 +0000)
committerflorian <florian@openbsd.org>
Sat, 29 Jun 2024 17:25:56 +0000 (17:25 +0000)
Since the latest libunbound update the frontend process would segfault
about once a day on one of my MX servers with what looks like a
use-after-free deep inside of libunbound.

Maybe we are poking too much at internals and the shared cache is too
much of a hack. #ifdef for now to ease investigation, but it is
possible that this code just has to go.

sbin/unwind/resolver.c

index 5f02544..ee2a83c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: resolver.c,v 1.166 2024/05/21 05:00:48 jsg Exp $      */
+/*     $OpenBSD: resolver.c,v 1.167 2024/06/29 17:25:56 florian Exp $  */
 
 
 /*
@@ -158,8 +158,10 @@ void                        asr_resolve_done(struct asr_result *, void *);
 void                    new_resolver(enum uw_resolver_type,
                             enum uw_resolver_state);
 struct uw_resolver     *create_resolver(enum uw_resolver_type);
+#ifdef UNIFIED_CACHE
 void                    setup_unified_caches(void);
 void                    set_unified_cache(struct uw_resolver *);
+#endif /* UNIFIED_CACHE */
 void                    free_resolver(struct uw_resolver *);
 void                    set_forwarders(struct uw_resolver *,
                             struct uw_forwarder_head *, int);
@@ -222,10 +224,12 @@ struct event_base         *ev_base;
 RB_GENERATE(force_tree, force_tree_entry, entry, force_tree_cmp)
 
 int                             val_id = -1;
+#ifdef UNIFIED_CACHE
 struct slabhash                        *unified_msg_cache;
 struct rrset_cache             *unified_rrset_cache;
 struct key_cache               *unified_key_cache;
 struct val_neg_cache           *unified_neg_cache;
+#endif /* UNIFIED_CACHE */
 
 int                             dns64_present;
 int                             available_afs = HAVE_IPV4 | HAVE_IPV6;
@@ -431,7 +435,9 @@ resolver(int debug, int verbose)
                fatalx("local libunbound/util/alloc.c diff lost");
        alloc_clear(&cache_alloc_test);
 
+#ifdef UNIFIED_CACHE
        setup_unified_caches();
+#endif /* UNIFIED_CACHE */
 
        TAILQ_INIT(&autoconf_forwarder_list);
        TAILQ_INIT(&trust_anchors);
@@ -1156,7 +1162,9 @@ new_resolver(enum uw_resolver_type type, enum uw_resolver_state state)
                check_resolver(resolvers[type]);
                break;
        case VALIDATING:
+#ifdef UNIFIED_CACHE
                set_unified_cache(resolvers[type]);
+#endif /* UNIFIED_CACHE */
                /* FALLTHROUGH */
        case RESOLVING:
                resolvers[type]->state = state;
@@ -1166,6 +1174,7 @@ new_resolver(enum uw_resolver_type type, enum uw_resolver_state state)
        }
 }
 
+#ifdef UNIFIED_CACHE
 void
 set_unified_cache(struct uw_resolver *res)
 {
@@ -1198,6 +1207,7 @@ set_unified_cache(struct uw_resolver *res)
                fatalx("failed to set unified caches, libunbound/validator/"
                    "validator.c diff lost");
 }
+#endif /* UNIFIED_CACHE */
 
 static const struct {
        const char *name;
@@ -1393,8 +1403,6 @@ create_resolver(enum uw_resolver_type type)
 void
 free_resolver(struct uw_resolver *res)
 {
-       struct val_env  *val_env;
-
        if (res == NULL)
                return;
 
@@ -1402,8 +1410,11 @@ free_resolver(struct uw_resolver *res)
                res->stop = 1;
        else {
                evtimer_del(&res->check_ev);
+#ifdef UNIFIED_CACHE
                if (res->ctx != NULL) {
                        if (res->ctx->env->msg_cache == unified_msg_cache) {
+                               struct val_env  *val_env;
+
                                val_env = (struct val_env*)
                                    res->ctx->env->modinfo[val_id];
                                res->ctx->env->msg_cache = NULL;
@@ -1414,12 +1425,14 @@ free_resolver(struct uw_resolver *res)
                                res->ctx->env->neg_cache = NULL;
                        }
                }
+#endif /* UNIFIED_CACHE */
                ub_ctx_delete(res->ctx);
                asr_resolver_free(res->asr_ctx);
                free(res);
        }
 }
 
+#ifdef UNIFIED_CACHE
 void
 setup_unified_caches(void)
 {
@@ -1470,6 +1483,7 @@ setup_unified_caches(void)
        val_env->neg_cache = NULL;
        ub_ctx_delete(ctx);
 }
+#endif /* UNIFIED_CACHE */
 
 void
 set_forwarders(struct uw_resolver *res, struct uw_forwarder_head
@@ -1836,6 +1850,7 @@ show_mem(pid_t pid)
        struct ctl_mem_info      cmi;
 
        memset(&cmi, 0, sizeof(cmi));
+#ifdef UNIFIED_CACHE
        cmi.msg_cache_used = slabhash_get_mem(unified_msg_cache);
        cmi.msg_cache_max = slabhash_get_size(unified_msg_cache);
        cmi.rrset_cache_used = slabhash_get_mem(&unified_rrset_cache->table);
@@ -1844,6 +1859,7 @@ show_mem(pid_t pid)
        cmi.key_cache_max = slabhash_get_size(unified_key_cache->slab);
        cmi.neg_cache_used = unified_neg_cache->use;
        cmi.neg_cache_max = unified_neg_cache->max;
+#endif /* UNIFIED_CACHE */
        resolver_imsg_compose_frontend(IMSG_CTL_MEM_INFO, pid, &cmi,
            sizeof(cmi));