Lookup the start,len of the "execve" stub in libc.so, and tell the kernel
authorderaadt <deraadt@openbsd.org>
Sat, 18 Feb 2023 01:22:50 +0000 (01:22 +0000)
committerderaadt <deraadt@openbsd.org>
Sat, 18 Feb 2023 01:22:50 +0000 (01:22 +0000)
where it is with pinsyscall().  In non-static binaries, kernel execve(2)
will now insist upon being called from that small region.  Arriving from
a different region smells like ROP methodology, and the process is killed.

libexec/ld.so/Makefile
libexec/ld.so/loader.c
libexec/ld.so/syscall.h

index 3080432..c582139 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.83 2022/11/05 18:44:09 deraadt Exp $
+#      $OpenBSD: Makefile,v 1.84 2023/02/18 01:22:50 deraadt Exp $
 
 SUBDIR=ldconfig ldd
 MAN=   ld.so.1
@@ -28,8 +28,8 @@ SRCS+=        dl_uname.c dl_dirname.c strlcat.c strlen.c trace.c
 SRCS+= malloc.c reallocarray.c tib.c ffs.c
 
 syscall=close exit fstat getdents getentropy getthrid issetugid kbind \
-       mimmutable mmap mprotect munmap msyscall open pledge read \
-       __realpath sendsyslog __set_tcb sysctl thrkill utrace write
+       mimmutable mmap mprotect munmap msyscall open pledge pinsyscall \
+       read __realpath sendsyslog __set_tcb sysctl thrkill utrace write \
 
 .if (${MACHINE_ARCH} == "i386")
 syscall+=mquery
index 889712b..1413f43 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: loader.c,v 1.210 2023/01/29 20:30:56 gnezdo Exp $ */
+/*     $OpenBSD: loader.c,v 1.211 2023/02/18 01:22:50 deraadt Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -30,6 +30,7 @@
 
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <sys/syscall.h>
 #include <sys/exec.h>
 #ifdef __i386__
 # include <machine/vmparam.h>
@@ -316,7 +317,7 @@ _dl_setup_env(const char *argv0, char **envp)
 int
 _dl_load_dep_libs(elf_object_t *object, int flags, int booting)
 {
-       elf_object_t *dynobj;
+       elf_object_t *dynobj, *obj;
        Elf_Dyn *dynp;
        unsigned int loop;
        int libcount;
@@ -410,6 +411,21 @@ _dl_load_dep_libs(elf_object_t *object, int flags, int booting)
 
        _dl_cache_grpsym_list_setup(object);
 
+       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))
+                       continue;
+               sr = _dl_find_symbol("execve",
+                   SYM_SEARCH_SELF|SYM_PLT|SYM_WARNNOTFOUND, NULL, obj);
+               if (sr.sym)
+                       _dl_pinsyscall(SYS_execve,
+                           (void *)sr.obj->obj_base + sr.sym->st_value,
+                           sr.sym->st_size);
+               _dl_memset(&sr, 0, sizeof sr);
+               break;
+       }
        return(0);
 }
 
index a42f716..6e9394d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: syscall.h,v 1.3 2022/11/05 18:44:09 deraadt Exp $ */
+/*     $OpenBSD: syscall.h,v 1.4 2023/02/18 01:22:50 deraadt Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -51,6 +51,7 @@ void   *_dl_mmap(void *, size_t, int, int, int, off_t);
 int    _dl_mprotect(const void *, size_t, int);
 void   *_dl_mquery(void *, size_t, int, int, int, off_t);
 int    _dl_msyscall(void *addr, size_t len);
+int    _dl_pinsyscall(int, void *addr, size_t len);
 int    _dl_munmap(const void *, size_t);
 int    _dl_mimmutable(const void *, size_t);
 int    _dl_open(const char *, int);