diff options
Diffstat (limited to 'pseudo_util.c')
-rw-r--r-- | pseudo_util.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/pseudo_util.c b/pseudo_util.c index c867ed6..b58036f 100644 --- a/pseudo_util.c +++ b/pseudo_util.c @@ -43,6 +43,7 @@ static struct pseudo_variables pseudo_env[] = { { "PSEUDO_BINDIR", 13, NULL }, { "PSEUDO_LIBDIR", 13, NULL }, { "PSEUDO_LOCALSTATEDIR", 20, NULL }, + { "PSEUDO_IGNORE_PATHS", 19, NULL }, { "PSEUDO_PASSWD", 13, NULL }, { "PSEUDO_CHROOT", 13, NULL }, { "PSEUDO_UIDS", 11, NULL }, @@ -158,7 +159,7 @@ pseudo_get_value(const char *key) { if (pseudo_util_initted == -1) pseudo_init_util(); - for (i = 0; pseudo_env[i].key && memcmp(pseudo_env[i].key, key, pseudo_env[i].key_len + 1); i++) + for (i = 0; pseudo_env[i].key && strcmp(pseudo_env[i].key, key); i++) ; /* Check if the environment has it and we don't ... @@ -187,7 +188,7 @@ pseudo_set_value(const char *key, const char *value) { if (pseudo_util_initted == -1) pseudo_init_util(); - for (i = 0; pseudo_env[i].key && memcmp(pseudo_env[i].key, key, pseudo_env[i].key_len + 1); i++) + for (i = 0; pseudo_env[i].key && strcmp(pseudo_env[i].key, key); i++) ; if (pseudo_env[i].key) { @@ -678,7 +679,7 @@ pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurre if (!leave_this && is_dir) { int is_link = S_ISLNK(buf->st_mode); if (link_recursion >= PSEUDO_MAX_LINK_RECURSION && is_link) { - pseudo_diag("link recursion too deep, not expanding path '%s'.\n", newpath); + pseudo_debug(PDBGF_PATH, "link recursion too deep, not expanding path '%s'.\n", newpath); is_link = 0; } if (is_link) { @@ -688,14 +689,15 @@ pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurre linklen = readlink(newpath, linkbuf, pseudo_path_max()); if (linklen == -1) { - pseudo_diag("uh-oh! '%s' seems to be a symlink, but I can't read it. Ignoring.", newpath); + pseudo_debug(PDBGF_PATH, "uh-oh! '%s' seems to be a symlink, but I can't read it. Ignoring.\n", newpath); + *pcurrent = current; return 0; } /* null-terminate buffer */ linkbuf[linklen] = '\0'; - /* absolute symlink means start over! */ + /* absolute symlink means go back to root */ if (*linkbuf == '/') { - current = newpath; + current = root; } else { /* point back at the end of the previous path... */ current -= (elen + 1); @@ -790,11 +792,9 @@ static char *pathbufs[PATHBUFS] = { 0 }; static int pathbuf = 0; /* Canonicalize path. "base", if present, is an already-canonicalized - * path of baselen characters, presumed not to end in a /. path is - * the new path to be canonicalized. The tricky part is that path may - * contain symlinks, which must be resolved. - * if "path" starts with a /, then it is an absolute path, and - * we ignore base. + * path of baselen characters, presumed not to end in a / unless it is + * just "/". path is the new path to be canonicalized. The tricky part + * is that path may contain symlinks, which must be resolved. */ char * pseudo_fix_path(const char *base, const char *path, size_t rootlen, size_t baselen, size_t *lenp, int leave_last) { @@ -808,13 +808,28 @@ pseudo_fix_path(const char *base, const char *path, size_t rootlen, size_t basel pseudo_diag("can't fix empty path.\n"); return 0; } + if (baselen == 1) { + baselen = 0; + } + if (rootlen == 1) { + rootlen = 0; + } newpathlen = pseudo_path_max(); + pathlen = strlen(path); + /* Crazy shell code (e.g. libtool) can pass in a command pipeline as a path which exceeds the max path + * length the system can support (6000+ chars). This will fail in libc or the syscall but if we don't + * do something here, we'd segfault before it can do that. Leave path unchanged and let libc deal + * with it. + */ + if ((pathlen + baselen) >= newpathlen) { + return path; + } if (!pathbufs[pathbuf]) { pathbufs[pathbuf] = malloc(newpathlen); } newpath = pathbufs[pathbuf]; pathbuf = (pathbuf + 1) % PATHBUFS; - pathlen = strlen(path); + /* a trailing slash has special meaning, but processing * trailing slashes is expensive. */ @@ -966,6 +981,7 @@ pseudo_setupenv() { } snprintf(newenv, len, "%s:%s64", libdir_path, libdir_path); SETENV(PRELINK_PATH, newenv, 1); + free(newenv); } else if (!strstr(ld_library_path, libdir_path)) { size_t len = strlen(ld_library_path) + 1 + strlen(libdir_path) + 1 + (strlen(libdir_path) + 2) + 1; char *newenv = malloc(len); @@ -974,6 +990,7 @@ pseudo_setupenv() { } snprintf(newenv, len, "%s:%s:%s64", ld_library_path, libdir_path, libdir_path); SETENV(PRELINK_PATH, newenv, 1); + free(newenv); } else { /* nothing to do, ld_library_path exists and contains * our preferred path */ @@ -1594,7 +1611,7 @@ pseudo_logfile(char *filename, char *defname, int prefer_fd) { } free(filename); } - fd = open(pseudo_path, O_WRONLY | O_APPEND | O_CREAT, 0644); + fd = open(pseudo_path, O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC, 0644); if (fd == -1) { pseudo_diag("help: can't open log file %s: %s\n", pseudo_path, strerror(errno)); } else { |