untrusted comment: verify with openbsd-63-base.pub RWRxzbLwAd76ZTPeR5UICJ7Fkh7IYUPD9gbhntxdlDU4/EF6n1X1xwS7WerIb9qfPE6q/aTvpxNjvwgfLVIJOs9gP4dDSUd2OgE= OpenBSD 6.3 errata 028, February 5, 2019: The mincore() system call can be used to observe memory access patterns of other processes. Apply by doing: signify -Vep /etc/signify/openbsd-63-base.pub -x 028_mincore.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install a new kernel: KK=`sysctl -n kern.osversion | cut -d# -f1` cd /usr/src/sys/arch/`machine`/compile/$KK make obj make config make make install Index: sys/uvm/uvm_mmap.c =================================================================== RCS file: /cvs/src/sys/uvm/uvm_mmap.c,v retrieving revision 1.147 diff -u -p -r1.147 uvm_mmap.c --- sys/uvm/uvm_mmap.c 19 Feb 2018 08:59:53 -0000 1.147 +++ sys/uvm/uvm_mmap.c 10 Jan 2019 20:41:02 -0000 @@ -180,22 +180,13 @@ sys_mincore(struct proc *p, void *v, reg syscallarg(size_t) len; syscallarg(char *) vec; } */ *uap = v; - vm_page_t m; - char *vec, *pgi, *pgs; - struct uvm_object *uobj; - struct vm_amap *amap; - struct vm_anon *anon; - vm_map_entry_t entry, next; - vaddr_t start, end, lim; - vm_map_t map; + char *pgs; + vaddr_t start, end; vsize_t len, npgs; int error = 0; - map = &p->p_vmspace->vm_map; - start = (vaddr_t)SCARG(uap, addr); len = SCARG(uap, len); - vec = SCARG(uap, vec); if (start & PAGE_MASK) return (EINVAL); @@ -215,94 +206,11 @@ sys_mincore(struct proc *p, void *v, reg pgs = mallocarray(npgs, sizeof(*pgs), M_TEMP, M_WAITOK | M_CANFAIL); if (pgs == NULL) return (ENOMEM); - pgi = pgs; - /* - * Lock down vec, so our returned status isn't outdated by - * storing the status byte for a page. + * Lie. After all, the answer may change at anytime. */ - if ((error = uvm_vslock(p, vec, npgs, PROT_WRITE)) != 0) { - free(pgs, M_TEMP, npgs * sizeof(*pgs)); - return (error); - } - - vm_map_lock_read(map); - - if (uvm_map_lookup_entry(map, start, &entry) == FALSE) { - error = ENOMEM; - goto out; - } - - for (/* nothing */; - entry != NULL && entry->start < end; - entry = RBT_NEXT(uvm_map_addr, entry)) { - KASSERT(!UVM_ET_ISSUBMAP(entry)); - KASSERT(start >= entry->start); - - /* Make sure there are no holes. */ - next = RBT_NEXT(uvm_map_addr, entry); - if (entry->end < end && - (next == NULL || - next->start > entry->end)) { - error = ENOMEM; - goto out; - } - - lim = end < entry->end ? end : entry->end; - - /* - * Special case for objects with no "real" pages. Those - * are always considered resident (mapped devices). - */ - if (UVM_ET_ISOBJ(entry)) { - KASSERT(!UVM_OBJ_IS_KERN_OBJECT(entry->object.uvm_obj)); - if (entry->object.uvm_obj->pgops->pgo_fault != NULL) { - for (/* nothing */; start < lim; - start += PAGE_SIZE, pgi++) - *pgi = 1; - continue; - } - } - - amap = entry->aref.ar_amap; /* top layer */ - uobj = entry->object.uvm_obj; /* bottom layer */ - - for (/* nothing */; start < lim; start += PAGE_SIZE, pgi++) { - *pgi = 0; - if (amap != NULL) { - /* Check the top layer first. */ - anon = amap_lookup(&entry->aref, - start - entry->start); - if (anon != NULL && anon->an_page != NULL) { - /* - * Anon has the page for this entry - * offset. - */ - *pgi = 1; - } - } - - if (uobj != NULL && *pgi == 0) { - /* Check the bottom layer. */ - m = uvm_pagelookup(uobj, - entry->offset + (start - entry->start)); - if (m != NULL) { - /* - * Object has the page for this entry - * offset. - */ - *pgi = 1; - } - } - } - } - - out: - vm_map_unlock_read(map); - uvm_vsunlock(p, SCARG(uap, vec), npgs); - /* now the map is unlocked we can copyout without fear. */ - if (error == 0) - copyout(pgs, vec, npgs * sizeof(char)); + memset(pgs, 1, npgs * sizeof(*pgs)); + error = copyout(pgs, SCARG(uap, vec), npgs * sizeof(char)); free(pgs, M_TEMP, npgs * sizeof(*pgs)); return (error); }