Close races in vm object chain traversal for unlock

We were unlocking the vm object before reading the backing_object field.
In the meantime, the object could be freed and reused.  This could cause
us to go off the rails in the object chain traversal, failing to unlock
the rest of the objects in the original chain and corrupting the lock
state of the victim chain.

Reviewed by:	bdrewery, kib, markj, vangyzen
MFC after:	3 days
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D28926
This commit is contained in:
Ryan Libby 2021-02-25 12:11:19 -08:00
parent f1ab799927
commit d7671ad8d6
2 changed files with 6 additions and 5 deletions

View File

@ -84,7 +84,7 @@ procfs_doprocmap(PFS_FILL_ARGS)
struct vnode *vp;
char *fullpath, *freepath, *type;
struct ucred *cred;
vm_object_t obj, tobj, lobj;
vm_object_t lobj, nobj, obj, tobj;
int error, privateresident, ref_count, resident, shadow_count, flags;
vm_offset_t e_start, e_end;
vm_eflags_t e_eflags;
@ -144,7 +144,8 @@ procfs_doprocmap(PFS_FILL_ARGS)
}
if (obj != NULL)
kern_proc_vmmap_resident(map, entry, &resident, &super);
for (tobj = obj; tobj != NULL; tobj = tobj->backing_object) {
for (tobj = obj; tobj != NULL; tobj = nobj) {
nobj = tobj->backing_object;
if (tobj != obj && tobj != lobj)
VM_OBJECT_RUNLOCK(tobj);
}

View File

@ -2505,7 +2505,7 @@ kern_proc_vmmap_out(struct proc *p, struct sbuf *sb, ssize_t maxlen, int flags)
vm_map_entry_t entry, tmp_entry;
struct vattr va;
vm_map_t map;
vm_object_t obj, tobj, lobj;
vm_object_t lobj, nobj, obj, tobj;
char *fullpath, *freepath;
struct kinfo_vmentry *kve;
struct ucred *cred;
@ -2551,8 +2551,8 @@ kern_proc_vmmap_out(struct proc *p, struct sbuf *sb, ssize_t maxlen, int flags)
&kve->kve_resident, &super);
if (super)
kve->kve_flags |= KVME_FLAG_SUPER;
for (tobj = obj; tobj != NULL;
tobj = tobj->backing_object) {
for (tobj = obj; tobj != NULL; tobj = nobj) {
nobj = tobj->backing_object;
if (tobj != obj && tobj != lobj)
VM_OBJECT_RUNLOCK(tobj);
}