[master] 127964c48 Handle unformatable VCL_TIME to string conversion failures

Nils Goroll nils.goroll at uplex.de
Fri Apr 30 19:16:05 UTC 2021


commit 127964c48d1c780d036266218926d1b56680277c
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date:   Wed May 6 11:46:55 2020 +0200

    Handle unformatable VCL_TIME to string conversion failures
    
    For VCL_TIME values that would convert to a year element that can not fit
    in an int, gmtime_r would fail, and VTIM_format() would use random stack
    values when picking weekday and month strings.
    
    This patch changes VTIM_format to return "" when gmtime_r reports
    failures. This way the API is not changed. Callers can test for empty
    string to catch the failure if needed.
    
    VRT_TIME_string is patched to catch the VTIM_format error, and return NULL
    on failure.
    
    Fixes: #3308

diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index d31065245..c5a8d1633 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -840,8 +840,11 @@ VRT_TIME_string(VRT_CTX, VCL_TIME t)
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	p = WS_Alloc(ctx->ws, VTIM_FORMAT_SIZE);
-	if (p != NULL)
+	if (p != NULL) {
 		VTIM_format(t, p);
+		if (*p == '\0')
+			p = NULL;
+	}
 	return (p);
 }
 
diff --git a/bin/varnishtest/tests/r03308.vtc b/bin/varnishtest/tests/r03308.vtc
new file mode 100644
index 000000000..a97cb0cd5
--- /dev/null
+++ b/bin/varnishtest/tests/r03308.vtc
@@ -0,0 +1,20 @@
+varnishtest "Unformatable VCL_TIME"
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 -vcl+backend {
+	import std;
+
+	sub vcl_deliver {
+		set resp.http.ts = std.real2time(std.real("1e+22", 0), now);
+	}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.http.ts == ""
+} -run
diff --git a/lib/libvarnish/vtim.c b/lib/libvarnish/vtim.c
index 5b91fc970..676330e1b 100644
--- a/lib/libvarnish/vtim.c
+++ b/lib/libvarnish/vtim.c
@@ -167,11 +167,16 @@ VTIM_format(vtim_real t, char *p)
 	struct tm tm;
 	time_t tt;
 
+	AN(p);
 	tt = (time_t) t;
-	(void)gmtime_r(&tt, &tm);
-	AN(snprintf(p, VTIM_FORMAT_SIZE, "%s, %02d %s %4d %02d:%02d:%02d GMT",
-	    weekday_name[tm.tm_wday], tm.tm_mday, month_name[tm.tm_mon],
-	    tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec));
+	if (gmtime_r(&tt, &tm) != NULL)
+		AN(snprintf(p, VTIM_FORMAT_SIZE,
+			"%s, %02d %s %4d %02d:%02d:%02d GMT",
+			weekday_name[tm.tm_wday],
+			tm.tm_mday, month_name[tm.tm_mon],
+			tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec));
+	else
+		*p = '\0';
 }
 
 #ifdef TEST_DRIVER


More information about the varnish-commit mailing list