sync with OpenBSD -current
This commit is contained in:
parent
34a3d7e18a
commit
ee68147dcd
30 changed files with 722 additions and 211 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: library.c,v 1.93 2023/12/19 16:13:22 deraadt Exp $ */
|
||||
/* $OpenBSD: library.c,v 1.94 2024/01/16 19:07:31 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Dale Rahn
|
||||
|
@ -99,7 +99,7 @@ elf_object_t *
|
|||
_dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
|
||||
{
|
||||
struct range_vector imut, mut;
|
||||
int libfile, i;
|
||||
int libfile, libc = -1, i;
|
||||
struct load_list *next_load, *load_list = NULL;
|
||||
Elf_Addr maxva = 0, minva = ELF_NO_ADDR;
|
||||
Elf_Addr libaddr, loff, align = _dl_pagesz - 1;
|
||||
|
@ -109,8 +109,8 @@ _dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
|
|||
size_t exec_size = 0;
|
||||
Elf_Dyn *dynp = NULL;
|
||||
Elf_Ehdr *ehdr;
|
||||
Elf_Phdr *phdp;
|
||||
Elf_Phdr *ptls = NULL;
|
||||
Elf_Phdr *phdp, *ptls = NULL;
|
||||
Elf_Phdr *syscall_phdp = NULL;
|
||||
struct stat sb;
|
||||
|
||||
#define powerof2(x) ((((x) - 1) & (x)) == 0)
|
||||
|
@ -139,7 +139,6 @@ _dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
|
|||
if (flags & DF_1_NOOPEN) {
|
||||
_dl_close(libfile);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
_dl_read(libfile, hbuf, sizeof(hbuf));
|
||||
|
@ -316,11 +315,30 @@ _dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
|
|||
_dl_push_range_size(&mut, phdp->p_vaddr + loff,
|
||||
phdp->p_memsz);
|
||||
break;
|
||||
case PT_OPENBSD_SYSCALLS:
|
||||
syscall_phdp = phdp;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
libc = _dl_islibc(dynp, loff);
|
||||
if (libc) {
|
||||
if (syscall_phdp)
|
||||
_dl_pin(libfile, syscall_phdp, (void *)libaddr,
|
||||
(size_t)((exec_start + exec_size) - libaddr),
|
||||
exec_start, exec_size);
|
||||
|
||||
/*
|
||||
* XXX msyscall() can be removed once pinsyscalls()
|
||||
* is fully operational
|
||||
*/
|
||||
/* Request permission for system calls in libc.so's text segment */
|
||||
if (_dl_msyscall(exec_start, exec_size) == -1)
|
||||
_dl_printf("msyscall %lx %lx error\n",
|
||||
exec_start, exec_size);
|
||||
}
|
||||
_dl_close(libfile);
|
||||
|
||||
dynp = (Elf_Dyn *)((unsigned long)dynp + loff);
|
||||
|
@ -328,8 +346,6 @@ _dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
|
|||
(Elf_Phdr *)((char *)libaddr + ehdr->e_phoff), ehdr->e_phnum,type,
|
||||
libaddr, loff);
|
||||
if (object) {
|
||||
char *soname = (char *)object->Dyn.info[DT_SONAME];
|
||||
|
||||
object->load_size = maxva - minva; /*XXX*/
|
||||
object->load_list = load_list;
|
||||
/* set inode, dev from stat info */
|
||||
|
@ -339,17 +355,10 @@ _dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
|
|||
object->nodelete = nodelete;
|
||||
object->relro_addr = relro_addr;
|
||||
object->relro_size = relro_size;
|
||||
object->islibc = libc;
|
||||
_dl_set_sod(object->load_name, &object->sod);
|
||||
if (ptls != NULL && ptls->p_memsz)
|
||||
_dl_set_tls(object, ptls, libaddr, libname);
|
||||
|
||||
/* Request permission for system calls in libc.so's text segment */
|
||||
if (soname != NULL && !_dl_traceld &&
|
||||
_dl_strncmp(soname, "libc.so.", 8) == 0) {
|
||||
if (_dl_msyscall(exec_start, exec_size) == -1)
|
||||
_dl_printf("msyscall %lx %lx error\n",
|
||||
exec_start, exec_size);
|
||||
}
|
||||
_dl_bcopy(&mut, &object->mut, sizeof mut);
|
||||
_dl_bcopy(&imut, &object->imut, sizeof imut);
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: library_mquery.c,v 1.73 2023/12/19 16:13:22 deraadt Exp $ */
|
||||
/* $OpenBSD: library_mquery.c,v 1.74 2024/01/16 19:07:31 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Dale Rahn
|
||||
|
@ -102,15 +102,15 @@ elf_object_t *
|
|||
_dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
|
||||
{
|
||||
struct range_vector imut, mut;
|
||||
int libfile, i;
|
||||
int libfile, libc = -1, i;
|
||||
struct load_list *ld, *lowld = NULL;
|
||||
elf_object_t *object;
|
||||
Elf_Dyn *dynp = NULL;
|
||||
Elf_Ehdr *ehdr;
|
||||
Elf_Phdr *phdp;
|
||||
Elf_Phdr *phdp, *ptls = NULL;
|
||||
Elf_Phdr *syscall_phdp = NULL;
|
||||
Elf_Addr load_end = 0;
|
||||
Elf_Addr align = _dl_pagesz - 1, off, size;
|
||||
Elf_Phdr *ptls = NULL;
|
||||
Elf_Addr relro_addr = 0, relro_size = 0;
|
||||
struct stat sb;
|
||||
char hbuf[4096], *exec_start;
|
||||
|
@ -325,9 +325,28 @@ retry:
|
|||
_dl_push_range_size(&mut, phdp->p_vaddr + LOFF,
|
||||
phdp->p_memsz);
|
||||
break;
|
||||
case PT_OPENBSD_SYSCALLS:
|
||||
syscall_phdp = phdp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
libc = _dl_islibc(dynp, LOFF);
|
||||
if (libc) {
|
||||
if (syscall_phdp)
|
||||
_dl_pin(libfile, syscall_phdp, lowld->start,
|
||||
(size_t)((exec_start + exec_size) - LOFF),
|
||||
exec_start, exec_size);
|
||||
|
||||
/*
|
||||
* XXX msyscall() can be removed once pinsyscalls()
|
||||
* is fully operational
|
||||
*/
|
||||
/* Request permission for system calls in libc.so's text segment */
|
||||
if (_dl_msyscall(exec_start, exec_size) == -1)
|
||||
_dl_printf("msyscall %lx %lx error\n",
|
||||
exec_start, exec_size);
|
||||
}
|
||||
_dl_close(libfile);
|
||||
|
||||
dynp = (Elf_Dyn *)((unsigned long)dynp + LOFF);
|
||||
|
@ -335,8 +354,6 @@ retry:
|
|||
(Elf_Phdr *)((char *)lowld->start + ehdr->e_phoff), ehdr->e_phnum,
|
||||
type, (Elf_Addr)lowld->start, LOFF);
|
||||
if (object) {
|
||||
char *soname = (char *)object->Dyn.info[DT_SONAME];
|
||||
|
||||
object->load_size = (Elf_Addr)load_end - (Elf_Addr)lowld->start;
|
||||
object->load_list = lowld;
|
||||
/* set inode, dev from stat info */
|
||||
|
@ -346,18 +363,11 @@ retry:
|
|||
object->nodelete = nodelete;
|
||||
object->relro_addr = relro_addr;
|
||||
object->relro_size = relro_size;
|
||||
object->islibc = libc;
|
||||
_dl_set_sod(object->load_name, &object->sod);
|
||||
if (ptls != NULL && ptls->p_memsz)
|
||||
_dl_set_tls(object, ptls, (Elf_Addr)lowld->start,
|
||||
libname);
|
||||
|
||||
/* Request permission for system calls in libc.so's text segment */
|
||||
if (soname != NULL && !_dl_traceld &&
|
||||
_dl_strncmp(soname, "libc.so.", 8) == 0) {
|
||||
if (_dl_msyscall(exec_start, exec_size) == -1)
|
||||
_dl_printf("msyscall %lx %lx error\n",
|
||||
exec_start, exec_size);
|
||||
}
|
||||
_dl_bcopy(&mut, &object->mut, sizeof mut);
|
||||
_dl_bcopy(&imut, &object->imut, sizeof imut);
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: loader.c,v 1.219 2024/01/14 09:39:03 kettenis Exp $ */
|
||||
/* $OpenBSD: loader.c,v 1.220 2024/01/16 19:07:31 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
|
||||
|
@ -440,11 +440,14 @@ _dl_load_dep_libs(elf_object_t *object, int flags, int booting)
|
|||
|
||||
_dl_cache_grpsym_list_setup(object);
|
||||
|
||||
/*
|
||||
* XXX pinsyscall(SYS_execve,...) can be removed once pinsyscalls()
|
||||
* is fully operational
|
||||
*/
|
||||
for (obj = _dl_objects; booting && obj != NULL; obj = obj->next) {
|
||||
char *soname = (char *)obj->Dyn.info[DT_SONAME];
|
||||
struct sym_res sr;
|
||||
|
||||
if (!soname || _dl_strncmp(soname, "libc.so.", 8))
|
||||
if (!obj->islibc)
|
||||
continue;
|
||||
sr = _dl_find_symbol("execve",
|
||||
SYM_SEARCH_SELF|SYM_PLT|SYM_WARNNOTFOUND, NULL, obj);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: resolve.c,v 1.100 2023/07/08 14:09:43 jasper Exp $ */
|
||||
/* $OpenBSD: resolve.c,v 1.101 2024/01/16 19:07:31 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
|
||||
|
@ -29,6 +29,8 @@
|
|||
#define _DYN_LOADER
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <link.h>
|
||||
|
@ -36,6 +38,7 @@
|
|||
#include "util.h"
|
||||
#include "path.h"
|
||||
#include "resolve.h"
|
||||
#include "syscall.h"
|
||||
|
||||
/* substitution types */
|
||||
typedef enum {
|
||||
|
@ -745,3 +748,82 @@ _dl_debug_state(void)
|
|||
{
|
||||
/* Debugger stub */
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for DT_SONAME, and check if this is libc
|
||||
*/
|
||||
int
|
||||
_dl_islibc(Elf_Dyn *_dynp, Elf_Addr loff)
|
||||
{
|
||||
Elf_Dyn *d, *dynp = (Elf_Dyn *)((unsigned long)_dynp + loff);
|
||||
long base = 0;
|
||||
|
||||
for (d = dynp; d->d_tag != DT_NULL; d++)
|
||||
if (d->d_tag == DT_STRTAB) {
|
||||
base = d->d_un.d_ptr + loff;
|
||||
break;
|
||||
}
|
||||
if (base == 0)
|
||||
return 0;
|
||||
for (d = dynp; d->d_tag != DT_NULL; d++)
|
||||
if (d->d_tag == DT_SONAME) {
|
||||
if (_dl_strncmp((char *)(base + d->d_un.d_ptr),
|
||||
"libc.so.", 8) == 0)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_dl_pin(int file, Elf_Phdr *phdp, void *base, size_t len,
|
||||
void *exec_base, size_t exec_size)
|
||||
{
|
||||
struct pinsyscalls {
|
||||
u_int offset;
|
||||
u_int sysno;
|
||||
} *syscalls;
|
||||
int npins = 0, nsyscalls, i;
|
||||
u_int *pins = NULL;
|
||||
vaddr_t offset;
|
||||
|
||||
if (phdp->p_filesz > SYS_MAXSYSCALL * 2 * sizeof(*syscalls) ||
|
||||
phdp->p_filesz % sizeof(*syscalls) != 0 ||
|
||||
phdp->p_offset & 0x3)
|
||||
return;
|
||||
syscalls = _dl_mmap(NULL, phdp->p_filesz, PROT_READ,
|
||||
MAP_PRIVATE|MAP_FILE, file, phdp->p_offset);
|
||||
if (syscalls == MAP_FAILED)
|
||||
return;
|
||||
|
||||
/* Validate, and calculate pintable size */
|
||||
nsyscalls = phdp->p_filesz / sizeof(*syscalls);
|
||||
for (i = 0; i < nsyscalls; i++) {
|
||||
if (syscalls[i].sysno < 0 ||
|
||||
syscalls[i].sysno >= SYS_MAXSYSCALL ||
|
||||
syscalls[i].offset >= len)
|
||||
goto bad;
|
||||
npins = MAXIMUM(npins, syscalls[i].sysno);
|
||||
}
|
||||
npins++;
|
||||
|
||||
/*
|
||||
* Fill pintable: 0 = invalid, -1 = accept, else offset
|
||||
* from base, rebase to text_start while at it
|
||||
*/
|
||||
pins = _dl_calloc(npins, sizeof(u_int));
|
||||
offset = exec_base - base;
|
||||
for (i = 0; i < nsyscalls; i++) {
|
||||
if (pins[syscalls[i].sysno])
|
||||
pins[syscalls[i].sysno] = (u_int)-1; /* duplicated */
|
||||
else
|
||||
pins[syscalls[i].sysno] = syscalls[i].offset - offset;
|
||||
}
|
||||
base += offset;
|
||||
len = len - offset;
|
||||
bad:
|
||||
_dl_munmap(syscalls, phdp->p_filesz);
|
||||
if (pins)
|
||||
_dl_pinsyscalls(base, len, pins, npins);
|
||||
_dl_free(pins);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: resolve.h,v 1.106 2023/12/19 16:13:22 deraadt Exp $ */
|
||||
/* $OpenBSD: resolve.h,v 1.107 2024/01/16 19:07:31 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
|
||||
|
@ -245,6 +245,7 @@ struct elf_object {
|
|||
|
||||
struct range_vector imut;
|
||||
struct range_vector mut;
|
||||
int islibc;
|
||||
};
|
||||
|
||||
struct dep_node {
|
||||
|
@ -340,6 +341,9 @@ typedef void lock_cb(int);
|
|||
void _dl_thread_kern_go(lock_cb *);
|
||||
lock_cb *_dl_thread_kern_stop(void);
|
||||
|
||||
int _dl_islibc(Elf_Dyn *_dynp, Elf_Addr loff);
|
||||
void _dl_pin(int, Elf_Phdr *, void *, size_t, void *, size_t);
|
||||
|
||||
char *_dl_getenv(const char *, char **) __boot;
|
||||
void _dl_unsetenv(const char *, char **) __boot;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue