From: Claudio Jeker Subject: bgpd: fix accounting in chash.c To: tech@openbsd.org Date: Thu, 7 May 2026 11:04:35 +0200 The accounting in chash.c has two issues: - ch_table_resize() did not increase the global type->t_counts->cc_num_extendible value and so a later _ch_destroy() would underflow the accounting. - ch_sub_free() can be called with NULL, NULL arguments and then the accounting needs to be skipped. Fixing these issues is trivial. -- :wq Claudio Index: chash.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/chash.c,v diff -u -p -r1.9 chash.c --- chash.c 17 Mar 2026 10:31:03 -0000 1.9 +++ chash.c 6 May 2026 08:45:47 -0000 @@ -512,8 +512,10 @@ static void ch_sub_free(const struct ch_type *type, struct ch_table *t, struct ch_group *table, struct ch_meta *meta) { - t->ch_counts.cc_num_tables--; - type->t_counts->cc_num_tables--; + if (table != NULL) { + t->ch_counts.cc_num_tables--; + type->t_counts->cc_num_tables--; + } free(table); free(meta); } @@ -523,7 +525,7 @@ ch_sub_free(const struct ch_type *type, * Return 0 on success, -1 on failure and set errno. */ static int -ch_table_resize(struct ch_table *t) +ch_table_resize(const struct ch_type *type, struct ch_table *t) { struct ch_group **tables; struct ch_meta **metas; @@ -563,6 +565,7 @@ ch_table_resize(struct ch_table *t) t->ch_metas = metas; t->ch_counts.cc_num_extendible += oldsize; + type->t_counts->cc_num_extendible += oldsize; return 0; } @@ -627,7 +630,7 @@ ch_table_grow(const struct ch_type *type /* check if the extendible hashing table needs to grow */ if (meta->cs_local_level == t->ch_level) { - if (ch_table_resize(t) == -1) + if (ch_table_resize(type, t) == -1) goto fail; } @@ -720,7 +723,7 @@ _ch_init(const struct ch_type *type, str if (ch_sub_alloc(type, t, &table, &meta) == -1) goto fail; - if (ch_table_resize(t) == -1) + if (ch_table_resize(type, t) == -1) goto fail; ch_table_fill(t, 0, table, meta);