Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deny an access to shared memory from non-forked processes

I need to create a shared memory segment which contains some secret data. I use shmget and shmat functions to access the segment with 0600 rights. I want to share this segment of memory with forked processes only. I tried to create another application which tried to access this segment and it was unsuccessful, so it looks like it's working as I want.

But when I run the application which created the segment again, it can access the segment. How is it possible? Is a good idea to store secret data into shared memory?

like image 488
Dušan Kováčik Avatar asked Jan 12 '16 08:01

Dušan Kováčik


People also ask

Does a forked process share memory?

What fork() does is the following: It creates a new process which is a copy of the calling process. That means that it copies the caller's memory (code, globals, heap and stack), registers, and open files.

Do parent and child processes share memory?

Answer: Only the shared memory segments are shared between the parent process and the newly forked child process. Copies of the stack and the heap are made for the newly created process.

Can two processes share memory?

Processes don't share memory with other processes. Threads share memory with other threads of the same process.


2 Answers

You can mmap() shared and anonymous memory region by providing MAP_SHARED and MAP_ANONYMOUS flags in parent process. That memory will be accessible only to that process and its children. As memory segment is anonymous, no other processes will be able to refer to it, let alone access/map it:

void *shared_mem = mmap(NULL, n_bytes, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);

Parent process should create shared memory segment using mmap(). That memory segment is inherited by any child process created by fork(). Child process can simply use shared_mem pointer inherited from parent to refer to that memory segment:

#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    void *shared_mem = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);

    pid_t pid = fork();
    if (pid > 0) {
        // parent
        // use shared_mem here

    } else if (pid == 0) {
        // child
        // use shared_mem here

    } else {
        // error
    }
    return 0;
}
like image 60
el.pescado - нет войне Avatar answered Sep 30 '22 15:09

el.pescado - нет войне


The shared seg doesn't belong to a process, it belongs to a user. Effectively settings 0600 only allows that user for RW (and root), however any other process running as this user will have the same access.

Create a specific user, to be "used" (logged in) only for this purpose.

Is it a good idea to have secret data in a shared memory segment?

Think of the segment as a file - maybe a bit less easy to access (need to know IPC) - except it will disappear when the system shuts down.

Is it a good idea to store secrets in a file? Maybe not if the data is clear text.

In a file or in a shared mem segment, data encryption would be an improvement.

See this page for detailed explanations on how you can control a shmem segment.


OTOH if what you need is only to have a process exchanges information with her children, see processes piping. In this case the secret data is stored within the processes heap/stack memory, and is more difficult to reach by external processes owned by the same user. But the user "owning" the process may also read a process memory (via a core dump for instance) and search for the secret data. Much less easier, but still possible.

Note that in this case, if the secret data is available in the parent process before fork() is performed, children will automatically inherit of it.

Again, anyway, think encryption.

like image 28
Déjà vu Avatar answered Sep 30 '22 15:09

Déjà vu