From: Remi Gacogne Date: Mon, 17 Feb 2020 14:20:32 +0000 (+0100) Subject: Don't read potentially uninitalized memory if gethostname() failed X-Git-Tag: dnsdist-1.5.0-rc3~50^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F9114%2Fhead;p=thirdparty%2Fpdns.git 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. --- 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;