Try   HackMD

2021q3 Homework1 (quiz1)

contributed by <fwfly>

程式編譯後會出現 kallsyms_lookup_name undefine error

2021_summer_q1$ make
make -C /lib/modules/`uname -r`/build M=/home/fwfly/project/2021_summer_q1 modules
make[1]: Entering directory '/usr/src/linux-headers-5.8.0-59-generic'
  CC [M]  main.o
  LD [M]  hideproc.o
  MODPOST Module.symvers
ERROR: modpost: "kallsyms_lookup_name" [hideproc.ko] undefined!
make[2]: *** [scripts/Makefile.modpost:111: Module.symvers] Error 1
make[2]: *** Deleting file 'Module.symvers'
make[1]: *** [Makefile:1698: modules] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.8.0-59-generic'
make: *** [Makefile:9: all] Error 2

這個 https://github.com/h33p/kallsyms-mod 提供一個 livepatch 來處理 undefined 問題

使用 livepatch

先 copy 必要檔案到當前目錄

#cp kallsyms.c  kallsyms.h  kallsyms_kp.c  kallsyms_lp.c  ksyms.h  <測驗一目錄>

更改 main.c 檔案 include 的部分

#include <linux/list.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include "kallsyms.h"     // 新增 livepatch
#include "ksyms.h"        // 新增 livepatch

MODULE_LICENSE("GPL");
MODULE_AUTHOR("National Cheng Kung University, Taiwan");
...


KSYMDEF(kvm_lock);  // 新增 livepatch
KSYMDEF(vm_list);   // 新增 livepatch

static int _hideproc_init(void)
{   
    int err, dev_major;
    
    /* 以下為新增的 livepatch 部分 */
    int r;                      
    if ((r = init_kallsyms()))  
        return r;
    
    KSYMINIT_FAULT(kvm_lock);   
    KSYMINIT_FAULT(vm_list);    
    /* 到這裡為止 */

    dev_t dev;

...
...

更改 Makefile 來 compile livepatch 檔案

MODULENAME := hideproc
obj-m += $(MODULENAME).o
$(MODULENAME)-y += main.o kallsyms.o //新增 kallsyms.o
...

完整修改可以看這個部分
https://github.com/fwfly/2021_summer_q1/commit/1546cbf845d0d96c7a2f183b152034abef15153d

如果遇到 _hideproc_init crash

雖然 ko 檔 build 成功,但是執行時卻至 print 一個 killed

$ sudo insmod hideproc.ko 
Killed

如果用 dmsg 則會發現 module crash

[34345.866304] hideproc: loading out-of-tree module taints kernel.
[34345.866409] hideproc: module verification failed: signature and/or required key missing - tainting kernel
[34345.867707] @ _hideproc_init
[34345.867930] BUG: kernel NULL pointer dereference, address: 0000000000000000
[34345.867938] #PF: supervisor instruction fetch in kernel mode
[34345.867941] #PF: error_code(0x0010) - not-present page
[34345.867944] PGD 0 P4D 0 
[34345.867952] Oops: 0010 [#1] SMP NOPTI
[34345.867961] CPU: 2 PID: 9801 Comm: insmod Tainted: G           OE     5.8.0-59-generic #66~20.04.1-Ubuntu
[  182.857782] Hardware name: HP HP EliteBook 745 G3/807E, BIOS N73 Ver. 01.20 10/03/2017
[  182.857785] RIP: 0010:0x0
[  182.857789] Code: Unable to access opcode bytes at RIP 0xffffffffffffffd6.
[  182.857791] RSP: 0018:ffffb46f8215fc30 EFLAGS: 00010246
[  182.857793] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
[  182.857795] RDX: 0000000000000000 RSI: ffff8db5f5862688 RDI: ffffffffc1139206
[  182.857796] RBP: ffffb46f8215fc38 R08: 0000000000000000 R09: ffffb46f8215f9b8
[  182.857797] R10: ffff8db6752b7bff R11: 0000000000000000 R12: 000000000ed00001
[  182.857799] R13: ffff8db576676b60 R14: 0000000000000000 R15: ffffb46f8215fe70
[  182.857801] FS:  00007efcfa7dd540(0000) GS:ffff8db5faf80000(0000) knlGS:0000000000000000
[  182.857803] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  182.857804] CR2: ffffffffffffffd6 CR3: 0000000131592000 CR4: 00000000001406e0
[  182.857806] Call Trace:
[  182.857812]  kallsyms_lookup_name+0x15/0x20 [hideproc]
[  182.857817]  _hideproc_init+0xc6/0x1bd [hideproc]
[  182.857820]  ? device_read.cold+0x18/0x18 [hideproc]
[  182.857826]  do_one_initcall+0x4a/0x200
[  182.857829]  ? kfree+0x231/0x250
[  182.857836]  ? _cond_resched+0x19/0x30
[  182.857838]  ? kmem_cache_alloc_trace+0x177/0x240
[  182.857843]  do_init_module+0x62/0x250
[  182.857846]  load_module+0x1185/0x1390
[  182.857850]  ? ima_post_read_file+0x108/0x120
[  182.857854]  __do_sys_finit_module+0xc9/0x130
[  182.857857]  ? __do_sys_finit_module+0xc9/0x130
[  182.857860]  __x64_sys_finit_module+0x1a/0x20
[  182.857865]  do_syscall_64+0x49/0xc0
[  182.857868]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  182.857871] RIP: 0033:0x7efcfa3e389d
...

