summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2020-05-05 09:31:17 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2020-05-05 11:38:29 +0200
commitf33cf52faf733f5a6441a533f83e9b1cf2018245 (patch)
tree1e95600ddf3429a25ca8a6b7feea59f9f255c557
parentc40a494406aa3606be964b24d224ec4eb0c936e8 (diff)
downloadphp-git-f33cf52faf733f5a6441a533f83e9b1cf2018245.tar.gz
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.
-rw-r--r--NEWS3
-rw-r--r--TSRM/tsrm_win32.c16
-rw-r--r--ext/shmop/tests/shmop_open_private.phpt23
3 files changed, 35 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index 5acd1e9bb6..593cdc0701 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 7.3.19
+- Core:
+ . Fixed bug #79566 (Private SHM is not private on Windows). (cmb)
+
- Opcache:
. Fixed bug #79535 (PHP crashes with specific opcache.optimization_level).
(Nikita)
diff --git a/TSRM/tsrm_win32.c b/TSRM/tsrm_win32.c
index cb2520e294..6cedaa8360 100644
--- a/TSRM/tsrm_win32.c
+++ b/TSRM/tsrm_win32.c
@@ -616,14 +616,16 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
{/*{{{*/
shm_pair *shm;
char shm_segment[26], shm_info[29];
- HANDLE shm_handle, info_handle;
+ HANDLE shm_handle = NULL, info_handle = NULL;
BOOL created = FALSE;
- snprintf(shm_segment, sizeof(shm_segment), "TSRM_SHM_SEGMENT:%d", key);
- snprintf(shm_info, sizeof(shm_info), "TSRM_SHM_DESCRIPTOR:%d", key);
+ if (key != IPC_PRIVATE) {
+ snprintf(shm_segment, sizeof(shm_segment), "TSRM_SHM_SEGMENT:%d", key);
+ snprintf(shm_info, sizeof(shm_info), "TSRM_SHM_DESCRIPTOR:%d", key);
- shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
- info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
+ shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
+ info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
+ }
if (!shm_handle && !info_handle) {
if (flags & IPC_CREAT) {
@@ -634,8 +636,8 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
DWORD high = 0;
DWORD low = size;
#endif
- shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, high, low, shm_segment);
- info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), shm_info);
+ shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, high, low, key == IPC_PRIVATE ? NULL : shm_segment);
+ info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), key == IPC_PRIVATE ? NULL : shm_info);
created = TRUE;
}
if (!shm_handle || !info_handle) {
diff --git a/ext/shmop/tests/shmop_open_private.phpt b/ext/shmop/tests/shmop_open_private.phpt
new file mode 100644
index 0000000000..df969885c9
--- /dev/null
+++ b/ext/shmop/tests/shmop_open_private.phpt
@@ -0,0 +1,23 @@
+--TEST--
+shmop_open with IPC_PRIVATE creates private SHM
+--SKIPIF--
+<?php
+if (!extension_loaded('shmop')) die('skip shmop extension not available');
+?>
+--FILE--
+<?php
+$write = 'test';
+
+$shm1 = shmop_open(0, 'c', 0777, 1024);
+shmop_write($shm1, $write, 0);
+
+$shm2 = shmop_open(0, 'c', 0777, 1024);
+$read = shmop_read($shm2, 0, 4);
+
+var_dump(is_string($read) && $read !== $write);
+
+shmop_close($shm1);
+shmop_close($shm2);
+?>
+--EXPECT--
+bool(true)