Bug #75415 [Com]: shm_put_var() parallel bug.
Edit report at https://bugs.php.net/bug.php?id=75415&edit=1
ID: 75415
Comment by: abecker at mailbox dot org
Reported by: abc905 at mail dot ru
Summary: shm_put_var() parallel bug.
Status: Open
Type: Bug
Package: Semaphore related
Operating System: Linux Debian 4.9.0-4-amd64
PHP Version: 7.1.10
Block user comment: N
Private report: N
New Comment:
The shmop extension apparently has the same problem. And I want to add that of course the read
functions also need to be locked by a semaphore, not only the write functions.
Previous Comments:
------------------------------------------------------------------------
[2021-11-04 08:20:36] abecker at mailbox dot org
The problem is that the shm extension does not use semaphores to protect the shared memory from
parellel access. Parallel operations from different processes can thus result in memory corruption,
race conditions, and the error "Warning: shm_put_var(): Not enough shared memory left".
The problem is still present in PHP 8.0.12.
As a workaround, in PHP one must create a semaphore and always encapsulate shm_put_var within
sem_acquire and sem_release calls.
Here is an example in C how to use semaphore locks to access shared memory: https://www.ibm.com/docs/en/i/7.2?topic=programs-example-using-semaphore-set-shared-memory-functions
------------------------------------------------------------------------
[2017-10-22 10:04:41] abc905 at mail dot ru
Description:
------------
Run test script 1-10 times to see that in spite of the fact
shm_put_var returns true, shm_has_var() returns false.
Calling sem_get() fixes the bug
Test script:
---------------
$processes = 300;
$shmem = shm_attach(ftok(__FILE__, 'f'), 100000);
// If uncomment next line shm_put_var works correctly
// $sem = sem_get(ftok(__FILE__, 'a'));
for ($i = 1; $i <= $processes; $i++) {
if (pcntl_fork() === 0) {
usleep(100000);
$pid = getmypid();
$put_ok = shm_put_var($shmem, $pid, $i);
if ($put_ok && !shm_has_var($shmem, $pid)) {
print "shm_put_var() bug\n";
}
exit(0);
}
}
while (pcntl_wait($status) !== -1){}
shm_remove($shmem);
shm_detach($shmem);
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=75415&edit=1
Thread (3 messages)