往下看 call stack 可以看到問題是在 kallsyms_lookup_name

[  182.857812]  kallsyms_lookup_name+0x15/0x20 [hideproc]
[  182.857817]  _hideproc_init+0xc6/0x1bd [hideproc]

而其實問題是出在沒有把 init_kallsyms 的程式碼放上去(更先前的版本),修改後 insmod 就確認可以安裝上去

新增部分

KSYMDEF(kvm_lock);  // 新增 livepatch
KSYMDEF(vm_list);   // 新增 livepatch

static int _hideproc_init(void)
{   
    int err, dev_major;
    
    /* 以下為新增的 livepatch 部分 */
    int r;                      
    if ((r = init_kallsyms()))  
        return r;
    
    KSYMINIT_FAULT(kvm_lock);   
    KSYMINIT_FAULT(vm_list);    
    /* 到這裡為止 */

kallsyms-compat

嘗試的把 kallsyms patch 的 function 改成 static inline 放到 kallsysms-compact.h 裡面.

但是編譯卻會得到以下錯誤

$ make
make -C /lib/modules/`uname -r`/build M=/home/fwfly/project/kallsyms-compat modules
make[1]: Entering directory '/usr/src/linux-headers-5.8.0-63-generic'
  CC [M]  /home/fwfly/project/kallsyms-compat/main.o
In file included from /home/fwfly/project/kallsyms-compat/main.c:1:
/home/fwfly/project/kallsyms-compat/kallasys-compat.h:91:29: error: static declaration of ‘kallsyms_lookup_name’ follows non-static declaration
   91 | static inline unsigned long kallsyms_lookup_name(const char *name)
      |                             ^~~~~~~~~~~~~~~~~~~~
In file included from ./include/linux/ftrace.h:11,
                 from ./include/linux/livepatch.h:13,
                 from /home/fwfly/project/kallsyms-compat/kallasys-compat.h:59,
                 from /home/fwfly/project/kallsyms-compat/main.c:1:
./include/linux/kallsyms.h:76:15: note: previous declaration of ‘kallsyms_lookup_name’ was here
   76 | unsigned long kallsyms_lookup_name(const char *name);
      |               ^~~~~~~~~~~~~~~~~~~~

將上面的 kallsyms_lookup_name (inline static 函式) 改為 __kallsyms_lookup_name,然後再定義:

#define kallsyms_lookup_name(x) __kallsyms_lookup_name(x)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
jserv

Reference