cdockerarmalpine-linuxmusl

Issues with time() when running a C musl application in docker container on arm


My application is unable to handle time operations like time(2) when it runs in alpine docker container on an arm device.

What I have: I am building a native c application which is statically linked to musl with toolchain from musl.cc (arm-linux-musleabihf-gcc). I am using latest alpine container (without image tag).

How it behaves:

What's going wrong:

However, if I execute date in container's ash the output is valid. Thus, there seems to be a problem that only occurs in alpine containers on the ARM architecture. Funnily enough, I'm switching from Ubuntu to Alpine as we had similar problems there.

Does anyone have any idea what I am doing wrong?

Update #1: Same problem on ubuntu. So the problem seems to be on any docker basis image but only on arm devices.

Update #2: Here is a minimal example TimeTest.c

#include <stdio.h>
#include <string.h>
#include "time.h"
#include "errno.h"

int main()
{
    printf("hallo\n");

    time_t myTime;
    time_t result = time(&myTime);

    printf("result: %lld\n", result);

    if ((long)result < 0)
    {
        printf("time() error=%d: %s\n", errno, strerror(errno));
    }
    else
    {
        struct tm* tm_info = localtime(&myTime);
        printf("Current local time and date: %s\n", asctime(tm_info));
    }

    return 0;
}

CMakeLists.txt

cmake_minimum_required (VERSION 3.8)
project ("TimeTest")
if(BUILD_TARGET STREQUAL "ARM_MUSL")
    set(CMAKE_SYSTEM_PROCESSOR arm)
    set(CMAKE_C_COMPILER /usr/bin/arm-linux-musleabi-gcc)
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-stack-protector -mfloat-abi=softfp -static --static")
    set(CMAKE_LINK_SEARCH_END_STATIC TRUE)
endif()
add_executable (TimeTest "TimeTest.c")

Output on arm device

pi@raspberrypi:/tmp $ docker run --rm -it -v /tmp/TimeTest:/TimeTest alpine ash
/ # /TimeTest
hallo
result: -4696377169665647048
time() error=1: Operation not permitted

Solution

  • I am able to reproduce this exactly as described in the question. On my particular ARM hardware:

    $ docker --version
    Docker version 19.03.6, build 369ce74a3c [released approx. 2020-02-12]
    
    $ file demo
    demo: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV),
    statically linked, with debug_info, not stripped
    

    Using strace we can observe this behavior inside a container launched as reported:

    ...
    clock_gettime64(CLOCK_REALTIME, 0xbe9c5e10) = -1 EPERM (Operation not permitted)
    ...
    

    However, if we add the --privileged flag to the Docker command, it works:

    # ./demo
    hallo
    result: 1608983884
    Current local time and date: Sat Dec 26 11:58:04 2020
    

    This behavior is caused by a Docker issue: https://gitlab.alpinelinux.org/alpine/aports/-/issues/11774, which is fixed in this commit and rolled into Docker version 19.03.12 (?) and up.