From f28d5c9ac6af9fc6cfb8efecdaa1a42b4a93d351 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 12 Jun 2020 15:58:19 +0200 Subject: [PATCH] BUILD: proto_uxst: shut up yet another gcc's absurd warning When building with gcc-8 -fsanitize=address, we get this warning once on an strncpy() call in proto_uxst.c: src/proto_uxst.c:262:3: warning: 'strncpy' output may be truncated copying 107 bytes from a string of length 4095 [-Wstringop-truncation] strncpy(addr.sun_path, tempname, sizeof(addr.sun_path) - 1); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It happens despite the test on snprintf() at the top (since gcc's string handling is totally empiric), and requires the strlen() test to be placed "very close" to the strncpy() call (with "very close" yet to be determined). There's no other way to shut this one except disabling it. Given there's only one instance of this warning and the cost of dealing with it in the code is not huge, let's decorate the code to make gcc happily believe it is smart since it seems to have a mind of itself. --- src/proto_uxst.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/proto_uxst.c b/src/proto_uxst.c index 663f59a9b..89f4b2f06 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -215,7 +215,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle if (path[0]) { ret = snprintf(tempname, maxpathlen, "%s.%d.tmp", path, pid); - if (ret < 0 || ret >= maxpathlen) { + if (ret < 0 || ret >= sizeof(addr.sun_path)) { err |= ERR_FATAL | ERR_ALERT; msg = "name too long for UNIX socket (limit usually 97)"; goto err_return; @@ -248,6 +248,18 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle goto err_return; } + /* Note: this test is redundant with the snprintf one above and + * will never trigger, it's just added as the only way to shut + * gcc's painfully dumb warning about possibly truncated output + * during strncpy(). Don't move it above or smart gcc will not + * see it! + */ + if (strlen(tempname) >= sizeof(addr.sun_path)) { + err |= ERR_FATAL | ERR_ALERT; + msg = "name too long for UNIX socket (limit usually 97)"; + goto err_return; + } + strncpy(addr.sun_path, tempname, sizeof(addr.sun_path) - 1); addr.sun_path[sizeof(addr.sun_path) - 1] = 0; }