diff -upk.orig sysvinit-2.86.orig/src/halt.c sysvinit-2.86/src/halt.c --- sysvinit-2.86.orig/src/halt.c 2007-01-06 15:44:00 +0000 +++ sysvinit-2.86/src/halt.c 2007-01-06 16:20:36 +0000 @@ -227,7 +227,10 @@ int main(int argc, char **argv) exit(1); } - (void)chdir("/"); + if (chdir("/")) { + fprintf(stderr, "%s: chdir(/): %m\n", progname); + exit(1); + } if (!do_hard && !do_nothing) { /* diff -upk.orig sysvinit-2.86.orig/src/init.c sysvinit-2.86/src/init.c --- sysvinit-2.86.orig/src/init.c 2007-01-06 15:44:00 +0000 +++ sysvinit-2.86/src/init.c 2007-01-06 16:53:54 +0000 @@ -719,6 +719,24 @@ void console_stty(void) (void) close(fd); } +static ssize_t +write_loop(int fd, const char *buffer, size_t count) +{ + ssize_t offset = 0; + + while (count > 0) { + ssize_t block = write(fd, &buffer[offset], count); + + if (block < 0 && errno == EINTR) + continue; + if (block <= 0) + return offset ? offset : block; + offset += block; + count -= block; + } + return offset; +} + /* * Print to the system console */ @@ -727,7 +745,7 @@ void print(char *s) int fd; if ((fd = console_open(O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) { - write(fd, s, strlen(s)); + write_loop(fd, s, strlen(s)); close(fd); } } @@ -1549,9 +1567,9 @@ int ask_runlevel(void) if (fd < 0) return('S'); while(!strchr("0123456789S", lvl)) { - write(fd, prompt, sizeof(prompt) - 1); - buf[0] = 0; - read(fd, buf, sizeof(buf)); + write_loop(fd, prompt, sizeof(prompt) - 1); + if (read(fd, buf, sizeof(buf)) <= 0) + buf[0] = 0; if (buf[0] != 0 && (buf[1] == '\r' || buf[1] == '\n')) lvl = buf[0]; if (islower(lvl)) lvl = toupper(lvl); @@ -1820,12 +1838,15 @@ int make_pipe(int fd) { int fds[2]; - pipe(fds); + if (pipe(fds)) { + initlog(L_VB, "pipe: %m"); + return -1; + } dup2(fds[0], fd); close(fds[0]); fcntl(fds[1], F_SETFD, 1); fcntl(fd, F_SETFD, 0); - write(fds[1], Signature, 8); + write_loop(fds[1], Signature, 8); return fds[1]; } @@ -1854,7 +1875,10 @@ void re_exec(void) /* * construct a pipe fd --> STATE_PIPE and write a signature */ - fd = make_pipe(STATE_PIPE); + if ((fd = make_pipe(STATE_PIPE)) < 0) { + sigprocmask(SIG_SETMASK, &oldset, NULL); + initlog(L_CO, "Attempt to re-exec failed"); + } /* * It's a backup day today, so I'm pissed off. Being a BOFH, however, @@ -1898,10 +1922,10 @@ void re_exec(void) * We shouldn't be here, something failed. * Bitch, close the state pipe, unblock signals and return. */ + init_freeenv(env); close(fd); close(STATE_PIPE); sigprocmask(SIG_SETMASK, &oldset, NULL); - init_freeenv(env); initlog(L_CO, "Attempt to re-exec failed"); } @@ -2257,8 +2281,8 @@ void process_signals() /* See _what_ kind of SIGPWR this is. */ pwrstat = 0; if ((fd = open(PWRSTAT, O_RDONLY)) >= 0) { - c = 0; - read(fd, &c, 1); + if (read(fd, &c, 1) != 1) + c = 0; pwrstat = c; close(fd); unlink(PWRSTAT); @@ -2370,7 +2394,7 @@ int init_main() while((rc = wait(&st)) != f) if (rc < 0 && errno == ECHILD) break; - write(1, killmsg, sizeof(killmsg) - 1); + write_loop(1, killmsg, sizeof(killmsg) - 1); while(1) pause(); } #endif diff -upk.orig sysvinit-2.86.orig/src/killall5.c sysvinit-2.86/src/killall5.c --- sysvinit-2.86.orig/src/killall5.c 2007-01-06 15:44:00 +0000 +++ sysvinit-2.86/src/killall5.c 2007-01-06 16:11:13 +0000 @@ -210,13 +210,21 @@ int readproc() /* Read SID & statname from it. */ if ((fp = fopen(path, "r")) != NULL) { - buf[0] = 0; - fgets(buf, sizeof(buf), fp); + if (!fgets(buf, sizeof(buf), fp)) + buf[0] = '\0'; + + if (buf[0] == '\0') { + nsyslog(LOG_ERR, + "can't read from %s\n", path); + fclose(fp); + free(p); + continue; + } /* See if name starts with '(' */ s = buf; - while (*s != ' ') s++; - s++; + while (*s && *s != ' ') s++; + if (*s) s++; if (*s == '(') { /* Read program name. */ q = strrchr(buf, ')'); @@ -225,15 +233,16 @@ int readproc() nsyslog(LOG_ERR, "can't get program name from %s\n", path); + fclose(fp); free(p); continue; } s++; } else { q = s; - while (*q != ' ') q++; + while (*q && *q != ' ') q++; } - *q++ = 0; + if (*q) *q++ = 0; while (*q == ' ') q++; p->statname = (char *)xmalloc(strlen(s)+1); strcpy(p->statname, s); @@ -248,6 +257,7 @@ int readproc() p->sid = 0; nsyslog(LOG_ERR, "can't read sid from %s\n", path); + fclose(fp); free(p); continue; } diff -upk.orig sysvinit-2.86.orig/src/shutdown.c sysvinit-2.86/src/shutdown.c --- sysvinit-2.86.orig/src/shutdown.c 2007-01-06 15:44:00 +0000 +++ sysvinit-2.86/src/shutdown.c 2007-01-06 16:19:50 +0000 @@ -253,7 +253,8 @@ int spawn(int noerr, char *prog, ...) argv[i] = NULL; va_end(ap); - chdir("/"); + if (chdir("/")) + exit(1); environ = clean_env; execvp(argv[0], argv); @@ -583,7 +584,8 @@ int main(int argc, char **argv) /* Read pid of running shutdown from a file */ if ((fp = fopen(SDPID, "r")) != NULL) { - fscanf(fp, "%d", &pid); + if (fscanf(fp, "%d", &pid) != 1) + pid = 0; fclose(fp); } @@ -648,6 +650,12 @@ int main(int argc, char **argv) break; } + /* Go to the root directory */ + if (chdir("/")) { + fprintf(stderr, "shutdown: chdir(/): %m\n"); + exit(1); + } + /* Create a new PID file. */ unlink(SDPID); umask(022); @@ -671,8 +679,6 @@ int main(int argc, char **argv) sa.sa_handler = stopit; sigaction(SIGINT, &sa, NULL); - /* Go to the root directory */ - chdir("/"); if (fastboot) close(open(FASTBOOT, O_CREAT | O_RDWR, 0644)); if (forcefsck) close(open(FORCEFSCK, O_CREAT | O_RDWR, 0644));