Red Hat Training
A Red Hat training course is available for RHEL 8
4.9. Annobin 项目
Annobin 项目是 Watermark 规范项目的实施。水印规范项目旨在向可执行文件和可链接格式(ELF)对象添加标记以确定其属性。Annobin 项目由 annobin
插件和 annockeck
程序组成。
annobin
插件扫描 GNU Compiler Collection(GCC)命令行、编译状态和编译过程,并生成 ELF 注释。ELF 注释记录了二进制文件的构建方式,并为 annocheck
程序提供信息,以执行安全强化检查。
安全强化检查器是 annocheck
程序的一部分,默认启用。它检查二进制文件,以确定是否使用必要的安全强化选项构建程序并正确编译。nocheck
能够递归扫描 ELF 对象文件的目录、存档和 RPM 软件包。
文件必须采用 ELF 格式。anocheck
不会处理任何其他二进制文件类型。
下面的部分描述了如何:
-
使用
annobin
插件 -
使用
annocheck
程序 -
删除冗余
annobin
备注
4.9.1. 使用 annobin 插件
下面的部分描述了如何:
-
启用
annobin
插件 -
将选项传递给
annobin
插件
4.9.1.1. 启用 annobin 插件
下面的部分论述了如何通过 gcc
和 clang
启用 annobin
插件。
流程
要启用带有
gcc
的annobin
插件,请使用:$ gcc -fplugin=annobin
如果
gcc
找不到annobin
插件,请使用:$ gcc -iplugindir=/path/to/directory/containing/annobin/
将 /path/to/directory/containing/annobin/ 替换为包含
annobin
的目录的绝对路径。要查找包含
annobin
插件的目录,请使用:$ gcc --print-file-name=plugin
要启用带有
clang
的annobin
插件,请使用:$ clang -fplugin=/path/to/directory/containing/annobin/
将 /path/to/directory/containing/annobin/ 替换为包含
annobin
的目录的绝对路径。
4.9.1.2. 将选项传递给 annobin 插件
下面的部分论述了如何通过 gcc
和 clang
将选项传递给 annobin
插件。
流程
要使用
gcc
将选项传递给annobin
插件,请使用:$ gcc -fplugin=annobin -fplugin-arg-annobin-option file-name
将 选项 替换为
annobin
命令行参数,并使用文件名称替换 file-name。示例
要显示关于它的
annobin
用途的附加详情,请使用:$ gcc -fplugin=annobin -fplugin-arg-annobin-verbose file-name
用文件名替换 file-name。
要使用
clang
将选项传递给annobin
插件,请使用:$ clang -fplugin=/path/to/directory/containing/annobin/ -Xclang -plugin-arg-annobin -Xclang option file-name
使用
annobin
命令行参数替换 选项,并将 /path/to/directory/containing/annobin/ 替换为包含annobin
的目录的绝对路径。示例
要显示关于它的
annobin
用途的附加详情,请使用:$ clang -fplugin=/usr/lib64/clang/10/lib/annobin.so -Xclang -plugin-arg-annobin -Xclang verbose file-name
用文件名替换 file-name。
4.9.2. 使用 annocheck 程序
下面的部分论述了如何使用 annocheck
检查:
- 文件
- 目录
- RPM 软件包
-
annocheck
额外工具
无检查会以
递归方式扫描 ELF 对象文件的目录、存档和 RPM 软件包。文件必须采用 ELF 格式。ano check
不会处理任何其他二进制文件类型。
4.9.2.1. 使用 annocheck 检查文件
下面的部分论述了如何使用 annocheck
检查 ELF 文件。
流程
要检查文件,请使用:
$ annocheck file-name
使用 文件的名称替换 file-name。
文件必须采用 ELF 格式。anocheck
不会处理任何其他二进制文件类型。nocheck
进程包含 ELF 对象文件的静态库。
其他信息
-
有关
annocheck
和可能的命令行选项的详情,请查看annocheck
man page。
4.9.2.2. 使用 annocheck 检查目录
下面的部分论述了如何使用 annocheck
检查目录中的 ELF 文件。
流程
要扫描目录,请使用:
$ annocheck directory-name
使用目录名称替换 directory-name。
annocheck 自动检查
目录的内容、其子目录以及 目录中的任何存档和 RPM 包。
annocheck
只查找 ELF 文件。忽略其他文件类型。
其他信息
-
有关
annocheck
和可能的命令行选项的详情,请查看annocheck
man page。
4.9.2.3. 使用 annocheck 检查 RPM 软件包
下面的部分论述了如何使用 annocheck
检查 RPM 软件包中的 ELF 文件。
流程
要扫描 RPM 软件包,请使用:
$ annocheck rpm-package-name
使用 RPM 软件包的名称替换 rpm-package-name。
不检查
以递归方式扫描 RPM 软件包中的所有 ELF 文件。
annocheck
只查找 ELF 文件。忽略其他文件类型。
要使用提供的 debug info RPM 扫描 RPM 软件包,请使用:
$ annocheck rpm-package-name --debug-rpm debuginfo-rpm
使用 RPM 软件包的名称替换 rpm-package-name,使用与二进制 RPM 关联的调试信息 RPM 名称替换 debuginfo-rpm。
其他信息
-
有关
annocheck
和可能的命令行选项的详情,请查看annocheck
man page。
4.9.2.4. 使用 annocheck 额外工具
annocheck
包含用于检查二进制文件的多个工具。您可以通过 命令行选项启用这些工具。
下面的部分论述了如何启用:
-
内置
工具 -
备注
工具 -
section-size
工具
您可以同时启用多个工具。
默认启用强化检查器。
4.9.2.4.1. 通过工具 启用构建
您可以使用 annocheck
build-by
工具查找构建二进制文件的编译器的名称。
流程
要启用
内置的工具,
请使用:$ annocheck --enable-built-by
其他信息
-
有关
内置工具
的更多信息,请参阅--help
命令行选项。
4.9.2.4.2. 启用 备注
工具
您可以使用 annocheck
备注
工具显示由 annobin
插件创建的二进制文件内存储的注释。
流程
要启用
备注
工具,请使用:$ annocheck --enable-notes
备注按地址范围排序的顺序显示。
其他信息
-
有关
备注
工具的详情请参考--help
命令行选项。
4.9.2.4.3. 启用 section-size
工具
您可以使用 annocheck
部分-size
工具显示指定部分的大小。
流程
要启用
section-size
工具,请使用:$ annocheck --section-size=name
使用 named 部分的名称替换 name。输出仅限于特定的部分。最终产生累计结果。
其他信息
-
有关
section-size
工具的详情请参考--help
命令行选项。
4.9.2.4.4. 强化检查器基础知识
默认启用强化检查器。您可以使用 --disable-hardened 命令行选项禁用强化
检查程序。
4.9.2.4.4.1. 强化检查器选项
annocheck
程序检查以下选项:
-
lazy binding 被禁用,使用
-z now
linker 选项。 - 程序没有可执行的内存区域中的堆栈。
- GOT 表的重新定位设置为只读。
- 没有程序段设置全部三个读取、写入和执行权限位。
- 没有针对可执行代码的重新定位。
- 在运行时查找共享库的 runpath 信息仅包含根于 /usr 的目录。
-
程序在启用了
annobin
注释的情况下被编译。 -
该程序编译时启用了
-fstack-protector-strong
选项。 -
该程序使用
-D_FORTIFY_SOURCE=2
进行编译。 -
该程序使用
-D_GLIBCXX_ASSERTIONS
进行编译。 -
该程序编译时已启用
-f 例外
。 -
该程序编译时
启用了 -fstack-clash-protection
。 -
该程序编译为
-O2
或更高版本。 - 该程序没有任何可写位置的重新定位。
- 动态可执行文件具有动态分段。
-
共享库使用
-fPIC 或
-fPIE
进行编译。 -
使用
-fPIE
编译动态可执行文件并链接到-pie
。 -
如果可用,则使用
-fcf-protection=full
选项。 -
如果可用,则使用
-mbranch-
protection 选项。 -
如果可用,则使用
-mstackrealign
选项。
4.9.2.4.4.2. 禁用强化检查程序
下面的部分论述了如何禁用强化检查器。
流程
要在没有强化检查器的文件中扫描备注,请使用:
$ annocheck --enable-notes --disable-hardened file-name
使用 文件的名称替换 file-name。
4.9.3. 删除冗余 annobin 备注
使用 annobin
会增加二进制文件的大小。要减少使用 an nobin 编译的二进制文件的大小,
您可以删除冗余 annobin
备注。要删除冗余的 annobin
注释,请使用 objcopy
程序,该程序是 binutils
软件包的一部分。
流程
要删除冗余的
annobin
备注,请使用:$ objcopy --merge-notes file-name
用文件名替换 file-name。
4.9.4. GCC Toolset 12 中 annobin 的细节
在某些情况下,由于 GCC Toolset 12 中的 annobin
和 gcc
之间的同步问题,您的编译可能会失败,并显示类似如下的错误消息:
cc1: fatal error: inaccessible plugin file
opt/rh/gcc-toolset-12/root/usr/lib/gcc/architecture-linux-gnu/12/plugin/gcc-annobin.so
expanded from short plugin name gcc-annobin: No such file or directory
要临时解决这个问题,请从 annobin.so
文件中创建一个符号链接到 gcc-annobin.so
文件中:
# cd /opt/rh/gcc-toolset-12/root/usr/lib/gcc/architecture-linux-gnu/12/plugin
# ln -s annobin.so gcc-annobin.so
使用您系统中使用的构架替换 architecture :
-
aarch64
-
i686
-
ppc64le
-
s390x
-
x86_64