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.
This commit is contained in:
Christoph M. Becker 2020-05-05 09:31:17 +02:00
parent c40a494406
commit f33cf52faf
3 changed files with 35 additions and 7 deletions

3
NEWS
View File

@ -2,6 +2,9 @@ PHP NEWS
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 7.3.19 ?? ??? ????, PHP 7.3.19
- Core:
. Fixed bug #79566 (Private SHM is not private on Windows). (cmb)
- Opcache: - Opcache:
. Fixed bug #79535 (PHP crashes with specific opcache.optimization_level). . Fixed bug #79535 (PHP crashes with specific opcache.optimization_level).
(Nikita) (Nikita)

View File

@ -616,14 +616,16 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
{/*{{{*/ {/*{{{*/
shm_pair *shm; shm_pair *shm;
char shm_segment[26], shm_info[29]; char shm_segment[26], shm_info[29];
HANDLE shm_handle, info_handle; HANDLE shm_handle = NULL, info_handle = NULL;
BOOL created = FALSE; BOOL created = FALSE;
snprintf(shm_segment, sizeof(shm_segment), "TSRM_SHM_SEGMENT:%d", key); if (key != IPC_PRIVATE) {
snprintf(shm_info, sizeof(shm_info), "TSRM_SHM_DESCRIPTOR:%d", key); 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); shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info); info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
}
if (!shm_handle && !info_handle) { if (!shm_handle && !info_handle) {
if (flags & IPC_CREAT) { if (flags & IPC_CREAT) {
@ -634,8 +636,8 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
DWORD high = 0; DWORD high = 0;
DWORD low = size; DWORD low = size;
#endif #endif
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, high, low, shm_segment); 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), shm_info); info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), key == IPC_PRIVATE ? NULL : shm_info);
created = TRUE; created = TRUE;
} }
if (!shm_handle || !info_handle) { if (!shm_handle || !info_handle) {

View File

@ -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)