Add kern_mmap_racct_check(), a helper to verify limits in vm_mmap*().
Reviewed by: markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D24652
This commit is contained in:
parent
fbf2a77876
commit
67a659d282
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=365486
@ -62,6 +62,7 @@ struct sockaddr;
|
||||
struct stat;
|
||||
struct thr_param;
|
||||
struct uio;
|
||||
struct vm_map;
|
||||
|
||||
typedef int (*mmap_check_fp_fn)(struct file *, int, int, int);
|
||||
|
||||
@ -197,8 +198,10 @@ int kern_mlock(struct proc *proc, struct ucred *cred, uintptr_t addr,
|
||||
size_t len);
|
||||
int kern_mmap(struct thread *td, uintptr_t addr, size_t len, int prot,
|
||||
int flags, int fd, off_t pos);
|
||||
int kern_mmap_req(struct thread *td, const struct mmap_req *mrp);
|
||||
int kern_mmap_racct_check(struct thread *td, struct vm_map *map,
|
||||
vm_size_t size);
|
||||
int kern_mmap_maxprot(struct proc *p, int prot);
|
||||
int kern_mmap_req(struct thread *td, const struct mmap_req *mrp);
|
||||
int kern_mprotect(struct thread *td, uintptr_t addr, size_t size, int prot);
|
||||
int kern_msgctl(struct thread *, int, int, struct msqid_ds *);
|
||||
int kern_msgrcv(struct thread *, int, void *, size_t, long, int, long *);
|
||||
|
@ -1509,6 +1509,39 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_mmap_racct_check(struct thread *td, vm_map_t map, vm_size_t size)
|
||||
{
|
||||
int error;
|
||||
|
||||
RACCT_PROC_LOCK(td->td_proc);
|
||||
if (map->size + size > lim_cur(td, RLIMIT_VMEM)) {
|
||||
RACCT_PROC_UNLOCK(td->td_proc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
if (racct_set(td->td_proc, RACCT_VMEM, map->size + size)) {
|
||||
RACCT_PROC_UNLOCK(td->td_proc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
if (!old_mlock && map->flags & MAP_WIREFUTURE) {
|
||||
if (ptoa(pmap_wired_count(map->pmap)) + size >
|
||||
lim_cur(td, RLIMIT_MEMLOCK)) {
|
||||
racct_set_force(td->td_proc, RACCT_VMEM, map->size);
|
||||
RACCT_PROC_UNLOCK(td->td_proc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
error = racct_set(td->td_proc, RACCT_MEMLOCK,
|
||||
ptoa(pmap_wired_count(map->pmap)) + size);
|
||||
if (error != 0) {
|
||||
racct_set_force(td->td_proc, RACCT_VMEM, map->size);
|
||||
RACCT_PROC_UNLOCK(td->td_proc);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
RACCT_PROC_UNLOCK(td->td_proc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal version of mmap that maps a specific VM object into an
|
||||
* map. Called by mmap for MAP_ANON, vm_mmap, shm_mmap, and vn_mmap.
|
||||
@ -1518,39 +1551,15 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
|
||||
vm_prot_t maxprot, int flags, vm_object_t object, vm_ooffset_t foff,
|
||||
boolean_t writecounted, struct thread *td)
|
||||
{
|
||||
boolean_t curmap, fitit;
|
||||
vm_offset_t max_addr;
|
||||
int docow, error, findspace, rv;
|
||||
bool curmap, fitit;
|
||||
|
||||
curmap = map == &td->td_proc->p_vmspace->vm_map;
|
||||
if (curmap) {
|
||||
RACCT_PROC_LOCK(td->td_proc);
|
||||
if (map->size + size > lim_cur(td, RLIMIT_VMEM)) {
|
||||
RACCT_PROC_UNLOCK(td->td_proc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
if (racct_set(td->td_proc, RACCT_VMEM, map->size + size)) {
|
||||
RACCT_PROC_UNLOCK(td->td_proc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
if (!old_mlock && map->flags & MAP_WIREFUTURE) {
|
||||
if (ptoa(pmap_wired_count(map->pmap)) + size >
|
||||
lim_cur(td, RLIMIT_MEMLOCK)) {
|
||||
racct_set_force(td->td_proc, RACCT_VMEM,
|
||||
map->size);
|
||||
RACCT_PROC_UNLOCK(td->td_proc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
error = racct_set(td->td_proc, RACCT_MEMLOCK,
|
||||
ptoa(pmap_wired_count(map->pmap)) + size);
|
||||
if (error != 0) {
|
||||
racct_set_force(td->td_proc, RACCT_VMEM,
|
||||
map->size);
|
||||
RACCT_PROC_UNLOCK(td->td_proc);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
RACCT_PROC_UNLOCK(td->td_proc);
|
||||
error = kern_mmap_racct_check(td, map, size);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user