Skip to content

Round-trip failure when parsing future dates (year 2106) #124

@hgarrereyn

Description

@hgarrereyn

Hi, there is a potential bug with how httpGetDateTime handles dates in far (but not super distant) future.

This bug was reproduced on 881de11.

Description

Both httpGetDateString and httpGetDateTime operate on a time_t value (8 bytes on modern systems). However, parsing a date near the 2^32-1 boundary (e.g. Sun, 07 Feb 2106 06:28:15 GMT) causes a rounding error which leads httpGetDateTime to produce incorrect results.

I believe the cause is due to use of int internally, hence the arithmetic wraps around and is the cast to time_t which sign extends.

POC

The following testcase demonstrates the bug:

testcase.cpp

#include <cstdio>
#include <ctime>
#include <cassert>
extern "C" {
#include "/fuzz/src/cups/http.h"
}
int main(){
  char buf[64];
  printf("sizeof(time_t): %zu\n", sizeof(time_t));
  time_t t = (time_t)4294967295ULL; // Sun, 07 Feb 2106 06:28:15 GMT (2^32-1)
  printf("t: %zu\n", t);
  if (!httpGetDateString(t, buf, sizeof(buf))) return 0; // formatting succeeded in testing
  printf("buf: %s\n", buf);
  time_t parsed = httpGetDateTime(buf);
  printf("parsed: %zu\n", parsed);
  assert(parsed == t);
  return 0;
}

stdout

sizeof(time_t): 8
t: 4294967295
buf: Sun, 07 Feb 2106 06:28:15 GMT
parsed: 18446744073709551615
test: /fuzz/testcase.cpp:16: int main(): Assertion `parsed == t' failed.
Steps to Reproduce

The crash was triaged with the following Dockerfile:

Dockerfile

# Ubuntu 22.04 with some packages pre-installed
FROM hgarrereyn/stitch_repro_base@sha256:3ae94cdb7bf2660f4941dc523fe48cd2555049f6fb7d17577f5efd32a40fdd2c

RUN git clone https://github.com/OpenPrinting/libcups.git /fuzz/src && \
    cd /fuzz/src && \
    git checkout 881de116d71c695f125bf2d47acc3a988b9afaee && \
    git submodule update --init --remote --recursive

ENV LD_LIBRARY_PATH=/fuzz/install/lib
ENV ASAN_OPTIONS=hard_rss_limit_mb=1024:detect_leaks=0

RUN echo '#!/bin/bash\nexec clang-17 -fsanitize=address -O0 "$@"' > /usr/local/bin/clang_wrapper && \
    chmod +x /usr/local/bin/clang_wrapper && \
    echo '#!/bin/bash\nexec clang++-17 -fsanitize=address -O0 "$@"' > /usr/local/bin/clang_wrapper++ && \
    chmod +x /usr/local/bin/clang_wrapper++

# Install build dependencies
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
    pkg-config \
    libavahi-client-dev \
    libnss-mdns \
    libssl-dev \
    zlib1g-dev \
    libpng-dev \
    ca-certificates \
    make \
    && rm -rf /var/lib/apt/lists/*

# Provide a dummy pdfio pkg-config file so configure doesn't try to build the embedded submodule
# We won't build the tools that require PDFio, only the libcups library.
RUN mkdir -p /usr/local/lib/pkgconfig && \
    printf "prefix=/usr/local\nexec_prefix=\${prefix}\nlibdir=\${exec_prefix}/lib\nincludedir=\${prefix}/include\n\nName: pdfio\nDescription: Dummy PDFio for building libcups library only\nVersion: 1.6.0\nLibs: \nCflags: \n" > /usr/local/lib/pkgconfig/pdfio.pc

# Build and install libcups (static only) into /fuzz/install
WORKDIR /fuzz/src
ENV CC=clang_wrapper CXX=clang_wrapper++
RUN ./configure --prefix=/fuzz/install --disable-shared --enable-static --with-tls=openssl --disable-dbus
# Build only the library (skip tools that may need external PDFio)
RUN make -j"$(nproc)" DIRS=cups && make -j"$(nproc)" DIRS=cups install

Build Command

clang++-17 -fsanitize=address -g -O0 -o /fuzz/test /fuzz/testcase.cpp -I/fuzz/src/cups -I/fuzz/install/include/cups -L/fuzz/install/lib -lcups3 -lavahi-client -lavahi-common -lssl -lcrypto -lz -lpthread -lm && /fuzz/test

Reproduce

  1. Copy Dockerfile and testcase.cpp into a local folder.
  2. Build the repro image:
docker build . -t repro --platform=linux/amd64
  1. Compile and run the testcase in the image:
docker run \
    -it --rm \
    --platform linux/amd64 \
    --mount type=bind,source="testcase.cpp",target=/fuzz/testcase.cpp \
    repro \
    bash -c "clang++-17 -fsanitize=address -g -O0 -o /fuzz/test /fuzz/testcase.cpp -I/fuzz/src/cups -I/fuzz/install/include/cups -L/fuzz/install/lib -lcups3 -lavahi-client -lavahi-common -lssl -lcrypto -lz -lpthread -lm && /fuzz/test"


Additional Info

This testcase was discovered by STITCH, an autonomous fuzzing system. All reports are reviewed manually (by a human) before submission.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions