Rod Evans <[EMAIL PROTECTED]> wrote:

> Joerg Schilling wrote:
> > Is there a way to reliably retrieve the path to a library?
> > 
> > I tried to opendir("/proc/<pid>/path/")
> > and readdir()/readlink() the entries. If all library 
> > names differ, this allows to find the path to any lib of
> > interest.
> > 
> > Unfortunately, this does not help if there are two 
> > libraries with the same name (e.g. /tmp/libm.so.2
> > and /lib/libm.so.2). Is there a way to get the 
> > path that is related to a handle returned by dlopen()?
>
> You can use dlinfo() to get the origin of the dlopen()
> caller, together with the pathnames that were opened:

Thank you, but both do not help for the purpose I like to use it.
I need to get a path name that is reliable and useable for security checks.

I found a solution using dlsym and procfs.
The problem is that I need an address from inside the module in case 
I like to get the name for an arbitrary library handle. Do you believe that it
should always work to try retrieving the address for "_DYNAMIC"?

The code below detects the case when somebody did rename or unlink the 
object after it has been loaded:

#include <procfs.h> 
 
 
getlibpath(handle, path, len) 
        void    *handle; 
        char    *path; 
        size_t  len; 
{ 
        struct prmap    pm; 
        int             f; 
        char            nbuf[PATH_MAX]; 
        uintptr_t       p; 
        int             l = -1; 
 
        path[0] = '\0'; 
 
        p = dlsym(handle, "_DYNAMIC"); 
        if (p == NULL) 
                p = dlsym(handle, "_GLOBAL_OFFSET_TABLE_"); 
        if (p == NULL) 
                p = dlsym(handle, "_PROCEDURE_LINKAGE_TABLE_"); 
        if (p == NULL) 
                (-1); 
         
        snprintf(nbuf, sizeof (nbuf), "/proc/%lld/map", 
                                (long long) getpid()); 
        f = open(nbuf, 0); 
        if (f < 0) 
                return (-1); 
 
        while (read(f, &pm, sizeof (pm)) > 0) { 
                if (p >= pm.pr_vaddr && p <= (pm.pr_vaddr + pm.pr_size)) { 
                        l = getxpath(pm.pr_mapname, path, len); 
                        break; 
                } 
        } 
        close(f); 
        return (l); 
} 

int 
getprocpath(path, len) 
        char    *path; 
        size_t  len; 
{ 
        return (getxpath("a.out", path, len)); 
} 

int 
getxpath(name, path, len) 
        char    *name; 
        char    *path; 
        size_t  len; 
{ 
        DIR     *d; 
        struct dirent *de; 
        char    dbuf[1024]; 
        char    *dp; 
        char    *n; 
        int     l = -1; 
 
        path[0] = '\0'; 
 
        snprintf(dbuf, sizeof (dbuf), "/proc/%lld/path/", 
                                (long long) getpid()); 
 
        d = opendir(dbuf); 
        if (d == NULL) { 
                perror("opendir"); 
                exit(1); 
        } 
        dp = dbuf + strlen(dbuf); 
        while (de = readdir(d)) { 
                n = de->d_name; 
                if (strcmp(n, name)) 
                        continue; 
                snprintf(dp, sizeof (dbuf) - (dp - dbuf), "%s", n); 
                l = readlink(dbuf, path, len); 
                if (l >= 0 && l < len) 
                        path[l] = '\0'; 
                break; 
        } 
        return (l); 
} 

Jörg

-- 
 EMail:[EMAIL PROTECTED] (home) Jörg Schilling D-13353 Berlin
       [EMAIL PROTECTED]                (uni)  
       [EMAIL PROTECTED]     (work) Blog: http://schily.blogspot.com/
 URL:  http://cdrecord.berlios.de/old/private/ ftp://ftp.berlios.de/pub/schily
_______________________________________________
opensolaris-discuss mailing list
opensolaris-discuss@opensolaris.org

Reply via email to