b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

LSM哎呀内存错误的根本原因分析与解决方法

电脑杂谈  发布时间:2020-09-23 11:02:24  来源:网络整理

光线cms 手机访问 路径或参数错误_ug40内存访问冲突补丁_内存访问错误

糟糕是Linux内核中最常见的异常错误情况。本文介绍如何通过分析特定的Oops示例来分析和解决此类问题。

1.糟糕,LSM内核模块中出现了

插入LSM的ko模块,内核会打印以下日志:

[  415.746844] BUG: unable to handle kernel paging request at ffffffffaa6f0210
[ 415.746846] PGD 3fc0e067 P4D 3fc0e067 PUD 3fc0f063 PMD 34367063 PTE 800000003faf0061
[ 415.746849] Oops: 0003 [#1] SMP PTI
[ 415.746851] CPU: 0 PID: 8366 Comm: insmod Tainted: G OE 4.19.82-wwh #1
[ 415.746852] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/29/2019
[ 415.746856] RIP: 0010:init_lsm_hooks+0x1cd/0x1f0 [xxx_security]
[ 415.746857] Code: 00 00 48 8b 41 10 48 89 71 20 48 8b 10 48 85 d2 75 05 eb 25 48 89 c2 48 8b 02 48 85 c0 75 f5 48 c7 01 00 00 00 00 48 89 51 08 <48> 89 0a 48 83 c1 28 48 39 f9 75 cc 31 c0 c3 48 c7 01 00 00 00 00
[ 415.746858] RSP: 0018:ffffa763c332fcb0 EFLAGS: 00010246
[ 415.746859] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffffc0ae2020
[ 415.746859] RDX: ffffffffaa6f0210 RSI: ffffffffc0adfaa9 RDI: ffffffffc0ae2458
[ 415.746860] RBP: ffffffffc0ada000 R08: 000000000000006d R09: ffffffffaa5c11f3
[ 415.746860] R10: ffffffffaa63c310 R11: ffffffffaa63c6a0 R12: ffffffffc0ae2fc0
[ 415.746861] R13: ffffffffc0ae2e58 R14: ffffa763c332fe98 R15: ffffffffc0ae2e40
[ 415.746862] FS: 00007fdf33491200(0000) GS:ffff9ac97bc00000(0000) knlGS:0000000000000000
[ 415.746863] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 415.746863] CR2: ffffffffaa6f0210 CR3: 0000000077222004 CR4: 00000000003606f0
[ 415.746880] Call Trace:
[ 415.746883] init_module+0x34/0xc0 [xxx_security]
[ 415.746886] do_one_initcall+0x46/0x1c3
[ 415.746889] ? _cond_resched+0x15/0x30
[ 415.746890] ? kmem_cache_alloc_trace+0x155/0x1d0
[ 415.746892] do_init_module+0x5a/0x210
[ 415.746894] load_module+0x215b/0x2390
[ 415.746897] ? __do_sys_finit_module+0xa8/0x110
[ 415.746898] __do_sys_finit_module+0xa8/0x110
[ 415.746900] do_syscall_64+0x55/0xf0
[ 415.746901] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 415.746910] RIP: 0033:0x7fdf335abf59

2.糟糕,获取错误地址分析

先看第一行:

 BUG: unable to handle kernel paging request at ffffffffaa6f0210

无法处理虚拟地址处的内核分页请求是内存访问异常错误,通常是由于以下三个原因:

当虚拟地址为0x00000000时,表示使用了空指针。虚拟地址不超过内核地址空间范围,表明指针所指向的内存受到一定的限制;否则,指针将超出内核地址空间范围;

以上日志中的错误地址ffffffffaa6f0210在内核地址空间范围内,可以判断为篡改受限内存的尝试导致了错误;例如,在分配声明为const的变量时会发生此错误。

3.初步分析了导致Oops的内核代码位置

接下来查看日志中的RIP信息:

RIP: 0010:init_lsm_hooks+0x1cd/0x1f0 [xxx_security]

通常,在这种情况下,我们从Oops收集的最有用的信息是EIP和错误的呼叫地址。对于64位用户,您可能需要检查RIP,EIP / RIP通常可以标识发生问题的站点。在此示例中,我们可以看到Oops中的RIP位于init_lsm_hooks的0x1cd字节位置,并且init_lsm_hooks占用0x1f0字节大小。它为我们提供了非常有用的信息,告诉我们在哪里寻找错误的代码。下面将详细描述准确查找错误代码的过程。

内存访问错误_ug40内存访问冲突补丁_光线cms 手机访问 路径或参数错误

