簡體   English   中英

如何防止一個進程使用另一個進程使用的內存?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM