循环遍历内核空间中的链表

Posted

技术标签:

【中文标题】循环遍历内核空间中的链表【英文标题】:Loop through linked list in kernel space 【发布时间】:2021-04-17 00:54:37 【问题描述】:

我正在尝试遍历task_struct 内的 vma(由指针 mm 引用)。我正在做的是尝试打印 struct vm_area_struct 的一些属性(具体来说,我正在尝试打印 vm_start)。我的问题是我不断收到 NULL 指针取消引用错误。

#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/sched/signal.h>
#include <linux/sched/task_stack.h>

void print_mmap(struct vm_area_struct *mmap)
 
        while (mmap != NULL)
        
            printk(KERN_INFO "vm_start: %lu\n", mmap->vm_start);
            mmap = mmap->vm_next;
        




void procs_info_print(void)

  struct task_struct *task_list;
  size_t process_counter = 0;
  for_each_process(task_list)
        printk(KERN_INFO "new process\n");
        volatile long state = task_list->state; /* state of the process */
        struct mm_struct *mm = task_list->mm; /* address space of this process */
        struct vm_area_struct *mmap = mm->mmap; /* list of VMAs */
                print_mmap(mmap);

        struct files_struct *files = task_list->files; /* list of open files */
        /* registers */
        unsigned long tasks_ax = task_pt_regs(task_list)->ax;
        unsigned long tasks_bx = task_pt_regs(task_list)->bx;
        unsigned long tasks_cx = task_pt_regs(task_list)->cx;
        unsigned long tasks_dx = task_pt_regs(task_list)->dx;
        unsigned long tasks_ip = task_pt_regs(task_list)->ip; /* program counter */
        unsigned long tasks_sp = task_pt_regs(task_list)->sp;
        unsigned long tasks_bp = task_pt_regs(task_list)->bp;
        unsigned long tasks_si = task_pt_regs(task_list)->si;
        unsigned long tasks_di = task_pt_regs(task_list)->di;
      
  printk(KERN_INFO "== Number of process: %zu\n", process_counter);


static int __init entry(void)

  procs_info_print();
  return 0;


static void __exit end(void)

  printk(KERN_INFO, "Exiting\n");


module_init(entry);
module_exit(end);


我得到的错误是


