This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[sw@network-analysis.ltd.uk] libc/2181: segmentation fault in getaddrinfo()



Hi Uli,

what's about this bug report?

Andreas



>Number:         2181
>Category:       libc
>Synopsis:       segmentation fault in getaddrinfo()
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    libc-gnats
>State:          open
>Quarter:        
>Keywords:       
>Class:          sw-bug
>Submitter-Id:   gnatsweb
>Arrival-Date:   Fri Apr 06 07:13:52 -0400 2001
>Cases:          
>Originator:     Sak Wathanasin
>Release:        glibc 2.2.1, 2.2.2
>Organization:
Network Analysis Ltd
>Environment:
Host type: i386-redhat-linux-gnu
System: Linux 2.2.18 #16 Thu Jan 25 10:55:25 GMT 2001 i686
>Description:
If called with a "hints" struct where the protocol type
is not specified, getaddrinfo() gets a segment violation. In
.../sysdeps/posix/getaddrinfo.c, the routine gaih_inet has 
a for loop (line 417)

for (++tp; tp->name != NULL; ++tp) {
...
}

The exit test is wrong because the field "name" is a char[]
that is embedded inside *tp (type = struct gaih_typeproto),
and will never be NULL.

In case you're wondering, bind 9.1.x uses code that is like
the test code below, and doing, e.g., "dig @foo" will result
in a seg violation.
>How-To-Repeat:
/* compile with
	cc -g -o test test.c
 and run eg
	./test localhost
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>

main (int argc, char** argv)
{
        struct in_addr in4;
        struct addrinfo *res = NULL,
                        hints;
        int result = 0;
        char buf[101] = {0};

        memset(&hints, 0, sizeof(hints));
        hints.ai_family = PF_INET;
        result = getaddrinfo(argv[1], NULL, &hints, &res);
        if (result == 0) {
                /* succeeded */
                inet_ntop(AF_INET, &(((struct sockaddr_in *)(res->ai_addr))->sin_addr), buf, INET_ADDRSTRLEN);
                printf("Addr = %s\n", buf);
        }
        else {
                printf("Lookup failed\n");
        }
}
>Fix:
--- sysdeps/posix/getaddrinfo.c.gai     Wed Jan 24 08:57:10 2001
+++ sysdeps/posix/getaddrinfo.c Thu Apr  5 11:43:38 2001
@@ -414,7 +414,7 @@
       /* Neither socket type nor protocol is set.  Return all socket types
         we know about.  */
       struct gaih_servtuple **lastp = &st;
-      for (++tp; tp->name != NULL; ++tp)
+      for (++tp; tp->name[0] != '\0'; ++tp)
        {
          struct gaih_servtuple *newp;

>Unformatted:
 





-- 
 Andreas Jaeger
  SuSE Labs aj@suse.de
   private aj@arthur.inka.de
    http://www.suse.de/~aj

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]