• Bug#874798: libc6: mktime() does not set errno when it fails

    From g1@21:1/5 to All on Sat Sep 9 20:40:01 2017
    XPost: linux.debian.bugs.dist

    Package: libc6
    Version: 2.24-11+deb9u1
    Severity: normal
    Tags: upstream

    When mktime() fails to convert a struct tm to a time_t, it returns -1.
    It should also set errno to EOVERFLOW in order to distinguish the failure
    from the legitimate case of converting "1 second before the epoch".

    The following program, when run on a 32-bit system, shows that mktime
    does not comply to the standard. On recent amd64 systems, time_t is 64
    bit long, therefore failure doesn't occur for the same broken down times.

    Best regards,
    g.b.

    #define _POSIX_C_SOURCE 200112L

    #include <stdio.h>
    #include <time.h>
    #include <assert.h>
    #include <errno.h>
    #include <stdlib.h>

    int main() {
    struct tm tm0;
    struct tm *ptm;
    time_t t;
    int eno;

    assert(sizeof t == 4); /* need 32 bit to trigger failure in 1900 */

    /* nail timezone to UTC */
    setenv("TZ", "UTC", 1);
    tzset();

    t = -1; /* 1 sec before epoch */
    ptm = gmtime_r(&t, &tm0);
    assert(ptm != NULL);
    errno = 0;
    t = mktime(&tm0);
    eno = errno;
    printf("struct TM: %d-%d-%d %02d:%02d:%02d (dst=%d)\n", 1900 + tm0.tm_year,
    1 + tm0.tm_mon, tm0.tm_mday, tm0.tm_hour, tm0.tm_min,
    tm0.tm_sec, tm0.tm_isdst);
    printf("mktime(): retval %ld (expected -1), "
    "errno %d (expected 0)\n", (long) t, eno);

    tm0.tm_year = 0; /* warp to year 1900 */
    /* bad conversion for 32-bit time_t, should return -1 and set errno */
    errno = 0;
    t = mktime(&tm0);
    eno = errno;
    printf("struct TM: %d-%d-%d %02d:%02d:%02d (dst=%d)\n", 1900 + tm0.tm_year,
    1 + tm0.tm_mon, tm0.tm_mday, tm0.tm_hour, tm0.tm_min,
    tm0.tm_sec, tm0.tm_isdst);
    printf("mktime(): retval %ld (expected -1), "
    "errno %d (expected EOVERFLOW=%d)\n", (long) t, eno, EOVERFLOW);
    return 0;
    }


    -- System Information:
    Debian Release: 9.1
    APT prefers stable
    APT policy: (500, 'stable')
    Architecture: i386 (i686)

    Kernel: Linux 4.9.0-3-686 (SMP w/1 CPU core)
    Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US.UTF-8 (charmap=UTF-8)
    Shell: /bin/sh linked to /bin/dash
    Init: sysvinit (via /sbin/init)

    Versions of packages libc6 depends on:
    ii libgcc1 1:6.3.0-18

    libc6 recommends no packages.

    Versions of packages libc6 suggests:
    ii debconf [debconf-2.0] 1.5.61
    pn glibc-doc <none>
    ii libc-l10n 2.24-11+deb9u1
    ii locales 2.24-11+deb9u1

    -- debconf information excluded

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)