Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

105258
1323
114607


[리눅스커널][디버깅] 슬럽(슬랩) 오브젝트 레드존 데이터 구조 T32로 메모리 디버깅(2) 14. Memory Management

할당(Alloc)된 슬럽 오브젝트 데이터 스트럭처 파악하기 

이전 포스팅에서는 Free 슬럽 오브젝트 주소인 0xC0067BC0 기준으로 어떤 패턴의 자료구조인지 파악했습니다. 
이번 시간에서는 이미 할당된 슬럽 오브젝트의 데이터 스트럭처를 파악하겠습니다.

________address|_data________|value_____________|symbol
   NSD:C0067A80| 41 1A 17 00  0x171A41 //<-- "kmalloc-64" 슬럽 오브젝트 시작 주소
   NSD:C0067A84| 11 00 00 00  0x11                
   NSD:C0067A88| 01 00 00 00  0x1                 
   NSD:C0067A8C| 01 00 00 00  0x1                
   NSD:C0067A90| 90 2B 8E C4  0xC48E2B90
   NSD:C0067A94| 50 C0 60 C9  0xC960C050
   NSD:C0067A98| 10 24 ED C4  0xC4ED2410
   NSD:C0067A9C| 1D C4 FB C6  0xC6FBC41D
   NSD:C0067AA0| 00 00 00 00  0x0                 
   NSD:C0067AA4| 00 00 00 00  0x0                 
   NSD:C0067AA8| 00 00 00 00  0x0                
   NSD:C0067AAC| E4 96 FA D7  0xD7FA96E4
   NSD:C0067AB0| 40 EA 67 DC  0xDC67EA40
   NSD:C0067AB4| C0 96 FA D7  0xD7FA96C0
   NSD:C0067AB8| 00 00 00 00  0x0               
   NSD:C0067ABC| 00 00 00 00  0x0        //<-- "kmalloc-64" 슬럽 오브젝트 끝 주소          
   NSD:C0067AC0| CC CC CC CC  0xCCCCCCCC //<<-- 레드존: #define SLUB_RED_ACTIVE 0xcc
   NSD:C0067AC4| 00 78 06 C0  0xC0067800 //<<-- 다음 "kmalloc-64"  슬럽 오브젝트 주소
   NSD:C0067AC8| BC 53 93 C0  0xC09353BC         \\vmlinux\binder\binder_inc_ref_for_node+0x74 //<<-- 오브젝트 할당 주소
   NSD:C0067ACC| BC 53 93 C0  0xC09353BC         \\vmlinux\binder\binder_inc_ref_for_node+0x74 //<<-- 오브젝트 할당 콜스택, 시작
   NSD:C0067AD0| 18 83 93 C0  0xC0938318         \\vmlinux\binder\binder_transaction+0xFD8
   NSD:C0067AD4| C4 9F 93 C0  0xC0939FC4         \\vmlinux\binder\binder_thread_write+0xA90
   NSD:C0067AD8| 90 AB 93 C0  0xC093AB90         \\vmlinux\binder\binder_ioctl\__out+0x1F0
   NSD:C0067ADC| C4 A4 23 C0  0xC023A4C4         \\vmlinux\fs/ioctl\do_vfs_ioctl+0x53C
   NSD:C0067AE0| 48 A6 23 C0  0xC023A648         \\vmlinux\fs/ioctl\sys_ioctl+0x4C
   NSD:C0067AE4| 1C 62 10 C0  0xC010621C         \\vmlinux\Global\__sys_trace_return //<<-- 오브젝트 할당 콜스택, 끝
   NSD:C0067AE8| 00 00 00 00  0x0             
   NSD:C0067AEC| 00 00 00 00  0x0            
   NSD:C0067AF0| 00 00 00 00  0x0             
   NSD:C0067AF4| 00 00 00 00  0x0               
   NSD:C0067AF8| 00 00 00 00  0x0                
   NSD:C0067AFC| 00 00 00 00  0x0            
   NSD:C0067B00| 00 00 00 00  0x0               
   NSD:C0067B04| 00 00 00 00  0x0                
   NSD:C0067B08| 00 00 00 00  0x0                 
   NSD:C0067B0C| 05 00 00 00  0x5                
   NSD:C0067B10| 86 50 00 00  0x5086
   NSD:C0067B14| 04 83 01 00  0x18304
   NSD:C0067B18| 00 67 2E C0  0xC02E6700         \\vmlinux\extents\ext4_ext_map_blocks\out2+0x10 //<<-- 오브젝트 해제한 주소와 콜스택 시작
   NSD:C0067B1C| 40 D3 2B C0  0xC02BD340         \\vmlinux\ext4/inode\ext4_map_blocks\found+0xC0
   NSD:C0067B20| CC FE 2B C0  0xC02BFECC         .linux\ext4/inode\mpage_map_and_submit_extent+0x1AC
   NSD:C0067B24| 04 0A 2C C0  0xC02C0A04         \\vmlinux\ext4/inode\ext4_writepages\retry+0x2AC
   NSD:C0067B28| 84 FB 24 C0  0xC024FB84         .mlinux\fs-writeback\__writeback_single_inode+0x10C
   NSD:C0067B2C| 28 05 25 C0  0xC0250528         \\vmlinux\fs-writeback\writeback_sb_inodes+0x260
   NSD:C0067B30| 28 07 25 C0  0xC0250728         \\vmlinux\fs-writeback\__writeback_inodes_wb+0x64
   NSD:C0067B34| 40 09 25 C0  0xC0250940         \\vmlinux\fs-writeback\wb_writeback+0x1DC
   NSD:C0067B38| 20 14 25 C0  0xC0251420         \\vmlinux\fs-writeback\bdi_writeback_workfn+0x270
   NSD:C0067B3C| 08 BA 13 C0  0xC013BA08         \\vmlinux\workqueue\process_one_work+0x28C
   NSD:C0067B40| 28 C2 13 C0  0xC013C228         \\vmlinux\workqueue\worker_thread\recheck+0x314
   NSD:C0067B44| 70 FB 13 C0  0xC013FB70         \\vmlinux\kernel/kthread\kthread+0xD8
   NSD:C0067B48| 38 61 10 C0  0xC0106138         \\vmlinux\Global\ret_from_fork+0x14  //<<-- 오브젝트 해제 콜스택 끝
   NSD:C0067B4C| 00 00 00 00  0x0                
   NSD:C0067B50| 00 00 00 00  0x0                 
   NSD:C0067B54| 00 00 00 00  0x0                
   NSD:C0067B58| 00 00 00 00  0x0               
   NSD:C0067B5C| 03 00 00 00  0x3                
   NSD:C0067B60| 6B 01 00 00  0x16B               
   NSD:C0067B64| 03 83 01 00  0x18303

