Fix GH-14537: shmop Windows 11 crashes the process

The error handling code isn't entirely right in two places.
One of the code blocks is dead because of an always-false condition, and
another code block is missing the assignment of a NULL pointer.

Getting the exact same behaviour is not entirely possible because you
can't extend the size of a shared memory region after it was made with
the Windows APIs we use, unless we destroy the region and recreate it,
but that has other consequences.
However, it certainly shouldn't crash.

Closes GH-14707.
This commit is contained in:
Niels Dossche 2024-06-28 18:26:47 +02:00
parent 5a32b510ef
commit 39a3266576
No known key found for this signature in database
GPG key ID: B8A8AD166DF0E2E5
3 changed files with 32 additions and 2 deletions

2
NEWS
View file

@ -10,6 +10,8 @@ PHP NEWS
. Fixed bug GH-14596 (crashes with ASAN and ZEND_RC_DEBUG=1).
(David Carlier)
- Shmop:
. Fixed bug GH-14537 (shmop Windows 11 crashes the process). (nielsdos)
04 Jul 2024, PHP 8.2.21

View file

@ -709,6 +709,7 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
CloseHandle(shm->segment);
}
UnmapViewOfFile(shm->descriptor);
shm->descriptor = NULL;
return -1;
}
@ -744,8 +745,8 @@ TSRM_API int shmdt(const void *shmaddr)
shm->descriptor->shm_lpid = getpid();
shm->descriptor->shm_nattch--;
ret = 1;
if (!ret && shm->descriptor->shm_nattch <= 0) {
ret = 0;
if (shm->descriptor->shm_nattch <= 0) {
ret = UnmapViewOfFile(shm->descriptor) ? 0 : -1;
shm->descriptor = NULL;
}

View file

@ -0,0 +1,27 @@
--TEST--
GH-14537: shmop Windows 11 crashes the process
--EXTENSIONS--
shmop
--SKIPIF--
<?php
if (PHP_OS_FAMILY !== 'Windows') die('skip only for Windows');
?>
--FILE--
<?php
$str = 'Hello World';
$shm_key = ftok(__FILE__, 'p');
$shm_id1 = shmop_open($shm_key, 'c', 0644, strlen($str));
shmop_delete($shm_id1);
var_dump($shm_id1);
$shm_id2 = shmop_open($shm_key, 'c', 0644, strlen($str) + 10);
var_dump($shm_id2);
?>
--EXPECTF--
object(Shmop)#1 (0) {
}
Warning: shmop_open(): Unable to attach or create shared memory segment "No error" in %s on line %d
bool(false)