diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-08-16 12:54:41 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-09-14 14:45:05 +0200 |
commit | 22778b589af94261c2d8d0665220770d0b56d1a8 (patch) | |
tree | 97bdb1c058f030d30dfe0d566630010572a4fb35 /vm/memory_object.c | |
parent | 81747ac6d3e846d1955edaa94dee9065e541b7d8 (diff) |
vm: fix locking issues
Avoid accessing fields of `vm_object' objects without having it
locked. These problems have been found using a code transformation
done by Coccinelle that instrumented all accesses with a runtime
check, and manual inspection.
* vm/memory_object.c (memory_object_data_supply): Avoid accessing
fields without the lock.
* vm/vm_fault.c (vm_fault_page): Likewise.
* vm/vm_map.c (vm_map_submap): Properly lock `object'.
(vm_map_copy_overwrite): Avoid accessing fields without the lock.
(vm_map_copyin): Lock `src_object'.
* vm/vm_object.c (_vm_object_setup): Likewise.
(vm_object_allocate): Likewise.
(vm_object_terminate): Avoid accessing fields without the lock.
(vm_object_copy_slowly): Lock `new_object'.
(vm_object_copy_delayed): Lock `src_object' earlier, lock `new_copy'.
(vm_object_shadow): Lock `result'.
(vm_object_enter): Properly lock `object'. Avoid accessing fields
without the lock.
* vm/vm_pageout.c (vm_pageout_setup): Properly lock `old_object'.
Diffstat (limited to 'vm/memory_object.c')
-rw-r--r-- | vm/memory_object.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/vm/memory_object.c b/vm/memory_object.c index 097ed23..0a07429 100644 --- a/vm/memory_object.c +++ b/vm/memory_object.c @@ -101,6 +101,7 @@ kern_return_t memory_object_data_supply( vm_page_t *page_list; boolean_t was_absent; vm_map_copy_t orig_copy = data_copy; + pager_request_t pager_request; /* * Look for bogus arguments @@ -270,6 +271,7 @@ retry_lookup: /* * Send reply if one was requested. */ + pager_request = object->pager_request; vm_object_paging_end(object); vm_object_unlock(object); @@ -279,7 +281,7 @@ retry_lookup: if (IP_VALID(reply_to)) { memory_object_supply_completed( reply_to, reply_to_type, - object->pager_request, + pager_request, original_offset, original_length, result, @@ -788,7 +790,9 @@ MACRO_END continue; case MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN: - case MEMORY_OBJECT_LOCK_RESULT_MUST_RETURN: + case MEMORY_OBJECT_LOCK_RESULT_MUST_RETURN:; + vm_offset_t object_paging_offset; + /* * The clean and return cases are similar. * @@ -811,6 +815,7 @@ MACRO_END PAGEOUT_PAGES; } + object_paging_offset = object->paging_offset; vm_object_unlock(object); /* @@ -821,8 +826,7 @@ MACRO_END if (new_object == VM_OBJECT_NULL) { new_object = vm_object_allocate(original_size); new_offset = 0; - paging_offset = m->offset + - object->paging_offset; + paging_offset = m->offset + object_paging_offset; pageout_action = page_lock_result; } @@ -831,7 +835,7 @@ MACRO_END * new object. */ m = vm_pageout_setup(m, - m->offset + object->paging_offset, + m->offset + object_paging_offset, new_object, new_offset, should_flush); @@ -859,11 +863,12 @@ MACRO_END } if (IP_VALID(reply_to)) { + pager_request_t pager_request = object->pager_request; vm_object_unlock(object); /* consumes our naked send-once/send right for reply_to */ (void) memory_object_lock_completed(reply_to, reply_to_type, - object->pager_request, original_offset, original_size); + pager_request, original_offset, original_size); vm_object_lock(object); } |