diff --git a/chkconfig.c b/chkconfig.c index 8730cfba..fcc0a8bc 100644 --- a/chkconfig.c +++ b/chkconfig.c @@ -107,10 +107,10 @@ static void reloadSystemd(void) { } static int delService(char *name, int type, int level) { - int i, j, k, numservs, rc; + int i, j, k, numservs=0, rc; glob_t globres; struct service s; - struct service *services; + struct service *services = NULL; if ((rc = readServiceInfo(name, type, &s, 0))) { readServiceError(rc, name); @@ -123,15 +123,18 @@ static int delService(char *name, int type, int level) { if (LSB && level == -1) { numservs = readServices(&services); - if (numservs < 0) - return 1; + if (numservs < 0) { + rc=1; + goto finish; + } for (i = 0; i < numservs; i++) { if (services[i].startDeps) { for (j = 0; services[i].startDeps[j].name; j++) { if (!strcmp(services[i].startDeps[j].name, s.name)) { if (services[i].currentLevels) { - return 1; + rc=1; + goto finish; } } } @@ -141,8 +144,10 @@ static int delService(char *name, int type, int level) { if (!strcmp(services[i].stopDeps[j].name, s.name)) { for (k = 0; k <= 6; k++) { if (isConfigured(services[i].name, k, NULL, NULL) && - !(services[i].currentLevels & (1 << k))) - return 1; + !(services[i].currentLevels & (1 << k))) { + rc=1; + goto finish; + } } } } @@ -160,7 +165,11 @@ static int delService(char *name, int type, int level) { } } } - return 0; + +finish: + freeService(s); + freeServices(services, numservs); + return rc; } static inline int laterThan(int i, int j) { @@ -295,6 +304,7 @@ static int frobDependencies(struct service *s) { int numservs = 0; int nResolved = 0; int i; + int r = 0; numservs = readServices(&servs); if (numservs < 0) @@ -319,8 +329,10 @@ static int frobDependencies(struct service *s) { /* Resolve our target */ if (frobOneDependencies(s, servs, numservs, 1, LSB) == -1) - return 1; - return 0; + r=1; + + freeServices(servs, numservs); + return r; } static int addService(char *name, int type) { @@ -510,7 +522,6 @@ static int serviceNameCmp(const void *a, const void *b) { static int listService(char *item, int type) { DIR *dir; struct dirent *ent; - struct service *services; int i; int numServices = 0; int numServicesAlloced; @@ -521,6 +532,7 @@ static int listService(char *item, int type) { return showServiceInfoByName(item, type, 0); if (type & TYPE_INIT_D) { + struct service *services; numServices = readServices(&services); if (numServices < 0) return 1; @@ -530,10 +542,10 @@ static int listService(char *item, int type) { for (i = 0; i < numServices; i++) { if (systemd && isOverriddenBySystemd(services[i].name)) continue; - if (showServiceInfo(services[i], 1)) { - return 1; - } + (void) showServiceInfo(services[i], 1); } + + free(services); } if (isXinetdEnabled() && type & TYPE_XINETD) { @@ -579,8 +591,14 @@ static int listService(char *item, int type) { t = s; for (i = 0; i < numServices; i++, s++) { char *tmp = malloc(strlen(s->name) + 5); + if (!tmp) { + closedir(dir); + free(t); + return 1; + } sprintf(tmp, "%s:", s->name); printf("\t%-15s\t%s\n", tmp, s->levels ? _("on") : _("off")); + free(tmp); } closedir(dir); free(t); diff --git a/leveldb.c b/leveldb.c index 564a2079..7450e755 100644 --- a/leveldb.c +++ b/leveldb.c @@ -44,7 +44,7 @@ int selinux_restore(const char *name) { struct selabel_handle *hnd = NULL; struct stat buf; - security_context_t newcon = NULL; + char *newcon = NULL; int r = -1; hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); @@ -140,6 +140,8 @@ int readDescription(char *start, char *bufstop, char **english_desc, } { char *desc = malloc(end - start + 1); + if (!desc) + return 1; strncpy(desc, start, end - start); desc[end - start] = '\0'; @@ -152,6 +154,7 @@ int readDescription(char *start, char *bufstop, char **english_desc, while (isspace(*start) && start < bufstop) start++; if (start == bufstop || *start != '#') { + free(desc); return 1; } @@ -160,6 +163,7 @@ int readDescription(char *start, char *bufstop, char **english_desc, while (isspace(*start) && start < bufstop) start++; if (start == bufstop) { + free(desc); return 1; } @@ -222,15 +226,22 @@ int readXinetdServiceInfo(char *name, struct service *service) { struct stat sb; char *buf = NULL, *ptr; char *eng_desc = NULL, *start; + int r; - asprintf(&filename, XINETDDIR "/%s", name); - - if ((fd = open(filename, O_RDONLY)) < 0) + r = asprintf(&filename, XINETDDIR "/%s", name); + if (r < 0) + return -1; + fd = open(filename, O_RDONLY); + free(filename); + if(fd < 0) goto out_err; + fstat(fd, &sb); if (!S_ISREG(sb.st_mode)) goto out_err; buf = malloc(sb.st_size + 1); + if (!buf) + goto out_err; if (read(fd, buf, sb.st_size) != sb.st_size) goto out_err; close(fd); @@ -300,15 +311,31 @@ int readXinetdServiceInfo(char *name, struct service *service) { buf = ptr; } *service = serv; + free(start); return 0; out_err: if (fd >= 0) close(fd); free(buf); - free(filename); return -1; } + +void freeService(struct service s) { + free(s.name); + free(s.startDeps); + free(s.stopDeps); + free(s.softStartDeps); + free(s.softStopDeps); + free(s.provides); +} + +void freeServices(struct service *s, int n) { + for (int i = 0; i < n; i++) + freeService(s[i]); + free(s); +} + int readServices(struct service **services) { DIR *dir; struct dirent *ent; @@ -350,6 +377,8 @@ int readServices(struct service **services) { if (!readServiceInfo(ent->d_name, TYPE_INIT_D, servs + numservs, 0)) numservs++; } + + closedir(dir); *services = servs; return numservs; } @@ -525,6 +554,7 @@ int parseServiceInfo(int fd, char *name, struct service *service, int honorHide, tmpbufstart = (char *)malloc(sb.st_size + 1); if (tmpbufstart == NULL) { close(fd); + munmap(bufstart, sb.st_size); return -1; } @@ -719,6 +749,7 @@ int parseServiceInfo(int fd, char *name, struct service *service, int honorHide, if (!partialOk && ((serv.levels == -1) || !serv.desc || (!serv.isLSB && (serv.sPriority == -1 || serv.kPriority == 100)))) { + freeService(serv); return 1; } @@ -845,7 +876,7 @@ int setXinetdService(struct service s, int on) { int oldfd, newfd; char oldfname[100], newfname[100]; char tmpstr[50]; - char *buf, *ptr, *tmp; + char *buf, *ptr, *tmp, *start; struct stat sb; mode_t mode; int r; @@ -874,6 +905,7 @@ int setXinetdService(struct service s, int on) { free(buf); return -1; } + start = buf; while (buf) { tmp = buf; ptr = strchr(buf, '\n'); @@ -894,6 +926,7 @@ int setXinetdService(struct service s, int on) { } buf = ptr; } + free(start); close(newfd); unlink(oldfname); r = rename(newfname, oldfname); @@ -1089,12 +1122,12 @@ int runlevelsToTargets(int runlevels, char ***targets, int *n_targets) { char **tmp; int n_ret = 0; int found = 0; - char *t; int i, j; int r; for (i = 0; i <= 6; i++) { if (1 << i & runlevels) { + char *t = NULL; runlevel[8] = '0' + i; r = readSystemdUnitProperty(runlevel, "Id", &t); if (r < 0) @@ -1109,6 +1142,7 @@ int runlevelsToTargets(int runlevels, char ***targets, int *n_targets) { if (!found) { tmp = (char **)realloc(ret, sizeof(char *) * (n_ret + 1)); if (tmp == NULL) { + free(t); r = -ENOMEM; goto fail; } diff --git a/leveldb.h b/leveldb.h index e308d86e..bfaa9aee 100644 --- a/leveldb.h +++ b/leveldb.h @@ -56,6 +56,8 @@ struct service { int parseLevels(char *str, int emptyOk); +void freeService(struct service s); +void freeServices(struct service *s, int n); /* returns 0 on success, 1 if the service is not chkconfig-able, -1 if an I/O error occurs (in which case errno can be checked) */ int readServiceInfo(char *name, int type, struct service *service, diff --git a/ntsysv.c b/ntsysv.c index 3ab9c57a..8164cd72 100644 --- a/ntsysv.c +++ b/ntsysv.c @@ -318,6 +318,7 @@ static int getServices(struct service **servicesPtr, int *numServicesPtr, if (!(dir = opendir(RUNLEVELS "/init.d"))) { fprintf(stderr, "failed to open " RUNLEVELS "/init.d: %s\n", strerror(errno)); + free(services); return 2; } @@ -372,6 +373,7 @@ static int getServices(struct service **servicesPtr, int *numServicesPtr, if (!(dir = opendir(XINETDDIR))) { fprintf(stderr, "failed to open " XINETDDIR ": %s\n", strerror(errno)); + freeServices(services, numServices); return 2; } @@ -400,6 +402,7 @@ static int getServices(struct service **servicesPtr, int *numServicesPtr, fprintf(stderr, _("error reading info for service %s: %s\n"), ent->d_name, strerror(errno)); closedir(dir); + freeServices(services, numServices); return 2; } else if (!rc) numServices++; @@ -408,8 +411,11 @@ static int getServices(struct service **servicesPtr, int *numServicesPtr, if (err) { fprintf(stderr, _("error reading from directory %s: %s\n"), XINETDDIR, strerror(err)); + freeServices(services, numServices); return 1; } + + closedir(dir); } getSystemdServices(&services, &numServices);