The code responsible for filling a page with repeated copies of the
signal trampoline code assumes that PAGE_SIZE % sigfillsz == 0.
While this is true on all currently supported OpenBSD platforms, this
might not be the case in the future (and isn't the case on some
no-longer official platforms).
The following diff makes sure that we don't try to write more than
PAGE_SIZE bytes in this page. Another possibility would be to assert
that PAGE_SIZE % sigfillsz == 0 and only apply this diff once it becomes
truly needed.
Index: sys/kern/kern_exec.c
===================================================================
RCS file: /OpenBSD/src/sys/kern/kern_exec.c,v
retrieving revision 1.208
diff -u -p -r1.208 kern_exec.c
--- sys/kern/kern_exec.c 2 Aug 2019 02:17:35 -0000 1.208
+++ sys/kern/kern_exec.c 25 Nov 2019 10:09:48 -0000
@@ -832,7 +832,7 @@ exec_sigcode_map(struct process *pr, str
if (e->e_sigobject == NULL) {
extern int sigfillsiz;
extern u_char sigfill[];
- size_t off;
+ size_t off, left;
vaddr_t va;
int r;
@@ -846,8 +846,12 @@ exec_sigcode_map(struct process *pr, str
return (ENOMEM);
}
- for (off = 0; off < round_page(sz); off += sigfillsiz)
- memcpy((caddr_t)va + off, sigfill, sigfillsiz);
+ for (off = 0, left = round_page(sz); left != 0;
+ off += sigfillsiz) {
+ size_t chunk = ulmin(left, sigfillsiz);
+ memcpy((caddr_t)va + off, sigfill, chunk);
+ left -= chunk;
+ }
memcpy((caddr_t)va, e->e_sigcode, sz);
uvm_unmap(kernel_map, va, va + round_page(sz));
}