提交 568b8075 编写于 作者: R Rich Felker

proper path searching for dynamic linker

first, use $LD_LIBRARY_PATH unless suid. if that fails, read path from
/etc/ld-musl-$ARCH.path and fallback to a builtin default.
上级 f9370318
#include <string.h> #include <string.h>
#include <elf.h> #include <elf.h>
#define ETC_LDSO_PATH "/etc/ld-musl-i386.path"
#define IS_COPY(x) ((x)==R_386_COPY) #define IS_COPY(x) ((x)==R_386_COPY)
static inline void do_single_reloc(size_t *reloc_addr, int type, size_t sym_val, size_t sym_size, unsigned char *base_addr, size_t addend) static inline void do_single_reloc(size_t *reloc_addr, int type, size_t sym_val, size_t sym_size, unsigned char *base_addr, size_t addend)
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#include <string.h> #include <string.h>
#include <elf.h> #include <elf.h>
#define ETC_LDSO_PATH "/etc/ld-musl-x86_64.path"
#define IS_COPY(x) ((x)==R_X86_64_COPY) #define IS_COPY(x) ((x)==R_X86_64_COPY)
static inline void do_single_reloc(size_t *reloc_addr, int type, size_t sym_val, size_t sym_size, unsigned char *base_addr, size_t addend) static inline void do_single_reloc(size_t *reloc_addr, int type, size_t sym_val, size_t sym_size, unsigned char *base_addr, size_t addend)
......
...@@ -48,7 +48,7 @@ struct dso ...@@ -48,7 +48,7 @@ struct dso
}; };
static struct dso *head, *tail, *libc; static struct dso *head, *tail, *libc;
static int trust_env; static char *env_path, *sys_path;
#define AUX_CNT 15 #define AUX_CNT 15
#define DYN_CNT 34 #define DYN_CNT 34
...@@ -205,6 +205,20 @@ static void *map_library(int fd, size_t *lenp, unsigned char **basep, size_t *dy ...@@ -205,6 +205,20 @@ static void *map_library(int fd, size_t *lenp, unsigned char **basep, size_t *dy
return map; return map;
} }
static int path_open(const char *name, const char *search)
{
char buf[2*NAME_MAX+2];
const char *s, *z;
int l, fd;
for (s=search; *s; s+=l+!!z) {
z = strchr(s, ':');
l = z ? z-s : strlen(s);
snprintf(buf, sizeof buf, "%.*s/%s", l, s, name);
if ((fd = open(buf, O_RDONLY))>=0) return fd;
}
return -1;
}
static struct dso *load_library(const char *name) static struct dso *load_library(const char *name)
{ {
unsigned char *base, *map; unsigned char *base, *map;
...@@ -242,14 +256,20 @@ static struct dso *load_library(const char *name) ...@@ -242,14 +256,20 @@ static struct dso *load_library(const char *name)
if (name[0] == '/') { if (name[0] == '/') {
fd = open(name, O_RDONLY); fd = open(name, O_RDONLY);
} else { } else {
static const char path[] = "/lib/\0/usr/local/lib/\0/usr/lib/\0";
const char *s;
char buf[NAME_MAX+32];
if (strlen(name) > NAME_MAX || strchr(name, '/')) return 0; if (strlen(name) > NAME_MAX || strchr(name, '/')) return 0;
for (s=path; *s; s+=strlen(s)+1) { fd = -1;
strcpy(buf, s); if (env_path) fd = path_open(name, env_path);
strcat(buf, name); if (fd < 0) {
if ((fd = open(buf, O_RDONLY))>=0) break; if (!sys_path) {
FILE *f = fopen(ETC_LDSO_PATH, "r");
if (f) {
if (getline(&sys_path, (size_t[1]){0}, f) > 0)
sys_path[strlen(sys_path)-1]=0;
fclose(f);
}
}
if (sys_path) fd = path_open(name, sys_path);
else fd = path_open(name, "/lib:/usr/local/lib:/usr/lib");
} }
} }
if (fd < 0) return 0; if (fd < 0) return 0;
...@@ -342,11 +362,19 @@ void *__dynlink(int argc, char **argv, size_t *got) ...@@ -342,11 +362,19 @@ void *__dynlink(int argc, char **argv, size_t *got)
struct dso lib, app; struct dso lib, app;
/* Find aux vector just past environ[] */ /* Find aux vector just past environ[] */
for (i=argc+1; argv[i]; i++); for (i=argc+1; argv[i]; i++)
if (!memcmp(argv[i], "LD_LIBRARY_PATH=", 16))
env_path = argv[i]+16;
auxv = (void *)(argv+i+1); auxv = (void *)(argv+i+1);
decode_vec(auxv, aux, AUX_CNT); decode_vec(auxv, aux, AUX_CNT);
/* Only trust user/env if kernel says we're not suid/sgid */
if ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
|| aux[AT_GID]!=aux[AT_EGID]) {
env_path = 0;
}
/* Relocate ldso's DYNAMIC pointer and load vector */ /* Relocate ldso's DYNAMIC pointer and load vector */
decode_vec((void *)(got[0] += aux[AT_BASE]), lib_dyn, DYN_CNT); decode_vec((void *)(got[0] += aux[AT_BASE]), lib_dyn, DYN_CNT);
...@@ -385,11 +413,6 @@ void *__dynlink(int argc, char **argv, size_t *got) ...@@ -385,11 +413,6 @@ void *__dynlink(int argc, char **argv, size_t *got)
/* At this point the standard library is fully functional */ /* At this point the standard library is fully functional */
/* Only trust user/env if kernel says we're not suid/sgid */
trust_env = (aux[0]&0x7800)==0x7800
&& aux[AT_UID]==aux[AT_EUID]
&& aux[AT_GID]==aux[AT_EGID];
head = tail = &app; head = tail = &app;
libc = &lib; libc = &lib;
app.next = 0; app.next = 0;
...@@ -398,6 +421,7 @@ void *__dynlink(int argc, char **argv, size_t *got) ...@@ -398,6 +421,7 @@ void *__dynlink(int argc, char **argv, size_t *got)
reloc_all(head); reloc_all(head);
free_all(head); free_all(head);
free(sys_path);
errno = 0; errno = 0;
return (void *)aux[AT_ENTRY]; return (void *)aux[AT_ENTRY];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册