]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-resolve: check that name fits in the specified packet length
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 27 Nov 2017 13:54:55 +0000 (13:54 +0000)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 28 Nov 2017 08:25:38 +0000 (09:25 +0100)
Coverity complained that we didn't check if the data is long enough.

src/libsystemd/sd-resolve/sd-resolve.c

index 986768e7b398dc4f2e08714fe68a1ea152cf9576..e62afd9bfbda43328bf2f7c299b4bdd1cd05d4bc 100644 (file)
@@ -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;
+                                }
                         }
                 }