Systemd-swap: 最近在一些基于 ARM 的系统上添加 SystemCallFilters 的问题

创建于 2020-06-30  ·  16评论  ·  资料来源: Nefelim4ag/systemd-swap

你好!

我在几台带有 ArchLinuxARM 的单板计算机(Raspberry Pi 设备和 Odroid XU4 - 均基于 ARMv7)上使用systemd-swap

最近对hasgedsystemd-swap 的软件包更新导致失败和核心转储。 相同版本的包更新在 x64 ArchLinux 系统上没有问题。

systemd-swap 4.2.x 为 shell 脚本调用的各种二进制文件生成转储,最终没有配置 zswap/zram。 这里有很多垃圾:

TIME                            PID   UID   GID SIG COREFILE  EXE
Tue 2020-06-27 12:40:15 MDT     269     0     0  31 present   /usr/bin/sort
Tue 2020-06-27 12:40:18 MDT     378     0     0  31 present   /usr/bin/mkswap
Tue 2020-06-27 12:40:21 MDT     512     0     0  31 present   /usr/bin/mkswap
Tue 2020-06-27 12:40:23 MDT     553     0     0  31 present   /usr/bin/mkswap
Tue 2020-06-27 12:40:25 MDT     591     0     0  31 present   /usr/bin/mkswap
Tue 2020-06-27 12:40:28 MDT     617     0     0  31 present   /usr/bin/mkswap
Tue 2020-06-27 12:40:30 MDT     643     0     0  31 present   /usr/bin/mkswap
Tue 2020-06-27 12:40:32 MDT     671     0     0  31 present   /usr/bin/mkswap
Tue 2020-06-27 12:40:34 MDT     708     0     0  31 present   /usr/bin/mkswap
Tue 2020-06-27 12:40:36 MDT     739     0     0  31 present   /usr/bin/blkid

在 archlinuxarm.org 论坛上找到了特定于 hasged 软件包的线程:

https://archlinuxarm.org/forum/viewtopic.php?f=15&t=14549

hasged 的​​问题可以追溯到在 systemd 服务中添加了几个 SystemCallFilters。 这里有 github 问题:

https://github.com/jirka-h/haveged/issues/41

已经推送了一个更新,对其服务文件中的SystemCallFilterSystemCallErrorNumber设置进行了一些小的调整。 现在一切都在 ARMv7(以及 x64)板上运行良好。

我最终为 systemd-swap 添加了 systemd 服务覆盖以添加SystemCallErrorNumber=EPERM 。 类似于为 hasged 实现的内容... systemd-swap.service 文件中的其他所有内容都保持不变。

[Service]
SystemCallErrorNumber=EPERM

添加那 1 行 - systemd-swap 4.2.3 再次工作。 没有更多的核心转储!

我想在这里发布一个问题,希望您可以考虑将SystemCallErrorNumber=EPERM添加到上游服务文件中。 它可以帮助非 x64 系统的用户。

完全理解这是否对您不感兴趣……它与使用覆盖一样容易。

谢谢你。

所有16条评论

有趣的是,您的更改实际上并没有解决根本问题(据我所知),它只会使得如果systemd-swap执行不在SystemCallFilter白名单上的内容,它会出错而不是终止过程。

我很想知道是什么系统调用导致了这个错误并将其添加到白名单中。:thinking:
您可以...吗:

  1. 看看删除SystemCallArchitectures=native解决问题?
  2. systemd-swap行添加一个x以便它读取set -xuo pipefail然后再试一次? (并提供完整的日志(尽管它们可能太长而无法在评论中上传,因此您可能需要使用粘贴箱))。

不幸的是,我只拥有 x86 硬件,所以我无法自己测试。

是的,这也是我的看法。 添加SystemCallErrorNumber=EPERM只会返回错误,不会立即终止进程。 也许不理想 - 我明白。

在将脚本中的第 3 行更改为set -xuo pipefail后,我在 Odroid-XU4 上粘贴了三个测试: https ://pastebin.com/UZk74aKx