[  139.457092] new process
[  139.457094] vm_start: 94895486087168
[  139.457095] vm_start: 94895489552384
[  139.457096] vm_start: 94895489794048
[  139.457098] vm_start: 94895495430144
[  139.457099] vm_start: 139802326335488
[  139.457100] vm_start: 139802326470656
[  139.457101] vm_start: 139802460553216
[  139.457102] vm_start: 139802460688384
[  139.457103] vm_start: 139802574995456
[  139.457104] vm_start: 139802574999552
[  139.457105] vm_start: 139802583388160
[  139.457106] vm_start: 139802583392256
[  139.457108] vm_start: 139802591780864
[  139.457109] vm_start: 139802593472512
[  139.457110] vm_start: 139802595565568
[  139.457111] vm_start: 139802595569664
[  139.457112] vm_start: 139802595573760
[  139.457113] vm_start: 139802595692544
[  139.457114] vm_start: 139802597785600
[  139.457115] vm_start: 139802597789696
[  139.457116] vm_start: 139802597793792
[  139.457117] vm_start: 139802597875712
[  139.457118] vm_start: 139802599968768
[  139.457119] vm_start: 139802599972864
[  139.457120] vm_start: 139802599976960
[  139.457121] vm_start: 139802600017920
[  139.457123] vm_start: 139802602110976
[  139.457124] vm_start: 139802602115072
[  139.457125] vm_start: 139802602119168
[  139.457126] vm_start: 139802602151936
[  139.457127] vm_start: 139802604244992
[  139.457128] vm_start: 139802604249088
[  139.457129] vm_start: 139802604253184
[  139.457130] vm_start: 139802604670976
[  139.457131] vm_start: 139802606764032
[  139.457132] vm_start: 139802606768128
[  139.457133] vm_start: 139802606784512
[  139.457134] vm_start: 139802606788608
[  139.457135] vm_start: 139802606804992
[  139.457136] vm_start: 139802608898048
[  139.457138] vm_start: 139802608902144
[  139.457139] vm_start: 139802608906240
[  139.457140] vm_start: 139802608922624
[  139.457141] vm_start: 139802611015680
[  139.457142] vm_start: 139802611019776
[  139.457143] vm_start: 139802611023872
[  139.457144] vm_start: 139802611048448
[  139.457145] vm_start: 139802613141504
[  139.457146] vm_start: 139802613145600
[  139.457147] vm_start: 139802613149696
[  139.457148] vm_start: 139802613161984
[  139.457149] vm_start: 139802615255040
[  139.457151] vm_start: 139802615259136
[  139.457152] vm_start: 139802615263232
[  139.457153] vm_start: 139802615721984
[  139.457154] vm_start: 139802617819136
[  139.457155] vm_start: 139802617823232
[  139.457156] vm_start: 139802617827328
[  139.457157] vm_start: 139802617933824
[  139.457158] vm_start: 139802620026880
[  139.457159] vm_start: 139802620030976
[  139.457160] vm_start: 139802620035072
[  139.457161] vm_start: 139802620051456
[  139.457162] vm_start: 139802620162048
[  139.457163] vm_start: 139802622255104
[  139.457164] vm_start: 139802622259200
[  139.457165] vm_start: 139802622263296
[  139.457166] vm_start: 139802622410752
[  139.457168] vm_start: 139802624507904
[  139.457169] vm_start: 139802624512000
[  139.457170] vm_start: 139802624516096
[  139.457171] vm_start: 139802624720896
[  139.457172] vm_start: 139802626813952
[  139.457173] vm_start: 139802626818048
[  139.457174] vm_start: 139802626822144
[  139.457175] vm_start: 139802626846720
[  139.457176] vm_start: 139802628939776
[  139.457177] vm_start: 139802628943872
[  139.457178] vm_start: 139802628947968
[  139.457179] vm_start: 139802630078464
[  139.457180] vm_start: 139802632175616
[  139.457181] vm_start: 139802632183808
[  139.457182] vm_start: 139802632204288
[  139.457183] vm_start: 139802632208384
[  139.457184] vm_start: 139802632224768
[  139.457185] vm_start: 139802634321920
[  139.457187] vm_start: 139802634326016
[  139.457188] vm_start: 139802634330112
[  139.457189] vm_start: 139802634629120
[  139.457190] vm_start: 139802636726272
[  139.457191] vm_start: 139802636730368
[  139.457192] vm_start: 139802636738560
[  139.457193] vm_start: 139802636767232
[  139.457194] vm_start: 139802638860288
[  139.457195] vm_start: 139802638864384
[  139.457196] vm_start: 139802638868480
[  139.457197] vm_start: 139802638929920
[  139.457198] vm_start: 139802641022976
[  139.457199] vm_start: 139802641027072
[  139.457200] vm_start: 139802641031168
[  139.457201] vm_start: 139802641121280
[  139.457203] vm_start: 139802643214336
[  139.457204] vm_start: 139802643218432
[  139.457205] vm_start: 139802643222528
[  139.457600] vm_start: 139802643341312
[  139.457601] vm_start: 139802645438464
[  139.457602] vm_start: 139802645442560
[  139.457604] vm_start: 139802645446656
[  139.457605] vm_start: 139802645487616
[  139.457606] vm_start: 139802645540864
[  139.457607] vm_start: 139802647633920
[  139.457608] vm_start: 139802647638016
[  139.457609] vm_start: 139802647642112
[  139.457610] vm_start: 139802647932928
[  139.457611] vm_start: 139802650030080
[  139.457612] vm_start: 139802650046464
[  139.457613] vm_start: 139802650050560
[  139.457614] vm_start: 139802650054656
[  139.457616] vm_start: 139802650386432
[  139.457617] vm_start: 139802652479488
[  139.457618] vm_start: 139802652487680
[  139.457619] vm_start: 139802652491776
[  139.457620] vm_start: 139802652495872
[  139.457621] vm_start: 139802652647424
[  139.457622] vm_start: 139802654740480
[  139.457623] vm_start: 139802654744576
[  139.457624] vm_start: 139802654748672
[  139.457625] vm_start: 139802654756864
[  139.457626] vm_start: 139802654965760
[  139.457627] vm_start: 139802657058816
[  139.457628] vm_start: 139802657161216
[  139.457629] vm_start: 139802657165312
[  139.457631] vm_start: 139802657193984
[  139.457632] vm_start: 139802659287040
[  139.457633] vm_start: 139802659291136
[  139.457634] vm_start: 139802659295232
[  139.457635] vm_start: 139802661093376
[  139.457636] vm_start: 139802663186432
[  139.457637] vm_start: 139802663751680
[  139.457638] vm_start: 139802663755776
[  139.457639] vm_start: 139802663763968
[  139.457640] vm_start: 139802665758720
[  139.457641] vm_start: 139802667855872
[  139.457642] vm_start: 139802667872256
[  139.457644] vm_start: 139802667880448
[  139.457645] vm_start: 139802667896832
[  139.457646] vm_start: 139802669998080
[  139.457647] vm_start: 139802670153728
[  139.457648] vm_start: 139802670157824
[  139.457649] vm_start: 139802670161920
[  139.457650] vm_start: 140733449646080
[  139.457651] vm_start: 140733451108352
[  139.457652] vm_start: 140733451120640
[  139.457653] new process
[  139.463574] BUG: kernel NULL pointer dereference, address: 0000000000000000
[  139.463592] #PF: supervisor read access in kernel mode
[  139.463595] #PF: error_code(0x0000) - not-present page

