Reputation: 9
Suppose there are two processes: One is my own process and the other process generates random memory address and modifies the content in it (we don't have any control over it).
The first process (my own process):
// Process 1
int *ptr = (int*)malloc(sizeof(int)); // Suppose the address is 0x138145800
*ptr = 45;
printf("%d", *ptr);
sleep();
printf("%d", *ptr);
The second process (an external process that I have no control):
// Process 2
int *ptr1;
ptr1 = (int*)0x138145800; // Random memory address is generated
*ptr1 = 25;
printf("%d", *ptr1);
When the first process is in sleep, the second process to which we don't have any control, modifies the value used by process 1.
How to prevent the second process from doing so by changing only the first process?
One possible way might be to use locks. However to use lock for every variable process 1 uses will be very inefficient. Is there any efficient way to solve the problem?
Upvotes: 0
Views: 148
Reputation: 6258
The operating system prevents a program from accessing memory in another program's stack by design. No program needs to worry about this.
For illustrative purposes, I ran this scenario on a CentOS image:
Program 1:
int main() {
char *p = "Hello World";
}
Which, when run produces:
Dump of assembler code for function main:
0x00000000004004f0 <+0>: push %rbp
0x00000000004004f1 <+1>: mov %rsp,%rbp
=> 0x00000000004004f4 <+4>: movq $0x4005a0,-0x8(%rbp)
0x00000000004004fc <+12>: mov $0x0,%eax
0x0000000000400501 <+17>: pop %rbp
0x0000000000400502 <+18>: retq
End of assembler dump.
We can see that the register 0x4005a0
holds "Hello World"
:
(gdb) x /s 0x4005a0
0x4005a0: "Hello World"
Without killing the previous process, we can run another C program that accesses this register:
int main() {
char * hello_world = (char *) 0x4005a0;
printf("%s", hello_world);
}
Which, when run, produces:
L??L??D??A??H??H9?u?H?[]A\A]A^A_?ff.?
And in a separate GDB session (separate from the two programs):
(gdb) x /s 0x4005a0
0x4005a0: <Address 0x4005a0 out of bounds>
So we can observe a few principles of modern memory architecture at work here. The OS is managing the memory of the program so that the scenario you described would not occur.
In the second run of the program, it's actually able to print out some text (gibberish) because when a program is run, is actually allotted a virtual address space which, by definition, is the set of ranges of virtual addresses that an operating system makes available to a process. While these two programs use the same virtual address (0x4005a0
), in the second instance it is just free memory.
If a program were to step out of this boundary, the OS would send the classic SIGSEGV
and terminate the program. A segmentation fault by definition is triggered by the OS about a memory access violation.
So clearly from a programmatic standpoint, there is nothing that can be done nor needs to be done as this memory management is handled by the OS. Your program is safe in this regard, presuming it's running on a modern OS.
Upvotes: 2