歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux中為什麼要隨機函數棧的起始地址

Linux中為什麼要隨機函數棧的起始地址

日期:2017/2/28 16:07:50   编辑:Linux教程

1. 如前文(http://www.linuxidc.com/Linux/2011-08/41869.htm)所述,為了執行一個程序,首先do_execve建立數據結構,並將一些數據從用戶空間拷貝到內核空間,然後調用search_binary_handler加載可執行文件映像。

  1. int do_execve(char * filename,
  2. char __user *__user *argv,
  3. char __user *__user *envp,
  4. struct pt_regs * regs)
2. search_binary_handler()尋找對應的handler。對於elf 文件,即是load_elf_binary。
  1. int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)

3. load_elf_binary()讀取可執行文件頭文件信息,進行簡單的一致性檢測,分配用戶模式的頁表,設置棧的起始地址,加載可執行文件映像到內存;然後調用create_elf_tables(); 最後調用start_thread(),執行_start函數開始的代碼。
  1. static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)

4. create_elf_tables()將參數指針,環境變量數組指針壓入用戶模式的棧。

  1. static int
  2. create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
  3. unsigned long load_addr, unsigned long interp_load_addr)
值得注意的是,create_elf_tables()很可能會在壓棧前調整棧指針。比如,在支持超線程的體系結構裡面,通過隨機化初始棧指針,可以減少進程間在L1上的競爭。如下所示,隨機化初始棧指針的頁內偏移量,並使得棧指針保持16字節對齊。
  1. unsigned long arch_align_stack(unsigned long sp)
  2. {
  3. if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
  4. sp -= get_random_int() % 8192;
  5. return sp & ~0xf;
  6. }
為什麼針對頁內偏移呢?

在某些體系結構中,首先要完成從邏輯地址到物理地址的轉換,然後才能去cache中查找該物理地址是否已經在cache當中。這樣,cache命中的代價較高。一種常用的技巧是,在L1中,邏輯地址索引-物理地址比較(virtually indexed, physically tagged)[1]。思路是,利用邏輯地址與物理地址的頁內偏移一樣的特點,用頁內偏移進行索引,頁號通過TLB轉換成物理頁號進行tag比較。這樣,可以不經轉換,就先索引,從而加快速度。這樣,如果兩個邏輯地址的塊內偏移一樣,它們索引的cache行也就一樣,所以需要隨機化頁內偏移來減少L1的競爭。其缺點是,L1的set大小,不能超過頁的大小。換言之:

L1的大小 <= 相聯度 * 塊的大小 * 頁的大小

5. start_thread(),執行_start函數開始的代碼
  1. void
  2. start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
  3. {
  4. set_user_gs(regs, 0);
  5. regs->fs = 0;
  6. set_fs(USER_DS);
  7. regs->ds = __USER_DS;
  8. regs->es = __USER_DS;
  9. regs->ss = __USER_DS;
  10. regs->cs = __USER_CS;
  11. regs->ip = new_ip;
  12. regs->sp = new_sp;
  13. /*
  14. * Free the old FP and other extended state
  15. */
  16. free_thread_xstate(current);
  17. }
參考:[1] Computer Architecture: A Quantitative Approach, Fourth Edition. Page 291-292.
Copyright © Linux教程網 All Rights Reserved