海思平台程序运行出现无法在虚拟地址处理内核分页请求错误

来源:互联网 发布:模拟炒股软件 编辑:程序博客网 时间:2024/05/15 23:41

程序执行后出现错误提示无法在虚拟地址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 : [<c01cfeac>]    lr : [<c00a03c8>]    psr: 80000013
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

目錄

  • 結論
    • SDK050新增下例造成問題
    • 產生下例的oops問題
    • 目前修正方式
  • 比較目前開發Hi3536及HI3535平台
    • toolchain
    • memcpy oops
  • test alignment
    • pc
    • hi3535
    • hi3536
  • single char test
  • 其它
  • 參考

結論

目前使用Hi3536 Hi3536_SDK_V1.0.5.0版本
遇到系系使用相關pipe功能將會產生oops
因此去除SDK050的内核漏洞修复

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

產生下例的oops問題

  • copy_to_iter_bvec

    1234567891011
    CPU: 0 PID: 1364 Comm: grep Not tainted 3.10.0_hi3536 #1task: ce941800 ti: cde58000 task.ti: cde58000PC is at kmap_atomic+0x20/0x12cLR is at copy_to_iter_bvec+0x4c/0x12cpc : [<c002061c>]    lr : [<c00a5ff8>]    psr: 80000013sp : cde59df8  ip : 00000000  fp : 00000001r10: 0000045a  r9 : cde59e8c  r8 : cde59ed0r7 : 00000000  r6 : cdd41000  r5 : cde58038  r4 : b6f1ae4cr3 : cde58000  r2 : 00000002  r1 : 0000045a  r0 : b6f1ae4cFlags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment userControl: 10c5387d  Table: 4ee6006a  DAC: 00000015
  • at _memcpy

    12345678910111213
    Internal error: Oops: 805 [#1] SMP ARMModules linked in:CPU: 3 PID: 2878 Comm: awk Not tainted 3.10.0_hi3536 #1task: ce08a000 ti: ce7f2000 task.ti: ce7f2000PC is at _memcpy+0xf0/0x330LR is at 0x6fpc : [<c02cc770>]    lr : [<0000006f>]    psr: 20000013sp : ce7f3dec  ip : 00000003  fp : 00000001r10: 00000030  r9 : ce7f3e8c  r8 : ce7f3ed0r7 : 00000000  r6 : cdc0b000  r5 : 00000030  r4 : 0000004dr3 : 00000020  r2 : 0000002c  r1 : cdc0b003  r0 : 6220b001Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment userCont

目前修正方式

去除050版的内核漏洞修复
[hi3536 sdk050 kernel patch]


比較目前開發Hi3536及HI3535平台

itemhi3535hi3536uclib/glibc gcc4.4.14.8.3kernelLinux version 3.4.35_hi3535Linux version 3.10.0_hi3536uclibclibuClibc-0.9.32.1.solibuClibc-0.9.33.2.sobusyboxbusybox-1.16.1busybox-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

toolchain

  • 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

memcpy oops

  • memcpy oops
    1234567891011121314151617
    Jan  1 00:00:21 login[1069]: root login on 'pts/0'Unable to handle kernel paging request at virtual address f25b1001pgd = ce43c000[f25b1001] *pgd=00000000Internal error: Oops: 805 [#1] SMP ARMModules 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 #1task: cec5e000 ti: cd8fa000 task.ti: cd8fa000PC is at _memcpy+0xf0/0x330LR is at 0x6fpc : [<c02cc770>]    lr : [<0000006f>]    psr: 20000013sp : cd8fbdec  ip : 00000003  fp : 00000001r10: 00000030  r9 : cd8fbe8c  r8 : cd8fbed0r7 : 00000000  r6 : cd8ed000  r5 : 00000030  r4 : 0000004dr3 : 00000020  r2 : 0000002c  r1 : cd8ed003  r0 : f25b1001Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment userControl: 10c5387d  Table: 4e43c06a  DAC: 00000015

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造成的

    • 採用xm雄邁板子flash,直接測試,正常(即無memcpy oops)
    • 採用xm-rootfs, 自已產生-kernel ,測試異常(即產生memcpy oops)
    • 採用xm-rootfs, xm-kernel ,測試正常
    • 採用自製的rootfs及xm-kernel,正常(即無memcpy oops)
    • 採用自製的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異常


test alignment

pc

  • $ cat aligment.c
    1234567
    #include <stdio.h>int main(){    char *str = "\x01\x23\x45\x67\x89\xab\xcd\xef";    unsigned *u = (unsigned *) (str);    printf( "%08x\n", *u);    return 0;}

./a.out
67452301

  • cat aligment.c
    1234567
    #include <stdio.h>int main(){    char *str = "\x01\x23\x45\x67\x89\xab\xcd\xef";    unsigned *u = (unsigned *) (str +1);    printf( "%08x\n", *u);    return 0;}

./a.out
89674523

hi3535

  • cat alignment
    123456789
    /proc/cpu # cat alignment User:           0System:         0Skipped:        0Half:           0Word:           0DWord:          0Multi:          0User faults:    2 (fixup)

./a.out
89674523

  • alignment
    1234567891011121314151617181920212223242526272829
    /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:           0System:         0Skipped:        0Half:           0Word:           0DWord:          0Multi:          0User faults:    3 (fixup+warn)/proc/cpu # /test/a.out 89674523/proc/cpu # echo 2 > alignment /proc/cpu # cat alignment User:           0System:         0Skipped:        0Half:           0Word:           0DWord:          0Multi:          0User faults:    2 (fixup)

hi3536

./a.out
89674523


single char test

  • cat singlechar.c

    1234567
    #include <stdio.h>int main(){    char c1 = 0xff, c2 = 0x01;    printf( (c1 > c2) ? "c1>c2\n" : "c1 <= c2" );    return 0;}
  • pc
    $ ./a.out
    c1 <= c2

  • hi3535
    /test # ./a.out
    c1>c2

ARM Toolchain特有- 以char宣告的unsigned char數值
所以跟gcc實做有問題


其它

  • hi3536 uclibc

    123456
    $ nm -D libuClibc-0.9.33.2.so | grep memcpy0000c474 T __aeabi_memcpy0000c474 T __aeabi_memcpy40000c474 T __aeabi_memcpy8000319e0 T memcpy00034978 T wmemcpy
  • mem_alignment
    cpu為需要對齊(alignmen),當程式發生非對齊,kernel提供相對應該處理程序
    /proc/cpu/aligment



0 0