测试 1 - 删除 SystemCallArchitectures=native。 来自 sort 和 mkswap 的相同故障/核心转储
测试 2 - 使用来自 systemd-swap 4.2.3 的未修改的 systemd-swap.service 文件运行。 相同的故障/核心转储。
测试 3 - 重新添加 SystemCallErrorNumber=EPERM... 当然,工作正常。

所有 3 个测试都包含在同一个 pastebin 中。 搜索“测试”以找到每一个。

如果还有什么我可以测试或尝试的,我很乐意提供帮助。

您可以尝试使用SystemCallFilter=@system-service <strong i="5">@swap</strong> <strong i="6">@module</strong> uname和其他所有未修改的内容吗?

如果这导致崩溃,请提供 mkswap 的堆栈跟踪。 它应该在崩溃后立即出现在日志中。 或者,您可以使用 gdb 使用gdb -c <dumped core>thread apply all bt full类的东西通过转储的核心获得它。

您还可以尝试使用瞬态单元获得最小的再现器,这可能更便于调试:

dd if=/dev/zero of=test count=32 bs=1M
sudo systemd-run -t -d -p Type=exec -p "SystemCallFilter=@system-service <strong i="13">@swap</strong> @module" -p SystemCallArchitectures=native mkswap test`

我无法在 AArch64/ARM64、ARMv8 上重现。

不幸的是,将unameSystemCallFilter仍然会导致转储。 :( 有关堆栈跟踪,请参见下文。不幸的是,没有符号。

FWIW,我确实运行zswap_enabled=0zram_enabled=1 - 没有实际的交换分区,所以我只使用 zram 作为交换。

我有一个 Odroid-N2 也运行 archlinuxarm,它的设置与 Odroid-XU4 和 Pi3 基本相同。 不过我没有在 N2 上使用 systemd-swap。 为了看看会发生什么,我在 N2 上安装了带有“stock”服务文件的 systemd-swap。 我像在 XU4 上一样禁用了 zswap 并启用了 zram。 在 N2 上运行良好 - 没有核心转储。 N2 是 ARMv8/aarch64。 XU4/Pi3 都是 ARMv7。 和你一样,我也不能在 ARMv8/aarch64 上重现。

我可能会为旧的 Pi3 挖出另一张 SD 卡,然后尝试使用 Raspbian(或???)而不是 archlinuxarm。 也许这是他们的 ARMv7 版本的一些奇怪的 archlinuxarm 特定问题?

仍然很乐意尝试任何其他建议……但如果您没有想法,请完全理解。

Jul 01 20:20:59 xu4 systemd-swap[256]: /usr/bin/systemd-swap: line 52: 
   335 Bad system call         (core dumped) mkswap "${zram_dev}" &> /dev/null
Jul 01 20:20:59 xu4 systemd-swap[256]: + systemctl daemon-reload
Jul 01 20:21:00 xu4 systemd-coredump[338]: Process 335 (mkswap) of user 0 dumped core.

                                           Stack trace of thread 335:
                                           #0  0x00000000b6e04e58 posix_fadvise64 (libc.so.6 + 0xd2e58)


           PID: 335 (mkswap)
           UID: 0 (root)
           GID: 0 (root)
        Signal: 31 (SYS)
     Timestamp: Wed 2020-07-01 20:20:59 MDT (18min ago)
  Command Line: mkswap /dev/zram0
    Executable: /usr/bin/mkswap
 Control Group: /system.slice/systemd-swap.service
          Unit: systemd-swap.service
         Slice: system.slice
       Boot ID: 734e377074d04e70a5da783259d3fb10
    Machine ID: b16181464c2c4ea7adb0a759515a8a9a
      Hostname: xu4
       Storage: /var/lib/systemd/coredump/core.mkswap.0.734e3770[...]00.lz4
       Message: Process 335 (mkswap) of user 0 dumped core.

                Stack trace of thread 335:
                #0  0x00000000b6e04e58 posix_fadvise64 (libc.so.6 + 0xd2e58)



Thread 1 (LWP 335):
#0  0xb6e04e58 in posix_fadvise64 () from /usr/lib/libc.so.6
No symbol table info available.
#1  0xb6e8fe68 in blkid_probe_set_device () from /usr/lib/libblkid.so.1
No symbol table info available.
#2  0x00000000 in ?? ()
No symbol table info available.
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
quit

也许这是他们的 ARMv7 版本的一些奇怪的 archlinuxarm 特定问题?

它可能。

@system-service应该已经包含fadvise64系统调用,所以如果他们没有修改 systemd 的系统调用组并将其删除(参见systemd-analyze syscall-filter @system-service ),它不应该尝试将其列入白名单的任何区别,但如果您还没有,您可以尝试。
这当然是假设它总是在那个确切的系统调用上崩溃。

由于它似乎与systemd-swap没有直接关系,并且由于 systemd 文档实际上建议添加SystemCallErrorNumber=EPERM ,因此我认为应该将其添加到服务单元中。

如果您可以获得调试标志并在此处发布核心转储,以便我们可以看到mkswap哪个函数导致错误,那就太好了。

我仍然偏爱仅添加SystemCallErrorNumber=EPERM的原始解决方案 - 哈哈哈。 所以我很高兴你已经做到了。 非常感激! 为将来的版本保存 systemd 服务覆盖。 👍

我也有点好奇它为什么在 ARMv7 设备上进行核心转储。 它不仅是mkswap ,还有sortblkid 。 我要拿一对旧的 ARMv7 R-Pis 并进行 ArchlinuxARM 和 Raspian/Debian 的全新/当前安装。 将用systemd-swap测试两者,看看问题是否在两个操作系统中都出现。 会看看我是否能得到更多结实的转储。

虽然不存在调试符号,但由于动态符号表,我们仍然知道在崩溃之前调用了哪些函数。

mkswap调用blkid_probe_set_device调用posix_fadvise (系统调用的一个薄包装)来禁用内核执行的预读。

据我所知,所有提到的崩溃实用程序都以一种或另一种方式使用fadvise64系统调用。

我仍然有一些问题可以在没有调试符号/全新安装的情况下回答:

  • 我想查看mkswap (是否类似?)、 sortblkid的其他一些堆栈跟踪。
  • 它们会在所有调用中崩溃吗?
  • 如我之前的帖子中提到的那样,使用瞬态单元独立调用它们的结果是什么?
  • fadvise64列入白名单有帮助吗?

是的, mkswapsortblkid每次都会崩溃 - 总是有指向posix_fadvise64的堆栈跟踪。 mkswap 瞬态单元测试也是如此。

我验证了fadvise64 (和 fadvise64_64)都在默认的@system-service systemd 系统调用过滤器列表中。 将其列入白名单没有任何区别。 :(

还对新的 Raspbian 安装进行了快速测试,结果相同......所以看起来它不是 ArchlinuxARM 特定的问题。

在 systemd 和任何系统调用过滤器之外运行strace mkswap temp没有问题——正如您所期望的:

fadvise64_64(3, 0, 0, POSIX_FADV_RANDOM) = 0

运行strace mkswap temp通过systemd(您瞬时单位修改-好主意!)与@system-service <strong i="19">@swap</strong> <strong i="20">@module</strong> @debug所有列入白名单显示systemd在fadvise64_64呼叫植草权利过程:

fadvise64_64(3, 0, 0, POSIX_FADV_RANDOM) = ?
+++ killed by SIGSYS (core dumped) +++

我正处于弄清楚发生了什么的知识/能力的最后阶段。 😄

谢谢。

这听起来像是 ARMv7 上的一些 systemd/seccomp 怪异之处。

如果您让 systemd 为不相关的系统调用安装 seccomp 过滤器(例如来自 @过时或@通过像SystemCallFilter=~ptrace这样的黑名单进行调试,它会崩溃吗?

除此之外,我不知道任何其他方法可以在不深入细节的情况下进一步调试。 我认为最好的做法是将此报告给 systemd 维护者/开发人员。

除非将SystemCallErrorNumber=EPERM也添加到服务中,否则将不相关的内容列入黑名单仍会导致崩溃。

...但正如您所提到的,这似乎是 ARMv7 的一些奇怪的 systemd/seccomp 问题。

作为我自己好奇心的另一项测试,我使用以下 SystemCall* 设置编辑了systemd-swap.service

SystemCallArchitectures=native
SystemCallFilter=@system-service <strong i="10">@swap</strong> <strong i="11">@module</strong>
SystemCallFilter=~finit_module
SystemCallErrorNumber=EPERM

我专门列入黑名单finit_module -所以zram模块应该无法负荷。

在运行 ArchlinuxARM w/systemd 245.6 的 Odroid-N2 (aarch64) 上,它如您所料失败了 - 无法加载zram模块。 有或没有SystemCallErrorNumber=EPERM一切看起来在 N2/aar​​ch64 和 seccomp 上正常工作。

Jul 02 19:08:26 n2 systemd[1]: Starting Manage swap spaces on zram, files and partitions....
Jul 02 19:08:27 n2 systemd-swap[3924]: INFO: Load: /etc/systemd/swap.conf
Jul 02 19:08:27 n2 systemd-swap[3924]: WARN: Combining zram with zswap/swapfc/swapd_auto_swapon [...]
Jul 02 19:08:27 n2 systemd-swap[3924]: INFO: Zram: check availability
Jul 02 19:08:27 n2 systemd-swap[3924]: INFO: Zram: not part of kernel, trying to find zram module
Jul 02 19:08:27 n2 systemd-swap[3963]: modprobe: ERROR: could not insert 'zram': Operation not permitted
Jul 02 19:08:27 n2 systemd[1]: Started Manage swap spaces on zram, files and partitions..
Jul 02 19:08:28 n2 systemd-swap[4040]: modprobe: ERROR: could not insert 'zram': Operation not permitted
Jul 02 19:08:29 n2 systemd-swap[4042]: modprobe: ERROR: could not insert 'zram': Operation not permitted
Jul 02 19:08:30 n2 systemd-swap[4043]: modprobe: ERROR: could not insert 'zram': Operation not permitted
Jul 02 19:08:31 n2 systemd-swap[4044]: modprobe: ERROR: could not insert 'zram': Operation not permitted
Jul 02 19:08:49 n2 systemd-swap[4052]: modprobe: ERROR: could not insert 'zram': Operation not permitted
Jul 02 19:08:50 n2 systemd-swap[4053]: modprobe: ERROR: could not insert 'zram': Operation not permitted
Jul 02 19:08:51 n2 systemd-swap[4054]: modprobe: ERROR: could not insert 'zram': Operation not permitted
Jul 02 19:08:52 n2 systemd-swap[4056]: modprobe: ERROR: could not insert 'zram': Operation not permitted
Jul 02 19:08:53 n2 systemd-swap[4057]: modprobe: ERROR: could not insert 'zram': Operation not permitted
Jul 02 19:08:54 n2 systemd-swap[3924]: INFO: Zram: module successfully loaded
Jul 02 19:08:54 n2 systemd-swap[3924]: INFO: Zram: trying to initialize free device
Jul 02 19:08:54 n2 systemd-swap[3924]: WARN: Zram: zramctl can't find free device
Jul 02 19:08:54 n2 systemd-swap[3924]: INFO: Zram: using workaround hook for hot add
Jul 02 19:08:54 n2 systemd-swap[3924]: ERRO: Zram: this kernel does not support hot adding zram devices [...]
Jul 02 19:08:54 n2 systemd[1]: systemd-swap.service: Main process exited, code=exited, status=1/FAILURE
Jul 02 19:08:54 n2 systemd[1]: systemd-swap.service: Failed with result 'exit-code'.

在一个古老的 Pi2 (armv7l) 上也运行 ArchlinuxARM w/systemd 245.6 它不会失败! zram模块加载没有问题,即使由于黑名单应该不可能。

Jul 02 19:14:07 alarmpi systemd[1]: Starting Manage swap spaces on zram, files and partitions....
Jul 02 19:14:08 alarmpi systemd-swap[299]: INFO: Load: /etc/systemd/swap.conf
Jul 02 19:14:08 alarmpi systemd[1]: Started Manage swap spaces on zram, files and partitions..
Jul 02 19:14:08 alarmpi systemd-swap[299]: WARN: Combining zram with zswap/swapfc/swapd_auto_swapon [...]
Jul 02 19:14:08 alarmpi systemd-swap[299]: INFO: Zram: check availability
Jul 02 19:14:08 alarmpi systemd-swap[299]: INFO: Zram: not part of kernel, trying to find zram module
Jul 02 19:14:09 alarmpi systemd-swap[299]: INFO: Zram: module successfully loaded
Jul 02 19:14:10 alarmpi systemd-swap[299]: INFO: Zram: trying to initialize free device
Jul 02 19:14:10 alarmpi systemd-swap[299]: INFO: Zram: initialized: /dev/zram0
Jul 02 19:14:12 alarmpi systemd-swap[299]: INFO: Zram: trying to initialize free device
Jul 02 19:14:13 alarmpi systemd-swap[299]: INFO: Zram: initialized: /dev/zram0
Jul 02 19:14:14 alarmpi systemd-swap[299]: INFO: Zram: trying to initialize free device
Jul 02 19:14:14 alarmpi systemd-swap[299]: INFO: Zram: initialized: /dev/zram1
Jul 02 19:14:16 alarmpi systemd-swap[299]: INFO: Zram: trying to initialize free device
Jul 02 19:14:16 alarmpi systemd-swap[299]: INFO: Zram: initialized: /dev/zram2
Jul 02 19:14:17 alarmpi systemd-swap[299]: INFO: swapD: pickup devices from systemd-gpt-auto-generator
Jul 02 19:14:17 alarmpi systemd-swap[299]: INFO: swapD: searching swap devices

像SystemCallFilter /东东的Seccomp看起来坏/忽略armv7l设备上......绝对核心转储,除非SystemCallErrorNumber=EPERM的。服务文件也被配置。 使用相同的 Pi2 和 Raspbian(与 ArchlinuxARM)进行的非常简短的测试显示了相同的问题。 在 Odroid-XU4(也是 armv7l)上 - 同样的问题。

所以我很感激你添加了SystemCallErrorNumber=EPERM因为它似乎不会在其他平台上引起任何问题,并且神奇地修复了 armv7l 上严重损坏的情况。 👍 我会多做一点谷歌搜索/阅读/测试。 如果我可以用一些证据和/或证据写出一些听起来并不荒谬的东西,我可能会向 systemd 人员提交一个问题,看看他们可能会提出什么建议。 😄

感谢您的帮助和耐心! 谢谢你。

除非将SystemCallErrorNumber=EPERM也添加到服务中,否则将不相关的内容列入黑名单仍会导致崩溃。

...但正如您所提到的,这似乎是 ARMv7 的一些奇怪的 systemd/seccomp 问题。

是的,这就是我试图通过将无关呼叫列入黑名单而不过滤任何其他内容来测试的内容。

SystemCallErrorNumber=EPERM只是将EPERM返回给违规进程,而不是发送SIGSYS并因此转储核心。

我想这可能会引入一些未定义的行为,如果进程依赖于系统调用来运行并且不检查是否成功。 所以我会称这是一种解决方法,而不是解决方案。

下一步可能是启用 systemd 调试,因为您的黑名单测试显示有问题。

https://freedesktop.org/wiki/Software/systemd/Debugging/

祝你好运。

我想这是作为 ArchlinuxARM 错误关闭的? 它是否也会影响其他发行版?

无论发行版如何,都应该影响 ARM 平台。

它是硬件的东西还是 linux 的东西?

Linux 的问题,问题是我们的服务加固依赖于 systemd 的白名单,该白名单为某些 ARM 系统调用配置错误,因此虽然系统调用应该被允许,但它们不是。

此页面是否有帮助?
0 / 5 - 0 等级