从 RPM 规范文件中提取 shell 脚本以进行静态分析

Posted

技术标签:

【中文标题】从 RPM 规范文件中提取 shell 脚本以进行静态分析【英文标题】:Extracting shell scripts from an RPM spec file for static analysis 【发布时间】:2015-06-27 15:48:20 【问题描述】:

我想在嵌入在规范文件中的脚本上运行ShellCheck,该文件将在部署 RPM 的地方运行。我有 .spec sn-ps 之类的,

%setup -q
cat > ./example.sh << EOF
#!/bin/sh
echo "example"
EOF

除了钩子,

%post
#!/bin/sh
echo "Hello"

有没有办法以编程方式提取这些 shell sn-ps 以运行像 ShellCheck 这样的脚本分析工具?就像rpmbuild --save-temps 或类似的概念?还是每个脚本都需要绑定已知文本,以便我可以使用流工具(grepawksed 等)?

我有很多我不想修改的规范文件。例如检查安全相关项目的脚本等,而无需解析规范文件。搜索bison + spec 给出了错误的概念,我认为您需要解析 RPM 宏和许多其他机器;或者语法比我想象的要简单?

【问题讨论】:

【参考方案1】:

我最近也在考虑为我的一些 RPM 这样做。

您可以从规范文件本身使用 python 获取%prep、'%build'、%install 等部分。

CentOS 5 代码:

import rpm

ts = rpm.ts()

spec = ts.parseSpec("package.spec")

for section in ['build', 'clean', 'install', 'prep']:
    try:
        print '%s' % (getattr(s, section,)())
    except:
        pass

CentOS 6 代码:

import rpm

spec = rpm.spec('package.spec')

for section in ['build', 'clean', 'install', 'prep']:
    if hasattr(spec, section):
        print '%s' % (getattr(spec, section),)

似乎没有办法(在 CentOS 5 或 6 中)获取 pre/post/etc 的内容。通过 python 编写的脚本。

因此,您可能只需要使用 rpm -qp --scripts 将它们从构建的 RPM 中取出,然后将该输出拆分为临时文件并对其运行 shellcheck。

【讨论】:

spec 文件中的部分是小脚本,而不是脚本。不同之处在于,在喂入外壳之前会附加前/后部分(带有宏扩展)。保存实际脚本的最简单方法是使用宏包装 /bin/sh 调用。 然而,shellcheck 不会对改进 scriptlet 有太大帮助。大多数构建/安装 scriptlet 都太简单了,不会出错。语法检查(在 rpm5 中实现)有助于防止一些打包错误。但是 shellcheck 擅长发现的文件路径中的(比如说)空格的安全问题无法识别 %post 中的“rm -rf /”之类的严重缺陷,因为该命令的语法格式正确。 @JeffJohnson 是的,缺少宏定义可能是这里的问题。有没有办法以可靠的方式转储生成的脚本?在没有--clean 和自定义_tmppath 的情况下运行构建可能吗?而且我也同意它不会捕获太多,但它捕获的任何东西至少是一些帮助。不过,我可能也应该在答案中提到rpmlint。嗯...实际上我想知道我是否可以让rpmlint 通过 shellcheck 运行小脚本。 这是个好建议。另外,我不打算使用 shellcheck 来保证安全。 Shellscript 是一个具体的例子。主要问题是“如何提取脚本”?你可以教 shellscript 更多的安全特性或者自己写。前/后应该是简单的,并且大多数 RPM 没有它们,所以视觉审计可能是最简单的,这是一个很好的观点。此外,任何分析工具或某些外部函数都可以将%rpm_var 变量视为未知的$shell_var。语法不同,所以需要一个特殊情况,这是一个很好的观点。 提示:最简单的提取相当于“rpm -q --xml”,它提取源/二进制标头中存在的真正所见即所得的所有内容。然后使用字典或方便的数据结构在 python 中设计你想要的任何 API。您想使用 headerSprintf 的绑定进行提取(这是扩展 popt 别名时使用 --xml 完成的所有操作)

以上是关于从 RPM 规范文件中提取 shell 脚本以进行静态分析的主要内容,如果未能解决你的问题,请参考以下文章

编写 shell 脚本以提取日志文件的最后 24 小时:Raspbian on Pi

用于从文本文件中提取数据的 Shell 脚本

使用 shell 脚本提取 package.json 版本

Shell编程规范与变量

用于从文本日志文件中提取/检索值的 Shell 脚本(sqlcode 字段值)

使用bash shell脚本从文件中查找和提取特定字符串后的值?