Rewrite findtty() in bootlogd.c to not chance working directory, to
authorPetter Reinholdtsen <pere@hungry.com>
Fri, 7 Feb 2014 11:06:57 +0000 (11:06 +0000)
committerPetter Reinholdtsen <pere@hungry.com>
Fri, 7 Feb 2014 11:06:57 +0000 (11:06 +0000)
reduce the amount of failure that can happin in that function.

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

doc/Changelog
src/bootlogd.c

index c1e70a2d472abd7a8078e9f861e74124a4ab470c..1758dd763915957b2e53e16b8b088a24e3e3ae7f 100644 (file)
@@ -73,6 +73,8 @@ sysvinit (2.89dsf) UNRELEASED; urgency=low
     Debian.
   * Adjust makefile to make it easier to link all binaries statically.
     Patch from Matias A. Fonzo and Dragora.
     Debian.
   * Adjust makefile to make it easier to link all binaries statically.
     Patch from Matias A. Fonzo and Dragora.
+  * Rewrite findtty() in bootlogd.c to not chance working directory, to
+    reduce the amount of failure that can happin in that function.
 
  -- Petter Reinholdtsen <pere@hungry.com>  Sun Apr 11 11:28:55 CEST 2010
 
 
  -- Petter Reinholdtsen <pere@hungry.com>  Sun Apr 11 11:28:55 CEST 2010
 
index f6c8716d00fa672290d32e8bc7751d3f14f188e4..34d05c201f35b4cb4910193630819ae26504a696 100644 (file)
@@ -112,55 +112,56 @@ static int findtty(char *res, const char *startdir, size_t rlen, dev_t dev)
 {
        DIR             *dir;
        struct dirent   *ent;
 {
        DIR             *dir;
        struct dirent   *ent;
-       struct stat     st;
        int             r = -1;
        int             r = -1;
-       char *olddir = getcwd(NULL, 0);
 
 
-       if (chdir(startdir) < 0 || (dir = opendir(".")) == NULL) {
+       if ((dir = opendir(startdir)) == NULL) {
                int msglen = strlen(startdir) + 11;
                char *msg = malloc(msglen);
                snprintf(msg, msglen, "bootlogd: %s", startdir);
                perror(msg);
                free(msg);
                int msglen = strlen(startdir) + 11;
                char *msg = malloc(msglen);
                snprintf(msg, msglen, "bootlogd: %s", startdir);
                perror(msg);
                free(msg);
-               chdir(olddir);
                return -1;
        }
        while ((ent = readdir(dir)) != NULL) {
                return -1;
        }
        while ((ent = readdir(dir)) != NULL) {
-               if (lstat(ent->d_name, &st) != 0)
+               struct stat st;
+               int pathlen = strlen(startdir) + strlen(ent->d_name) + 2;
+               char *path = malloc(pathlen);
+               snprintf(path, pathlen, "%s/%s", startdir, ent->d_name);
+
+               if (lstat(path, &st) != 0) {
+                       free(path);
                        continue;
                        continue;
+               }
                if (S_ISDIR(st.st_mode)
                    && 0 != strcmp(".", ent->d_name)
                    && 0 != strcmp("..", ent->d_name)) {
                if (S_ISDIR(st.st_mode)
                    && 0 != strcmp(".", ent->d_name)
                    && 0 != strcmp("..", ent->d_name)) {
-                       char *path = malloc(rlen);
-                       snprintf(path, rlen, "%s/%s", startdir, ent->d_name);
                        r = findtty(res, path, rlen, dev);
                        r = findtty(res, path, rlen, dev);
-                       free(path);
                        if (0 == r) { /* device found, return */
                        if (0 == r) { /* device found, return */
+                               free(path);
                                closedir(dir);
                                closedir(dir);
-                               chdir(olddir);
                                return 0;
                        }
                                return 0;
                        }
+                       free(path);
                        continue;
                }
                        continue;
                }
+               free(path);
+               path = NULL;
                if (!S_ISCHR(st.st_mode))
                        continue;
                if (st.st_rdev == dev) {
                        if ( (strlen(ent->d_name) + strlen(startdir) + 1) >= rlen) {
                                fprintf(stderr, "bootlogd: console device name too long\n");
                                closedir(dir);
                if (!S_ISCHR(st.st_mode))
                        continue;
                if (st.st_rdev == dev) {
                        if ( (strlen(ent->d_name) + strlen(startdir) + 1) >= rlen) {
                                fprintf(stderr, "bootlogd: console device name too long\n");
                                closedir(dir);
-                               chdir(olddir);
                                return -1;
                        } else {
                                snprintf(res, rlen, "%s/%s", startdir, ent->d_name);
                                closedir(dir);
                                return -1;
                        } else {
                                snprintf(res, rlen, "%s/%s", startdir, ent->d_name);
                                closedir(dir);
-                               chdir(olddir);
                                return 0;
                        }
                }
        }
        closedir(dir);
 
                                return 0;
                        }
                }
        }
        closedir(dir);
 
-       chdir(olddir);
        return r;
 }
 
        return r;
 }