【发布时间】:2023-01-04 22:51:15
【问题描述】:
在我开始之前,还有其他问题提到 ls -l 产生了问号,但这些是由于权限问题。这个问题是不同的。希望!
我有一个退役的 Docker 主机:
- 内核 3.10
- 泊坞窗 18.06
- glibc 2.17
- libseccomp 2.3.1
- 核心工具 8.22
我有一个 SLES 15 docker 镜像
- glibc 2.31
- 核心工具 8.32
我使用docker run -it --rm -u root <docker-image> bash启动容器
我进入的主目录有一个 bin 目录,我可以使用 ls 查看该目录,但如果我使用 ls -l,我会得到很多问号。
$ ls
bin
$ ls -l
ls: cannot access 'bin': Operation not permitted
total 0
d????????? ? ? ? ? ? bin
根据我的研究,ls 在 coreutils 8.32 及更高版本中使用 statx 系统调用。 statx 在内核 4.11 中添加到 Linux; glibc 2.28 中添加了库支持。我认为这解释了 ls -l 命令的输出——Docker 使用主机的内核,而主机的内核是 3.10,没有实现 statx。
当我在没有任何 seccomp 配置文件的情况下启动 Docker 容器时,ls -l 工作正常!
docker run -it --rm --security-opt seccomp=unconfined -u root <docker-image> bash
$ ls
bin
$ ls -l
total 0
drwxr-xr-x 2 abcuser abcuser 6 Jul 4 2022 bin
现在看来,这不是真正的内核,也不是statx 支持,但这是由于 seccomp 配置文件。但是,statx 是 whitelisted in Docker 18.04,我示例中的主机运行的是 18.06。
我确实在某处读到一条提交消息(忘记保存链接),它说如果 statx 不可用,ls 实现默认为 stat。如果是这样,ls -l 应该使用默认的 seccomp 配置文件。
谁能解释为什么 ls -l 不能使用默认的 seccomp 配置文件?另外,当底层内核没有实现 statx 时,谁能解释 ls -l 在没有 seccomp 配置文件的情况下如何工作?
我确实捕获了strace。感兴趣的部分如下。
使用默认 seccomp 配置文件的 Strace:
statx(AT_FDCWD, "bin", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW, STATX_MODE|STATX_NLINK|STATX_UID|STATX_GID|STATX_MTIME|STATX_SIZE, 0x7ffcb567a4f0) = -1 ENOSYS (Function not implemented)
ls: write(2, "ls: ", 4) = -1 ENOSYS (Function not implemented)
cannot access 'bin'write(2, "cannot access 'bin'", 19) = -1 ENOSYS (Function not implemented)
: Operation not permittedwrite(2, ": Operation not permitted", 25) = -1 ENOSYS (Function not implemented)
write(2, "\n", 1) = -1 ENOSYS (Function not implemented)
getdents64(3, 0x560b1d8ff920, 32768) = -1 ENOSYS (Function not implemented)
close(3) = -1 ENOSYS (Function not implemented)
fstat(1, 0x7ffcb567a890) = -1 ENOSYS (Function not implemented)
total 0
write(1, "total 0\n", 8) = -1 ENOSYS (Function not implemented)
openat(AT_FDCWD, "/etc/localtime", O_RDONLY|O_CLOEXEC) = -1 ENOSYS (Function not implemented)
d????????? ? ? ? ? ? bin
write(1, "d????????? ? ? ? ? ? "..., 36) = -1 ENOSYS (Function not implemented)
close(1) = -1 ENOSYS (Function not implemented)
close(2) = -1 ENOSYS (Function not implemented)
没有任何 seccomp 配置文件的 Strace:
statx(AT_FDCWD, "bin", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW, STATX_MODE|STATX_NLINK|STATX_UID|STATX_GID|STATX_MTIME|STATX_SIZE, 0x7ffec5a21b10) = -1 ENOSYS (Function not implemented)
newfstatat(AT_FDCWD, "bin", {st_mode=S_IFDIR|0755, st_size=6, ...}, AT_SYMLINK_NOFOLLOW) = 0
lgetxattr("bin", "security.selinux", 0x55d9b494d930, 255) = -1 ENODATA (No data available)
getxattr("bin", "system.posix_acl_access", NULL, 0) = -1 ENODATA (No data available)
...
<I can see a lot more calls including calls to stat multiple times but I have cut it short. >
...
正如您在 statx 调用之后所看到的,下一个调用是不同的。如果这确实是 seccomp 配置文件未列入白名单 statx 的问题,是否有办法通过在 docker 主机或容器上运行任何特定命令来找出哪些系统调用被列入白名单?我没有任何自定义 seccomp 配置文件,所以我使用的是默认配置文件。
【问题讨论】:
标签: docker glibc gnu-coreutils seccomp statx