size_t n, l;
const char *s, *t, *origin;
char *d;
- if (p->rpath) return 0;
- if (!p->rpath_orig) return -1;
+ if (p->rpath || !p->rpath_orig) return 0;
if (!strchr(p->rpath_orig, '$')) {
p->rpath = p->rpath_orig;
return 0;
s = p->rpath_orig;
while ((t=strchr(s, '$'))) {
if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9))
- return -1;
+ return 0;
s = t+1;
n++;
}
- if (n > SSIZE_MAX/PATH_MAX) return -1;
+ if (n > SSIZE_MAX/PATH_MAX) return 0;
if (p->kernel_mapped) {
/* $ORIGIN searches cannot be performed for the main program
* since the library's pathname came from a trusted source
* (either system paths or a call to dlopen). */
if (libc.secure)
- return -1;
+ return 0;
l = readlink("/proc/self/exe", buf, buf_size);
- if (l >= buf_size)
+ if (l == -1) switch (errno) {
+ case ENOENT:
+ case ENOTDIR:
+ case EACCES:
+ break;
+ default:
return -1;
+ }
+ if (l >= buf_size)
+ return 0;
buf[l] = 0;
origin = buf;
} else {
if (strlen(name) > NAME_MAX) return 0;
fd = -1;
if (env_path) fd = path_open(name, env_path, buf, sizeof buf);
- for (p=needed_by; fd == -1 && p; p=p->needed_by)
- if (!fixup_rpath(p, buf, sizeof buf))
+ for (p=needed_by; fd == -1 && p; p=p->needed_by) {
+ if (fixup_rpath(p, buf, sizeof buf) < 0)
+ fd = -2; /* Inhibit further search. */
+ if (p->rpath)
fd = path_open(name, p->rpath, buf, sizeof buf);
+ }
if (fd == -1) {
if (!sys_path) {
char *prefix = 0;