먼저 kmalloc-64 슬럽 오브젝트 패이로드 주소를 보겠습니다. C0067A80 주소는 kmalloc() 함수로 메모리 할당을 한 다음 디바이스 드바이버에서 
쓰고 있는 데이터입니다.    
   NSD:C0067A80| 41 1A 17 00  0x171A41 //<-- "kmalloc-64" 슬럽 오브젝트 시작 주소
   NSD:C0067A84| 11 00 00 00  0x11                
   NSD:C0067A88| 01 00 00 00  0x1                 
   NSD:C0067A8C| 01 00 00 00  0x1                
   NSD:C0067A90| 90 2B 8E C4  0xC48E2B90
   NSD:C0067A94| 50 C0 60 C9  0xC960C050
   NSD:C0067A98| 10 24 ED C4  0xC4ED2410
   NSD:C0067A9C| 1D C4 FB C6  0xC6FBC41D
   NSD:C0067AA0| 00 00 00 00  0x0                 
   NSD:C0067AA4| 00 00 00 00  0x0                 
   NSD:C0067AA8| 00 00 00 00  0x0                
   NSD:C0067AAC| E4 96 FA D7  0xD7FA96E4
   NSD:C0067AB0| 40 EA 67 DC  0xDC67EA40
   NSD:C0067AB4| C0 96 FA D7  0xD7FA96C0
   NSD:C0067AB8| 00 00 00 00  0x0               
   NSD:C0067ABC| 00 00 00 00  0x0        //<-- "kmalloc-64" 슬럽 오브젝트 끝 주소          

그러면 이 kmalloc-64 슬럽 오브젝트를 어떤 구조체로 쓰고 있는지 확인해볼까요? 
이 정보를 확인하기 위해 슬럽 오브젝트를 할당한 콜스택 정보를 활용할 필요가 있습니다.
   NSD:C0067AC8| BC 53 93 C0  0xC09353BC         \\vmlinux\binder\binder_inc_ref_for_node+0x74 //<<-- 오브젝트 할당 주소
   NSD:C0067ACC| BC 53 93 C0  0xC09353BC         \\vmlinux\binder\binder_inc_ref_for_node+0x74 //<<-- 오브젝트 할당  

