sync with OpenBSD -current

This commit is contained in:
purplerain 2024-01-16 16:00:24 +00:00
parent 34a3d7e18a
commit ee68147dcd
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
30 changed files with 722 additions and 211 deletions

View file

@ -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 {

View file

@ -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 {

View file

@ -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);

View file

@ -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);
}

View file

@ -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;