bin/88117: support of $ORIGIN in rtld-elf.
Nakata Maho
maho at FreeBSD.org
Fri Oct 28 00:00:30 PDT 2005
>Number: 88117
>Category: bin
>Synopsis: support of $ORIGIN in rtld-elf.
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Fri Oct 28 07:00:28 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator: Nakata Maho
>Release: 5.4-RELEASE
>Organization:
FreeBSD.org
>Environment:
FreeBSD satie.private.org 5.4-RELEASE-p6 FreeBSD 5.4-RELEASE-p6 #0: Sat Sep 3 09:47:26 JST 2005 maho at satie.private.org:/usr/src/sys/i386/compile/MAHO i386
>Description:
if $ORIGIN is passed via -rpath, option of ld, we replace $ORIGIN
by full path of current directory where the execultables or shared
libs exist.
e.g.
% pwd
/u/l/c
gcc -Wl,-rpath,'$ORIGIN' foo.o -ltest1 -ltest2
ldd ./a.out
./a.out
libc.so.5 => /lib/libc.so.5 (0x123333)
libtest1.so.6 => /u/l/c/libtest1.so.6 (0x12345678)
libtest2.so.3 => /u/l/c/libtest2.so.3 (0x90ABCDEF)
etc. we also allow such usage as well, like LD_LIBRARY_PATH.
gcc -Wl,-rpath,'$ORIGIN/../:$ORIGIN' foo.o -ltest1 -ltest2
>How-To-Repeat:
>Fix:
--- /usr/src/libexec/rtld-elf/rtld.c.org Sun Oct 23 19:11:26 2005
+++ /usr/src/libexec/rtld-elf/rtld.c Tue Oct 25 14:49:34 2005
@@ -862,6 +862,10 @@
{
char *pathname;
char *name;
+ char *rpath;
+ char *origin_realpath;
+ char *p, *q, *r;
+ int i;
if (strchr(xname, '/') != NULL) { /* Hard coded pathname */
if (xname[0] != '/' && !trust) {
@@ -878,9 +882,31 @@
dbg(" Searching for \"%s\"", name);
+/* expand $ORIGIN in refobj->rpath if not NULL */
+ rpath=NULL;
+ if(refobj->rpath!=NULL){
+ rpath = xmalloc(PATH_MAX); /* full rpath with $ORIGIN expanded */
+ origin_realpath = xmalloc(PATH_MAX);
+ realpath(refobj->path, origin_realpath); /* expand $ORIGIN by real path */
+ i=strlen(origin_realpath);
+ while(origin_realpath[i]!='/') {origin_realpath[i--]='\0';} origin_realpath[i]='\0';/* basename */
+ q=(char *)refobj->rpath;
+ p=strstr(q,"$ORIGIN");
+ r=rpath;
+ if(p==NULL) {rpath=(char *)refobj->rpath;}else{
+ while(p!=NULL){
+ for(i=0;q+i<p;i++){ *(r++)=*(q+i);}
+ strcpy(r,origin_realpath);
+ r=r+strlen(origin_realpath);
+ q=p+strlen("$ORIGIN");
+ p=strstr(q,"$ORIGIN");
+ }
+ }
+ }
+
if ((pathname = search_library_path(name, ld_library_path)) != NULL ||
(refobj != NULL &&
- (pathname = search_library_path(name, refobj->rpath)) != NULL) ||
+ (pathname = search_library_path(name, rpath)) != NULL) ||
(pathname = search_library_path(name, gethints())) != NULL ||
(pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL)
return pathname;
I don't know how to free rpath and origin_realpath...
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list