Dear tech, currently the MAP_CONCEAL flag for mmap(2) can be bypassed with a stack overflow. FreeBSD introduced a similar flag called MAP_NOCORE. They also save the auxinfo pointer in some struct that is attached to the proc struct, similar to the diff below.
Here is an example CTF challenge: /* * Setup: * make mmap * echo 'this is a well kept secret' > flag.txt * printf 'flag.txt\0' | ./mmap * strings mmap.core | grep secret */ #include <sys/mman.h> #include <err.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> char * load_file(char *path) { char *addr; int fd; fd = open(path, O_RDONLY); if ((addr = mmap((char *)0x40000, 0x100, PROT_READ, MAP_FIXED | MAP_CONCEAL, fd, 0)) == MAP_FAILED) err(1, NULL); close(fd); return (addr); } int main(void) { char file[0x100]; char *buf; puts("Content-type: text/html\n"); puts("<h1>simple mmap</h1><p>POST filename to /cgi-bin/mmap</p>"); read(0, file, 0x1000); buf = load_file(file); printf("load: %p\n", buf); fflush(stdout); return (0); } With the following python program (on amd64) I can generate an input string that writes the MAP_CONCEALED content of flag.txt to the core file: import struct p64 = lambda x: struct.pack("<Q", x) leak=0x40000 pwn = (b"flag.txt" + b"\x00"*8 + (p64(leak) + p64(0) )* 100) import sys sys.stdout.buffer.write(pwn) Below is a diff that addresses this. OK? mbuhl Index: kern/exec_elf.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/kern/exec_elf.c,v retrieving revision 1.174 diff -u -p -r1.174 exec_elf.c --- kern/exec_elf.c 5 Nov 2022 10:31:16 -0000 1.174 +++ kern/exec_elf.c 6 Nov 2022 13:33:53 -0000 @@ -1221,9 +1221,6 @@ coredump_walk_elf(vaddr_t start, vaddr_t int coredump_notes_elf(struct proc *p, void *iocookie, size_t *sizep) { - struct ps_strings pss; - struct iovec iov; - struct uio uio; struct elfcore_procinfo cpi; Elf_Note nhdr; struct process *pr = p->p_p; @@ -1282,23 +1279,7 @@ coredump_notes_elf(struct proc *p, void /* Second, write an NT_OPENBSD_AUXV note. */ notesize = sizeof(nhdr) + elfround(sizeof("OpenBSD")) + elfround(ELF_AUX_WORDS * sizeof(char *)); - if (iocookie) { - iov.iov_base = &pss; - iov.iov_len = sizeof(pss); - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_offset = (off_t)pr->ps_strings; - uio.uio_resid = sizeof(pss); - uio.uio_segflg = UIO_SYSSPACE; - uio.uio_rw = UIO_READ; - uio.uio_procp = NULL; - - error = uvm_io(&p->p_vmspace->vm_map, &uio, 0); - if (error) - return (error); - - if (pss.ps_envstr == NULL) - return (EIO); + if (iocookie && pr->ps_auxinfo) { nhdr.namesz = sizeof("OpenBSD"); nhdr.descsz = ELF_AUX_WORDS * sizeof(char *); @@ -1315,7 +1296,7 @@ coredump_notes_elf(struct proc *p, void return (error); error = coredump_write(iocookie, UIO_USERSPACE, - pss.ps_envstr + pss.ps_nenvstr + 1, nhdr.descsz); + (caddr_t)pr->ps_auxinfo, nhdr.descsz); if (error) return (error); } Index: kern/kern_exec.c =================================================================== RCS file: /mount/openbsd/cvs/src/sys/kern/kern_exec.c,v retrieving revision 1.238 diff -u -p -r1.238 kern_exec.c --- kern/kern_exec.c 30 Oct 2022 17:43:40 -0000 1.238 +++ kern/kern_exec.c 6 Nov 2022 10:37:19 -0000 @@ -492,6 +492,8 @@ sys_execve(struct proc *p, void *v, regi if (!copyargs(&pack, &arginfo, stack, argp)) goto exec_abort; + pr->ps_auxinfo = (vaddr_t)pack.ep_auxinfo; + /* copy out the process's ps_strings structure */ if (copyout(&arginfo, (char *)pr->ps_strings, sizeof(arginfo))) goto exec_abort; Index: sys/proc.h =================================================================== RCS file: /mount/openbsd/cvs/src/sys/sys/proc.h,v retrieving revision 1.334 diff -u -p -r1.334 proc.h --- sys/proc.h 23 Jul 2022 22:10:59 -0000 1.334 +++ sys/proc.h 6 Nov 2022 10:37:19 -0000 @@ -215,6 +215,7 @@ struct process { char ps_comm[_MAXCOMLEN]; /* command name, incl NUL */ vaddr_t ps_strings; /* User pointers to argv/env */ + vaddr_t ps_auxinfo; /* User pointer to auxinfo */ vaddr_t ps_timekeep; /* User pointer to timekeep */ vaddr_t ps_sigcode; /* [I] User pointer to signal code */ vaddr_t ps_sigcoderet; /* [I] User ptr to sigreturn retPC */