32-bit Executables Not Sleeping Inside a Docker Container

Viewed 378

Windows 10 is the host system.
Docker Desktop 3.2.2 (WSL2 integration).
WSL2 Ubuntu 20.04.

#include <unistd.h>
int main() { sleep(1); return 0; }

Compile the code three different ways:

gcc -o foobar-64 foobar.c
gcc -mx32 -o foobar-3264 foobar.c
gcc -m32 -o foobar-32 foobar.c

Everything runs fine. All executables sleep for a second.

Now try the same thing in Docker:

docker pull ubuntu:20.04
docker run --rm --interactive --tty ubuntu:20.04 bash
# then once inside: apt update && apt install build-essential g++-multilib

Do the same thing. Only the first two executables sleep properly. The "purely 32-bit executable" does not. It returns immediately.

root@f24cf548c966:~# time ./foobar-64

real    0m1.002s
user    0m0.001s
sys     0m0.000s
root@f24cf548c966:~# time ./foobar-3264

real    0m1.003s
user    0m0.002s
sys     0m0.000s
root@f24cf548c966:~# time ./foobar-32

real    0m0.001s
user    0m0.001s
sys     0m0.000s

I don't have a VM running Linux to try this out on to see if it's a WSL2 thing or not.

Any clues what's going on?

[edit]

So I figured on trying 'strace' on the program and revealed something interesting ...

outside the container:

clock_nanosleep_time64(CLOCK_REALTIME, 0, {tv_sec=1, tv_nsec=0}, 0xffd2f09c) = 0

inside the container:

clock_nanosleep_time64(CLOCK_REALTIME, 0, {tv_sec=1, tv_nsec=0}, 0xffd2339c) = -1 EPERM (Operation not permitted)

Both inside and outside the container I did verify the executable type:

foobar-32: ELF 32-bit LSB shared object, Intel 80386, ...
1 Answers

Apparently this is a Docker thing. The EPERM thing triggered some more searching and I found this

https://unix.stackexchange.com/questions/598471/docker-container-shows-sleep-cannot-read-realtime-clock-operation-not-permit

which talked about running with --privileged which did "fix" the problem but the more interesting link in that post was

https://github.com/moby/moby/commit/89fabf0f241292e929fbb2fbb794d58d8d697ab5

which talked about updates to the default seccomp to add 64-bit time_t syscalls (one of which is clock_nanosleep_time64.

Have to figure out how to make use of this information in my context (AMIs in AWS EKS) but at least this isn't something new.

Related