From: Zbigniew Jędrzejewski-Szmek Date: Mon, 27 Nov 2017 13:54:55 +0000 (+0000) Subject: sd-resolve: check that name fits in the specified packet length X-Git-Tag: v236~102^2~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1a96c8e1ccb06f87b6bfaff4639390ecd00af588;p=thirdparty%2Fsystemd.git sd-resolve: check that name fits in the specified packet length Coverity complained that we didn't check if the data is long enough. --- diff --git a/src/libsystemd/sd-resolve/sd-resolve.c b/src/libsystemd/sd-resolve/sd-resolve.c index 986768e7b39..e62afd9bfbd 100644 --- a/src/libsystemd/sd-resolve/sd-resolve.c +++ b/src/libsystemd/sd-resolve/sd-resolve.c @@ -33,6 +33,7 @@ #include "sd-resolve.h" #include "alloc-util.h" +#include "dns-domain.h" #include "fd-util.h" #include "io-util.h" #include "list.h" @@ -812,25 +813,36 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len assert(length >= sizeof(NameInfoResponse)); assert(q->type == REQUEST_NAMEINFO); - q->ret = ni_resp->ret; - q->_errno = ni_resp->_errno; - q->_h_errno = ni_resp->_h_errno; - - if (ni_resp->hostlen > 0) { - q->host = strndup((const char*) ni_resp + sizeof(NameInfoResponse), ni_resp->hostlen-1); - if (!q->host) { - q->ret = EAI_MEMORY; - q->_errno = ENOMEM; - q->_h_errno = 0; + if (ni_resp->hostlen > DNS_HOSTNAME_MAX || + ni_resp->servlen > DNS_HOSTNAME_MAX || + sizeof(NameInfoResponse) + ni_resp->hostlen + ni_resp->servlen > length + 2) { + q->ret = EAI_SYSTEM; + q->_errno = -EIO; + q->_h_errno = 0; + + } else { + q->ret = ni_resp->ret; + q->_errno = ni_resp->_errno; + q->_h_errno = ni_resp->_h_errno; + + if (ni_resp->hostlen > 0) { + q->host = strndup((const char*) ni_resp + sizeof(NameInfoResponse), + ni_resp->hostlen-1); + if (!q->host) { + q->ret = EAI_MEMORY; + q->_errno = ENOMEM; + q->_h_errno = 0; + } } - } - if (ni_resp->servlen > 0) { - q->serv = strndup((const char*) ni_resp + sizeof(NameInfoResponse) + ni_resp->hostlen, ni_resp->servlen-1); - if (!q->serv) { - q->ret = EAI_MEMORY; - q->_errno = ENOMEM; - q->_h_errno = 0; + if (ni_resp->servlen > 0) { + q->serv = strndup((const char*) ni_resp + sizeof(NameInfoResponse) + ni_resp->hostlen, + ni_resp->servlen-1); + if (!q->serv) { + q->ret = EAI_MEMORY; + q->_errno = ENOMEM; + q->_h_errno = 0; + } } }