4
0
Эх сурвалжийг харах

cpg: Memory not unmapped in cpg_zcb_free

Function in cpg_zcb_alloc (from code lib/cpg.c) creates
/dev/shm/corosync_zerocopy-XXXXX and does mmap

The memory is allocated by corosync service (function zcb_alloc
in exec/cpg.c) also and both shares this memory via mmap
(uses MAP_SHARED in mmap call)

Corosync calls unlink which deletes the file from /dev/shm while
closing the file descriptor, but unmap is not happening correctly
while calling cpg_zcb_free.

So:
- still the deleted file holds the memory
- As munmap is not happening correctly, the number of mappings per
  process gets exceeded and corosync dies with ENOMEM

From gdb, the size passed to munmap appears to be zero and address
looks wrong. Also in the code return code of munmap is not checked.

The patch adds check for:
-  munmap return code and getting correct address for munmap

Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Reviewed-by: Jan Friesse <jfriesse@redhat.com>
Athira Rajeev 10 жил өмнө
parent
commit
1130e18595
1 өөрчлөгдсөн 6 нэмэгдсэн , 2 устгасан
  1. 6 2
      lib/cpg.c

+ 6 - 2
lib/cpg.c

@@ -943,11 +943,12 @@ cs_error_t cpg_zcb_free (
 	void *buffer)
 {
 	cs_error_t error;
+	unsigned int res;
 	struct cpg_inst *cpg_inst;
 	mar_req_coroipcc_zc_free_t req_coroipcc_zc_free;
 	struct qb_ipc_response_header res_coroipcs_zc_free;
 	struct iovec iovec;
-	struct coroipcs_zc_header *header = (struct coroipcs_zc_header *)((char *)buffer - sizeof (struct coroipcs_zc_header));
+	struct coroipcs_zc_header *header = (struct coroipcs_zc_header *)((char *)buffer - sizeof (struct coroipcs_zc_header) - sizeof (struct req_lib_cpg_mcast));
 
 	error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void *)&cpg_inst));
 	if (error != CS_OK) {
@@ -969,7 +970,10 @@ cs_error_t cpg_zcb_free (
 		&res_coroipcs_zc_free,
 		sizeof (struct qb_ipc_response_header));
 
-	munmap ((void *)header, header->map_size);
+	res = munmap ((void *)header, header->map_size);
+	if (res == -1) {
+			return (-1);
+	}
 
 	hdb_handle_put (&cpg_handle_t_db, handle);