但linux kernel 打开CONFIG_FORTIFY_SOURCE 后,就了memcpy等函数的检测。
代码
static void copytmp(char *ptmp)
{
memcpy(ptmp, chtmp, 130);
}
char pch[124];
static int test_proc_show(struct seq_file *m, void *v)
{
copytmp(pch);
}
汇编
从汇编中可以看到根本没有调用什么memcpy, 最后调用到了__fortify_panic
(gdb) disassemble copytmp
Dump of assembler code for function copytmp:
0xffff80008037fb98 <+0>: paciasp
0xffff80008037fb9c <+4>: stp x29, x30, [sp, #-16]!
0xffff80008037fba0 <+8>: mov x1, #0x82 // #130
0xffff80008037fba4 <+12>: mov x29, sp
0xffff80008037fba8 <+16>: mov x0, #0x7c // #124
0xffff80008037fbac <+20>: bl 0xffff80008054a2bc <__write_overflow_field>
0xffff80008037fbb0 <+24>: mov x2, #0x82 // #130
0xffff80008037fbb4 <+28>: mov x1, #0x7c // #124
0xffff80008037fbb8 <+32>: mov w0, #0x11 // #17
0xffff80008037fbbc <+36>: bl 0xffff80008054acd8 <__fortify_panic>
End of assembler dump.
执行是出现:
[ 20.008476] kernel BUG at lib/string_helpers.c:1037!
[ 20.008994] Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP
在编译是可以推断 ptmp的大小为 char pch[124]; 124。
代码
static void copytmp(char *ptmp)
{
memcpy(ptmp, chtmp, 130);
}
static int test_proc_show(struct seq_file *m, void *v)
{
char *pch = NULL;
pch = kmalloc(120, GFP_KERNEL);
copytmp(pch);
return 0;
}
汇编
(gdb) disassemble copytmp
Dump of assembler code for function copytmp:
0xffff80008037fb98 <+0>: paciasp
0xffff80008037fb9c <+4>: stp x29, x30, [sp, #-16]!
0xffff80008037fba0 <+8>: mov x2, #0x82 // #130
0xffff80008037fba4 <+12>: mov x29, sp
0xffff80008037fba8 <+16>: adrp x1, 0xffff800082aaa000 <iomap_ioend_bioset+40>
0xffff80008037fbac <+20>: add x1, x1, #0x318
0xffff80008037fbb0 <+24>: bl 0xffff800081041430 <memmove>
0xffff80008037fbb4 <+28>: ldp x29, x30, [sp], #16
0xffff80008037fbb8 <+32>: autiasp
0xffff80008037fbbc <+36>: ret
End of assembler dump.
(gdb)
可以看到没有关于memcpy的检测
应为在编译是,无法推断出copytmp(char *ptmp) ptmp的大小。所以执行也没有问题
那问题是,既然在编译时已经发现问题,为什么不在编译时,直接报错。
代码
static void copytmp(char *ptmp)
{
memcpy(ptmp, chtmp, 130);
}
char chdata[124];
static int test_proc_show(struct seq_file *m, void *v)
{
char *ptmp = NULL;
ptmp = kmalloc(150, GFP_KERNEL);
copytmp(ptmp);
copytmp(chdata);
}
汇编
(gdb) disassemble copytmp
Dump of assembler code for function copytmp:
0xffff80008037fb98 <+0>: paciasp
0xffff80008037fb9c <+4>: stp x29, x30, [sp, #-16]!
0xffff80008037fba0 <+8>: mov x2, #0x82 // #130
0xffff80008037fba4 <+12>: mov x29, sp
0xffff80008037fba8 <+16>: adrp x1, 0xffff800082aaa000 <iomap_ioend_bioset+40>
0xffff80008037fbac <+20>: add x1, x1, #0x318
0xffff80008037fbb0 <+24>: bl 0xffff8000810423b0 <memmove>
0xffff80008037fbb4 <+28>: ldp x29, x30, [sp], #16
0xffff80008037fbb8 <+32>: autiasp
0xffff80008037fbbc <+36>: ret
没有检测代码了, 执行也没有问题。