summaryrefslogtreecommitdiffstats
path: root/src/core/manager-serialize.c
diff options
context:
space:
mode:
authorLuca Boccassi <bluca@debian.org>2023-04-28 00:23:30 +0200
committerLuca Boccassi <bluca@debian.org>2023-05-19 16:18:23 +0200
commitd936595672cf3ee7c1c547f8fd30512f82be8784 (patch)
treed9828ff3c9b9387e78013adbb3f7ee824669f8cc /src/core/manager-serialize.c
parentratelimit: add ratelimit_left helper (diff)
downloadsystemd-d936595672cf3ee7c1c547f8fd30512f82be8784.tar.xz
systemd-d936595672cf3ee7c1c547f8fd30512f82be8784.zip
manager: restrict Dump*() to privileged callers or ratelimit
Dump*() methods can take quite some time due to the amount of data to serialize, so they can potentially stall the manager. Make them privileged, as they are debugging tools anyway. Use a new 'dump' capability for polkit, and the 'reload' capability for SELinux, as that's also non-destructive but slow. If the caller is not privileged, allow it but rate limited to 10 calls every 10 minutes.
Diffstat (limited to 'src/core/manager-serialize.c')
-rw-r--r--src/core/manager-serialize.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c
index 4570f06b73..c2b6fc1db6 100644
--- a/src/core/manager-serialize.c
+++ b/src/core/manager-serialize.c
@@ -165,6 +165,14 @@ int manager_serialize(
(void) serialize_item_format(f, "user-lookup", "%i %i", copy0, copy1);
}
+ (void) serialize_item_format(f,
+ "dump-ratelimit",
+ USEC_FMT " " USEC_FMT " %u %u",
+ m->dump_ratelimit.begin,
+ m->dump_ratelimit.interval,
+ m->dump_ratelimit.num,
+ m->dump_ratelimit.burst);
+
bus_track_serialize(m->subscribed, f, "subscribed");
r = dynamic_user_serialize(m, f, fds);
@@ -550,6 +558,21 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
* remains set until all serialized contents are handled. */
if (deserialize_varlink_sockets)
(void) varlink_server_deserialize_one(m->varlink_server, val, fds);
+ } else if ((val = startswith(l, "dump-ratelimit="))) {
+ usec_t begin, interval;
+ unsigned num, burst;
+
+ if (sscanf(val, USEC_FMT " " USEC_FMT " %u %u", &begin, &interval, &num, &burst) != 4)
+ log_notice("Failed to parse dump ratelimit, ignoring: %s", val);
+ else {
+ /* If we changed the values across versions, flush the counter */
+ if (interval != m->dump_ratelimit.interval || burst != m->dump_ratelimit.burst)
+ m->dump_ratelimit.num = 0;
+ else
+ m->dump_ratelimit.num = num;
+ m->dump_ratelimit.begin = begin;
+ }
+
} else {
ManagerTimestamp q;