Oops日志中的代码行将在尖括号中包含引起Oops的第一条指令,这是RIP值的第一字节。如:

Code: 00 00 48 8b 41 10 48 89 71 20 48 8b 10 48 85 d2 75 05 eb 25 48 89 c2 48 8b 02 48 85 c0 75 f5 48 c7 01 00 00 00 00 48 89 51 08 <48> 89 0a 48 83 c1 28 48 39 f9 75 cc 31 c0 c3 48 c7 01 00 00 00 00

是的

如果您没有自己编译vmlinux时想找到错误的代码行,则可以使用这种代码行。但是要注意cpu的体系结构,某些体系结构(例如常见的x86)指令的长度不相等;

4.糟糕的错误代码分析

再次查看错误代码行:

Oops: 0003 [#1] SMP PTI

其中,0003是错误代码。发生异常时,硬件会将其压入堆栈。通过此操作,您可以了解导致Oops的一般原因。

对于x86架构,错误代码的定义如下:

Page fault error code bits:

bit 0 == 0: no page found 1: protection fault
bit 1 == 0: read access 1: write access
bit 2 == 0: kernel-mode access 1: user-mode access
bit 3 == 1: use of reserved bit detected
bit 4 == 1: fault was an instruction fetch

通常使用低3位数字,具体含义为:

如果将位0清除为0,则异常是由于页面不存在引起的;否则,是由于无效的访问权限引起的。如果将第一位清零,则异常是由读取访问或执行访问引起的;否则,异常是由写访问引起的。如果将位2清除为0,则在内核模式下发生异常;否则,在内核模式下发生异常。否则,例外会在用户模式下发生。

因此,以上示例中的错误代码0003表示:

该异常是由无效的访问权限引起的,即被访问的地址具有相应的物理页面,但没有访问权限;异常是由写操作引起的;总之,该异常是在内核模式下发生的,总的来说,该异常是由于内核在未经写许可的情况下写入地址所致;

ug40内存访问冲突补丁_内存访问错误_光线cms 手机访问 路径或参数错误

Oops中的[#1]表示崩溃次数。

5.通过gdb找到错误的内核代码文件和行号

接下来,使用gdb调试进行进一步的动态分析,以确定错误代码文件和行号。

首先,您需要通过add-symbol-file命令将符号文件添加到调试器。符号文件是LSM模块通过insmod命令插入错误(即xxx_security出现在日志中)时使用的内核模块的.o文件。

insmod命令:

[  415.746851] CPU: 0 PID: 8366 Comm: insmod Tainted: G           OE     4.19.82-wwh #1

xxx_security模块:

[  415.746883]  init_module+0x34/0xc0 [xxx_security]

add-symbol-file命令具有两个参数:

获得地址如下:

$ sudo cat /sys/module/xxx_security/sections/.text
0xffffffffc0ada000

然后通过gdb调试xxx_security.ko:

(gdb) add-symbol-file xxx_security.o 0xffffffffc0ada000
add symbol table from file "xxx_security.o" at
.text_addr = 0xffffffffc0ada000
(y or n) y
Reading symbols from xxx_security.o...done.

根据上面的RIP行,可以获得错误函数的名称和偏移量:

ug40内存访问冲突补丁_光线cms 手机访问 路径或参数错误_内存访问错误

RIP: 0010:init_lsm_hooks+0x1cd/0x1f0 [xxx_security]

下一步是按以下步骤反汇编init_lsm_hooks函数:

(gdb) disassemble init_lsm_hooks
Dump of assembler code for function init_lsm_hooks:
Address range 0x150 to 0x33c:
0x0000000000000150 <+0>: callq 0x155 5>
0x0000000000000312 <+450>: movq $0x0,(%rcx)
0x0000000000000319 <+457>: mov %rdx,0x8(%rcx)
0x000000000000031d <+461>: mov %rcx,(%rdx)
0x0000000000000320 <+464>: add $0x28,%rcx
0x0000000000000324 <+468>: cmp %rdi,%rcx

从上面可以看出,init_lsm_hooks函数的起始地址为0x150,错误的偏移量为0x1cd。

0x150 + 0x1cd = 0x31d,那么如何使用该地址对应.c中的特定行?

(gdb) l *0x000000000000031d
0x31d is in init_lsm_hooks (./include/linux/compiler.h:220).
215 {
216 switch (size) {
217 case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
218 case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
219 case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
220 case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
221 default:
222 barrier();
223 __builtin_memcpy((void *)p, (const void *)res, size);
224 barrier();


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shoujiruanjian/article-321339-1.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...