diff options
author | Guillem Jover <guillem@debian.org> | 2014-05-01 16:34:24 +0200 |
---|---|---|
committer | Guillem Jover <guillem@debian.org> | 2015-09-14 05:44:07 +0200 |
commit | 3db7a6eb4fd16b4cea475009bd80be3a41ada014 (patch) | |
tree | 4b0a500fddecee6e1bab692412b4b2d451778f38 /utils/start-stop-daemon.c | |
parent | 3ce3a7adeb8c815734a35b95aee96bacd1aafde4 (diff) | |
download | dpkg-3db7a6eb4fd16b4cea475009bd80be3a41ada014.tar.gz |
s-s-d: Fix short-lived memory leaks
As a side effect now a missing group after ‘:’ on --chuid is a fatal
error.
Warned-by: coverity
Diffstat (limited to 'utils/start-stop-daemon.c')
-rw-r--r-- | utils/start-stop-daemon.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/utils/start-stop-daemon.c b/utils/start-stop-daemon.c index c35f44812..dc1e5f49d 100644 --- a/utils/start-stop-daemon.c +++ b/utils/start-stop-daemon.c @@ -307,6 +307,17 @@ xstrdup(const char *str) fatal("strdup(%s) failed", str); } +static char * +xstrndup(const char *str, size_t n) +{ + char *new_str; + + new_str = strndup(str, n); + if (new_str) + return new_str; + fatal("strndup(%s, %zu) failed", str, n); +} + static void timespec_gettime(struct timespec *ts) { @@ -733,14 +744,15 @@ validate_proc_schedule(void) static void parse_proc_schedule(const char *string) { - char *policy_str, *prio_str; + char *policy_str; + size_t policy_len; int prio = 0; - policy_str = xstrdup(string); - policy_str = strtok(policy_str, ":"); - prio_str = strtok(NULL, ":"); + policy_len = strcspn(string, ":"); + policy_str = xstrndup(string, policy_len); - if (prio_str && parse_unsigned(prio_str, 10, &prio) != 0) + if (string[policy_len] == ':' && + parse_unsigned(string + policy_len + 1, 10, &prio) != 0) fatal("invalid process scheduler priority"); proc_sched = xmalloc(sizeof(*proc_sched)); @@ -764,14 +776,15 @@ parse_proc_schedule(const char *string) static void parse_io_schedule(const char *string) { - char *class_str, *prio_str; + char *class_str; + size_t class_len; int prio = 4; - class_str = xstrdup(string); - class_str = strtok(class_str, ":"); - prio_str = strtok(NULL, ":"); + class_len = strcspn(string, ":"); + class_str = xstrndup(string, class_len); - if (prio_str && parse_unsigned(prio_str, 10, &prio) != 0) + if (string[class_len] == ':' && + parse_unsigned(string + class_len + 1, 10, &prio) != 0) fatal("invalid IO scheduler priority"); io_sched = xmalloc(sizeof(*io_sched)); @@ -970,6 +983,7 @@ parse_options(int argc, char * const *argv) const char *schedule_str = NULL; const char *proc_schedule_str = NULL; const char *io_schedule_str = NULL; + size_t changeuser_len; int c; for (;;) { @@ -1033,9 +1047,12 @@ parse_options(int argc, char * const *argv) case 'c': /* --chuid <username>|<uid> */ /* We copy the string just in case we need the * argument later. */ - changeuser = xstrdup(optarg); - changeuser = strtok(changeuser, ":"); - changegroup = strtok(NULL, ":"); + changeuser_len = strcspn(optarg, ":"); + changeuser = xstrndup(optarg, changeuser_len); + if (optarg[changeuser_len] == ':' && + optarg[changeuser_len + 1] == '\0') + fatal("missing group name"); + changegroup = xstrdup(optarg + changeuser_len + 1); break; case 'g': /* --group <group>|<gid> */ changegroup = optarg; |