Skip to content

$echo_timer_elapsed is corrupted on 32-bit platforms with 64-bit time_t #127

Description

@janmojzis

Hi,

$echo_timer_elapsed produces corrupted values on 32-bit platforms where time_t is 64-bit, such as armhf systems.

Example output:

elapsed 17592186044416.611 sec.
elapsed 93427976913289250.458 sec.

In some cases the result can also be negative:

-8549631993283870719.457

The problem is reproducible with echo-nginx-module 0.65 and nginx 1.30.4 on armhf. The relevant test failures can be seen in this CI log:

https://ci.debian.net/data/autopkgtest/testing/armhf/libn/libnginx-mod-http-echo/74055259/log.gz

The issue appears to be a varargs type mismatch in src/ngx_http_echo_timer.c:

v->len = ngx_snprintf(p, size, "%T.%03M",
ms / 1000, ms % 1000) - p;

The nginx-specific %T format specifier expects a time_t, while ms / 1000 has type ngx_msec_int_t. On a 32-bit platform with a 64-bit time_t, ngx_snprintf() therefore reads an argument with the wrong width,
resulting in undefined behaviour and corrupted output.

Explicitly converting both arguments to the types required by the format specifiers fixes the issue:

--- a/src/ngx_http_echo_timer.c
+++ b/src/ngx_http_echo_timer.c
@@ -76,7 +76,8 @@ ngx_http_echo_timer_elapsed_variable(ngx_http_request_t *r,
         return NGX_ERROR;
     }

-    v->len = ngx_snprintf(p, size, "%T.%03M", ms / 1000, ms % 1000) - p;
+    v->len = ngx_snprintf(p, size, "%T.%03M", (time_t) (ms / 1000),
+                          (ngx_msec_t) (ms % 1000)) - p;
     v->data = p;

     v->valid = 1;

Jan

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions