When checking to see if a shared object is already loaded, look for
a device/inode match if no pathname match is found.
This commit is contained in:
parent
926ea445fe
commit
7360ae0f2a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=50609
@ -27,6 +27,7 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
@ -47,7 +48,7 @@ static int protflags(int); /* Elf flags -> mmap protection */
|
||||
* for the shared object. Returns NULL on failure.
|
||||
*/
|
||||
Obj_Entry *
|
||||
map_object(int fd, const char *path)
|
||||
map_object(int fd, const char *path, const struct stat *sb)
|
||||
{
|
||||
Obj_Entry *obj;
|
||||
union {
|
||||
@ -228,6 +229,10 @@ map_object(int fd, const char *path)
|
||||
}
|
||||
|
||||
obj = obj_new();
|
||||
if (sb != NULL) {
|
||||
obj->dev = sb->st_dev;
|
||||
obj->ino = sb->st_ino;
|
||||
}
|
||||
obj->mapbase = mapbase;
|
||||
obj->mapsize = mapsize;
|
||||
obj->textsize = round_page(segs[0]->p_vaddr + segs[0]->p_memsz) -
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <err.h>
|
||||
@ -244,7 +245,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
||||
if (aux_info[AT_EXECFD] != NULL) { /* Load the main program. */
|
||||
int fd = aux_info[AT_EXECFD]->a_un.a_val;
|
||||
dbg("loading main program");
|
||||
obj_main = map_object(fd, argv0);
|
||||
obj_main = map_object(fd, argv0, NULL);
|
||||
close(fd);
|
||||
if (obj_main == NULL)
|
||||
die();
|
||||
@ -983,20 +984,42 @@ static Obj_Entry *
|
||||
load_object(char *path)
|
||||
{
|
||||
Obj_Entry *obj;
|
||||
int fd = -1;
|
||||
struct stat sb;
|
||||
|
||||
for (obj = obj_list->next; obj != NULL; obj = obj->next)
|
||||
if (strcmp(obj->path, path) == 0)
|
||||
break;
|
||||
|
||||
if (obj == NULL) { /* First use of this object, so we must map it in */
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* If we didn't find a match by pathname, open the file and check
|
||||
* again by device and inode. This avoids false mismatches caused
|
||||
* by multiple links or ".." in pathnames.
|
||||
*
|
||||
* To avoid a race, we open the file and use fstat() rather than
|
||||
* using stat().
|
||||
*/
|
||||
if (obj == NULL) {
|
||||
if ((fd = open(path, O_RDONLY)) == -1) {
|
||||
_rtld_error("Cannot open \"%s\"", path);
|
||||
return NULL;
|
||||
}
|
||||
if (fstat(fd, &sb) == -1) {
|
||||
_rtld_error("Cannot fstat \"%s\"", path);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
for (obj = obj_list->next; obj != NULL; obj = obj->next) {
|
||||
if (obj->ino == sb.st_ino && obj->dev == sb.st_dev) {
|
||||
close(fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obj == NULL) { /* First use of this object, so we must map it in */
|
||||
dbg("loading \"%s\"", path);
|
||||
obj = map_object(fd, path);
|
||||
obj = map_object(fd, path, &sb);
|
||||
close(fd);
|
||||
if (obj == NULL) {
|
||||
free(path);
|
||||
|
@ -49,6 +49,7 @@ typedef unsigned char bool;
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
struct stat;
|
||||
struct Struct_Obj_Entry;
|
||||
|
||||
typedef struct Struct_Objlist_Entry {
|
||||
@ -82,6 +83,8 @@ typedef struct Struct_Obj_Entry {
|
||||
Objlist dldags; /* Object belongs to these dlopened DAGs (%) */
|
||||
Objlist dagmembers; /* DAG has these members (%) */
|
||||
char *path; /* Pathname of underlying file (%) */
|
||||
dev_t dev; /* Object's filesystem's device */
|
||||
ino_t ino; /* Object's inode number */
|
||||
unsigned long mark; /* Set to "curmark" to avoid repeat visits */
|
||||
int refcount;
|
||||
int dl_refcount; /* Number of times loaded by dlopen */
|
||||
@ -135,7 +138,7 @@ typedef struct Struct_Obj_Entry {
|
||||
#define RTLD_VERSION 1
|
||||
|
||||
extern void _rtld_error(const char *, ...) __printflike(1, 2);
|
||||
extern Obj_Entry *map_object(int, const char *);
|
||||
extern Obj_Entry *map_object(int, const char *, const struct stat *);
|
||||
extern void *xcalloc(size_t);
|
||||
extern void *xmalloc(size_t);
|
||||
extern char *xstrdup(const char *);
|
||||
|
Loading…
Reference in New Issue
Block a user