commit db3ea6af9bdd0b1af16e8792663afdb6b4d407b3 Author: Hristo Venev Date: Mon Oct 13 18:34:37 2014 +0300 strv and everything else: strv_length() should return size_t. Some nasty things can happen if a strv is too big to be processed correctly but still fits in memory. diff --git a/src/activate/activate.c b/src/activate/activate.c index 0a1df37..a1ba90c 100644 --- a/src/activate/activate.c +++ b/src/activate/activate.c @@ -139,7 +139,7 @@ static int launch(char* name, char **argv, char **env, int fds) { static const char* tocopy[] = {"TERM=", "PATH=", "USER=", "HOME="}; _cleanup_strv_free_ char **envp = NULL; _cleanup_free_ char *tmp = NULL; - unsigned n_env = 0, length; + size_t n_env = 0, length; char **s; unsigned i; diff --git a/src/boot/boot-loader.c b/src/boot/boot-loader.c index d44fdb3..aba33ad 100644 --- a/src/boot/boot-loader.c +++ b/src/boot/boot-loader.c @@ -81,8 +81,8 @@ static char *loader_fragment_read_title(const char *fragment) { int boot_loader_read_entries(struct boot_info *info) { _cleanup_strv_free_ char **files = NULL; static const char *loader_dir[] = { "/boot/loader/entries", NULL}; - unsigned int count; - unsigned int i; + size_t count; + size_t i; int err; err = conf_files_list_strv(&files, ".conf", NULL, loader_dir); diff --git a/src/core/namespace.c b/src/core/namespace.c index c221509..4fbffba 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -113,7 +113,7 @@ static int mount_path_compare(const void *a, const void *b) { return 0; } -static void drop_duplicates(BindMount *m, unsigned *n) { +static void drop_duplicates(BindMount *m, size_t *n) { BindMount *f, *t, *previous; assert(m); @@ -433,7 +433,7 @@ int setup_namespace( unsigned mount_flags) { BindMount *m, *mounts = NULL; - unsigned n; + size_t n; int r = 0; if (mount_flags == 0) diff --git a/src/core/unit.c b/src/core/unit.c index 0389e6e..d43cb29 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2721,7 +2721,7 @@ bool unit_need_daemon_reload(Unit *u) { _cleanup_strv_free_ char **t = NULL; char **path; struct stat st; - unsigned loaded_cnt, current_cnt; + size_t loaded_cnt, current_cnt; assert(u); diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index c72d23e..389a003 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -262,6 +262,7 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { _cleanup_free_ char *p = NULL, *s = NULL; char **a; int r; + size_t l; r = file_of_uid(uid, &p); if (r < 0) @@ -292,7 +293,11 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) { return -ENOMEM; strv_uniq(a); - r = strv_length(a); + l = strv_length(a); + if (l > INT_MAX) { + return -ENOMEM; + } + r = l; if (array) *array = a; @@ -583,7 +588,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui _cleanup_free_ char *p = NULL, *s = NULL, *t = NULL; _cleanup_strv_free_ char **a = NULL; _cleanup_free_ uid_t *b = NULL; - unsigned n = 0; + size_t n = 0, alen; int r; r = file_of_seat(seat, &p); @@ -635,7 +640,11 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui } } - r = strv_length(a); + alen = strv_length(a); + if (alen > INT_MAX) { + return -ENOMEM; + } + r = alen; if (sessions) { *sessions = a; diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c index d63e6f9..ff2e167 100644 --- a/src/libsystemd/sd-network/sd-network.c +++ b/src/libsystemd/sd-network/sd-network.c @@ -58,6 +58,7 @@ static int network_get_strv(const char *key, char ***ret) { _cleanup_strv_free_ char **a = NULL; _cleanup_free_ char *s = NULL; int r; + size_t n; assert_return(ret, -EINVAL); @@ -76,7 +77,11 @@ static int network_get_strv(const char *key, char ***ret) { return -ENOMEM; strv_uniq(a); - r = strv_length(a); + n = strv_length(a); + if (n > INT_MAX) { + return -ENOMEM; + } + r = n; *ret = a; a = NULL; @@ -196,6 +201,7 @@ static int network_get_link_strv(const char *key, int ifindex, char ***ret) { _cleanup_free_ char *p = NULL, *s = NULL; _cleanup_strv_free_ char **a = NULL; int r; + size_t n; assert_return(ifindex > 0, -EINVAL); assert_return(ret, -EINVAL); @@ -218,7 +224,11 @@ static int network_get_link_strv(const char *key, int ifindex, char ***ret) { return -ENOMEM; strv_uniq(a); - r = strv_length(a); + n = strv_length(a); + if (n > INT_MAX) { + return -ENOMEM; + } + r = n; *ret = a; a = NULL; diff --git a/src/shared/strv.c b/src/shared/strv.c index 0df978d..9421a02 100644 --- a/src/shared/strv.c +++ b/src/shared/strv.c @@ -101,8 +101,8 @@ char **strv_copy(char * const *l) { return r; } -unsigned strv_length(char * const *l) { - unsigned n = 0; +size_t strv_length(char * const *l) { + size_t n = 0; if (!l) return 0; @@ -116,7 +116,7 @@ unsigned strv_length(char * const *l) { char **strv_new_ap(const char *x, va_list ap) { const char *s; char **a; - unsigned n = 0, i = 0; + size_t n = 0, i = 0; va_list aq; /* As a special trick we ignore all listed strings that equal @@ -219,8 +219,7 @@ int strv_extend_strv_concat(char ***a, char **b, const char *suffix) { char **strv_split(const char *s, const char *separator) { const char *word, *state; - size_t l; - unsigned n, i; + size_t l, n, i; char **r; assert(s); @@ -250,8 +249,7 @@ char **strv_split(const char *s, const char *separator) { int strv_split_quoted(char ***t, const char *s) { const char *word, *state; - size_t l; - unsigned n, i; + size_t l, n, i; char **r; assert(s); @@ -284,7 +282,7 @@ int strv_split_quoted(char ***t, const char *s) { char **strv_split_newlines(const char *s) { char **l; - unsigned n; + size_t n; assert(s); @@ -380,7 +378,7 @@ char *strv_join_quoted(char **l) { int strv_push(char ***l, char *value) { char **c; - unsigned n; + size_t n; if (!value) return 0; @@ -399,7 +397,7 @@ int strv_push(char ***l, char *value) { int strv_push_prepend(char ***l, char *value) { char **c; - unsigned n, i; + size_t n, i; if (!value) return 0; @@ -489,7 +487,7 @@ char **strv_remove(char **l, const char *s) { char **strv_parse_nulstr(const char *s, size_t l) { const char *p; - unsigned c = 0, i = 0; + size_t c = 0, i = 0; char **v; assert(s || l <= 0); diff --git a/src/shared/strv.h b/src/shared/strv.h index 9c9633c..4372363 100644 --- a/src/shared/strv.h +++ b/src/shared/strv.h @@ -35,7 +35,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free); #define _cleanup_strv_free_ _cleanup_(strv_freep) char **strv_copy(char * const *l); -unsigned strv_length(char * const *l) _pure_; +size_t strv_length(char * const *l) _pure_; int strv_extend_strv(char ***a, char **b); int strv_extend_strv_concat(char ***a, char **b, const char *suffix); diff --git a/src/shared/util.c b/src/shared/util.c index 5f6249e..0e03619 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -3188,7 +3188,7 @@ fail: char **replace_env_argv(char **argv, char **env) { char **ret, **i; - unsigned k = 0, l = 0; + size_t k = 0, l = 0; l = strv_length(argv); @@ -3202,7 +3202,7 @@ char **replace_env_argv(char **argv, char **env) { if ((*i)[0] == '$' && (*i)[1] != '{') { char *e; char **w, **m; - unsigned q; + size_t q; e = strv_env_get(env, *i+1); if (e) { diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 8d6d162..c1c93a5 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -4806,7 +4806,7 @@ static int switch_root(sd_bus *bus, char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_free_ char *cmdline_init = NULL; const char *root, *init; - unsigned l; + size_t l; int r; l = strv_length(args);