使用GCC Arm工具链开发的项目, 在升级到 arm-gnu-toolchain-12.2 之后, 编译出现警告
arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld: warning: Build/app.elf has a LOAD segment with RWX permissions
关于 LOAD segment with RWX permissions 警告这是 Binutils 2.39 引入的一个新的安全类型的警告, GCC在升级版本时会带着新版本的 Binutils 一起发布. 如果要消除这个警告, 要么修改ld文件, 要么屏蔽掉它.
说明这篇文章里有比较详细的说明https://www.redhat.com/en/blog/linkers-warnings-about-executable-stacks-and-segments
The executable segment warnings
当程序载入内存时会分段载入, 一些属于可执行的代码,一些属于数据, 可读或者可读可写, 可能还有一些用于其它特殊用途. 每一段内存都会区分可读、可写和可执行这三个属性, 如果一个内存段同时具有这三种属性, 则存在受到攻击的可能性, 因此在这种情况下链接器将产生以下警告
warning: <file> has a LOAD segment with RWX permissions
这个警告表示elf文件中存在一个或多个存在安全问题的段, 可以通过运行readelf程序进行查看
readelf -lW <file>
注意: 在readelf的输出中, 段的可执行标志被标记为E而不是X, 三个属性的标识为RWE而不是RWX. 警告出现的常见原因是使用自定义连接脚本进行链接, 该脚本未将代码和数据分成不同的段, 所以最好的解决办法是更新连接脚本. readelf命令将显示每个段包含哪些部分, 可以通过这些信息计算出连接器映射需要如何更新, 才能将代码部分和可写的数据部分分开.
消除 LOAD segment with RWX permissions 警告选项一: 使用 --no-warn-rwx-segments 屏蔽
- 如果连接使用的是ld, 可以用
--no-warn-rwx-segments
选项 - 如果连接使用的是gcc, 直接用会提示无法识别的选项, 需要用
-Wl,--no-warn-rwx-segments
这样的方式
$ readelf -lW app.elf Elf file type is EXEC (Executable file)Entry point 0x15e1There are 3 program headers, starting at offset 52Program Headers:TypeOffsetVirtAddrPhysAddrFileSiz MemSizFlg AlignLOAD0x010000 0x00000000 0x00000000 0x026f4 0x026f4 RWE 0x10000LOAD0x020000 0x20000000 0x000026f4 0x00088 0x00334 RW0x10000LOAD0x000334 0x20000334 0x0000277c 0x00000 0x00004 RW0x10000 Section to Segment mapping:Segment Sections...00.isr_vector .text .rodata .init_array .fini_array01.data .bss02._user_heap_stack
其中LOAD0x010000 0x08000000 0x08000000 0x03ffc 0x03ffc RWE 0x10000
就是存在问题的segment, 如果要消除这个警告, 可以将ld文件中的 .init_array 和 .fini_array 这部分注释掉, 代码如下. 这部分是 startup 文件中 __libc_init_array
使用的, 如果不需要可以直接删除, 对应的编译参数也可以加上-nostartfiles
..preinit_array:{PROVIDE_HIDDEN (__preinit_array_start = .);KEEP (*(.preinit_array*))PROVIDE_HIDDEN (__preinit_array_end = .);} >FLASH.init_array :{PROVIDE_HIDDEN (__init_array_start = .);KEEP (*(SORT(.init_array.*)))KEEP (*(.init_array*))PROVIDE_HIDDEN (__init_array_end = .);} >FLASH.fini_array :{PROVIDE_HIDDEN (__fini_array_start = .);KEEP (*(SORT(.fini_array.*)))KEEP (*(.fini_array*))PROVIDE_HIDDEN (__fini_array_end = .);} >FLASH
这样编译完之后的结果如下, 第一个segment中, Flg变成了R E就没问题了.$ readelf -lW app.elf Elf file type is EXEC (Executable file)Entry point 0x1549There are 3 program headers, starting at offset 52Program Headers:TypeOffsetVirtAddrPhysAddrFileSiz MemSizFlg AlignLOAD0x010000 0x00000000 0x00000000 0x02654 0x02654 R E 0x10000LOAD0x020000 0x20000000 0x00002654 0x00088 0x00318 RW0x10000LOAD0x000318 0x20000318 0x000026dc 0x00000 0x00300 RW0x10000 Section to Segment mapping:Segment Sections...00.isr_vector .text .rodata01.data .bss02._user_heap_stack
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [s905l3]性价比神机mgv3000全网首拆,刷armbian实现更多价值!
- Qt Designer、PyUIC、PyRcc PyCharm安装PyQt5及其工具详细教程
- Jupyter notebook导入Pycharm项目的.py文件里的模块及方法
- 多少度是warm
- 多云容器编排 Karmada-Operator 实践
- marmot是什么档次的?
- arms是什么身体部位
- 华为nova 8推送HarmonyOS 3.0.0.161更新 华为note8能升级鸿蒙吗
- 关于 HarmonyOS的系列讲解 harmonyos是华为什么型号手机
- charmhoo是什么牌子轮胎?