From d2c42ed25f0488c40f61479ac7feb729d98e1d38 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 23 Aug 2013 15:51:59 -0400 Subject: 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. --- src/ldso/dynlink.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') 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); -- cgit v1.2.1