* Fix counting message lines in wall. Patch from Petr Lautrbach.
authorDr. Werner Fink <werner@suse.de>
Tue, 15 Mar 2011 13:16:55 +0000 (13:16 +0000)
committerDr. Werner Fink <werner@suse.de>
Tue, 15 Mar 2011 13:16:55 +0000 (13:16 +0000)
* Fix bad printf conversion specifier in wall. Patch from S├ębastien Luttringer.
* Add patches from Openwall project. Thanks goes to Solar Designer.

git-svn-id: svn://svn.sv.gnu.org/sysvinit/sysvinit/trunk@101 456724a4-4300-0410-8514-c89748c515a2

doc/Changelog
src/bootlogd.c
src/halt.c
src/init.c
src/killall5.c
src/shutdown.c
src/wall.c

index 50e67e7f846ef35ad0f35d8230d30887c617c63d..488baa4b4517283488f5b67a83ff2f361d91c204 100644 (file)
@@ -1,6 +1,9 @@
 sysvinit (2.89dsf) UNRELEASED; urgency=low
 
   [ Werner Fink ]
+  * Fix counting message lines in wall. Patch from Petr Lautrbach.
+  * Fix bad printf conversion specifier in wall. Patch from S├ębastien Luttringer.
+  * Add patches from Openwall project. Thanks goes to Solar Designer.
   * Add code to detect the system consoles with the help of the
     new /proc/consoles files of linux kernel 2.6.38+
   * Try to make utmpdump IPv6 valid, change based on suggestion from
index 3a12f3da890e074506fe4942575b79ab1c3d1517..9343997d5fe3a92d1a54be93afe5640ac8d2bb80 100644 (file)
@@ -108,7 +108,7 @@ void handler(int sig)
 /*
  *     Scan /dev and find the device name.
  */
