diff options
author | Luca Boccassi <bluca@debian.org> | 2023-04-28 00:23:30 +0200 |
---|---|---|
committer | Luca Boccassi <bluca@debian.org> | 2023-05-19 16:18:23 +0200 |
commit | d936595672cf3ee7c1c547f8fd30512f82be8784 (patch) | |
tree | d9828ff3c9b9387e78013adbb3f7ee824669f8cc /src/core/manager-serialize.c | |
parent | ratelimit: add ratelimit_left helper (diff) | |
download | systemd-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.c | 23 |
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; |