diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ldso/dynlink.c | 26 | 
1 files changed, 18 insertions, 8 deletions
| diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 0eb763e7..4a371839 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -599,8 +599,7 @@ static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)  	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; @@ -609,11 +608,11 @@ static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)  	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 @@ -623,10 +622,18 @@ static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)  		 * 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 { @@ -735,9 +742,12 @@ static struct dso *load_library(const char *name, struct dso *needed_by)  		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; | 
