[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