diff options
author | Bill Nottingham <notting@redhat.com> | 2004-05-04 16:27:20 +0000 |
---|---|---|
committer | Bill Nottingham <notting@redhat.com> | 2004-05-04 16:27:20 +0000 |
commit | 8bc12cb8bd7088e5f067fb15687204a1837abdc1 (patch) | |
tree | c8bd7a3596fafaef754e01a70e79cf480585d31d | |
parent | 5e212fb145ee5483f7b3134217b9527b18cbd33e (diff) | |
download | initscripts-8bc12cb8bd7088e5f067fb15687204a1837abdc1.tar initscripts-8bc12cb8bd7088e5f067fb15687204a1837abdc1.tar.gz initscripts-8bc12cb8bd7088e5f067fb15687204a1837abdc1.tar.bz2 initscripts-8bc12cb8bd7088e5f067fb15687204a1837abdc1.tar.xz initscripts-8bc12cb8bd7088e5f067fb15687204a1837abdc1.zip |
cleanup fd leaks, mem leaks, other bogosities (#119987, <linux_4ever@yahoo.com>)
-rw-r--r-- | src/initlog.c | 1 | ||||
-rw-r--r-- | src/minilogd.c | 1 | ||||
-rw-r--r-- | src/process.c | 31 | ||||
-rw-r--r-- | src/usernetctl.c | 28 |
4 files changed, 49 insertions, 12 deletions
diff --git a/src/initlog.c b/src/initlog.c index 4320d9bc..13a376ec 100644 --- a/src/initlog.c +++ b/src/initlog.c @@ -63,6 +63,7 @@ void readConfiguration(char *fname) { data=malloc(sbuf.st_size+1); if (read(fd,data,sbuf.st_size)!=sbuf.st_size) { close(fd); + free(data); return; } close(fd); diff --git a/src/minilogd.c b/src/minilogd.c index b33b102a..b7cbc8c0 100644 --- a/src/minilogd.c +++ b/src/minilogd.c @@ -155,6 +155,7 @@ int main(int argc, char **argv) { dup2(sock,0); dup2(sock,1); dup2(sock,2); + close(sock); bzero(&addr, sizeof(addr)); addr.sun_family = AF_LOCAL; diff --git a/src/process.c b/src/process.c index 5a1571e2..c17680bf 100644 --- a/src/process.c +++ b/src/process.c @@ -33,7 +33,7 @@ extern regex_t **regList; int forkCommand(char **args, int *outfd, int *errfd, int *cmdfd, int quiet) { /* Fork command 'cmd', returning pid, and optionally pointer * to open file descriptor fd */ - int fdout, fderr, fdcmd, pid; + int fdout=-1, fderr=-1, fdcmd=-1, pid; int outpipe[2], errpipe[2], fdpipe[2]; int ourpid; @@ -63,6 +63,8 @@ int forkCommand(char **args, int *outfd, int *errfd, int *cmdfd, int quiet) { } else { fdcmd = open("/dev/null",O_WRONLY); } + if (fdout==-1 || fderr==-1 || fdcmd==-1) + return -1; ourpid = getpid(); if ((pid = fork())==-1) { perror("fork"); @@ -139,7 +141,6 @@ int forkCommand(char **args, int *outfd, int *errfd, int *cmdfd, int quiet) { int monitor(char *cmdname, int pid, int numfds, int *fds, int reexec, int quiet, int debug) { struct pollfd *pfds; - char *buf=malloc(8192*sizeof(char)); char *outbuf=NULL; char *tmpstr=NULL; int x,y,rc=-1; @@ -165,6 +166,9 @@ int monitor(char *cmdname, int pid, int numfds, int *fds, int reexec, int quiet, usleep(500); if (((x=poll(pfds,numfds,500))==-1)&&errno!=EINTR) { perror("poll"); + free(pfds); + if (procpath) + free(procpath); return -1; } if (!reexec) { @@ -176,16 +180,22 @@ int monitor(char *cmdname, int pid, int numfds, int *fds, int reexec, int quiet, if (stat(procpath,&sbuf)&&!stat("/proc/cpuinfo",&sbuf)) done=1; } + if (x<0) + continue; y=0; while (y<numfds) { if ( x && ((pfds[y].revents & (POLLIN | POLLPRI)) )) { int bytesread = 0; do { - buf=calloc(8192,sizeof(char)); + char *buf=calloc(8192,sizeof(char)); bytesread = read(pfds[y].fd,buf,8192); if (bytesread==-1) { perror("read"); + free(pfds); + if (procpath) + free(procpath); + free(buf); return -1; } if (bytesread) { @@ -245,6 +255,7 @@ int monitor(char *cmdname, int pid, int numfds, int *fds, int reexec, int quiet, } } } + free(buf); } while ( bytesread==8192 ); } y++; @@ -256,8 +267,18 @@ int monitor(char *cmdname, int pid, int numfds, int *fds, int reexec, int quiet, if (quiet && output) { write(1,outbuf,strlen(outbuf)); } + free(pfds); + if (procpath) + free(procpath); + if(outbuf) + free(outbuf); return (rc); } + free(pfds); + if (procpath) + free(procpath); + if(outbuf) + free(outbuf); return 0; } @@ -283,10 +304,14 @@ int runCommand(char *cmd, int reexec, int quiet, int debug) { cmdname+=3; if (!reexec) { pid=forkCommand(args,&fds[0],&fds[1],NULL,quiet); + if (pid == -1) + return -1; x=monitor(cmdname,pid,2,fds,reexec,quiet,debug); } else { setenv("IN_INITLOG","yes",1); pid=forkCommand(args,NULL,NULL,&fds[0],quiet); + if (pid == -1) + return -1; unsetenv("IN_INITLOG"); x=monitor(cmdname,pid,1,&fds[0],reexec,quiet,debug); } diff --git a/src/usernetctl.c b/src/usernetctl.c index 2574d725..aa77c8a5 100644 --- a/src/usernetctl.c +++ b/src/usernetctl.c @@ -22,7 +22,7 @@ #include <limits.h> /* This will be running setuid root, so be careful! */ -static char * safeEnviron[] = { +static const char * safeEnviron[] = { "PATH=/bin:/sbin:/usr/bin:/usr/sbin", "HOME=/root", NULL @@ -39,11 +39,11 @@ usage(void) { } static size_t -testSafe(char *ifaceConfig) { +testSafe(char *ifaceConfig, int fd) { struct stat sb; /* These shouldn't be symbolic links -- anal, but that's fine w/ mkj. */ - if (lstat(ifaceConfig, &sb)) { + if (fstat(fd, &sb)) { fprintf(stderr, "failed to stat %s: %s\n", ifaceConfig, strerror(errno)); exit(1); @@ -78,15 +78,25 @@ userCtl(char *file) { int fd = -1, retval = NOT_FOUND; size_t size = 0; - size = testSafe(file); - - buf = contents = malloc(size + 2); - + /* Open the file and then test it to see if we like it. This way + we avoid switcheroo attacks. */ if ((fd = open(file, O_RDONLY)) == -1) { fprintf(stderr, "failed to open %s: %s\n", file, strerror(errno)); exit(1); } + size = testSafe(file, fd); + if (size > INT_MAX) { + fprintf(stderr, "file %s is too big\n", file); + exit(1); + } + + buf = contents = malloc(size + 2); + if (contents == NULL) { + fprintf(stderr, "failed to allocate memory\n"); + exit(1); + } + if (read(fd, contents, size) != size) { perror("error reading device configuration"); exit(1); @@ -105,7 +115,7 @@ userCtl(char *file) { while (chptr >= contents && isspace(*chptr)) chptr--; *(++chptr) = '\0'; - if (!strncmp(contents, "USERCTL=", 8)) { + if (!strncasecmp(contents, "USERCTL=", 8)) { contents += 8; if ((contents[0] == '"' && contents[strlen(contents) - 1] == '"') || @@ -116,7 +126,7 @@ userCtl(char *file) { contents[strlen(contents) - 1] = '\0'; } - if (!strcmp(contents, "yes") || !strcmp(contents, "true")) + if (!strcasecmp(contents, "yes") || !strcasecmp(contents, "true")) retval = FOUND_TRUE; else retval = FOUND_FALSE; |