谁能帮我循环直到我到达这个链表的末尾而不抛出错误?

我在内核中读到 vma 也是根据红黑树组织的。但是,在检查内核中的代码后,我找不到存储在节点中的任何信息。这可能是遍历 vma 的更可靠的方法。但是现在我不知道如何访问存储在其中的数据(据说)。

【问题讨论】:

在循环条件中,您需要将 iterator 本身与 NULL 进行比较,而不是其 vm_next 字段:while(mmap != NULL)。参见例如该代码:elixir.bootlin.com/linux/v5.10.6/source/arch/parisc/kernel/… @Tsyvarev 我做了你建议的改变,但我仍然得到错误。你能在你的最后运行代码,看看你是否没有收到错误? 奇怪的是,它似乎很好地完成了一个进程,然后它突然在下一个进程上得到一个空指针引用。 检查迭代器是否为 NULL 是迭代链表的正确方法。可能,您的代码的其他部分是错误的。例如。 “新进程”表示要创建的新进程,它使您正在迭代的对象。 我将发布到目前为止的其余代码以展示我所做的工作。请稍等。 【参考方案1】:
while(mmap->vm_next != NULL)

看起来不对。循环控制关闭 1,mmap 可能为空。试试这个

while(mmap != NULL)

某些进程(即僵尸进程)没有可用的 VM 指针。

【讨论】:

感谢您的回复。我之前将我的代码更改为这个建议(有人已经建议过这个)但它没有任何区别。我将更新示例中的代码以反映这一点,因为它更干净。 @rogerroger69:如果我是你,我会开始检查所有内容是否为空,比如 mm 本身。

以上是关于循环遍历内核空间中的链表的主要内容,如果未能解决你的问题,请参考以下文章

第四季-专题7-Linux内核链表

Linux内核(10) - 内核中的链表

C - 如何释放在其节点中具有链表的链表?

内核数据结构 内核链表分析

内核数据结构 内核链表分析

Linux内核链表深度分析