-static int findtty(char *res, const char *startdir, int rlen, dev_t dev)
+static int findtty(char *res, const char *startdir, size_t rlen, dev_t dev)
 {
        DIR             *dir;
        struct dirent   *ent;
@@ -145,7 +145,7 @@ static int findtty(char *res, const char *startdir, int rlen, dev_t dev)
                if (!S_ISCHR(st.st_mode))
                        continue;
                if (st.st_rdev == dev) {
-                       if ( (int) (strlen(ent->d_name) + strlen(startdir) + 1) >= rlen) {
+                       if ( (strlen(ent->d_name) + strlen(startdir) + 1) >= rlen) {
                                fprintf(stderr, "bootlogd: console device name too long\n");
                                closedir(dir);
                                chdir(olddir);
@@ -208,7 +208,7 @@ int findpty(int *master, int *slave, char *name)
  *     See if a console taken from the kernel command line maps
  *     to a character device we know about, and if we can open it.
  */
-int isconsole(char *s, char *res, int rlen)
+int isconsole(char *s, char *res, size_t rlen)
 {
        struct consdev  *c;
        int             l, sl, i, fd;
@@ -238,7 +238,7 @@ int isconsole(char *s, char *res, int rlen)
  *     Find out the _real_ console. Assume that stdin is connected to
  *     the console device (/dev/console).
  */
-int consolename(char *res, int rlen)
+int consolename(char *res, size_t rlen)
 {
 #ifdef TIOCGDEV
        unsigned int    kdev;
index 499e9734056c487b11e906367f7d6920bc96f6e3..5b9430ccd3d1a0b30fca5eb77f77424f496e85f0 100644 (file)
@@ -239,7 +239,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) {
                /*
index 7d3827c8eb63daffa5595307412f80b6eb60b3a5..d379fb2a856cfabbb5afc3c46a3271b76d863f45 100644 (file)
@@ -89,6 +89,7 @@
 /* Set a signal handler. */
 #define SETSIG(sa, sig, fun, flags) \
                do { \
+                       memset(&sa, 0, sizeof(sa)); \
                        sa.sa_handler = fun; \
                        sa.sa_flags = flags; \
                        sigemptyset(&sa.sa_mask); \
@@ -809,6 +810,24 @@ void console_stty(void)
        (void) close(fd);
 }
 
+static  ssize_t
+safe_write(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
  */
@@ -817,7 +836,7 @@ void print(char *s)
        int fd;
 
        if ((fd = console_open(O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) {
-               write(fd, s, strlen(s));
+               safe_write(fd, s, strlen(s));
                close(fd);
        }
 }
@@ -1669,9 +1688,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));
+               safe_write(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);
@@ -1956,12 +1975,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);
+       safe_write(fds[1], Signature, 8);
 
        return fds[1];
 }
@@ -1991,7 +2013,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, 
@@ -2033,10 +2058,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");
 }
 
@@ -2406,8 +2431,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);
@@ -2415,8 +2440,8 @@ void process_signals()
                /* Path changed 2010-03-20.  Look for the old path for a while. */
                initlog(L_VB, "warning: found obsolete path %s, use %s instead",
                        PWRSTAT_OLD, PWRSTAT);
-               c = 0;
-               read(fd, &c, 1);
+               if (read(fd, &c, 1) != 1)
+                       c = 0;
                pwrstat = c;
                close(fd);
                unlink(PWRSTAT_OLD);
@@ -2533,7 +2558,7 @@ void init_main(void)
                while((rc = wait(&st)) != f)
                        if (rc < 0 && errno == ECHILD)
                                break;
-               write(1, killmsg, sizeof(killmsg) - 1);
+               safe_write(1, killmsg, sizeof(killmsg) - 1);
                while(1) pause();
        }
 #endif
@@ -2808,7 +2833,7 @@ int main(int argc, char **argv)
                p = argv[0];
 
        /* Common umask */
-       umask(022);
+       umask(umask(077) | 022);
 
        /* Quick check */
        if (geteuid() != 0) {
index 7d753bd43e1f51dd5798b8b5d179b1039203b9b4..3d35364c1d01cec1c286bc24ba440e4d4e0cae1f 100644 (file)
@@ -75,6 +75,7 @@ char *Version = "@(#)killall5 2.86 31-Jul-2004 miquels@cistron.nl";
 
 /* Info about a process. */
 typedef struct proc {
+       char *pathname;         /* full path to executable        */
        char *argv0;            /* Name as found out from argv[0] */
        char *argv0base;        /* `basename argv[1]`             */
        char *argv1;            /* Name as found out from argv[1] */
@@ -206,8 +207,8 @@ int mount_proc(void)
                }
                if (pid == 0) {
                        /* Try a few mount binaries. */
-                       execv("/sbin/mount", args);
                        execv("/bin/mount", args);
+                       execv("/sbin/mount", args);
 
                        /* Okay, I give up. */
                        nsyslog(LOG_ERR, "cannot execute mount");
@@ -486,6 +487,7 @@ int readproc(int do_stat)
                if (p->argv0) free(p->argv0);
                if (p->argv1) free(p->argv1);
                if (p->statname) free(p->statname);
+               free(p->pathname);
                free(p);
        }
        plist = NULL;
@@ -505,13 +507,21 @@ int readproc(int do_stat)
 
                /* 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, ')');
@@ -520,18 +530,20 @@ int readproc(int do_stat)
                                        nsyslog(LOG_ERR,
                                        "can't get program name from /proc/%s\n",
                                                path);
+                                       fclose(fp);
                                        if (p->argv0) free(p->argv0);
                                        if (p->argv1) free(p->argv1);
                                        if (p->statname) free(p->statname);
+                                       free(p->pathname);
                                        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);
@@ -546,9 +558,11 @@ int readproc(int do_stat)
                                p->sid = 0;
                                nsyslog(LOG_ERR, "can't read sid from %s\n",
                                        path);
+                               fclose(fp);
                                if (p->argv0) free(p->argv0);
                                if (p->argv1) free(p->argv1);
                                if (p->statname) free(p->statname);
+                               free(p->pathname);
                                free(p);
                                continue;
                        }
@@ -560,6 +574,7 @@ int readproc(int do_stat)
                        if (p->argv0) free(p->argv0);
                        if (p->argv1) free(p->argv1);
                        if (p->statname) free(p->statname);
+                       free(p->pathname);
                        free(p);
                        continue;
                }
@@ -607,6 +622,7 @@ int readproc(int do_stat)
                        if (p->argv0) free(p->argv0);
                        if (p->argv1) free(p->argv1);
                        if (p->statname) free(p->statname);
+                       free(p->pathname);
                        free(p);
                        continue;
                }
@@ -623,6 +639,16 @@ int readproc(int do_stat)
                case DO_STAT:
                        if (stat(path, &st) != 0)
                                break;
+                       else {
+                               char buf[PATH_MAX];
+
+                               f = readlink(path, buf, sizeof buf);
+                               if (f > 0) {
+                                       p->pathname = (char *)xmalloc(f + 1);
+                                       memcpy(p->pathname, buf, f);
+                                       p->pathname[f] = '\0';
+                               }
+                       }
                        p->dev = st.st_dev;
                        p->ino = st.st_ino;
                default:
@@ -761,6 +787,20 @@ PIDQ_HEAD *pidof(char *prog)
 
        /* If we didn't find a match based on dev/ino, try the name. */
        if (!foundone) for (p = plist; p; p = p->next) {
+               if (prog[0] == '/') {
+                       if (!p->pathname)
+                               continue;
+                       if (strcmp(prog, p->pathname)) {
+                               int len = strlen(prog);
+                               if (strncmp(prog, p->pathname, len))
+                                       continue;
+                               if (strcmp(" (deleted)", p->pathname + len))
+                                       continue;
+                       }
+                       add_pid_to_q(q, p);
+                       continue;
+               }
+
                ok = 0;
 
                /*             matching        nonmatching
index 7e997da84e3acee8f29b45e110969d625fc403df..384b4ff1558396e032806e0858c47b10dc8d67b9 100644 (file)
@@ -154,7 +154,7 @@ int init_setenv(char *name, char *value)
        struct init_request     request;
        struct sigaction        sa;
        int                     fd;
-       int                     nl, vl;
+       size_t                  nl, vl;
 
        memset(&request, 0, sizeof(request));
        request.magic = INIT_MAGIC;
@@ -286,7 +286,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);
@@ -627,7 +628,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);
        }
 
@@ -692,6 +694,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);
@@ -715,8 +723,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));
 
index 92d9fb4175bee55e7db253aaaa2ffdd9a2cc2713..e480eee651daaf44b8b905366b3064cb5b657e79 100644 (file)
@@ -102,14 +102,14 @@ int main(int argc, char **argv)
 
   i = 0;
   for (p = buf; *p; p++) {
-       if (*p == '\n' && i++ > MAXLINES) {
+       if (*p == '\n' && ++i >= MAXLINES) {
                *++p = 0;
                break;
        }
   }
 
   openlog("wall", LOG_PID, LOG_USER);
-  syslog(LOG_INFO, "wall: user %s broadcasted %d lines (%d chars)",
+  syslog(LOG_INFO, "wall: user %s broadcasted %d lines (%zu chars)",
        whoami, i, strlen(buf));
   closelog();