summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2006-07-17 06:45:03 +0000
committeralc <alc@FreeBSD.org>2006-07-17 06:45:03 +0000
commit50001bf11957ef9bb1be28e28f803df45bae9028 (patch)
tree534cdf1add6d7ddbe22439ff48e1c200c8cda080 /sys/vm
parentb92d5e9b3309e7e8e90821b27f84a671c7c48002 (diff)
downloadFreeBSD-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.c19
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;
OpenPOWER on IntegriCloud