Make overflow/wraparound checking more robust and unbreak len=0 in
vslock(), mlock(), and munlock(). Reviewed by: bde
This commit is contained in:
parent
2d02e7d4d4
commit
df17b6c2c8
@ -186,19 +186,22 @@ useracc(addr, len, rw)
|
||||
int
|
||||
vslock(void *addr, size_t len)
|
||||
{
|
||||
vm_offset_t end, start;
|
||||
int error, npages;
|
||||
vm_offset_t end, last, start;
|
||||
vm_size_t npages;
|
||||
int error;
|
||||
|
||||
last = (vm_offset_t)addr + len;
|
||||
start = trunc_page((vm_offset_t)addr);
|
||||
end = round_page((vm_offset_t)addr + len);
|
||||
if (end <= start)
|
||||
end = round_page(last);
|
||||
if (last < (vm_offset_t)addr || end < (vm_offset_t)addr)
|
||||
return (EINVAL);
|
||||
npages = atop(end - start);
|
||||
if (npages > vm_page_max_wired)
|
||||
return (ENOMEM);
|
||||
PROC_LOCK(curproc);
|
||||
if (npages + pmap_wired_count(vm_map_pmap(&curproc->p_vmspace->vm_map)) >
|
||||
atop(lim_cur(curproc, RLIMIT_MEMLOCK))) {
|
||||
if (ptoa(npages +
|
||||
pmap_wired_count(vm_map_pmap(&curproc->p_vmspace->vm_map))) >
|
||||
lim_cur(curproc, RLIMIT_MEMLOCK)) {
|
||||
PROC_UNLOCK(curproc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
@ -894,26 +894,28 @@ mlock(td, uap)
|
||||
struct mlock_args *uap;
|
||||
{
|
||||
struct proc *proc;
|
||||
vm_offset_t addr, end, start;
|
||||
vm_size_t size;
|
||||
int error, npages;
|
||||
vm_offset_t addr, end, last, start;
|
||||
vm_size_t npages, size;
|
||||
int error;
|
||||
|
||||
error = suser(td);
|
||||
if (error)
|
||||
return (error);
|
||||
addr = (vm_offset_t)uap->addr;
|
||||
size = uap->len;
|
||||
last = addr + size;
|
||||
start = trunc_page(addr);
|
||||
end = round_page(addr + size);
|
||||
if (end <= start)
|
||||
end = round_page(last);
|
||||
if (last < addr || end < addr)
|
||||
return (EINVAL);
|
||||
npages = atop(end - start);
|
||||
if (npages > vm_page_max_wired)
|
||||
return (ENOMEM);
|
||||
proc = td->td_proc;
|
||||
PROC_LOCK(proc);
|
||||
if (npages + pmap_wired_count(vm_map_pmap(&proc->p_vmspace->vm_map)) >
|
||||
atop(lim_cur(proc, RLIMIT_MEMLOCK))) {
|
||||
if (ptoa(npages +
|
||||
pmap_wired_count(vm_map_pmap(&proc->p_vmspace->vm_map))) >
|
||||
lim_cur(proc, RLIMIT_MEMLOCK)) {
|
||||
PROC_UNLOCK(proc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
@ -1036,7 +1038,7 @@ munlock(td, uap)
|
||||
struct thread *td;
|
||||
struct munlock_args *uap;
|
||||
{
|
||||
vm_offset_t addr, end, start;
|
||||
vm_offset_t addr, end, last, start;
|
||||
vm_size_t size;
|
||||
int error;
|
||||
|
||||
@ -1045,9 +1047,10 @@ munlock(td, uap)
|
||||
return (error);
|
||||
addr = (vm_offset_t)uap->addr;
|
||||
size = uap->len;
|
||||
last = addr + size;
|
||||
start = trunc_page(addr);
|
||||
end = round_page(addr + size);
|
||||
if (end <= start)
|
||||
end = round_page(last);
|
||||
if (last < addr || end < addr)
|
||||
return (EINVAL);
|
||||
error = vm_map_unwire(&td->td_proc->p_vmspace->vm_map, start, end,
|
||||
VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
|
||||
|
Loading…
Reference in New Issue
Block a user