about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2013-08-23 15:51:59 -0400
committerRich Felker <dalias@aerifal.cx>2013-08-23 15:51:59 -0400
commitd2c42ed25f0488c40f61479ac7feb729d98e1d38 (patch)
treec9e0c7d66e7d79a4a8774e3d0cd28b970a5c08c8
parentcc51505a32930754d2cf281c15caa1829b8436e9 (diff)
downloadmusl-d2c42ed25f0488c40f61479ac7feb729d98e1d38.tar.gz
musl-d2c42ed25f0488c40f61479ac7feb729d98e1d38.tar.xz
musl-d2c42ed25f0488c40f61479ac7feb729d98e1d38.zip
fix bugs in $ORIGIN handling
1. an occurrence of ${ORIGIN} before $ORIGIN would be ignored due to
the strstr logic. (note that rpath contains multiple :-delimited paths
to be searched.)

2. data read by readlink was not null-terminated.
-rw-r--r--src/ldso/dynlink.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index cbddeba7..573af750 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -462,7 +462,9 @@ static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)
 	}
 	n = 0;
 	s = p->rpath_orig;
-	while ((t=strstr(s, "$ORIGIN")) || (t=strstr(s, "${ORIGIN}"))) {
+	while ((t=strchr(s, '$'))) {
+		if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9))
+			return -1;
 		s = t+1;
 		n++;
 	}
@@ -477,8 +479,10 @@ static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)
 		 * (either system paths or a call to dlopen). */
 		if (libc.secure)
 			return -1;
-		if (readlink("/proc/self/exe", buf, buf_size) >= buf_size)
+		l = readlink("/proc/self/exe", buf, buf_size);
+		if (l >= buf_size)
 			return -1;
+		buf[l] = 0;
 		origin = buf;
 	} else {
 		origin = p->name;
@@ -490,11 +494,13 @@ static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)
 
 	d = p->rpath;
 	s = p->rpath_orig;
-	while ((t=strstr(s, "$ORIGIN")) || (t=strstr(s, "${ORIGIN}"))) {
+	while ((t=strchr(s, '$'))) {
 		memcpy(d, s, t-s);
 		d += t-s;
 		memcpy(d, origin, l);
 		d += l;
+		/* It was determined previously that the '$' is followed
+		 * either by "ORIGIN" or "{ORIGIN}". */
 		s = t + 7 + 2*(t[1]=='{');
 	}
 	strcpy(d, s);