Skip to content

Commit dccbc0f

Browse files
committed
UCM/TEST: Generate VM_UNMAP event for shmat(REMAP) and mmap(FIXED)
These 2 calls can override an existing memory mapping, so generate a VM_UNMAP event for the old address range.
1 parent ff28459 commit dccbc0f

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

src/ucm/event/event.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ void *ucm_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t off
198198

199199
ucm_event_enter();
200200

201+
if ((flags & MAP_FIXED) && (addr != NULL)) {
202+
ucm_dispatch_vm_munmap(addr, length);
203+
}
204+
201205
event.mmap.result = MAP_FAILED;
202206
event.mmap.address = addr;
203207
event.mmap.size = length;
@@ -287,6 +291,7 @@ void *ucm_mremap(void *old_address, size_t old_size, size_t new_size, int flags)
287291

288292
void *ucm_shmat(int shmid, const void *shmaddr, int shmflg)
289293
{
294+
uintptr_t attach_addr;
290295
ucm_event_t event;
291296
khiter_t iter;
292297
size_t size;
@@ -298,6 +303,15 @@ void *ucm_shmat(int shmid, const void *shmaddr, int shmflg)
298303
shmid, shmaddr, shmflg);
299304

300305
size = ucm_shm_size(shmid);
306+
307+
if ((shmflg & SHM_REMAP) && (shmaddr != NULL)) {
308+
attach_addr = (uintptr_t)shmaddr;
309+
if (shmflg & SHM_RND) {
310+
attach_addr -= attach_addr % SHMLBA;
311+
}
312+
ucm_dispatch_vm_munmap((void*)shmaddr, size);
313+
}
314+
301315
event.shmat.result = MAP_FAILED;
302316
event.shmat.shmid = shmid;
303317
event.shmat.shmaddr = shmaddr;

test/gtest/ucm/malloc_hook.cc

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,3 +646,90 @@ UCS_TEST_F(malloc_hook_cplusplus, mmap_ptrs) {
646646
unset();
647647

648648
}
649+
650+
UCS_TEST_F(malloc_hook_cplusplus, remap_override) {
651+
652+
/*
653+
* Test memory mapping functions which override an existing mapping
654+
*/
655+
656+
size_t size = ucs_get_page_size() * 800;
657+
void *buffer;
658+
int shmid;
659+
660+
set();
661+
662+
EXPECT_EQ(0u, m_mapped_size);
663+
EXPECT_EQ(0u, m_unmapped_size);
664+
665+
/* 1. Map a large buffer */
666+
{
667+
buffer = mmap(NULL, size, PROT_READ|PROT_WRITE,
668+
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
669+
ASSERT_NE(MAP_FAILED, buffer) << strerror(errno);
670+
671+
EXPECT_EQ(size, m_mapped_size);
672+
EXPECT_EQ(0u, m_unmapped_size);
673+
}
674+
675+
/*
676+
* 2. Map another buffer in the same place.
677+
* Expected behavior: unmap event on the old buffer
678+
*/
679+
{
680+
m_mapped_size = m_unmapped_size = 0;
681+
682+
void *remap = mmap(buffer, size, PROT_READ|PROT_WRITE,
683+
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
684+
ASSERT_EQ(buffer, remap);
685+
686+
EXPECT_EQ(size, m_mapped_size);
687+
EXPECT_EQ(size, m_unmapped_size);
688+
}
689+
690+
/* 3. Create a shared memory segment */
691+
{
692+
shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | SHM_R | SHM_W);
693+
ASSERT_NE(-1, shmid) << strerror(errno);
694+
}
695+
696+
/*
697+
* 4. Attach the segment at the same buffer address.
698+
* Expected behavior: unmap event on the old buffer
699+
*/
700+
{
701+
m_mapped_size = m_unmapped_size = 0;
702+
703+
void *shmaddr = shmat(shmid, buffer, SHM_REMAP);
704+
ASSERT_EQ(buffer, shmaddr);
705+
706+
EXPECT_EQ(size, m_mapped_size);
707+
EXPECT_EQ(size, m_unmapped_size);
708+
}
709+
710+
/* 5. Detach the sysv segment */
711+
{
712+
m_mapped_size = m_unmapped_size = 0;
713+
714+
shmdt(buffer);
715+
716+
EXPECT_EQ(size, m_unmapped_size);
717+
}
718+
719+
/* 6. Remove the shared memory segment */
720+
{
721+
int ret = shmctl(shmid, IPC_RMID, NULL);
722+
ASSERT_NE(-1, ret) << strerror(errno);
723+
}
724+
725+
/* 7. Unmap the buffer */
726+
{
727+
m_mapped_size = m_unmapped_size = 0;
728+
729+
munmap(buffer, size);
730+
731+
EXPECT_EQ(size, m_unmapped_size);
732+
}
733+
734+
unset();
735+
}

0 commit comments

Comments
 (0)