Skip to content

Commit f33cf52

Browse files
committed
Fix #79566: Private SHM is not private on Windows
We map the POSIX semantics of `IPC_PRIVATE` by creating unnamed file mapping objects on Windows. While that is not particularly useful for ext/shmop, which is the only bundled extension which uses `shmget()`, it may be useful for external extensions.
1 parent c40a494 commit f33cf52

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 7.3.19
44

5+
- Core:
6+
. Fixed bug #79566 (Private SHM is not private on Windows). (cmb)
7+
58
- Opcache:
69
. Fixed bug #79535 (PHP crashes with specific opcache.optimization_level).
710
(Nikita)

TSRM/tsrm_win32.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -616,14 +616,16 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
616616
{/*{{{*/
617617
shm_pair *shm;
618618
char shm_segment[26], shm_info[29];
619-
HANDLE shm_handle, info_handle;
619+
HANDLE shm_handle = NULL, info_handle = NULL;
620620
BOOL created = FALSE;
621621

622-
snprintf(shm_segment, sizeof(shm_segment), "TSRM_SHM_SEGMENT:%d", key);
623-
snprintf(shm_info, sizeof(shm_info), "TSRM_SHM_DESCRIPTOR:%d", key);
622+
if (key != IPC_PRIVATE) {
623+
snprintf(shm_segment, sizeof(shm_segment), "TSRM_SHM_SEGMENT:%d", key);
624+
snprintf(shm_info, sizeof(shm_info), "TSRM_SHM_DESCRIPTOR:%d", key);
624625

625-
shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
626-
info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
626+
shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
627+
info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
628+
}
627629

628630
if (!shm_handle && !info_handle) {
629631
if (flags & IPC_CREAT) {
@@ -634,8 +636,8 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
634636
DWORD high = 0;
635637
DWORD low = size;
636638
#endif
637-
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, high, low, shm_segment);
638-
info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), shm_info);
639+
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, high, low, key == IPC_PRIVATE ? NULL : shm_segment);
640+
info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), key == IPC_PRIVATE ? NULL : shm_info);
639641
created = TRUE;
640642
}
641643
if (!shm_handle || !info_handle) {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
shmop_open with IPC_PRIVATE creates private SHM
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('shmop')) die('skip shmop extension not available');
6+
?>
7+
--FILE--
8+
<?php
9+
$write = 'test';
10+
11+
$shm1 = shmop_open(0, 'c', 0777, 1024);
12+
shmop_write($shm1, $write, 0);
13+
14+
$shm2 = shmop_open(0, 'c', 0777, 1024);
15+
$read = shmop_read($shm2, 0, 4);
16+
17+
var_dump(is_string($read) && $read !== $write);
18+
19+
shmop_close($shm1);
20+
shmop_close($shm2);
21+
?>
22+
--EXPECT--
23+
bool(true)

0 commit comments

Comments
 (0)