[master] ee33662a1 do not pass a NULL pointer from strerror() to vsnprintf via VSL

Nils Goroll nils.goroll at uplex.de
Thu Nov 1 11:07:11 UTC 2018


commit ee33662a162cbc4fcc7fb8a93d143f85b7786eae
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Thu Nov 1 11:45:11 2018 +0100

    do not pass a NULL pointer from strerror() to vsnprintf via VSL
    
    (at leat on solaris) strerror() itself may fail for an out-of-memory
    condition (because the localization code contains memory
    allocations). In order to handle this situation, we need to save the
    original errno because strerror() may also set errno.
    
    This issue exists in many more places all over the code, but in the
    pool_breed case we likely failed pthread_create for an out-of-memory
    condition, and in the panic handler we want to make sure that we
    trip no follow-up panic under any circumstances.
    
    In general, while fixing all strerror() calls would unnecessarily
    complicate the code, doing so should be justified for these cases.
    
    Fixes #2815

diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c
index 8282ed814..13223c29d 100644
--- a/bin/varnishd/cache/cache_panic.c
+++ b/bin/varnishd/cache/cache_panic.c
@@ -666,8 +666,12 @@ pan_ic(const char *func, const char *file, int line, const char *cond,
 
 	pan_backtrace(pan_vsb);
 
-	if (err)
-		VSB_printf(pan_vsb, "errno = %d (%s)\n", err, strerror(err));
+	if (err) {
+		q = strerror(err);
+		if (q == NULL)
+			q = "(strerror failed)";
+		VSB_printf(pan_vsb, "errno = %d (%s)\n", err, q);
+	}
 
 	q = THR_GetName();
 	if (q != NULL)
diff --git a/bin/varnishd/cache/cache_wrk.c b/bin/varnishd/cache/cache_wrk.c
index 4d546ffd3..a4d9a33ad 100644
--- a/bin/varnishd/cache/cache_wrk.c
+++ b/bin/varnishd/cache/cache_wrk.c
@@ -437,6 +437,8 @@ pool_breed(struct pool *qp)
 	pthread_t tp;
 	pthread_attr_t tp_attr;
 	struct pool_info *pi;
+	const char *strerr;
+	int err;
 
 	AZ(pthread_attr_init(&tp_attr));
 	AZ(pthread_attr_setdetachstate(&tp_attr, PTHREAD_CREATE_DETACHED));
@@ -452,8 +454,12 @@ pool_breed(struct pool *qp)
 	pi->qp = qp;
 
 	if (pthread_create(&tp, &tp_attr, pool_thread, pi)) {
+		err = errno;
+		strerr = strerror(errno);
+		if (strerr == NULL)
+			strerr = "(strerror failed)";
 		VSL(SLT_Debug, 0, "Create worker thread failed %d %s",
-		    errno, strerror(errno));
+		    err, strerr);
 		Lck_Lock(&pool_mtx);
 		VSC_C_main->threads_failed++;
 		Lck_Unlock(&pool_mtx);


More information about the varnish-commit mailing list