nwrap: Better check service string sanity.
authorRobin Hack <hack.robin@gmail.com>
Tue, 13 Oct 2015 12:41:14 +0000 (14:41 +0200)
committerMichael Adam <obnox@samba.org>
Mon, 11 Jan 2016 11:25:28 +0000 (12:25 +0100)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11501

Patch use strtol() instead of atoi() to convert strings to numbers.
This helps better check sanity of service input string.

Signed-off-by: Robin Hack <hack.robin@gmail.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Michael Adam <obnox@samba.org>
lib/nss_wrapper/nss_wrapper.c

index f85395e189797a17d94cdf564d8ecb13568c7aa6..21fc10810d3f8ac0214397195da3241923f8b51a 100644 (file)
@@ -5077,33 +5077,42 @@ static int nwrap_getaddrinfo(const char *node,
        }
 
        if (service != NULL && service[0] != '\0') {
-               if (isdigit((int)service[0])) {
-                       port = (unsigned short)atoi(service);
-               } else {
-                       const char *proto = NULL;
-                       struct servent *s;
+               const char *proto = NULL;
+               struct servent *s;
+               char *end_ptr;
+               long sl;
 
-                       if (hints->ai_protocol != 0) {
-                               struct protoent *pent;
+               errno = 0;
+               sl = strtol(service, &end_ptr, 10);
 
-                               pent = getprotobynumber(hints->ai_protocol);
-                               if (pent != NULL) {
-                                       proto = pent->p_name;
-                               }
+               if (*end_ptr == '\0' || end_ptr != service) {
+                       port = sl;
+                       goto valid_port;
+               } else if (hints->ai_flags & AI_NUMERICSERV) {
+                       return EAI_SERVICE;
+               }
+
+               if (hints->ai_protocol != 0) {
+                       struct protoent *pent;
+
+                       pent = getprotobynumber(hints->ai_protocol);
+                       if (pent != NULL) {
+                               proto = pent->p_name;
                        }
+               }
 
-                       s = getservbyname(service, proto);
-                       if (s != NULL) {
-                               port = ntohs(s->s_port);
-                       } else {
-                               if (p != NULL) {
-                                       freeaddrinfo(p);
-                               }
-                               return EAI_SERVICE;
+               s = getservbyname(service, proto);
+               if (s != NULL) {
+                       port = ntohs(s->s_port);
+               } else {
+                       if (p != NULL) {
+                               freeaddrinfo(p);
                        }
+                       return EAI_SERVICE;
                }
        }
 
+valid_port:
        rc = 0;
        if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET) {
                rc = inet_pton(AF_INET, node, &addr.in.v4);