[英]How to prevent a process from using memory used by another process?
假設有兩個進程:一個是我自己的進程,另一個進程生成隨機內存地址並修改其中的內容(我們對此沒有任何控制權)。
第一個過程(我自己的過程):
// Process 1
int *ptr = (int*)malloc(sizeof(int)); // Suppose the address is 0x138145800
*ptr = 45;
printf("%d", *ptr);
sleep();
printf("%d", *ptr);
第二個過程(我無法控制的外部過程):
// Process 2
int *ptr1;
ptr1 = (int*)0x138145800; // Random memory address is generated
*ptr1 = 25;
printf("%d", *ptr1);
當第一個進程處於睡眠狀態時,我們無法控制的第二個進程將修改進程1使用的值。
如何僅通過更改第一個進程來防止第二個進程這樣做?
一種可能的方法是使用鎖。 但是,要對每個1使用的變量進程使用鎖,效率將非常低下。 有什么有效的方法可以解決問題?
操作系統設計使程序無法訪問另一個程序堆棧中的內存。 沒有程序需要擔心這一點。
出於說明目的,我在CentOS映像上運行了該場景:
程序1:
int main() {
char *p = "Hello World";
}
運行時會產生:
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.
我們可以看到寄存器0x4005a0
包含"Hello World"
:
(gdb) x /s 0x4005a0
0x4005a0: "Hello World"
在不取消前一個過程的情況下,我們可以運行另一個訪問該寄存器的C程序:
int main() {
char * hello_world = (char *) 0x4005a0;
printf("%s", hello_world);
}
運行時會產生:
L??L??D??A??H??H9?u?H?[]A\A]A^A_?ff.?
並在一個單獨的GDB會話中(與兩個程序分開):
(gdb) x /s 0x4005a0
0x4005a0: <Address 0x4005a0 out of bounds>
因此,我們可以在這里觀察現代內存架構的一些原理。 操作系統正在管理程序的內存,因此不會發生您描述的情況。
在程序的第二次運行中,它實際上能夠打印一些文本(亂碼),因為在運行程序時,實際上分配了一個虛擬地址空間,根據定義,虛擬地址空間是操作系統所虛擬地址范圍的集合提供給流程。 雖然這兩個程序使用相同的虛擬地址( 0x4005a0
),但在第二種情況下,它只是空閑內存。
如果程序要跳出此邊界,則操作系統將發送經典的SIGSEGV
並終止程序。 根據定義,操作系統會觸發有關內存訪問沖突的分段錯誤。
因此,從程序設計的角度來看,很明顯,由於此內存管理是由OS處理的,因此沒有任何事情可以做,也不需要做。 在這方面,假設您的程序在現代OS上運行,則它是安全的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.