From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.2 required=3.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 670491F677 for ; Wed, 30 Aug 2023 05:10:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1693372246; bh=Av4c6BJsbmDqyg3znroslC5pb1BngEwdGjVuVSQQSqs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ZUNApcFUY6mWol4bRuuACAHIIGe8+lCqqnDH3zVKVJe+wm0j0MQA8eUE9MDA11tjO 3IqsT309EgTHXjCmAqopmmmIcv5U7WnT5RD0cRehdfEmFJA1FL/sIKpZn0Jcw/HW4j Y2aUz7rzPy9Rq8hqckzEtMQJvfIqTmnTXgom+SZQ= From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 7/7] xap_helper.h: fix double-free on OpenBSD hdestroy Date: Wed, 30 Aug 2023 05:10:45 +0000 Message-Id: <20230830051045.330641-8-e@80x24.org> In-Reply-To: <20230830051045.330641-1-e@80x24.org> References: <20230830051045.330641-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: hdestroy on OpenBSD assumes each key in the table can be freed, so use strdup to fulfil that requirement. This behavior differs from tested behavior on glibc and FreeBSD, as well as what I can see from reading the musl and NetBSD source code. OpenBSD may be the only relevant OS which requires this workaround. --- lib/PublicInbox/xap_helper.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/PublicInbox/xap_helper.h b/lib/PublicInbox/xap_helper.h index 92210511..17085adc 100644 --- a/lib/PublicInbox/xap_helper.h +++ b/lib/PublicInbox/xap_helper.h @@ -460,6 +460,16 @@ static enum exc_iter dump_roots_iter(struct req *req, return ITER_OK; } +static char *hsearch_enter_key(char *s) +{ +#if defined(__OpenBSD__) /* hdestroy frees each key */ + char *ret = strdup(s); + if (!ret) perror("strdup"); + return ret; +#endif // glibc, musl, FreeBSD, NetBSD do not free keys + return s; +} + static bool cmd_dump_roots(struct req *req) { CLEANUP_DUMP_ROOTS struct dump_roots_tmp drt = {}; @@ -511,7 +521,8 @@ static bool cmd_dump_roots(struct req *req) } for (size_t i = 0; i < tot; ) { ENTRY e; - e.key = drt.entries[i++]; + e.key = hsearch_enter_key(drt.entries[i++]); + if (!e.key) return false; e.data = drt.entries[i++]; if (!hsearch(e, ENTER)) { warn("hsearch(%s => %s, ENTER)", e.key,