aboutsummaryrefslogtreecommitdiffstats
path: root/pseudo_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'pseudo_util.c')
-rw-r--r--pseudo_util.c43
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 {