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
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:
Jan