php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #10044 Bug in shm_remove() and inadequate implementation of SYSVSem.
Submitted: 2001-03-28 20:18 UTC Modified: 2001-05-15 03:49 UTC
From: swm at linuxworld dot com dot au Assigned:
Status: Closed Package: Semaphore related
PHP Version: 4.0.4pl1 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: swm at linuxworld dot com dot au
New email:
PHP Version: OS:

 

 [2001-03-28 20:18 UTC] swm at linuxworld dot com dot au
There is a bug in shm_remove() that comes from the fact
that the function is treating its argument, shm_identifier,
as a shm key. The function argument should be
shm_identifier. The patch appended fixes this problem.

There is also an implementation issue with SYSV Semaphores.
There is no method of removing unrequired semaphores. See
the patch appended for a function, sem_remove, which can do
this.

I am happy to take over maintenance of this section.

As for the patches, I have had to cut and paste them so I am
unsure if Mozilla has wrapped certain lines. If so, I will
email them.

-----
Patch
-----

--- ext/sysvshm/sysvshm.c.orig  Fri Mar 16 01:22:16 2001
+++ ext/sysvshm/sysvshm.c       Fri Mar 16 01:42:15 2001
@@ -173,26 +173,40 @@
 /* }}} */
 /* {{{ proto int shm_remove(int shm_identifier)
    Removes shared memory from Unix systems */
+
+/* patched to use the correct argument Fri Mar 16 01:22:50
EST 2001
+ * Gavin Sherry gavin@linuxworld.com.au
+ */
+
 PHP_FUNCTION(shm_remove)
 {
-       pval **arg_key;
+       pval **arg_id;
        long id;
-       key_t key;
+       int type;
+       sysvshm_shm *shm_list_ptr;
 
-       if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1,
&arg_key) == FAILUR
E) {
+       if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1,
&arg_id) == FAILURE
) {
                WRONG_PARAM_COUNT;
        }
 
-       convert_to_long_ex(arg_key);
+       convert_to_long_ex(arg_id);
        
-       key = (*arg_key)->value.lval;
+       id = (*arg_id)->value.lval;
 
+/*
+ * this isn't what we're looking to do 
+ */
+
+/*
        if((id=shmget(key,0,0))<0) {
                php_error(E_WARNING, "%d is not a existing
SysV shared memory ke
y", key);
                RETURN_FALSE;
        }
-       if(shmctl(id,IPC_RMID,NULL)<0) {
-               php_error(E_WARNING, "shm_remove() failed
for key 0x%x: %s", key
, strerror(errno));
+*/
+
+       shm_list_ptr = (sysvshm_shm *) zend_list_find(id,
&type);
+       if(shmctl(shm_list_ptr->id,IPC_RMID,NULL)<0) {
+               php_error(E_WARNING, "shm_remove() failed
for key 0x%x, id %i: %s",shm_list_ptr->key,id,strerror(errno));
                RETURN_FALSE;
        } 

--- ext/sysvsem/php_sysvsem.h.orig      Fri Mar 16 01:44:26 2001
+++ ext/sysvsem/php_sysvsem.h   Fri Mar 16 01:44:17 2001
@@ -30,6 +30,7 @@
 PHP_FUNCTION(sem_get);
 PHP_FUNCTION(sem_acquire);
 PHP_FUNCTION(sem_release);
+PHP_FUNCTION(sem_remove);
 
 typedef struct {
        int le_sem;

--- ext/sysvsem/sysvsem.c.orig  Thu Mar 15 22:40:18 2001
+++ ext/sysvsem/sysvsem.c       Thu Mar 15 23:15:17 2001
@@ -53,6 +53,7 @@
        PHP_FE(sem_get,                 NULL)
        PHP_FE(sem_acquire,             NULL)
        PHP_FE(sem_release,             NULL)
+       PHP_FE(sem_remove,              NULL)
        {NULL, NULL, NULL}
 };
 
@@ -92,6 +93,14 @@
        sysvsem_sem *sem_ptr = (sysvsem_sem *)rsrc->ptr;
        struct sembuf sop[2];
 
+/*
+ * if count == -1, semaphore has been removed
+ * Need better way to handle this
+ */
+
+       if(sem_ptr->count == -1) {
+               return;
+       }
        /* Decrement the usage count. */
 
        sop[0].sem_num = SYSVSEM_USAGE;
@@ -343,6 +352,63 @@
 {
        php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
 }
+/* }}} */
+
+
+
+
+/* {{{ proto int sem_remove(int id)
+   Removes semaphore from Unix systems */
+
+/*
+ * contributed by Gavin Sherry gavin@linuxworld.com.au
+ * Fri Mar 16 00:50:13 EST 2001
+ */
+
+PHP_FUNCTION(sem_remove)
+{
+        pval **arg_id;
+        int id,type;
+       sysvsem_sem *sem_ptr;
+#if HAVE_SEMUN
+       union semun un;
+#endif
+        if(ZEND_NUM_ARGS() != 1 ||
zend_get_parameters_ex(1, &arg_id) == FAILUR
E) {
+                WRONG_PARAM_COUNT;
+        }
+        convert_to_long_ex(arg_id);
+
+        id = (*arg_id)->value.lval;
+
+        sem_ptr = (sysvsem_sem *) zend_list_find(id, &type);
+
+        if (type!=php_sysvsem_module.le_sem) {
+                php_error(E_WARNING, "%d is not a SysV
semaphore index", id);
+                RETURN_FALSE;
+        }
+
+#if HAVE_SEMUN
+        if(semctl(sem_ptr->semid,NULL,IPC_STAT,un)<0) {
+#else
+       if(semctl(sem_ptr->semid,NULL,IPC_STAT,NULL)<0) {
+#endif
+                php_error(E_WARNING, "%d is not a existing
SysV Semaphore Id", 
id);
+                RETURN_FALSE;
+        }
+
+       if(semctl(sem_ptr->semid,NULL,IPC_RMID,NULL)<0) {
+                php_error(E_WARNING, "sem_remove() failed
for id %d: %s", id, s
trerror(errno));
+                RETURN_FALSE;
+        }
+       
+       /* let release_sysvsem_sem knows we have removed
+        * the semaphore to avoid issues with releasing.
+        */ 
+
+       sem_ptr->count = -1;
+        RETURN_TRUE;
+}
+
 /* }}} */
 
 #endif /* HAVE_SYSVSEM */

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-05-15 03:49 UTC] swm@php.net
Fix in current CVS
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 28 10:01:29 2024 UTC