Devtools chroot 被用戶 run 目錄污染事件

出自Arch Linux 中文社区 维护者 Wiki
跳至導覽 跳至搜尋

概況

2019年12月1日凌晨一點,lilydjwg 收到多封 lilac 的報錯。錯誤信息如下:

==> ERROR: '/var/lib/archbuild/extra-x86_64/root' does not appear to be an Arch chroot.
==> ERROR: Aborting...

隨後發現幾乎所有 lilac 包都遇到此錯誤。調查發現 /var/lib/archbuild/extra-x86_64/root 下有一個已掛載的系統 /run 目錄,裏邊包含一些用戶 run 目錄的掛載。

事故調查

根據目錄中殘留的文件確定時間戳:

1712 (archlinuxcn-build-e5) /var/lib/archbuild/extra-x86_64
### stat root
  文件:root
  大小:60              块:0          IO 块:4096   目录
设备:2dh/45d   Inode:66952       硬链接:3
权限:(0755/drwxr-xr-x)  Uid:(    0/    root)   Gid:(    0/    root)
最近访问:2019-11-30 23:43:32.647435418 +0800
最近更改:2019-11-30 23:43:11.560712233 +0800
最近改动:2019-11-30 23:43:11.560712233 +0800
创建时间:-
1713 (archlinuxcn-build-e5) /var/lib/archbuild/extra-x86_64
### stat root.lock
  文件:root.lock
  大小:0               块:0          IO 块:4096   普通空文件
设备:2dh/45d   Inode:70381120    硬链接:1
权限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
最近访问:2019-11-30 23:43:36.414112131 +0800
最近更改:2019-12-01 01:47:50.312800053 +0800
最近改动:2019-12-01 01:47:50.312800053 +0800
创建时间:-

然後分析 journalctl 日誌。

事件線

  • Nov 25 20:46:27 system boot
  • Nov 25 20:50:41 megumifox extra-x86_64-build
  • Nov 25 20:51:04 megumifox initilizing root chroot
  • Nov 25 20:51:04 a-wing run acquire
  • Nov 25 20:51:09 a-wing run release
  • Nov 25 20:51:09 root chroot release, axionl sees umount of run, others see umount of a-wing's run
  • Nov 25 22:22:34 yan12125 run release, root/run already polluted
  • Nov 30 23:42:32 dctxmei login
  • Nov 30 23:43:11 dctxmei extra-x86_64-build -c
  • Nov 30 23:43:32 dctxmei extra-x86_64-build -c

run acquire 表示用戶的 run 目錄被掛載,run release 表示被卸載。

在開機後不久,由於 /var/lib/archbuild 目錄為空,devtools 會開始建立新的 root chroot。這時剛好 a-wing 登錄,導致 run 目錄的掛載事件被擴散到 chroot 內。數天後,dctxmei 使用 -c 參數重建 root chroot 時失敗,問題顯現。

解決方案

臨時

umount -l 有問題的 run 目錄,然後 rm -r --one-file-system 刪除整個 extra-x86_64。

長期

修改 devtools-archlinuxcn 中的 mkarchroot 腳本,在調用 pacstrap 時使用 unshare 以避免系統的掛載擴散進去。

diff -Naur a/usr/bin/mkarchroot b/usr/bin/mkarchroot
--- a/usr/bin/mkarchroot        2019-11-19 16:26:19.000000000 +0800
+++ b/usr/bin/mkarchroot        2019-12-01 18:04:51.762383615 +0800
@@ -332,7 +332,7 @@
        cp "$file" "$working_dir$file"
 done
 
-pacstrap -Mcd ${pac_conf:+-C "$pac_conf"} "$working_dir" \
+unshare -m pacstrap -Mcd ${pac_conf:+-C "$pac_conf"} "$working_dir" \
        "${cache_dirs[@]/#/--cachedir=}" "$@" || die 'Failed to install all packages'
 
 printf '%s.UTF-8 UTF-8\n' en_US de_DE > "$working_dir/etc/locale.gen"

類似事故

前不久發現過一起類似的事故,由於當時 build-cleaner 清理腳本未做跨文件系統的檢查,直接導致 system D-Bus 的 socket 文件被刪除,進而計劃重啟。

  • Nov 18 21:30:10 felix run acquire
  • Nov 18 22:02:32 felix extra-x86_64-build start
  • Nov 18 22:06:20 felix extra-x86_64-build end
  • Nov 18 22:14:23 felixonmars2 run acquire
  • Nov 18 22:22:06 felix chroot release without /run
  • Nov 18 22:27:16 yan12125 run acquire
  • Nov 18 22:31:45 yan12125 run release, felixonmars2/run & felix/run already polluted
  • Nov 18 22:57   felixonmars2 chroot known broken with tmp
  • Nov 19 01:41:33 yan12125 run acquire
  • Nov 19 02:48:52 yan12125 run release
  • Nov 19 09:42:57 felixonmars2 chroot release
  • Nov 19 09:43:07 felixonmars2 logout
  • Nov 19 09:43:07 felix logout
  • Nov 19 09:43:07 felix run release
  • Nov 19 09:43:07 felixonmars2 run release
  • Nov 19 09:57    felixonmars2 chroot recovered
  • Nov 19 09:57    felix chroot known broken with /run 1053 (felixonmars3)
  • Nov 20 13:29:10 felix still has processes running
  • Nov 25 20:44:07 felixonmars3 logout

事故一開始是 felixonmars2 的 chroot 中包含已掛載的 tmp 目錄從而清理失敗。到第二天上午的時候,登出導致該 chroot 下的諸多文件系統被卸載,此 chroot 恢復正常。然而 felix chroot 依舊有問題,直接後來手工卸載。

幾個疑點:

  • felixonmars2 chroot 為什麼隔了數小時才開始卸載?此時鎖文件為什麼沒有被上鎖?是使用該 chroot 的進程有泄漏嗎?
  • felix chroot 的 run 目錄為什麼會被掛載在外面的 mount ns?除了 root chroot 之外,用戶的 chroot 應當只會通過 arch-nspawn 使用 systemd-nspawn,其掛載是私有的,也沒有看到有 bind mount /run 的地方。

外部連結

  • devtools 上游的 bug 報告:FS#64698