Bug 2124510

Summary: Check file permission command not work on aarch64 container
Product: [Fedora] Fedora Reporter: TommyLike <tommylikehu>
Component: coreutilsAssignee: Kamil Dudka <kdudka>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: low Docs Contact:
Priority: unspecified    
Version: 35CC: admiller, jamartis, jarodwilson, jkadlcik, kdudka, kzak, ooprala, ovasik, p, sebastian.kisela, svashisht
Target Milestone: ---   
Target Release: ---   
Hardware: aarch64   
OS: Other   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2022-09-28 01:33:57 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description TommyLike 2022-09-06 11:37:18 UTC
Description of problem:
Unable to check file permission with test command on aarch64 container


Version-Release number of selected component (if applicable):
For fedora 37:
```
coreutils.aarch64                         9.1-6.fc37                   @anaconda
coreutils-common.aarch64                  9.1-6.fc37                   @anaconda
```

How reproducible:
write a test.sh with content and execute
```
if [ -w "/root" ] ; then echo 'Success!' ; fi
```
We can see the success on x86 container and nothing on aarch64 container

Image we use: 
1. registry.fedoraproject.org/fedora:35
2. registry.fedoraproject.org/fedora:36
3. registry.fedoraproject.org/fedora:37

Steps to Reproduce:
1.
2.
3.

Actual results:


Expected results:


Additional info:

Comment 1 Kamil Dudka 2022-09-06 11:48:46 UTC
If you write a shell script like this, you are most likely using the `[` built-in of the shell interpreter rather than the `[` binary provided by coreutils.  Could you please provide output of strace for the command?

