SEGVã¨ããæ¦å¿µãåå¨ããªãéå±ãªä¸ç
ãã®è¨äºã¯KobeUniv Advent Calendar 2015 - Adventar12/6ã®è¨äºã§ãã
æ¬ã«ã¬ã³ãã¼ã§ã¯KobeUniversityã®ç¾å½¹çã¾ãã¯åæ¥çãèªåã®ãã£ã¦ããäº(æè¡ç³»,ç工系ã«éãã)
ã«ã¤ãã¦èªç±ã«æ¸ãç©ã§ããããã身å
ãã¿ã§çµãã£ã¦ãã¾ãã¨æã£ã¦ãã¾ãããäºæ³ä»¥ä¸ã«
ããããã®æ¹ã«åå ãã¦é ãã¦ã¨ã¦ãå¬ããã§ãã(çµæ§geekãªæ¹ãããã§ããã¼)
ç§ã¯æ®æ®µä¸»ã«ä½ã¬ã¤ã¤ã¼(ï¼)ã触ã£ã¦ãã人éã§ãå
·ä½çã«ã¯ã·ã¹ãã ããã°ã©ã 7å²,ã»ãã¥ãªãã£3å²
ãããã®å²åã§æ´»åãã¦ãã¾ãã
ã§ãä»åã¯åè
ã®ã·ã¹ãã ããã°ã©ã ã«ã¤ãã¦ããã¢ããã°ã©ã ãä½æããããç´¹ä»ãã¾ãã
ãããªäºãã§ãããã¼ã¨ããç°¡åãªãã¢ãéãã¦ãã·ã¹ãã ããã°ã©ãã³ã°ã®é¢ç½ããæãã¦é ããã°å¹¸ãã§ãã
(å¾è
ã®ã»ãã¥ãªãã£ã«ã¤ãã¦ã¯æ¬ã«ã¬ã³ãã¼ã®ããã²ã¨ã¤è¨äºã§ã¾ãã¾ãçé¢ç®ã«æ¸ãäºå®ã§ãã)
ã§ä½ããããã§ãããä»åã¯ã¨ã³ã¸ãã¢ã馴æã¿ã®ã¨ã©ã¼ã§ãã
"Segmentation fault (ã³ã¢ãã³ã)"
ããOS(Linux)ãæ¹é ãã¦çºçããªãããã«ãã¦ã¿ã¾ãã以ä¸ã®ããã°ã©ã ãè¦ã¦ãã ããã
(segv.c)
#include <stdio.h> char a[4]; int main(){ a[-114514] = 'h'; printf("%c\n",a[-114514]); }
ãã¡ããã¡ãã§ããããããå®è¡ããã¨å½ç¶
$ gcc -O0 -o segv segv.c $ ./segv Segmentation fault (ã³ã¢ãã³ã)
SIGSEGVãé£ãã§ãã¾ãããããæ¹é æ¸ã¿ã®linuxä¸ã§åããã¨
$ ./segv h
ãªãã¨'h'ãåºåããã¾ãã
æ¹é ãããã¯ä»¥ä¸ã«ç½®ãã¦ããã¾ããubuntu14.04(trusty)ã®linuxã«ã¼ãã«3.13ã使ç¨ãã¦ãã¾ãã
åããã¼ã¸ã§ã³ã®ããã©ã«ã¼ãã«ã«ãé©ç¨ã§ãã¾ãã(ãã ãä½ãèµ·ãã£ã¦ã責任ã¯åãã¾ãããVMä¸ã§è¡ããã¨ããããããã¾ã)
gist.github.com
ä¸ã®ããããé©ç¨ãããmake menuconfigãå®è¡ã
Joke setup
---> [*] SIGSEGV must not happen |
ãONã«ãã¦ãã ããã
ããã¦ãã«ããã¦åèµ·åãå ç¨ã®ããã°ã©ã ãåããã¦ã¿ã¦ãã ããã
ã©ããã£ãã
SIGSEGVã¯ããããã¢ã¯ã»ã¹æ¨©çã«è¨±å¯ããã¦ããªãã£ããããã»ã¹ã®ç®¡çå¤ã®é åã«ã¢ã¯ã»ã¹ããå ´åã«çºçãã¾ãã
ãã®ãããªã¢ã¯ã»ã¹éåã¯CPUãè£è¶³ãããããããlinuxãç»é²ãã¦ããããã³ãã©ãå¼ã³åºã対å¦ããäºã«ãªã£ã¦ãã¾ãã
ãã®ãã³ãã©ã¯linuxã«ã¼ãã«å
ã§ã¯arch/x86/mm/fault.cå
ã®do_page_faultã«ãªã£ã¦ãã¾ãã
ã§ããã§æ°ãã«éåã¢ãã¬ã¹ã«å¯¾ãã¦ã»ã¯ã·ã§ã³ã確ä¿ãããã¼ã¸ãã©ã«ãå¦çã«ãã®ã¾ã¾æ¸¡ãã¦ç©çã¢ãã¬ã¹ãã¼ã¸ãæ¾ã£ã¦ããããæ¹é
ããã ãã§ãã
static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long error_code) { ... if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) { printk(KERN_INFO"<NO_SIG> not stack 0x%16lx 0x%16lx\n",vma->vm_start, address); #ifdef CONFIG_NO_SIGSEGV goto new_vma; #else bad_area(regs, error_code, address); return; #endif } new_vma:; unsigned long mm_flags = 0; mm_flags = 0x22; do_mmap_pgoff(0,address & PAGE_MASK,PAGE_SIZE,0x7,mm_flags,0,&populate); vma = find_vma(mm, address); ... }
ã§ã¯æ°ãã«ã»ã¯ã·ã§ã³ãå¢ãã¦ããäºã確èªãã¦ã¿ã¾ãããã
ä»åº¦ã¯ä»¥ä¸ã®ãããªããã°ã©ã ãå®è¡ãã¦ã¿ã¾ãã
#include <unistd.h> int main(){ *(unsigned long*)(0x1145140000) = 893; sleep(889464); }
ã¨ãã§ããªãã¢ãã¬ã¹ã«å¤ãå
¥ãã¦ãã¾ããã(ãããå½ç¶ã¡ããã¨åãã¾ã)
ã§ã¯ã»ã¯ã·ã§ã³ã¯ã¨è¨ãã¨
$ cat /proc/1415/maps 00400000-00401000 r-xp 00000000 fd:01 795520 /home/rkx/segv 00600000-00601000 r--p 00000000 fd:01 795520 /home/rkx/segv 00601000-00602000 rw-p 00001000 fd:01 795520 /home/rkx/segv 1145140000-1145141000 rwxp 00000000 00:00 0 7f4ed87fc000-7f4ed89b7000 r-xp 00000000 fd:01 786601 /lib/x86_64-linux-gnu/libc-2.19.so 7f4ed89b7000-7f4ed8bb6000 ---p 001bb000 fd:01 786601 /lib/x86_64-linux-gnu/libc-2.19.so 7f4ed8bb6000-7f4ed8bba000 r--p 001ba000 fd:01 786601 /lib/x86_64-linux-gnu/libc-2.19.so 7f4ed8bba000-7f4ed8bbc000 rw-p 001be000 fd:01 786601 /lib/x86_64-linux-gnu/libc-2.19.so 7f4ed8bbc000-7f4ed8bc1000 rw-p 00000000 00:00 0 7f4ed8bc1000-7f4ed8be4000 r-xp 00000000 fd:01 786581 /lib/x86_64-linux-gnu/ld-2.19.so 7f4ed8dd6000-7f4ed8dd9000 rw-p 00000000 00:00 0 7f4ed8de1000-7f4ed8de3000 rw-p 00000000 00:00 0 7f4ed8de3000-7f4ed8de4000 r--p 00022000 fd:01 786581 /lib/x86_64-linux-gnu/ld-2.19.so 7f4ed8de4000-7f4ed8de5000 rw-p 00023000 fd:01 786581 /lib/x86_64-linux-gnu/ld-2.19.so 7f4ed8de5000-7f4ed8de6000 rw-p 00000000 00:00 0 7ffc13787000-7ffc137a8000 rw-p 00000000 00:00 0 [stack] 7ffc137de000-7ffc137e0000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
ã¢ãã¬ã¹0x1145140000ã«ã¡ããã¨ç¡åã®ã»ã¯ã·ã§ã³ãã§ãã¦ãã¾ããããã«ä¸ã®å¤ãã¡ããã¨å
¥ã£ã¦ãã訳ã§ãã
(ã¡ãªã¿ã«ãµã¤ãºã0ã¨ãªã£ã¦ããã®ã¯ããã³ããã¼ã¸ã³ã°ã®å½±é¿ãã¨æããã¾ã)
ãããã«
é常ã«ãã ããªãæ¹é ã§ããã¦ã¼ã¶ã¼ç©ºéã§ã¯ä¸å¯è½ãªäºããã¨ãç°¡åã«å®ç¾ã§ãã¾ããã
ãã¡ãããããªãã¿æ¹é ã ãã§ãªããã£ã¨çé¢ç®ãªæ©è½ãèªåã§å®è£
ããLKMLãªã©ã«ããããæãã¦ã¿ãã®ãè¯ãã¨
æãã¾ããã¨ãããå°ãã§ãã·ã¹ãã ããã°ã©ã ã«èå³ãæã£ã¦é ããã°å¹¸ãã§ãã
次ã¯ã¡ããã¨çé¢ç®ã«ã»ãã¥ãªãã£ã®è¨äºãæ¸ãã¾ã....