Tuesday, February 17, 2026

LAB 5: Inter Process Communication – Shared Memory

Inter-Process Communication (IPCs)

            In every modern operating system, multiple programs run at the same time. Each of these programs have their own executing instances (think of them as an active unit of work which needs resources like CPU time, memory, files), which we call processes.

            By default, every process is independent (think of them as islands).  This simply means that they are isolated from one another and think that they are the sole process in the system. This is a direct result of the Memory Management Unit (MMU). The MMU is a computer hardware part that translates virtual memory addresses into physical addresses, as well as manages cache and enforces memory protection.  

            In order to keep up with the next parts of the lab, we will also need to explain what virtual memory, virtual memory address, and physical memory are.

            The “physical memory” is just the physical RAM of the computer, which is accessible for fast and precise data transfers or calculations within a system. 

            The virtual memory is simply a method that “extends” the RAM, meaning that it enables the system to compensate for physical memory shortages by temporarily transferring data from the RAM to the Disk storage.

            The virtual address is just a simple compartment of the whole virtual memory, as can be seen in the picture below.

As mentioned, all of this process is possible because of the MMU, which translates the virtual memory addresses into physical addresses with efficiency.

However, sometimes we also need these processes to communicate with each other. The processes that affect or are affected by one another are simply called Cooperating Processes.

Cooperating Processes are made possible by the Inter-Process Communication (IPC). IPC refers to the set of techniques that allows these processes to talk and share data with each other while theyre operating, so complex software can be run efficiently (a good example would be a shared database). We have a lot of IPC mechanisms, such as Named and Anonymous Pipes, mailslots, sockets, and even clipboards. However, in this lab, we will be focusing on a specific IPC named Shared Memory.  


Shared memory

            Among the various methods of IPCs, shared memory is one of the most efficient mechanisms, especially when it comes to performance-critical applications; think of it as the Ferrari of IPCs.

            Shared Memory, as a concept, is the memory region that can be accessed simultaneously by multiple processes. In an OS, each process has its own virtual address space. Shared memory then proceeds to create a shared region of memory that is accessible by multiple processes at the same time. This shared region is then mapped into the virtual address space of each of the processes, allowing them to read and write to the same physical memory location, as can be seen in the picture below.



            To fully grasp the concept of how shared memory initializes itself, we looked at the article below:

(https://www.geeksforgeeks.org/computer-organization-architecture/what-is-a-shared-memory/),  

Let's say we have two processes that want to communicate with each other, we'll call them P1 and P2. Let's also say that P1 has an address space which we’ll call A1, and P2 has an address space which we’ll call A2. In order for the shared memory to start, P1 will first take up some address space as a shared memory space, which we’ll also call S1. After P1 takes S1, it will then write into it the data that it wants to share. P2 will simply read from the shared data found in S1. Additionally, P1 can also give write rights to P2, as can be seen in the picture below:



An interesting fact about the shared memory is that only the creator process has the right to destroy the shared memory, which in our case means that only P1 can end the whole process.

While the concept of shared memory is easy, the process of how it actually works is a bit more challenging. For this part, we continued with another Geeks for Geeks article (https://www.geeksforgeeks.org/operating-systems/ipc-shared-memory/). From here, we understood the basic outline of how the shared memory operates:

Creation of Shared Memory Segment: The parent creates a shared memory segment. This can be done using system calls like shmget(), usually mostly done in Unix-like systems. This segment is then assigned the unique identifier (shmid).

Attaching to the Shared Memory Segment: The processes that need to access the shared memory attach themselves to this segment using shmat() system call. Once attached, the processes can directly read from and write to the shared memory, according to the privileges.

Synchronization: Since multiple processes can access the shared memory at the same time, synchronization between them is a must. This is done through synchronization mechanisms like semaphores. To put it simply, Semaphores are another IPC that are often used ensure data consistency.

Detaching and Deleting the Segment: When a process no longer needs access to the shared memory, it can detach from it using the shmdt() system call. Additionally, the parent process can also remove the shared memory by using the shmctl() system call.


Advantages

            The main benefit of Shared Memory is speed. Since this IPC processes directly read and write to the shared memory location.

            Additionally, it is highly efficient, since it eliminates the overhead associated with the message passing where data has to be copied from one process to another. This then also means that it can be particularly useful for transferring large amounts of data between the processes.


Disadvantages

            The main downside of shared memory is the complex synchronization. It requires explicit synchronizations to prevent race conditions (which make the code complex and error-prone). Additionally, it can sometimes be a tedious process since it requires manual cleanup by manually detaching and removing the segments.

            The manual cleanup can also lead to security risks, where unauthorized processes may access or modify data.


Security Exploitation cases

            Throughout history, there have been many cases where the Shared Memory IPC has been exploited by malware. Malware uses this IPC as a technique to split its functionality across multiple processes without writing data to the disk (which helps it evade antivirus file scans), or even generate network traffic (which helps it evade firewalls). This technique is called Shared Memory Injection.

The two main instances we have of shared memory injections are the SquidLoader and the RotaJakiro malware.

            SquidLoader is a very recent and relevant example that gained influence in late 2024. This specific malware used shared memory to create a complex graph of shared memory segments, in which it broke its encrypted payload into parts. This then would mean that analysis was made really hard since the full malicious code didn’t exist in one place until the exact moment of execution.

            RotaJakiro, on the other hand,d is classified as a Linux backdoor. Through the shmget() system call, it checked if other instances of the malware were already running as well as shared the PIDs between its various forked processes. This then allowed the malware's different parts to coordinate without sending any signals that could possibly be detected by the Endpoint Detection and Response tools.


Conclusion

            In conclusion, Shared Memory serves as a vital, high-performance Inter-Process Communication (IPC) mechanism that bridges the gap between isolated processes managed by the Memory Management Unit (MMU). By mapping a single physical memory region into the virtual address spaces of multiple distinct processes, it eliminates the overhead of data copying to achieve superior speed, effectively acting as the "Ferrari" of IPCs.  However, this efficiency necessitates rigorous implementation, requiring developers to manage manual memory lifecycles and enforce synchronization via semaphores to prevent race conditions. Ultimately, while shared memory is indispensable for performance-critical applications, it introduces a significant attack surface; as evidenced by malware like SquidLoader and RotaJakiro, the very features that facilitate direct access can be weaponized for stealthy injections and evasion, highlighting the critical trade-off between operational speed and system security.




No comments:

Post a Comment

LAB 10: APK Security Scanner - Multi-Agent Static Analysis pt.2

Taking Android Apps Apart: Building an AI-Powered Security Scanner Part 2: The Analysis, Execution and Findings In Part 1 we defined our obj...