[6.0] 6cb9c7669 Handle unformatable VCL_TIME to string conversion failures

Reza Naghibi reza at naghibi.com
Wed Aug 19 13:14:06 UTC 2020


commit 6cb9c7669a042fd6614e83298f323d0814b0e51d
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 4f34fba44..8eed99e4c 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -629,8 +629,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 14b9752d6..dc6e01e31 100644
--- a/lib/libvarnish/vtim.c
+++ b/lib/libvarnish/vtim.c
@@ -165,11 +165,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