Skip to content

Commit 3254c4e

Browse files
committed
Merge branch 'PHP-8.6'
* PHP-8.6: TSRM: Fix Windows shared memory payload offset
2 parents 46270d7 + aed9bab commit 3254c4e

2 files changed

Lines changed: 31 additions & 6 deletions

File tree

‎TSRM/tsrm_win32.c‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,7 @@ static key_t tsrm_choose_random_shm_key(key_t prev_key) {
633633
TSRM_API int shmget(key_t key, size_t size, int flags)
634634
{/*{{{*/
635635
shm_pair *shm;
636+
size_t mapping_size;
636637
char shm_segment[sizeof(SEGMENT_PREFIX INT_MIN_AS_STRING)];
637638
HANDLE shm_handle = NULL;
638639
BOOL created = FALSE;
@@ -648,16 +649,16 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
648649

649650
if (!shm_handle) {
650651
if (flags & IPC_CREAT) {
651-
if (size == 0 || size > SIZE_MAX - sizeof(shm->descriptor)) {
652+
if (size == 0 || size > SIZE_MAX - sizeof(*shm->descriptor)) {
652653
return -1;
653654
}
654-
size += sizeof(shm->descriptor);
655+
mapping_size = size + sizeof(*shm->descriptor);
655656
#if SIZEOF_SIZE_T == 8
656-
DWORD high = size >> 32;
657-
DWORD low = (DWORD)size;
657+
DWORD high = mapping_size >> 32;
658+
DWORD low = (DWORD)mapping_size;
658659
#else
659660
DWORD high = 0;
660-
DWORD low = size;
661+
DWORD low = mapping_size;
661662
#endif
662663
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, high, low, key == IPC_PRIVATE ? NULL : shm_segment);
663664
created = TRUE;
@@ -728,7 +729,7 @@ TSRM_API void *shmat(int key, const void *shmaddr, int flags)
728729
return (void*)-1;
729730
}
730731

731-
shm->addr = shm->descriptor + sizeof(shm->descriptor);
732+
shm->addr = shm->descriptor + 1;
732733
shm->descriptor->shm_atime = time(NULL);
733734
shm->descriptor->shm_lpid = getpid();
734735
shm->descriptor->shm_nattch++;

‎ext/shmop/tests/tsrm_shmat.phpt‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
TSRM Windows shmop keeps the payload within its mapping
3+
--EXTENSIONS--
4+
shmop
5+
--SKIPIF--
6+
<?php
7+
if (PHP_OS_FAMILY !== 'Windows') die('skip only for Windows');
8+
?>
9+
--FILE--
10+
<?php
11+
$shm = shmop_open(0, 'c', 0644, 65472);
12+
$payload = str_repeat('x', 65471) . 'z';
13+
var_dump($shm !== false);
14+
var_dump(shmop_size($shm));
15+
var_dump(shmop_write($shm, $payload, 0));
16+
var_dump(shmop_read($shm, 65471, 1));
17+
var_dump(shmop_delete($shm));
18+
?>
19+
--EXPECT--
20+
bool(true)
21+
int(65472)
22+
int(65472)
23+
string(1) "z"
24+
bool(true)

0 commit comments

Comments
 (0)