[php-src] Issue #9944: Windows C shmget(IPC_PRIVATE, ...) returns IPC_PRIVATE(0) instead of distinct id for new section
| From: | TysonAndre | Date: | Sun, 13 Nov 2022 19:18:10 +0000 |
| Subject: | [php-src] Issue #9944: Windows C shmget(IPC_PRIVATE, ...) returns IPC_PRIVATE(0) instead of distinct id for new section | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-242810@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/9944
Author: TysonAndre
### Description
The following code:
https://github.com/php/php-src/blob/php-8.2.0RC6/TSRM/tsrm_win32.c#L613-L683
```c
size_t size = 8192;
key_t key = IPC_PRIVATE; /* shm key */
oflag = IPC_CREAT | SHM_R | SHM_A;
if ((shmid = shmget(key, size, oflag)) < 0) {
zend_error_noreturn(E_CORE_ERROR, "shmget failed");
}
fprintf(stderr, "shmid %d\n", shmid);
```
Resulted in this output because nothing sets
key for IPC_PRIVATE:
```
shmid 0
```
But I expected this output instead:
```
shmid $distinct_nonzero_integer
```
If code calls shmget(IPC_PRIVATE) multiple times on Windows and gets IPC_PRIVATE as a result,
applications would need distinct ids to distinguish them in operations managing the shared memory
segments
- A symptom can be seen is that shmctl would fail to be set on the right shared memory segment
because there are distinct segments with the same id of 0 https://github.com/php/php-src/blob/php-8.2.0RC6/TSRM/tsrm_win32.c#L722
- On linux with the real shmget() i'd get identifiers such as 3964933, 3964935 and pointers
such as 0x7ff0dbe1f000, 0x7ff0eca55000 for multiple calls to fetch IPC_PRIVATE
Related to https://github.com/php/php-src/issues/9829 - I
believe TSRM/tsrm_win32.c for windows didn't attempt to support IPC_PRIVATE in PHP versions
prior to that
Noticed while investigating https://github.com/krakjoe/apcu/issues/445
when using more than one shared segment
```
if (flags & IPC_CREAT) {
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, high, low, key ==
IPC_PRIVATE ? NULL : shm_segment);
```
It seems like it should immediately choose a distinct id if key == IPC_PRIVATE -
it'd be clobbering the existing entry with the key 0, which would prevent detaching segments
other than the most recent one created with IPC_PRIVATE
https://github.com/php/php-src/blob/php-8.2.0RC6/TSRM/tsrm_win32.c#L652-L657
-----
https://man7.org/linux/man-pages/man2/shmget.2.html
```
RETURN VALUE [top](https://man7.org/linux/man-pages/man2/shmget.2.html#top_of_page)
On success, a valid shared memory identifier is returned. On
error, -1 is returned, and [errno](https://man7.org/linux/man-pages/man3/errno.3.html) is set
to indicate the error.
DESCRIPTION
shmget() returns the identifier of the System V shared memory
segment associated with the value of the argument key. It may be
used either to obtain the identifier of a previously created
shared memory segment (when shmflg is zero and key does not have
the value IPC_PRIVATE), or to create a new set.
A new shared memory segment, with size equal to the value of size
rounded up to a multiple of PAGE_SIZE, is created if key has the
value IPC_PRIVATE or key isn't IPC_PRIVATE, no shared memory
segment corresponding to key exists, and IPC_CREAT is specified
in shmflg.
```
### PHP Version
8.2
### Operating System
Windows