summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2010-06-28 18:12:42 +0000
committerkib <kib@FreeBSD.org>2010-06-28 18:12:42 +0000
commit2ab2a361d3c862dd71870aea0a9cae7ca13ce74f (patch)
treeefed7b427c61cfcfbc60fc0ae2663822549dc4c4
parentb6d8416eac525c06902bf03315b88189e10545e3 (diff)
downloadFreeBSD-src-2ab2a361d3c862dd71870aea0a9cae7ca13ce74f.zip
FreeBSD-src-2ab2a361d3c862dd71870aea0a9cae7ca13ce74f.tar.gz
Despite system call deregistration drains the threads executing System V
shm syscalls, and initial check for the number of allocated segments in the module deinitialization code, the following might happen: after the check for active segment, while waiting for threads to leave some other syscall, shmget(2) is called. Then, we can end up with the shared segment that cannot be detached since sysvshm module is unloaded. Prevent the leak by rechecking and disclaiming a reference to the vm object owned by sysvshm module, that might have grown during the drain. Tested by: pho Reviewed by: jhb MFC after: 1 month
-rw-r--r--sys/kern/sysv_shm.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
index 39e0923..e760a78 100644
--- a/sys/kern/sysv_shm.c
+++ b/sys/kern/sysv_shm.c
@@ -919,10 +919,18 @@ shmunload()
#endif
syscall_helper_unregister(shm_syscalls);
+ for (i = 0; i < shmalloced; i++) {
#ifdef MAC
- for (i = 0; i < shmalloced; i++)
mac_sysvshm_destroy(&shmsegs[i]);
#endif
+ /*
+ * Objects might be still mapped into the processes
+ * address spaces. Actual free would happen on the
+ * last mapping destruction.
+ */
+ if (shmsegs[i].u.shm_perm.mode != SHMSEG_FREE)
+ vm_object_deallocate(shmsegs[i].object);
+ }
free(shmsegs, M_SHM);
shmexit_hook = NULL;
shmfork_hook = NULL;
OpenPOWER on IntegriCloud