This could be a problem with inappropriately configured seccomp filter on the host (see bug #1900021).

Comment 2 TommyLike 2022-09-06 12:03:06 UTC
Sure, I paste the output here, the directory /root/123 exists and should have permission.



```
execve("/usr/bin/bash", ["bash", "./test.sh"], 0xffffeaa483a8 /* 11 vars */) = 0
brk(NULL)                               = 0xaaaad1dba000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xffff9fd8c000
faccessat(AT_FDCWD, "/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=7951, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 7951, PROT_READ, MAP_PRIVATE, 3, 0) = 0xffff9fd8a000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/libtinfo.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=204544, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 329912, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xffff9fd01000
mmap(0xffff9fd10000, 264376, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0xffff9fd10000
munmap(0xffff9fd01000, 61440)           = 0
munmap(0xffff9fd51000, 2232)            = 0
mprotect(0xffff9fd3d000, 61440, PROT_NONE) = 0
mmap(0xffff9fd4c000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2c000) = 0xffff9fd4c000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0\267\0\1\0\0\0Py\2\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=2250888, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 1805984, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xffff9fb57000
mmap(0xffff9fb60000, 1740448, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0xffff9fb60000
munmap(0xffff9fb57000, 36864)           = 0
munmap(0xffff9fd09000, 28320)           = 0
mprotect(0xffff9fcea000, 73728, PROT_NONE) = 0
mmap(0xffff9fcfc000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18c000) = 0xffff9fcfc000
mmap(0xffff9fd02000, 28320, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xffff9fd02000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xffff9fd88000
set_tid_address(0xffff9fd880f0)         = 117
set_robust_list(0xffff9fd88100, 24)     = 0
rseq(0xffff9fd88740, 0x20, 0, 0xd428bc00) = -1 EPERM (Operation not permitted)
mprotect(0xffff9fcfc000, 16384, PROT_READ) = 0
mprotect(0xffff9fd4c000, 16384, PROT_READ) = 0
mprotect(0xaaaac5eab000, 16384, PROT_READ) = 0
mprotect(0xffff9fd90000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
munmap(0xffff9fd8a000, 7951)            = 0
openat(AT_FDCWD, "/dev/tty", O_RDWR|O_NONBLOCK) = 3
close(3)                                = 0
getrandom("\x29\x68\x94\x33\x16\x2d\x2b\xbe", 8, GRND_NONBLOCK) = 8
brk(NULL)                               = 0xaaaad1dba000
brk(0xaaaad1ddb000)                     = 0xaaaad1ddb000
getuid()                                = 0
getgid()                                = 0
geteuid()                               = 0
getegid()                               = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
ioctl(-1, TIOCGPGRP, 0xffffcbbcea14)    = -1 EBADF (Bad file descriptor)
sysinfo({uptime=120336, loads=[32, 5280, 4064], totalram=25272201216, freeram=9367085056, sharedram=11456512, bufferram=821018624, totalswap=0, freeswap=0, procs=362, totalhigh=0, freehigh=0, mem_unit=1}) = 0
rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTART}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTART}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTART}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTSTP, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTSTP, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTTIN, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTTIN, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTTOU, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTTOU, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigaction(SIGQUIT, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
uname({sysname="Linux", nodename="25ea9bb4d815", ...}) = 0
newfstatat(AT_FDCWD, "/root", {st_mode=S_IFDIR|0550, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, ".", {st_mode=S_IFDIR|0550, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/root", {st_mode=S_IFDIR|0550, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
getpid()                                = 117
getppid()                               = 114
newfstatat(AT_FDCWD, ".", {st_mode=S_IFDIR|0550, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/root/.local/bin/bash", 0xffffcbbce628, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/root/bin/bash", 0xffffcbbce628, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/local/sbin/bash", 0xffffcbbce628, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/local/bin/bash", 0xffffcbbce628, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/sbin/bash", 0xffffcbbce628, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/bin/bash", {st_mode=S_IFREG|0755, st_size=1433752, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/bin/bash", {st_mode=S_IFREG|0755, st_size=1433752, ...}, 0) = 0
geteuid()                               = 0
getegid()                               = 0
getuid()                                = 0
getgid()                                = 0
faccessat(AT_FDCWD, "/usr/bin/bash", X_OK) = 0
newfstatat(AT_FDCWD, "/usr/bin/bash", {st_mode=S_IFREG|0755, st_size=1433752, ...}, 0) = 0
geteuid()                               = 0
getegid()                               = 0
getuid()                                = 0
getgid()                                = 0
faccessat(AT_FDCWD, "/usr/bin/bash", R_OK) = 0
newfstatat(AT_FDCWD, "/usr/bin/bash", {st_mode=S_IFREG|0755, st_size=1433752, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/bin/bash", {st_mode=S_IFREG|0755, st_size=1433752, ...}, 0) = 0
geteuid()                               = 0
getegid()                               = 0
getuid()                                = 0
getgid()                                = 0
faccessat(AT_FDCWD, "/usr/bin/bash", X_OK) = 0
newfstatat(AT_FDCWD, "/usr/bin/bash", {st_mode=S_IFREG|0755, st_size=1433752, ...}, 0) = 0
geteuid()                               = 0
getegid()                               = 0
getuid()                                = 0
getgid()                                = 0
faccessat(AT_FDCWD, "/usr/bin/bash", R_OK) = 0
newfstatat(AT_FDCWD, "/etc/nsswitch.conf", {st_mode=S_IFREG|0644, st_size=671, ...}, 0) = 0
newfstatat(AT_FDCWD, "/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=671, ...}, AT_EMPTY_PATH) = 0
read(3, "# Generated by authselect on Mon"..., 4096) = 671
read(3, "", 4096)                       = 0
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=671, ...}, AT_EMPTY_PATH) = 0
close(3)                                = 0
openat(AT_FDCWD, "/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=589, ...}, AT_EMPTY_PATH) = 0
lseek(3, 0, SEEK_SET)                   = 0
read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 589
close(3)                                = 0
getpid()                                = 117
getppid()                               = 114
getpid()                                = 117
getppid()                               = 114
getpgid(0)                              = 114
ioctl(2, TIOCGPGRP, [114])              = 0
rt_sigaction(SIGCHLD, {sa_handler=0xaaaac5da6940, sa_mask=[], sa_flags=SA_RESTART}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTART}, 8) = 0
prlimit64(0, RLIMIT_NPROC, NULL, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
openat(AT_FDCWD, "./test.sh", O_RDONLY) = 3
newfstatat(AT_FDCWD, "./test.sh", {st_mode=S_IFREG|0755, st_size=50, ...}, 0) = 0
ioctl(3, TCGETS, 0xffffcbbce9c0)        = -1 ENOTTY (Inappropriate ioctl for device)
lseek(3, 0, SEEK_CUR)                   = 0
read(3, "if [ -w \"/root/123\" ] ; then ech"..., 80) = 50
lseek(3, 0, SEEK_SET)                   = 0
prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024*1024, rlim_max=1024*1024}) = 0
fcntl(255, F_GETFD)                     = -1 EBADF (Bad file descriptor)
dup3(3, 255, 0)                         = 255
close(3)                                = 0
fcntl(255, F_SETFD, FD_CLOEXEC)         = 0
fcntl(255, F_GETFL)                     = 0x20000 (flags O_RDONLY|O_LARGEFILE)
newfstatat(255, "", {st_mode=S_IFREG|0755, st_size=50, ...}, AT_EMPTY_PATH) = 0
lseek(255, 0, SEEK_CUR)                 = 0
read(255, "if [ -w \"/root/123\" ] ; then ech"..., 50) = 50
faccessat2(AT_FDCWD, "/root/123", W_OK, AT_EACCESS) = -1 EPERM (Operation not permitted)
read(255, "", 50)                       = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
exit_group(0)                           = ?
+++ exited with 0 +++
```

Comment 3 Kamil Dudka 2022-09-26 13:03:43 UTC
Sorry for the delay, I somehow overlooked your reply.

(In reply to TommyLike from comment #2)
> faccessat2(AT_FDCWD, "/root/123", W_OK, AT_EACCESS) = -1 EPERM (Operation not permitted)

This ^^^ seems to be the culprit.  The `faccessat2` syscall returns EPERM when it should not.  This is most likely caused by an inappropriately configured seccomp filter on the host.  It should return ENOSYS for syscalls it does not know.  coreutils/bash cannot distinguish EPERM returned by the seccomp filter blocking the syscall from the actual error code returned by a working syscall.

Comment 4 TommyLike 2022-09-28 01:33:57 UTC
(In reply to Kamil Dudka from comment #3)
> Sorry for the delay, I somehow overlooked your reply.
> 
> (In reply to TommyLike from comment #2)
> > faccessat2(AT_FDCWD, "/root/123", W_OK, AT_EACCESS) = -1 EPERM (Operation not permitted)
> 
> This ^^^ seems to be the culprit.  The `faccessat2` syscall returns EPERM
> when it should not.  This is most likely caused by an inappropriately
> configured seccomp filter on the host.  It should return ENOSYS for syscalls
> it does not know.  coreutils/bash cannot distinguish EPERM returned by the
> seccomp filter blocking the syscall from the actual error code returned by a
> working syscall.

Thanks @Kamil, you are correct, It's related to the docker runtime, I upgrade the runc version and it works well, maybe it's related to this issue? https://github.com/opencontainers/runc/issues/2151

Comment 5 Kamil Dudka 2022-09-29 08:21:23 UTC
I do not know much about container technology but it seems related at first glance.  Thanks for confirmation!