52 lines
2.2 KiB
Diff
52 lines
2.2 KiB
Diff
From 65d848e9b31bdc6caedcac378375943e72d1011f Mon Sep 17 00:00:00 2001
|
|
From: Lennart Poettering <lennart@poettering.net>
|
|
Date: Wed, 20 Apr 2022 22:30:22 +0200
|
|
Subject: [PATCH] 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
|
|
---
|
|
src/libsystemd/sd-bus/bus-track.c | 16 +++++++++++++---
|
|
1 file changed, 13 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c
|
|
index 4c44162108c4d..e403555f8f83c 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;
|