mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-18 15:30:21 +00:00
When deallocating the vm object in elf_map_insert() due to
vm_map_insert() failure, drop the vnode lock around the call to vm_object_deallocate(). Since the deallocated object is the vm object of the vnode, we might get the vnode lock recursion there. In fact, it is almost impossible to make vm_map_insert() failing there on stock kernel. Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks
This commit is contained in:
parent
920adec330
commit
e3d8f8fed4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=314486
@ -422,13 +422,14 @@ __elfN(map_partial)(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
|
||||
}
|
||||
|
||||
static int
|
||||
__elfN(map_insert)(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
|
||||
vm_offset_t start, vm_offset_t end, vm_prot_t prot, int cow)
|
||||
__elfN(map_insert)(struct image_params *imgp, vm_map_t map, vm_object_t object,
|
||||
vm_ooffset_t offset, vm_offset_t start, vm_offset_t end, vm_prot_t prot,
|
||||
int cow)
|
||||
{
|
||||
struct sf_buf *sf;
|
||||
vm_offset_t off;
|
||||
vm_size_t sz;
|
||||
int error, rv;
|
||||
int error, locked, rv;
|
||||
|
||||
if (start != trunc_page(start)) {
|
||||
rv = __elfN(map_partial)(map, object, offset, start,
|
||||
@ -480,8 +481,12 @@ __elfN(map_insert)(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
|
||||
rv = vm_map_insert(map, object, offset, start, end,
|
||||
prot, VM_PROT_ALL, cow);
|
||||
vm_map_unlock(map);
|
||||
if (rv != KERN_SUCCESS)
|
||||
if (rv != KERN_SUCCESS) {
|
||||
locked = VOP_ISLOCKED(imgp->vp);
|
||||
VOP_UNLOCK(imgp->vp, 0);
|
||||
vm_object_deallocate(object);
|
||||
vn_lock(imgp->vp, locked | LK_RETRY);
|
||||
}
|
||||
}
|
||||
return (rv);
|
||||
} else {
|
||||
@ -538,7 +543,7 @@ __elfN(load_section)(struct image_params *imgp, vm_offset_t offset,
|
||||
cow = MAP_COPY_ON_WRITE | MAP_PREFAULT |
|
||||
(prot & VM_PROT_WRITE ? 0 : MAP_DISABLE_COREDUMP);
|
||||
|
||||
rv = __elfN(map_insert)(map,
|
||||
rv = __elfN(map_insert)(imgp, map,
|
||||
object,
|
||||
file_addr, /* file offset */
|
||||
map_addr, /* virtual start */
|
||||
@ -568,8 +573,8 @@ __elfN(load_section)(struct image_params *imgp, vm_offset_t offset,
|
||||
|
||||
/* This had damn well better be true! */
|
||||
if (map_len != 0) {
|
||||
rv = __elfN(map_insert)(map, NULL, 0, map_addr, map_addr +
|
||||
map_len, VM_PROT_ALL, 0);
|
||||
rv = __elfN(map_insert)(imgp, map, NULL, 0, map_addr,
|
||||
map_addr + map_len, VM_PROT_ALL, 0);
|
||||
if (rv != KERN_SUCCESS) {
|
||||
return (EINVAL);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user