From e7a0f37ce6729711b647ddea610f8b655a5d3732 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 17 Feb 2020 15:20:32 +0100 Subject: [PATCH] Don't read potentially uninitalized memory if gethostname() failed If the buffer is smaller than `HOST_NAME_MAX` (64 on Linux but up to 255 bytes in POSIX, which FreeBSD, MacOS etc honor) gethostname() might return -1 without null-terminating the buffer, causing an out-of-bounds read. As we look for the first '.' using `strchr()`, replacing it with a null byte, we also have a one-byte out-of-bounds write which might result in a crash or, albeit very unlikely, arbitrary code execution. --- pdns/auth-carbon.cc | 6 ++++-- pdns/dnsdist-carbon.cc | 6 ++++-- pdns/rec-carbon.cc | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pdns/auth-carbon.cc b/pdns/auth-carbon.cc index 09f776aa7c..5fd968c82c 100644 --- a/pdns/auth-carbon.cc +++ b/pdns/auth-carbon.cc @@ -41,9 +41,11 @@ try string namespace_name=arg()["carbon-namespace"]; string hostname=arg()["carbon-ourname"]; if(hostname.empty()) { - char tmp[80]; + char tmp[HOST_NAME_MAX+1]; memset(tmp, 0, sizeof(tmp)); - gethostname(tmp, sizeof(tmp)); + if (gethostname(tmp, sizeof(tmp)) != 0) { + throw std::runtime_error("The carbon-ourname setting has not been set and we are unable to determine the system's hostname: " + stringerror()); + } char *p = strchr(tmp, '.'); if(p) *p=0; hostname=tmp; diff --git a/pdns/dnsdist-carbon.cc b/pdns/dnsdist-carbon.cc index 26702dcb65..c5c1381d0b 100644 --- a/pdns/dnsdist-carbon.cc +++ b/pdns/dnsdist-carbon.cc @@ -59,9 +59,11 @@ try const std::string& namespace_name = conf.namespace_name; std::string hostname = conf.ourname; if(hostname.empty()) { - char tmp[80]; + char tmp[HOST_NAME_MAX+1]; memset(tmp, 0, sizeof(tmp)); - gethostname(tmp, sizeof(tmp)); + if (gethostname(tmp, sizeof(tmp)) != 0) { + throw std::runtime_error("The 'ourname' setting in 'carbonServer()' has not been set and we are unable to determine the system's hostname: " + stringerror()); + } char *p = strchr(tmp, '.'); if(p) *p=0; hostname=tmp; diff --git a/pdns/rec-carbon.cc b/pdns/rec-carbon.cc index 3eba50bd8c..ef1204d6ec 100644 --- a/pdns/rec-carbon.cc +++ b/pdns/rec-carbon.cc @@ -33,9 +33,11 @@ try namespace_name="pdns"; } if(hostname.empty()) { - char tmp[80]; + char tmp[HOST_NAME_MAX+1]; memset(tmp, 0, sizeof(tmp)); - gethostname(tmp, sizeof(tmp)); + if (gethostname(tmp, sizeof(tmp)) != 0) { + throw std::runtime_error("The 'carbon-ourname' setting has not been set and we are unable to determine the system's hostname: " + stringerror()); + } char *p = strchr(tmp, '.'); if(p) *p=0; -- 2.47.2