diff options
author | Vincenzo Maffione <vmaffione@FreeBSD.org> | 2021-03-20 17:15:50 +0000 |
---|---|---|
committer | Vincenzo Maffione <vmaffione@FreeBSD.org> | 2021-03-23 21:18:31 +0000 |
commit | 610706f5e71a2805688cb3c13e8605675b58802c (patch) | |
tree | 31e89dd25fb582a1c8c64c6d6f3e7074a11e78f3 | |
parent | 961e7887b9bad9dd446a2289f3e5266ad2d122ef (diff) | |
download | src-610706f5e71a2805688cb3c13e8605675b58802c.tar.gz src-610706f5e71a2805688cb3c13e8605675b58802c.zip |
netmap: fix issues in nm_os_extmem_create()
- Call vm_object_reference() before vm_map_lookup_done().
- Use vm_mmap_to_errno() to convert vm_map_* return values to errno.
- Fix memory leak of e->obj.
Reported by: markj
Reviewed by: markj
MFC after: 1 week
(cherry picked from commit ee7ffaa2e6e08b63efb4673610875d40964d5058)
-rw-r--r-- | sys/dev/netmap/netmap_freebsd.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c index ea9f4252a562..28f753b06f8c 100644 --- a/sys/dev/netmap/netmap_freebsd.c +++ b/sys/dev/netmap/netmap_freebsd.c @@ -663,6 +663,7 @@ nm_os_vi_detach(struct ifnet *ifp) #ifdef WITH_EXTMEM #include <vm/vm_map.h> +#include <vm/vm_extern.h> #include <vm/vm_kern.h> struct nm_os_extmem { vm_object_t obj; @@ -725,17 +726,18 @@ nm_os_extmem_create(unsigned long p, struct nmreq_pools_info *pi, int *perror) &obj, &index, &prot, &wired); if (rv != KERN_SUCCESS) { nm_prerr("address %lx not found", p); + error = vm_mmap_to_errno(rv); goto out_free; } + vm_object_reference(obj); + /* check that we are given the whole vm_object ? */ vm_map_lookup_done(map, entry); - // XXX can we really use obj after releasing the map lock? e->obj = obj; - vm_object_reference(obj); - /* wire the memory and add the vm_object to the kernel map, - * to make sure that it is not fred even if the processes that - * are mmap()ing it all exit + /* Wire the memory and add the vm_object to the kernel map, + * to make sure that it is not freed even if all the processes + * that are mmap()ing should munmap() it. */ e->kva = vm_map_min(kernel_map); e->size = obj->size << PAGE_SHIFT; @@ -744,12 +746,14 @@ nm_os_extmem_create(unsigned long p, struct nmreq_pools_info *pi, int *perror) VM_PROT_READ | VM_PROT_WRITE, 0); if (rv != KERN_SUCCESS) { nm_prerr("vm_map_find(%zx) failed", (size_t)e->size); + error = vm_mmap_to_errno(rv); goto out_rel; } rv = vm_map_wire(kernel_map, e->kva, e->kva + e->size, VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES); if (rv != KERN_SUCCESS) { nm_prerr("vm_map_wire failed"); + error = vm_mmap_to_errno(rv); goto out_rem; } @@ -759,9 +763,9 @@ nm_os_extmem_create(unsigned long p, struct nmreq_pools_info *pi, int *perror) out_rem: vm_map_remove(kernel_map, e->kva, e->kva + e->size); - e->obj = NULL; out_rel: vm_object_deallocate(e->obj); + e->obj = NULL; out_free: nm_os_free(e); out: |