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

Reply via email to