diff --git a/src/basic/env-util.h b/src/basic/env-util.h index 28338a1458..4063517660 100644 --- a/src/basic/env-util.h +++ b/src/basic/env-util.h @@ -3,6 +3,8 @@ #include "basic-forward.h" +#define ENVIRONMENT_ASSIGNMENTS_MAX 16384U + size_t sc_arg_max(void); bool env_name_is_valid(const char *e); diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 88de34c4ea..5b41e1befe 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1251,6 +1251,14 @@ static int list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_e /* Anyone can call this method */ + if (strv_length(states) > MANAGER_MAX_STATES_PER_CALL) + return sd_bus_error_set(reterr_error, SD_BUS_ERROR_LIMITS_EXCEEDED, + "Too many states in a single query."); + + if (strv_length(patterns) > MANAGER_MAX_PATTERNS_PER_CALL) + return sd_bus_error_set(reterr_error, SD_BUS_ERROR_LIMITS_EXCEEDED, + "Too many patterns in a single query."); + r = sd_bus_message_new_method_return(message, &reply); if (r < 0) return r; @@ -1434,6 +1442,10 @@ static int dump_impl( assert(message); + if (strv_length(patterns) > MANAGER_MAX_PATTERNS_PER_CALL) + return sd_bus_error_set(reterr_error, SD_BUS_ERROR_LIMITS_EXCEEDED, + "Too many patterns in a single query."); + /* 'status' access is the bare minimum always needed for this, as the policy might straight out * forbid a client from querying any information from systemd, regardless of any rate limiting. */ r = mac_selinux_access_check(message, "status", reterr_error); @@ -1880,6 +1892,10 @@ static int method_set_environment(sd_bus_message *message, void *userdata, sd_bu r = sd_bus_message_read_strv(message, &plus); if (r < 0) return r; + + if (strv_length(plus) > ENVIRONMENT_ASSIGNMENTS_MAX) + return sd_bus_error_set(reterr_error, SD_BUS_ERROR_LIMITS_EXCEEDED, + "Too many environment assignments in a single query."); if (!strv_env_is_valid(plus)) return sd_bus_error_set(reterr_error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments"); @@ -1911,6 +1927,9 @@ static int method_unset_environment(sd_bus_message *message, void *userdata, sd_ if (r < 0) return r; + if (strv_length(minus) > ENVIRONMENT_ASSIGNMENTS_MAX) + return sd_bus_error_set(reterr_error, SD_BUS_ERROR_LIMITS_EXCEEDED, + "Too many environment variable names in a single query."); if (!strv_env_name_or_assignment_is_valid(minus)) return sd_bus_error_set(reterr_error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments"); @@ -1947,6 +1966,9 @@ static int method_unset_and_set_environment(sd_bus_message *message, void *userd if (r < 0) return r; + if (strv_length(plus) > ENVIRONMENT_ASSIGNMENTS_MAX || strv_length(minus) > ENVIRONMENT_ASSIGNMENTS_MAX) + return sd_bus_error_set(reterr_error, SD_BUS_ERROR_LIMITS_EXCEEDED, + "Too many environment variable names or assignments in a single query."); if (!strv_env_name_or_assignment_is_valid(minus)) return sd_bus_error_set(reterr_error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments"); @@ -2177,6 +2199,14 @@ static int list_unit_files_by_patterns(sd_bus_message *message, void *userdata, /* Anyone can call this method */ + if (strv_length(states) > MANAGER_MAX_STATES_PER_CALL) + return sd_bus_error_set(reterr_error, SD_BUS_ERROR_LIMITS_EXCEEDED, + "Too many states in a single query."); + + if (strv_length(patterns) > MANAGER_MAX_PATTERNS_PER_CALL) + return sd_bus_error_set(reterr_error, SD_BUS_ERROR_LIMITS_EXCEEDED, + "Too many patterns in a single query."); + r = mac_selinux_access_check(message, "status", reterr_error); if (r < 0) return r; diff --git a/src/core/manager.h b/src/core/manager.h index abf1764d78..9afc70b39a 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -14,9 +14,13 @@ struct libmnt_monitor; -/* Enforce upper limit how many names we allow */ +/* Enforce upper limit on how many names we allow */ #define MANAGER_MAX_NAMES 131072 /* 128K */ +/* Enforce upper limit on the number of patterns/states requested over IPC */ +#define MANAGER_MAX_PATTERNS_PER_CALL 4096U +#define MANAGER_MAX_STATES_PER_CALL 256U + /* On sigrtmin+18, private commands */ enum { MANAGER_SIGNAL_COMMAND_DUMP_JOBS = _COMMON_SIGNAL_COMMAND_PRIVATE_BASE + 0, diff --git a/src/libsystemd/sd-json/json-util.h b/src/libsystemd/sd-json/json-util.h index 34d79d5238..cea2d368b4 100644 --- a/src/libsystemd/sd-json/json-util.h +++ b/src/libsystemd/sd-json/json-util.h @@ -9,8 +9,6 @@ #include "sd-forward.h" #include "string-util.h" /* IWYU pragma: keep */ -#define ENVIRONMENT_ASSIGNMENTS_MAX 1024U - #define JSON_VARIANT_REPLACE(v, q) \ do { \ typeof(v)* _v = &(v); \ diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index a9d15ca5f7..28f64b3c9b 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -435,6 +435,10 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu r = sd_bus_message_read_strv(message, &env); if (r < 0) return r; + + if (strv_length(env) > ENVIRONMENT_ASSIGNMENTS_MAX) + return sd_bus_error_set(error, SD_BUS_ERROR_LIMITS_EXCEEDED, + "Too many environment assignments in a single query."); if (!strv_env_is_valid(env)) return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");