位反转现象(Bit Flip)

  任何系统,硬件故障和软件故障都不可避免。比如车载系统,由于汽车行驶过程中的震动,发热等,很容易影响电子元件的特性,发生电容的0和1状态的切换。这对程序是致命的影响,会直接改变程序逻辑及运行结果。这种情况称之为位反转(Bit Flip)。

这种对安全要求高的场景,编程时需要对变量进行保护。常见方法是镜像法,即在两个不同的地方写入同一个变量,读取时对2个变量的值进行校验。如果结果不一致,就要进行容错处理。

1、什么是bitflip?

  cpu中(cache或寄存器)或DDR中或flash中的 一个或者多个bit发生位反转如0变为1,1变为0.这样的变化没有软件参与,是硬件自己变的!!

2、为什么会发生bitflip?

  • 器件不良-----比如cpu ddr flash 本身就有质量缺陷
  • 器件供电不足或者供电受到干扰-----cpu ddr flash的稳定工作需要一定的电压频率,如果供电不足或者波动较大 那么其内部状态会不稳定从而引起bitflip
  • 传输干扰-----数据在cpu-ddr或ddr-flash间流动时如果引脚干扰大也会导致传输出错(不过一般有传输校验这种 情况几率较小)
  • 引脚虚焊-----器件与主板的硬件有虚焊当然会有问题
  • 主板损坏或微损坏------导致送给器件的电或者信号不稳定

以上 除器件不良外都属于器件的供电或者其它信号会受到干扰或者不稳定的情况-----一般与主板强相关

下面直接以一个例子来分析。

pid: 481, tid: 13908, name: HwBinder:481_5 >>> /system/bin/cameraserver <<<

signal 4 (SIGILL), code --------, fault addr --------

r0 00000280 r1 000001e0 r2 ed6ff410 r3 00000000

r4 c69d2668 r5 ef0b7800 r6 00000003 r7 00003f23

r8 00000000 r9 ffffffff sl ef0b7ed0 fp ef2313c8

ip eea7bcc0 sp ed6ff3d0 lr f0019c4f pc f0019c92 cpsr 60000030

对应的调用堆栈如下:

#00 pc 00059c92 /system/lib/libgui.so (android::Surface::queueBuffer(ANativeWindowBuffer*, int)+249)
#01 pc 000a5865 /system/lib/libcameraservice.so (android::CameraHardwareInterface::enqueueBuffer(unsigned long long)+56)
#02 pc 000a5921 /system/lib/libcameraservice.so (_ZTv0_n68_N7android23CameraHardwareInterface13enqueueBufferEy+12)
#03 pc 000316ad /system/lib/android.hardware.camera.device@1.0.so

  

发生该种NE SIGILL,表示pc执行了非法指令,它的产生原因一般为如下几种:

<1>执行的文件本身出现问题,文件本身出错了

<2>执行了数据段中的内容

<3>堆栈被踩坏或溢出,导致执行了非法指令

<4>发生了bitflip导致指令跳转到非法地址

 

对于<1>可以对比coredump文件和libgui.so反汇编之后的汇编代码,确认是否一致,如果一致,说明so文件本身没有问题。

(gdb) x /8xh 0xf0019c8e

0xf0019c8e <android::Surface::queueBuffer(ANativeWindowBuffer*, int)+246>: 0xe9db 0x0108 0xf10d 0x0bb0 0xe9cd 0x332c 0xe9cd 0x012e

 

(gdb)通过gdb来看coredump中地址0xf0019c92附件的指令编码,从0xf0019c92- 0xf0019c95地址对应的编码为0xf10d 0x0bb0,

这个与libgui.so中偏移地址00059c92对应的编码是一样的,如下所示:

59c8e: e9db 0108 ldrd r0, r1, [fp, #32]

59c92: f10d 0bb0 add.w fp, sp, #176 ; 0xb0

 

因此,如果coredump中读取的内容与libgui.so中的编码是一样,那么说明不是文件本身出问题。

 

<2>执行了数据段的内容,这个可以根据pc地址以及结合maps中的虚拟地址范围来确定

<3>堆栈是否被踩坏,需要coredump打印堆栈中的内容以及结合前一帧堆栈内容来推导堆栈内容是否有异常,一般需要结合汇编代码来分析。

<4> bitflip是否跳转确认

[69422.917814] (1)[13908:HwBinder:481_5]HwBinder:481_5[13908]: undefined instruction: pc=00000000f0019c92

[69422.917848] (1)[13908:HwBinder:481_5]Code: aa100a8f b00cf8cd 0acff942 0108e9db (0bb0f90d)

上面语句表示pc地址00000000f0019c92对应的编码为0bb0f90d,也就是括号中的值,编码包括操作码和操作数,

括号前面的几个编码aa100a8f b00cf8cd 0acff942 0108e9db,它表示pc地址之前的几个地址对应的指令编码。

 

(gdb) p /x *0xf0019c92 从coredump信息可以看出0xf0019c92对应的指令编码为0xbb0f10d,

$12 = 0xbb0f10d //这个是正常的指令编码

对比0xbb0f10d与0bb0f90d,确实有一个 bit发生了跳转,0xbb0f10d 这个是正常的指令编码,但真正执行时却变为0bb0f90d,因此是硬件bit位发生了跳转导致NE,属于硬件问题。

对于bitflip一般需要做硬件交叉实验来进一步确认问题。

posted @ 2021-12-07 17:09  轻轻的吻  阅读(6095)  评论(0编辑  收藏  举报