Bug 16056

Summary: Shared memory & mutex ownership not correctly established for SysV mutexes.
Product: APR Reporter: Anthony Howe <achowe>
Component: APRAssignee: Apache Portable Runtime bugs mailinglist <bugs>
Status: NEEDINFO ---    
Severity: enhancement Keywords: PatchAvailable
Priority: P3    
Version: HEAD   
Target Milestone: ---   
Hardware: Other   
OS: Linux   
Attachments: Proposed solution.
extend apr_shm_create

Description Anthony Howe 2003-01-14 08:16:18 UTC
While attempting to port mod_watch to Apache 2.0, which uses both anonymous
shared memory and mutexes, I found that I kept getting EACCESS every time I
tried to lock the mutex. Now comparing my shared memory and mutex code used in
1.3 vs. that in the APR, the only difference I could find was that the APR code
fails to assign the uid/gid ownership of the mutex to that of the "prefork"
child processes (User/Group directives). Now the APR has no appropriate API for
changing the ownership of shared memory or a mutex.  

I tested my theory by adding the following code to my module, which proceeded to
function afterwards:

#if defined(APR_USE_SHMEM_SHMGET) || defined(APR_USE_SHMEM_SHMGET_ANON)
#include "arch/unix/shm.h"
#include "unixd.h"
#endif

#if defined(APR_HAS_SYSVSEM_SERIALIZE)
#include "arch/unix/global_mutex.h"
#include "unixd.h"
#endif

...

  rc = apr_shm_create((apr_shm_t **) &tp->shared, bytes, (const char *) 0, p);
  if (rc != APR_SUCCESS)
	goto error0;

#if defined(APR_USE_SHMEM_SHMGET) || defined(APR_USE_SHMEM_SHMGET_ANON)
/* Setup the access permissions for the shared memory so that child processes
 * that change their user/group can still access the shared memory after. This
 * should have been done in the APR library or (due to lack of clear
 * documentation) I'm misundestanding how anonymous mutexes and shared
 * memory work.
 */
{
	struct shmid_ds shmbuf;
        apr_shm_t *theMem = tp->shared;

        if (shmctl(theMem->shmid, IPC_STAT, &shmbuf) != 0)
                goto error1;
        shmbuf.shm_perm.uid = unixd_config.user_id;;
        shmbuf.shm_perm.gid = unixd_config.group_id;
        shmbuf.shm_perm.mode = 0600;
        if (shmctl(theMem->shmid, IPC_SET, &shmbuf) != 0)
                goto error1;
}
#endif

...

	rc = apr_global_mutex_create(
		(apr_global_mutex_t **) &tp->mutex,
		tp->lockfile, APR_LOCK_DEFAULT, p
	);
	if (rc != APR_SUCCESS)
		goto error1;

#if defined(APR_HAS_SYSVSEM_SERIALIZE)
/* || defined(APR_HAS_FCNTL_SERIALIZE) || defined(APR_HAS_FLOCK_SERIALIZE) */
/* Setup the access permissions for the mutex so that child processes
 * that change their user/group can still access the mutex after. This
 * should have been done in the APR library or (due to lack of clear
 * documentation) I'm misundestanding how anonymous mutexes and shared
 * memory work.
 */
{
        union semun ick;
        struct semid_ds sembuf;
        apr_global_mutex_t *theMutex = tp->mutex;

        ick.buf = &sembuf;
        if (semctl(theMutex->proc_mutex->interproc->filedes, 0, IPC_STAT, ick) != 0)
                goto error3;
        sembuf.sem_perm.uid = unixd_config.user_id;
        sembuf.sem_perm.gid = unixd_config.group_id;
        sembuf.sem_perm.mode = 0600;
        if (semctl(theMutex->proc_mutex->interproc->filedes, 0, IPC_SET, ick) != 0)
                goto error3;
}
#endif
Comment 1 Anthony Howe 2003-01-19 13:19:33 UTC
OK. After some further puttering about with mod_watch development, I stumbled
across the following API in <unixd.h> (damn I wish there was better
documentation for developers):

   unixd_set_proc_mutex_perms();
   unixd_set_gobal_mutex_perms();

However, I can't find the equivalent for the shared memory case.
Comment 2 Anthony Howe 2003-02-05 12:32:34 UTC
Created attachment 4740 [details]
Proposed solution.
Comment 3 William A. Rowe Jr. 2006-02-07 22:51:06 UTC
The feature you request is not inherently provided by APR; but I'm noting
your request as an enhancement; I concur that httpd providing all the workarounds
here in their unix.c sources really is lame.

Your concern expressed in the patch is a no-go for the proposed solution, opening
up the permissions for the mutex is definately a nonstarter for the very reasons
you mentioned in the comments.
Comment 4 William A. Rowe Jr. 2006-09-19 19:54:39 UTC
Mass reassign the 44 open apr-bugs to apr bug list
Comment 5 Davi Arnaut 2007-07-21 15:12:55 UTC
Created attachment 20532 [details]
extend apr_shm_create

It seems like for now we could extend apr_shm_create() to accept access
permissions. How about the attached patch?