diff options
author | alc <alc@FreeBSD.org> | 2006-07-17 06:45:03 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2006-07-17 06:45:03 +0000 |
commit | 50001bf11957ef9bb1be28e28f803df45bae9028 (patch) | |
tree | 534cdf1add6d7ddbe22439ff48e1c200c8cda080 /sys/vm | |
parent | b92d5e9b3309e7e8e90821b27f84a671c7c48002 (diff) | |
download | FreeBSD-src-50001bf11957ef9bb1be28e28f803df45bae9028.zip FreeBSD-src-50001bf11957ef9bb1be28e28f803df45bae9028.tar.gz |
Ensure that vm_object_deallocate() doesn't dereference a stale object
pointer: When vm_object_deallocate() sleeps because of a non-zero
paging in progress count on either object or object's shadow,
vm_object_deallocate() must ensure that object is still the shadow's
backing object when it reawakens. In fact, object may have been
deallocated while vm_object_deallocate() slept. If so, reacquiring
the lock on object can lead to a deadlock.
Submitted by: ups@
MFC after: 3 weeks
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/vm_object.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 8457529..cacaafa 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -529,8 +529,11 @@ retry: VM_OBJECT_UNLOCK(object); vm_object_pip_wait(robject, "objde1"); - VM_OBJECT_LOCK(object); - goto retry; + temp = robject->backing_object; + if (object == temp) { + VM_OBJECT_LOCK(object); + goto retry; + } } else if (object->paging_in_progress) { VM_OBJECT_UNLOCK(robject); object->flags |= OBJ_PIPWNT; @@ -538,10 +541,14 @@ retry: VM_OBJECT_MTX(object), PDROP | PVM, "objde2", 0); VM_OBJECT_LOCK(robject); - VM_OBJECT_LOCK(object); - goto retry; - } - VM_OBJECT_UNLOCK(object); + temp = robject->backing_object; + if (object == temp) { + VM_OBJECT_LOCK(object); + goto retry; + } + } else + VM_OBJECT_UNLOCK(object); + if (robject->ref_count == 1) { robject->ref_count--; object = robject; |