Posix Shared Memory and Semaphores Permissions Set Incorrectly by Open Calls

POSIX shared memory and semaphores permissions set incorrectly by open calls

It's probably umask.

Citing the manpage of shm_open:

   O_CREAT    Create  the  shared memory object if it does not exist.  The user and
group ownership of the object are taken from the corresponding effec‐
tive IDs of the calling process, and the object's permission bits are
set according to the low-order 9 bits of mode, except that those bits
set in the process file mode creation mask (see umask(2)) are cleared
for the new object. A set of macro constants which can be used to
define mode is listed in open(2). (Symbolic definitions of these
constants can be obtained by including <sys/stat.h>.)

So, in order to allow creating files which are world-writable, you'd need to set an umask permitting it, for example:

umask(0);

Set like this, umask won't affect any permissions on created files anymore. However, you should note that if you will then create another file without specifying permissions explicitly, it will be world-writable as well.

Thus, you may want to clear the umask only temporarily, and then restore it:

#include <sys/types.h>
#include <sys/stat.h>

...

void yourfunc()
{
// store old
mode_t old_umask = umask(0);

int fd = shm_open(SHARE_MEM_NAME,O_RDWR | O_CREAT,0606);

// restore old
umask(old_umask);
}

shm_open not setting group write access

Your issue is duplicate of below thread

POSIX shared memory and semaphores permissions set incorrectly by open calls

mode_t old_umask = umask(0);

int fd = shm_open("somekey", O_CREAT | O_RDWR, S_IRWXU | S_IRWXG);

// restore old
umask(old_umask);

where does sem_open shared memory on osx

From the man page of sem_open() on OS X:

There is no visible entry in the file system for the created object in
this implementation.

How do you correctly cleanup and re-use SysV shared memory segments?

I was misled into thinking it was proper form to call shmctl(segmentId, IPC_RMID) as soon as the process designated as the owner has attached to the shared memory.

In fact IPC_RMID should not be called until all processes have attached.

Part of the answer is here:

https://comp.unix.programmer.narkive.com/iLg3PhfZ/shmctl-ipc-rmid-oddity

It seems that IPC_RMID sets the segment to private so that no new processes can attach to it.

A way of guaranteeing a unique segment is deliberately using IPC_PRIVATE to start with:

id = shmget(IPC_PRIVATE, IPC_CREAT | mode);

This also avoids the need to use ftok() and risk colliding with another segment.
Unfortunately I cannot use that here as the interface is predicated on identifying the segment with ftok(). At least I understand the issue here.

Someone wiser may be able to chip in with better ways of cleaning up before re-use.

See also https://www.linuxquestions.org/questions/programming-9/shmctl-ipc_rmid-precludes-further-attachments-574636/

Also consider this question and answer: Linux IPC: shared memory recovery

POSIX semaphore with related processes running threads

(1) Your biggest problem by far is that you have managed to write a fork bomb. Because you don't exit either child in the fork loop each child is going to fall through and loop around and create their own children until you crash or bring the system down. You want something more like this:

while(i < 2)
{
fork_value = fork();

if(fork_value > 0)
i++;

if(fork_value == 0)
{
if(i==0)
{
printf("0 child is pid %d\n", getpid());

int res;
res = pthread_create(&a_thread,NULL,thread_write,NULL);
res = pthread_join(a_thread,&thread_result1);
exit(0);
}

if(i==1)
{
printf("1 child is pid %d\n", getpid());

int res;
res = pthread_create(&b_thread,NULL,thread_read,NULL);
res = pthread_join(b_thread,&thread_result2);
exit(0);
}
}
}

for (i = 0; i < 2; ++i)
wait(NULL);

Notice the wait on the children which you neglected.

(2) Always check your return codes. They are like safety belts, a bit of a drag but so helpful when you crash. (Yes, I didn't take my advice here but you should.)

(3) These names are awful.

unsigned short int read;
unsigned short int write;

Stay away from naming variables after system calls. It's confusing and just asking for trouble.

(4) Terminology wise, processes with a common ancestor, like these, are related. The parent can open shared memory and other resources and pass it on to the children. Unrelated processes would, for example, multiple instances of program launched from different terminals. They can share resources but not in the "inherited" way forked processes do.

It's late and didn't get around to looking at what you are doing with the threads and such but this should get you started.



Related Topics



Leave a reply



Submit