From: Lennart Poettering Date: Wed, 20 Apr 2022 20:30:22 +0000 (+0200) Subject: sd-bus: switch to a manual overflow check in sd_bus_track_add_name() X-Git-Tag: v251-rc2~88 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7f40cb7c86b0fff3a82096a9499570bad9c19fd2;p=thirdparty%2Fsystemd.git sd-bus: switch to a manual overflow check in sd_bus_track_add_name() This is generally used in a directly client controllable way, hence we should handle ref count overflow gracefully, instead of hitting an assert(). As discussed: https://github.com/systemd/systemd/pull/23099#discussion_r854341850 --- diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c index 4c44162108c..e403555f8f8 100644 --- a/src/libsystemd/sd-bus/bus-track.c +++ b/src/libsystemd/sd-bus/bus-track.c @@ -48,7 +48,7 @@ static struct track_item* track_item_free(struct track_item *i) { return mfree(i); } -DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(struct track_item, track_item, track_item_free); +DEFINE_PRIVATE_TRIVIAL_UNREF_FUNC(struct track_item, track_item, track_item_free); DEFINE_TRIVIAL_CLEANUP_FUNC(struct track_item*, track_item_unref); DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(track_item_hash_ops, char, string_hash_func, string_compare_func, struct track_item, track_item_free); @@ -190,8 +190,18 @@ _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) { i = hashmap_get(track->names, name); if (i) { - if (track->recursive) - track_item_ref(i); + if (track->recursive) { + assert(i->n_ref > 0); + + /* Manual oveflow check (instead of a DEFINE_TRIVIAL_REF_FUNC() helper or so), so + * that we can return a proper error, given this is almost always called in a + * directly client controllable way, and thus better should never hit an assertion + * here. */ + if (i->n_ref >= UINT_MAX) + return -EOVERFLOW; + + i->n_ref++; + } bus_track_remove_from_queue(track); return 0;