Linux內核4.4打開kasan功能並替換內核編譯器

基於高通820,Linux4.4內核使能kasan功能

 

1. 打開宏定義

CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y //GCC 5.0以上支持,主要優化執行效率
CONFIG_KCOV=y
CONFIG_TEST_KASAN=y//kasan 測試程序
CONFIG_FRAME_WARN=0

 

2. bootimage分區和內核image大小調整

打開kasan後,內核Image變大,需要調整lk加載內核地址以及boot.img分區大小

2. 1 調整內核加載地址大小

bootable/bootloader/lk/platform/msm8996/include/platform/iomap.h
+#define ABOOT_FORCE_RAMDISK_ADDR           DDR_START + 0x4700000
+#define ABOOT_FORCE_TAGS_ADDR              DDR_START + 0x4600000
根據image大小調整,這裏給kernel image 69.5M的空間。 dtbo.img 給1M,ramdisk.img 7M

0x80080000 -> 0x84600000 /* kernel image:69.5 */
0x84600000 -> 0x84700000 /*dtbo or tag:1M */
0x84700000 -> 0x84e00000 /* ramdisk:7M*/

這裏需要注意:

 kernel image 要配置合適,太大可能會佔用其他模塊地址,太小又會覆蓋dtbo和ramdisk.

可以根據System.map,查找內核符號_text和_end,把_end 減去_text就是kernel 真實佔用內存大小.

比如_text = 0xffffff9008080000,  _end = 0xffffff900c57f000; 則kernel size = 0x44ff000=68.9M

所以在lk中配置內核加載地址爲69.5M(0x80080000 -> 0x84600000)

dtbo和ramdisk大小,可以根據dtbo.img和ramdisk.img文件大小來確定.

2.2 調整boot.img打包大小:

當修改內核GCC爲高版本後,CONFIG_KASAN_INLINE生效,boot.img會大於默認打包大小64M.

在BoardConfig.mk中修改BOARD_BOOTIMAGE_PARTITION_SIZE=0x5000000// 80M

2.3 調整eMMC中boot.img分區大小

vendor/chipcode/xmart/common/config/emmc

boot_a和boot_b需要調整爲80M ;

3. test kasan測試kasan的功能

發現kasan_report功能會出現panic.

問題 原因是nearest_obj函數計算objects地址錯誤,沒有計算左邊的redzone

可以調用fixup_red_left進行修正.

static inline void *nearest_obj(struct kmem_cache *cache, struct page *page,
                void *x) {
    void *object = x - (x - page_address(page)) % cache->size;
    void *last_object = page_address(page) +
        (page->objects - 1) * cache->size;
    void *result = (unlikely(object > last_object)) ? last_object : object;

    result = fixup_red_left(cache, result);
    return result;
}

 

4. kasan不足

測試發現,kasan對棧和全局變量沒有保護,查閱文檔,發現是要gcc.5.0以上才支持,而android編譯器最新是aarch-linux-android-4.9.

5. 修改編譯內核的gcc版本爲7.4

5.1 下載gnu gcc,並放到prebuilts

prebuilts/gcc/linux-x86/aarch64/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu

修改內核交叉編譯器,高通平臺可以直接修改AndroidKernel.mk文件

KERNEL_CROSS_COMPILE := $(shell pwd)/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-

或者直接修改CROSS_COMPILE變量。

這樣替換內核交叉編譯器爲7.4以後,可以支持全局變量和棧溢出保護,以及CONFIG_KASAN_INLINE

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章