程序执行后出现错误提示无法在虚拟地址0a209001处理内核分页请求 这种问题
错误出现的日志为
Unable to handle kernel paging request at virtual address 0a209001
pgd = dbd38000
[0a209001] *pgd=00000000
Internal error: Oops: 805 [#3] SMP ARM
Modules linked in: nvp6124_ex(O) gpioi2c(O) hi3531a_adec(PO) hi3531a_aenc(PO) hi3531a_ao(PO) hi3531a_ai(PO) hi3531a_aio(PO) hi_rtc(O) hi3531a_ive(PO) hi3531a_vda(PO) hi3531a_h264e(PO) hi3531a_chnl(PO) hi3531a_venc(PO) hi3531a_rc(PO) hi3531a_hdmi(PO) hifb(PO) hi3531a_vou(PO) hi3531a_vpss(PO) hi3531a_viu(PO) hi3531a_vgs(PO) hi3531a_region(PO) hi3531a_tde(PO) hi3531a_vfmw(PO) hi3531a_vdec(PO) hi3531a_sys(PO) hi3531a_base(PO) hi_media(O) hiuser(O) mmz(O) [last unloaded: gpioi2c]
CPU: 0 PID: 1299 Comm: DvrUi2 Tainted: P D O 3.10.0 #30
task: df02b100 ti: dec3e000 task.ti: dec3e000
PC is at memcpy+0xcc/0x330
LR is at copy_to_iter_bvec+0x64/0x12c
pc : [
sp : dec3fe04 ip : 00000000 fp : 00000001
r10: 00000001 r9 : dec3fe94 r8 : dec3fed8
r7 : 00000000 r6 : df2a7001 r5 : 0a209000 r4 : 00000001
r3 : 00000000 r2 : 80000000 r1 : df2a7001 r0 : 0a209001
Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: 10c53c7d Table: 5bd3804a DAC: 00000015
如果出现这种错误,错误原因是因为系统内核的漏洞,自己经过很长时间的网上查找在无意中发现了最近发布的一篇文章才得以解决,
博客地址为http://erwinchang.github.io/2017/01/09/oops-memcpy/
为了防止上面的博客不能访问以下部分是我复制博主的内容。解决方法提供的内核补丁文件见这个下载地址http://download.csdn.net/detail/lizhu_csdn/9749481
目前使用Hi3536 Hi3536_SDK_V1.0.5.0版本
遇到系系使用相關pipe功能將會產生oops
因此去除SDK050的内核漏洞修复
Hi3536 V100R001C0xSPC050 序號:2(内核漏洞修复)
此修正使用了 copy_to_iter_bvec等(iov_iter.c)
為了修正:
CVE-2015-2686是在net/socket.c文件中,影響linux內核3.19.3之前版本。
由於sendto和recvfrom系統調用沒有驗證數據範圍,本地權限用戶,可以利用iov_iter接口的copy_from_iter方法來進行提權。
來源: https://read01.com/7PGEML.html
copy_to_iter_bvec
1 2 3 4 5 6 7 8 9 10 11 |
CPU: 0 PID: 1364 Comm: grep Not tainted 3.10.0_hi3536 #1 task: ce941800 ti: cde58000 task.ti: cde58000 PC is at kmap_atomic+0x20/0x12c LR is at copy_to_iter_bvec+0x4c/0x12c pc : [ |
at _memcpy
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Internal error: Oops: 805 [#1] SMP ARM Modules linked in: CPU: 3 PID: 2878 Comm: awk Not tainted 3.10.0_hi3536 #1 task: ce08a000 ti: ce7f2000 task.ti: ce7f2000 PC is at _memcpy+0xf0/0x330 LR is at 0x6f pc : [ |
去除050版的内核漏洞修复
[hi3536 sdk050 kernel patch]
item | hi3535 | hi3536 |
---|---|---|
uclib/glibc gcc | 4.4.1 | 4.8.3 |
kernel | Linux version 3.4.35_hi3535 | Linux version 3.10.0_hi3536 |
uclibc | libuClibc-0.9.32.1.so | libuClibc-0.9.33.2.so |
busybox | busybox-1.16.1 | busybox-1.20.2 |
hi3535
uclibc : arm-hisiv100-linux-uclibcgnueabi
glibc : arm-hisiv200-linux-gnueabi
hi3536
uclibc : arm-hisiv300-linux-uclibcgnueabi
glilbc : arm-hisiv100-linux-uclibcgnueabi
arm-hisiv300-linux-uclibcgnueabi
gcc version 4.8.3 20131202 (prerelease) (Hisilicon_v300)
1
|
--enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-arch=armv5te --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --enable-shared --enable-lto --enable-symvers=gnu --enable-__cxa_atexit --enable-nls --enable-clocale=gnu --enable-extra-hisi-multilibs
|
arm-hisiv100-linux-uclibcgnueabi
gcc version 4.4.1 (Hisilicon_v100(gcc4.4-290+uclibc_0.9.32.1+eabi+linuxpthread))
1
|
--enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-arch=armv5te --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --enable-shared --enable-lto --enable-symvers=gnu --enable-__cxa_atexit --disable-nls --enable-extra-hisi-multilibs
|
arm-hisiv400-linux-gnueabi-gcc
gcc version 4.8.3 20131202 (prerelease) (Hisilicon_v400)
1
|
--enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-arch=armv5te --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --enable-shared --enable-lto --enable-symvers=gnu --enable-__cxa_atexit --enable-nls --enable-clocale=gnu --enable-extra-hisi-multilibs
|
arm-hisiv200-linux-gnueabi
gcc version 4.4.1 (Hisilicon_v200(gcc4.4-290+glibc-2.11+eabi+nptl))
1
|
--enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-arch=armv5te --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --enable-shared --enable-lto --enable-symvers=gnu --enable-__cxa_atexit --disable-nls --enable-extra-hisi-multilibs
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Jan 1 00:00:21 login[1069]: root login on 'pts/0' Unable to handle kernel paging request at virtual address f25b1001 pgd = ce43c000 [f25b1001] *pgd=00000000 Internal error: Oops: 805 [#1] SMP ARM Modules linked in: hi3536_adec(PO) hi3536_aenc(PO) hi3536_ao(PO) hi3536_ai(PO) hi3536_aio(PO) acodec(PO) gpio(O) hi3536_ive(PO) hi3536_vda(PO) hi3536_jpege(PO) hi3536_h264e(PO) hi3536_) CPU: 1 PID: 2967 Comm: awk Tainted: P O 3.10.0_hi3536 #1 task: cec5e000 ti: cd8fa000 task.ti: cd8fa000 PC is at _memcpy+0xf0/0x330 LR is at 0x6f pc : [ |
hi3536 cpu是無支援非對齊 功能
由於gcc為4.8.3 預設為支援非對齊
因此gcc需要增加(-mno-unaligned-access)
記錄
將hi3536的busybox增加下例flag ( -mno-unaligned-access -fno-aggressive-loop-optimizations)
測試500 loop仍會發生
1
|
CONFIG_EXTRA_CFLAGS="-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4 -mno-unaligned-access -fno-aggressive-loop-optimizations"
|
將busybox由1.20.2降為1.16.1
沒有改善
改由使用xm環境測試
xx/workspace/bitbucket/hi3536/build-dir/hiv300/hixm/1.0.0/rootfs
相同情況
改由使用glibc測試
xx/workspace/bitbucket/hi3536/build-dir/hiv400/hixm/1.0.0/rootfs
相同情況
目前確定是自製kernel造成的
採用原廠提供prebuild kernel及自製的rootfs,測試異常(即產生memcpy oops)
single及master都測試一樣產生異常
Hi3536_SDK_V1.0.5.0/package/osdrv_single/image_uclibc/uImage_hi3536
Hi3536_SDK_V1.0.5.0/package/osdrv_single/image_uclibc/uImage_hi3536
測試sdk板子上面原本的kernel,正常
未修改kernel直接測試(make OSDRV_CROSS=arm-hisiv300-linux CPU_TYPE=single) , 測試異常
比較測試kernel,確定SDK040正常,SDK050異常
1 2 3 4 5 6 7 |
#include |
./a.out
67452301
1 2 3 4 5 6 7 |
#include |
./a.out
89674523
1 2 3 4 5 6 7 8 9 |
/proc/cpu # cat alignment User: 0 System: 0 Skipped: 0 Half: 0 Word: 0 DWord: 0 Multi: 0 User faults: 2 (fixup) |
./a.out
89674523
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/proc/cpu # echo 0 > alignment alignment: ignoring faults is unsafe on this CPU. Defaulting to fixup mode. /proc/cpu # echo 1 > alignment alignment: ignoring faults is unsafe on this CPU. Defaulting to fixup mode. /proc/cpu # cat alignment User: 0 System: 0 Skipped: 0 Half: 0 Word: 0 DWord: 0 Multi: 0 User faults: 3 (fixup+warn) /proc/cpu # /test/a.out 89674523 /proc/cpu # echo 2 > alignment /proc/cpu # cat alignment User: 0 System: 0 Skipped: 0 Half: 0 Word: 0 DWord: 0 Multi: 0 User faults: 2 (fixup) |
./a.out
89674523
cat singlechar.c
1 2 3 4 5 6 7 |
#include |
pc
$ ./a.out
c1 <= c2
hi3535
/test # ./a.out
c1>c2
ARM Toolchain特有- 以char宣告的unsigned char數值
所以跟gcc實做有問題
hi3536 uclibc
1 2 3 4 5 6 |
$ nm -D libuClibc-0.9.33.2.so | grep memcpy 0000c474 T __aeabi_memcpy 0000c474 T __aeabi_memcpy4 0000c474 T __aeabi_memcpy8 000319e0 T memcpy 00034978 T wmemcpy |
mem_alignment
cpu為需要對齊(alignmen),當程式發生非對齊,kernel提供相對應該處理程序
/proc/cpu/aligment