0xC09353BC 주소, 심볼 기준으로 binder_inc_ref_for_node+0x74 에서 kmalloc-64 슬럽 오브젝트를 할당했습니다.
관련 코드를 보겠습니다.
[https://elixir.bootlin.com/linux/v5.0.5/source/drivers/android/binder.c]
01 static int binder_inc_ref_for_node(struct binder_proc *proc,
02 struct binder_node *node,
03 bool strong,
04 struct list_head *target_list,
05 struct binder_ref_data *rdata)
06 {
07 struct binder_ref *ref;
08 struct binder_ref *new_ref = NULL;
09 int ret = 0;
10
11 binder_proc_lock(proc);
12 ref = binder_get_ref_for_node_olocked(proc, node, NULL);
13 if (!ref) {
14 binder_proc_unlock(proc);
15 new_ref = kmalloc(sizeof(*ref), GFP_KERNEL);

binder_inc_ref_for_node() 함수 15 번째 줄 코드를 보면 kmalloc() 함수로 메모리 할당을 합니다.
ref 사이즈 만큼 메모리를 할당하는데 이 ref의 정체는 07 번째 줄의 struct binder_ref 구조체입니다.

"kmalloc-64" 슬럽 오브젝트의 시작 주소가 0xC0067A80 이고 구조체가 struct binder_ref  이란 사실을 파악했습니다.  
   NSD:C0067A80| 41 1A 17 00  0x171A41 //<-- "kmalloc-64" 슬럽 오브젝트 시작 주소
   NSD:C0067A84| 11 00 00 00  0x11      

0xC0067A80 주소를 struct binder_ref 구조체로 캐스팅하면 다음과 같은 정보가 보입니다. 
v.v %t %s %d %h (struct binder_ref*)0xC0067A80
  (struct binder_ref *) (struct binder_ref*)0xC0067A80 = 0xC0067A80 -> (
    (struct binder_ref_data) data = ((int) debug_id = 1514049 = 0x00171A41, (uint32_t) desc = 17 = 0
    (struct rb_node) rb_node_desc = ((long unsigned int) __rb_parent_color = 3297651600 = 0xC48E2B90
    (struct rb_node) rb_node_node = ((long unsigned int) __rb_parent_color = 3338388509 = 0xC6FBC41D
    (struct hlist_node) node_entry = ((struct hlist_node *) next = 0x0, (struct hlist_node * *) ppre
    (struct binder_proc *) proc = 0xDC67EA40 -> (
      (struct hlist_node) proc_node = ((struct hlist_node *) next = 0xD2FA5B40, (struct hlist_node *
...
      (int) pid = 20533 = 0x5035,
      (struct task_struct *) tsk = 0xC5026500 -> (
        (long int) state = 1 = 0x1,
        (void *) stack = 0xC7E42000,
        (atomic_t) usage = ((int) counter = 4 = 0x4),
        (unsigned int) flags = 1077936448 = 0x40400140,
        (unsigned int) ptrace = 0 = 0x0,
        (struct llist_node) wake_entry = ((struct llist_node *) next = 0x0),
        (int) on_cpu = 0 = 0x0,
        (struct task_struct *) last_wakee = 0xD73ED580,
        (long unsigned int) wakee_flips = 18 = 0x12,
        (long unsigned int) wakee_flip_decay_ts = 177806 = 0x0002B68E,
        (int) wake_cpu = 2 = 0x2,
        (int) on_rq = 0 = 0x0,
        (int) prio = 120 = 0x78,
        (int) static_prio = 120 = 0x78,
        (int) normal_prio = 120 = 0x78,
        (unsigned int) rt_priority = 0 = 0x0,
        (struct sched_class *) sched_class = 0xC0F03468,
...

이 방식으로 메모리 정보를 파악할 수 있습니다.
    
이전 포스팅에서 다룬 내용과 중복된 부분은 넘어가겠습니다. 
이미 할당해 쓰고 있는 슬럽 오브젝트 데이터 스트럭처는 다음과 같습니다.
------------------------   
슬럽 오브젝트(페이로드)
Raw Data 가 채워져 있음
메모리를 할당해 쓰는 데이터
------------------------   
레드 존: 0xCCCC_CCCC 
//#define SLUB_RED_ACTIVE 0xcc
------------------------   
다음 슬럽 오브젝트 주소 
------------------------   
콜스택 
슬럽 오브젝트 할당: struct track 
슬럽 오브젝트 해제: struct track  
------------------------   

덧글

댓글 입력 영역