1. 原因
有小伙伴反馈编译ijkplayer的so在应用市场上传时,进行的漏洞扫描会提示:未使用编译器堆栈保护技术。
通常会是libijkffmpeg.so文件报错。
这个问题的解决方案也很简单。编译的时候添加开启Stack Canaries 功能就可以了。
1.1 风险介绍
为了检测栈中的溢出引入了Stack Canaries漏洞缓解技术。在所有函数调用发生时,向栈帧内压入一个额外的被称作canary的随机数,当栈中发生溢出时canary将被首先覆盖,之后才是EBP和返回地址。在函数返回之前,系统将执行一个额外的安全验证操作,将栈帧中原先存放的canary和.data中副本的值进行比较,如果两者不吻合,说明发生了栈溢出。而如果不使用Stack Canaries栈保护技术,发生栈溢出时系统并不会对程序进行保护。
而我们提示的未使用编译器堆栈保护技术,就是说我们的so库没有使用Stack Canaries栈保护技术。我们需要主动添加该保护技术。
使用该技术的唯一缺陷就是,会增加额外栈空间,增加程序体积。
2. 解决
2.1 常见解决方法
那么解决方法也很简单。在编译的Android.mk文件中添加:
LOCAL_CFLAGS := -Wall -O2 -U_FORTIFY_SOURCE -fstack-protector- all
如果是cmake编译,在CMakeLists.txt文件中添加:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-all")
关键字段就是:-fstack-protector-all
它还有其他属性可以设置。
参数 | 作用 |
---|---|
-fstack-protector | 对alloca系列函数和内部缓冲区大于八个字节的函数启用保护 |
-fstack-protector-strong | 增加对包含局部数组定义和地址引用的函数保护 |
-fstack-protector-all | 对所有函数启用保护 |
-fstack-protecto-explicit | 对包含stack protect属性的函数启用保护 |
-fno-stack-protector | 禁用保护 |
2.2 在ijkplayer添加保护
ijkplayer编译的是三个动态库,分别为:libijkffmpeg.so
,libijksdl.so
,libijkplayer.so
而使用的脚本是通过ndk进行编译的。配置文件Android.mk。
- libijkffmpeg.so 对应的mk文件:不同处理器对应了不同的mk文件,例如:
ijkplayer/android/ijkplayer/ijkplayer-armv7a/src/main/jni/ffmpeg/Android.mk
- libijksdl.so 对应的mk文件:
ijkplayer/ijkmedia/ijksdl/Android.mk
- libijkplayer.so 对应的mk文件:
ijkplayer/ijkmedia/ijkplayer/Android.mk
我们可以直接在该配置文件中,按照:2.1 常见解决方法。进行添加就可以了。
如果找不到,可以通过命令直接搜索下项目中的Android.mk文件就可以了:通过命令: find . -name 'Android.mk'
统一搜索就可以了。
2.2.1 libijkffmpeg.so
如果只是针对libijkffmpeg.so
文件添加的话,除了上面的mk文件中的添加以外,还可以在如下的两个脚本中添加方法要高效不少哦:
1.在 config/module.sh
文件中添加:(该方案,我尝试一直会提示-O2错误 没办法。不知道是不是我写错了)
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --extra-cflags='-Wall -O2 -U_FORTIFY_SOURCE -fstack-protector-all'"
通常module.sh 是指向了module-default.sh 或者module-lite.sh 上面的配置也可以添加到这两个文件里面。
2.在ijkplayer/android/contrib/tools/do-compile-ffmpeg.sh
脚本中添加设置:-U_FORTIFY_SOURCE -fstack-protector-all
。(如果你没有这个目录,说明你本地的ffmpeg脚本还没有执行过。)
效果如下所示:
代码语言:javascript复制FF_CFLAGS="-O3 -Wall -pipe
-std=c99
-ffast-math
-fstrict-aliasing -Werror=strict-aliasing
-Wno-psabi -Wa,--noexecstack
-DANDROID -DNDEBUG -U_FORTIFY_SOURCE -fstack-protector-all"
大家可以尝试自己进行编译一下就明白了。
如果想获取编译好的,可以通过关注公众号zinyan 。 公众号留言:
ijkplayer
得到我编译好的so库。
参考链接
栈溢出保护原理——Stack Canaries :https://blog.csdn.net/weixin_62675330/article/details/123146971
ijkplayer issues 4338:https://github.com/Bilibili/ijkplayer/issues/4338