Rewrite findtty() in bootlogd.c to not chance working directory, to

reduce the amount of failure that can happin in that function.
This commit is contained in:
Petter Reinholdtsen 2014-02-07 11:06:57 +00:00
parent cc3a4e2f9e
commit de1344feb8
2 changed files with 15 additions and 12 deletions

View File

@ -73,6 +73,8 @@ sysvinit (2.89dsf) UNRELEASED; urgency=low
Debian. Debian.
* Adjust makefile to make it easier to link all binaries statically. * Adjust makefile to make it easier to link all binaries statically.
Patch from Matias A. Fonzo and Dragora. 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

View File

@ -112,55 +112,56 @@ static int findtty(char *res, const char *startdir, size_t rlen, dev_t dev)
{ {
DIR *dir; DIR *dir;
struct dirent *ent; 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; int msglen = strlen(startdir) + 11;
char *msg = malloc(msglen); char *msg = malloc(msglen);
snprintf(msg, msglen, "bootlogd: %s", startdir); snprintf(msg, msglen, "bootlogd: %s", startdir);
perror(msg); perror(msg);
free(msg); free(msg);
chdir(olddir);
return -1; return -1;
} }
while ((ent = readdir(dir)) != NULL) { 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) if (S_ISDIR(st.st_mode)
&& 0 != strcmp(".", ent->d_name) && 0 != strcmp(".", ent->d_name)
&& 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)) if (!S_ISCHR(st.st_mode))
continue; continue;
if (st.st_rdev == dev) { if (st.st_rdev == dev) {
if ( (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"); fprintf(stderr, "bootlogd: console device name too long\n");
closedir(dir); closedir(dir);
chdir(olddir);
return -1; return -1;
} else { } else {
snprintf(res, rlen, "%s/%s", startdir, ent->d_name); snprintf(res, rlen, "%s/%s", startdir, ent->d_name);
closedir(dir); closedir(dir);
chdir(olddir);
return 0; return 0;
} }
} }
} }
closedir(dir); closedir(dir);
chdir(olddir);
return r; return r;
} }