--userns-block-fd can hang when given a closed descriptor

未关闭 适合新手
#826 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
72/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
c, linux

调研方向

首先阅读 --userns-block-fd 的参数解析,以及 bubblewrap.c:3179-3180 附近读取并关闭所提供描述符的设置代码。检查 child_wait_fd 和 setup_finished_pipe 如何分配,然后运行 issue 中的两种复现方式。完成标准是:已关闭的描述符会报错并被拒绝,且发生在设置过程可能挂起之前。

由索引模型根据 Issue 内容生成。

描述

bubblewrap 0.13.1 accepts a closed --userns-block-fd descriptor and can reuse its number for its internal eventfd or, with --json-status-fd, its setup-completion pipe.

Both runs below hung until timeout -s KILL 20 killed them (status 137).

To reproduce:

bwrap --unshare-user --info-fd 1 --userns-block-fd 4 --ro-bind / / --proc /proc --dev /dev /bin/true 3<&- 4<&-

strace:

2865  openat(AT_FDCWD, "/proc", O_RDONLY|O_PATH) = 3
2865  eventfd2(0, EFD_CLOEXEC)          = 4
2865  clone(child_stack=NULL, flags=CLONE_NEWNS|CLONE_NEWUSER|SIGCHLD) = 2866
2866  read(4,  <unfinished ...>
2865  read(4, 0x7ffe9b5a5857, 1)        = -1 EINVAL (Invalid argument)
2865  write(4, "\1\0\0\0\0\0\0\0", 8)   = -1 EBADF (Bad file descriptor)

child_wait_fd gets descriptor 4. The parent's 1-byte read of opt_userns_block_fd fails with EINVAL. The parent closes that descriptor (bubblewrap.c:3180), which is also child_wait_fd. Its write to child_wait_fd fails with EBADF, leaving the child blocked.

With --json-status-fd:

bwrap --unshare-user --info-fd 1 --json-status-fd 2 --userns-block-fd 5 --ro-bind / / --proc /proc --dev /dev /bin/true 3<&- 4<&- 5<&- 6<&-

strace:

2939  openat(AT_FDCWD, "/proc", O_RDONLY|O_PATH) = 3
2939  eventfd2(0, EFD_CLOEXEC)          = 4
2939  pipe2([5, 6], O_CLOEXEC)          = 0
2939  clone(child_stack=NULL, flags=CLONE_NEWNS|CLONE_NEWUSER|SIGCHLD) = 2940
2940  read(4,  <unfinished ...>
2939  read(5,

opt_userns_block_fd is the read end of setup_finished_pipe (descriptor 5). The parent blocks in its read (bubblewrap.c:3179) before writing child_wait_fd. The child blocks in its read of child_wait_fd.

A patched build checks descriptors with fcntl (fd, F_GETFD) during argument parsing. Both commands returned status 1:

bwrap: Invalid fd: 4: Bad file descriptor
bwrap: Invalid fd: 5: Bad file descriptor
主要语言
C
星标
9.4k
派生
408
PR 合并指标
30 天内没有已合并 PR

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

containers/bubblewrap 的其他 Issue

查看 containers/bubblewrap 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。