This patch fixes two IPv6 related problems. (1) Xdm compiled with IPv6 support failed to accept any chooser connections (even when only using IPv4). (2) There should be a one-to-one correspondence between successful getaddrinfo calls and freeaddrinfo calls. Any deviation from this one-to-one correspondence can lead to memory leaks and/or segmentation faults. diff -ur -N XOrg-6.9.0.orig/xc/lib/SM/sm_genid.c XOrg-6.9.0/xc/lib/SM/sm_genid.c --- XOrg-6.9.0.orig/xc/lib/SM/sm_genid.c 2005-05-17 23:25:16.000000000 +0200 +++ XOrg-6.9.0/xc/lib/SM/sm_genid.c 2006-06-23 23:23:54.000000000 +0200 @@ -179,8 +179,12 @@ { ptr2 = strchr (ptr1, '.'); len = ptr2 - ptr1; - if (!ptr2 || len > 3) + if (!ptr2 || len > 3) { +#if defined(IPv6) && defined(AF_INET6) + freeaddrinfo(first_ai); +#endif return (NULL); + } strncpy (temp, ptr1, len); temp[len] = '\0'; decimal[i] = atoi (temp); diff -ur -N XOrg-6.9.0.orig/xc/programs/Xserver/os/xdmcp.c XOrg-6.9.0/xc/programs/Xserver/os/xdmcp.c --- XOrg-6.9.0.orig/xc/programs/Xserver/os/xdmcp.c 2005-07-03 10:53:52.000000000 +0200 +++ XOrg-6.9.0/xc/programs/Xserver/os/xdmcp.c 2006-06-25 22:45:23.000000000 +0200 @@ -1603,6 +1603,10 @@ , &ai, &aifirst #endif ); +#if defined(IPv6) && defined(AF_INET6) + if (aifirst != NULL) + freeaddrinfo(aifirst); +#endif xdm_from = argv[i]; } diff -ur -N XOrg-6.9.0.orig/xc/programs/lbxproxy/di/pm.c XOrg-6.9.0/xc/programs/lbxproxy/di/pm.c --- XOrg-6.9.0.orig/xc/programs/lbxproxy/di/pm.c 2004-04-23 21:54:33.000000000 +0200 +++ XOrg-6.9.0/xc/programs/lbxproxy/di/pm.c 2006-06-24 00:02:07.000000000 +0200 @@ -383,7 +383,7 @@ if (colon) { #if defined(IPv6) && defined(AF_INET6) - struct addrinfo *ai, hints; + struct addrinfo *ai = NULL, hints; Bool bracketed = False; char canonaddr[INET6_ADDRSTRLEN]; int addrtype = AF_UNSPEC; diff -ur -N XOrg-6.9.0.orig/xc/programs/proxymngr/main.c XOrg-6.9.0/xc/programs/proxymngr/main.c --- XOrg-6.9.0.orig/xc/programs/proxymngr/main.c 2004-04-23 21:54:36.000000000 +0200 +++ XOrg-6.9.0/xc/programs/proxymngr/main.c 2006-06-24 01:17:01.000000000 +0200 @@ -518,8 +518,6 @@ hints.ai_flags = AI_CANONNAME; if (getaddrinfo(hostname, NULL, &hints, &ai) == 0) { canonname = ai->ai_canonname; - } else { - ai = NULL; } } #else diff -ur -N XOrg-6.9.0.orig/xc/programs/xdm/access.c XOrg-6.9.0/xc/programs/xdm/access.c --- XOrg-6.9.0.orig/xc/programs/xdm/access.c 2004-04-23 21:54:42.000000000 +0200 +++ XOrg-6.9.0/xc/programs/xdm/access.c 2006-06-25 22:36:46.000000000 +0200 @@ -310,7 +310,7 @@ void *addr=NULL; size_t addr_length=0; #if defined(IPv6) && defined(AF_INET6) - struct addrinfo *ai; + struct addrinfo *ai = NULL; #else struct hostent *hostent = gethostbyname (hostOrAlias); #endif @@ -346,17 +346,26 @@ Debug ("No such host %s\n", hostOrAlias); LogError ("Access file \"%s\", host \"%s\" not found\n", accessFile, hostOrAlias); free ((char *) h); +#if defined(IPv6) && defined(AF_INET6) + if (ai) + freeaddrinfo(ai); +#endif goto tryagain; } if (!XdmcpAllocARRAY8 (&h->entry.hostAddress, addr_length)) { LogOutOfMem ("ReadHostEntry\n"); free ((char *) h); +#if defined(IPv6) && defined(AF_INET6) + if (ai) + freeaddrinfo(ai); +#endif return NULL; } memmove( h->entry.hostAddress.data, addr, addr_length); #if defined(IPv6) && defined(AF_INET6) - freeaddrinfo(ai); + if (ai) + freeaddrinfo(ai); #endif } return h; @@ -430,7 +439,7 @@ int addrtype = 0; #if defined(IPv6) && defined(AF_INET6) - struct addrinfo *ai; + struct addrinfo *ai = NULL; if (getaddrinfo(displayOrAlias, NULL, NULL, &ai) == 0) { addrtype = ai->ai_addr->sa_family; @@ -457,6 +466,10 @@ { LogError ("Access file %s, display %s unknown\n", accessFile, displayOrAlias); free ((char *) d); +#if defined(IPv6) && defined(AF_INET6) + if (ai) + freeaddrinfo(ai); +#endif return NULL; } d->type = DISPLAY_ADDRESS; @@ -464,9 +477,17 @@ if (!XdmcpAllocARRAY8 (&display->clientAddress, addr_length)) { free ((char *) d); +#if defined(IPv6) && defined(AF_INET6) + if (ai) + freeaddrinfo(ai); +#endif return NULL; } memmove( display->clientAddress.data, addr, addr_length); +#if defined(IPv6) && defined(AF_INET6) + if (ai) + freeaddrinfo(ai); +#endif switch (addrtype) { #ifdef AF_UNIX diff -ur -N XOrg-6.9.0.orig/xc/programs/xdm/chooser.c XOrg-6.9.0/xc/programs/xdm/chooser.c --- XOrg-6.9.0.orig/xc/programs/xdm/chooser.c 2006-06-13 13:06:18.000000000 +0200 +++ XOrg-6.9.0/xc/programs/xdm/chooser.c 2006-06-24 01:39:00.000000000 +0200 @@ -742,6 +742,7 @@ } } } + freeaddrinfo(ai); } } #else diff -ur -N XOrg-6.9.0.orig/xc/programs/xdm/xdmcp.c XOrg-6.9.0/xc/programs/xdm/xdmcp.c --- XOrg-6.9.0.orig/xc/programs/xdm/xdmcp.c 2005-07-05 20:52:33.000000000 +0200 +++ XOrg-6.9.0/xc/programs/xdm/xdmcp.c 2006-06-25 22:15:56.000000000 +0200 @@ -578,8 +578,11 @@ { if (!strcmp (localhost, hostname)) { - if (!getString (name, 10)) - return 0; + if (!getString (name, 10)) { + if (ai) + freeaddrinfo(ai); + return NULL; + } sprintf (name, ":%d", displayNumber); } else @@ -605,15 +608,21 @@ } } - if (!getString (name, strlen (hostname) + 10)) - return 0; + if (!getString (name, strlen (hostname) + 10)) { + if (ai) + freeaddrinfo(ai); + return NULL; + } sprintf (name, "%s:%d", hostname, displayNumber); } } else { - if (!getString (name, INET6_ADDRSTRLEN + 10)) - return 0; + if (!getString (name, INET6_ADDRSTRLEN + 10)) { + if (ai) + freeaddrinfo(ai); + return NULL; + } if (multiHomed) { if (connectionType == FamilyInternet) { data = (CARD8 *) @@ -626,7 +635,9 @@ } if (inet_ntop(type, data, name, INET6_ADDRSTRLEN) == NULL) { free(name); - return 0; + if (ai) + freeaddrinfo(ai); + return NULL; } sprintf(name + strlen(name), ":%d", displayNumber); } @@ -1434,20 +1445,28 @@ struct addrinfo *ai = NULL, *nai; if (getaddrinfo(hostent->h_name, NULL, NULL, &ai) == 0) { for (nai = ai; nai != NULL; nai = nai->ai_next) { - if ((af_type == nai->ai_family) && - (connectionAddress->length == nai->ai_addrlen) && - (memcmp(connectionAddress->data,nai->ai_addr, - nai->ai_addrlen) == 0) ) { + if ((af_type == nai->ai_family) && ( + ((nai->ai_family == AF_INET) && + (connectionAddress->length == sizeof(struct in_addr)) && + (memcmp(connectionAddress->data, + &((struct sockaddr_in *)nai->ai_addr)->sin_addr, + connectionAddress->length) == 0)) || + ((nai->ai_family == AF_INET) && + (connectionAddress->length == sizeof(struct in6_addr)) && + (memcmp(connectionAddress->data, + &((struct sockaddr_in6 *)nai->ai_addr)->sin6_addr, + connectionAddress->length) == 0)))) break; - } } - if (ai == NULL) { + if (nai == NULL) { inet_ntop(af_type, connectionAddress->data, dotted, sizeof(dotted)); - LogError("Possible DNS spoof attempt %s->%s.", dotted, + LogError("Possible DNS spoof attempt %s->%s.\n", dotted, hostent->h_name); hostent = NULL; + } else { + local_name = hostent->h_name; } freeaddrinfo(ai); } else { @@ -1458,7 +1477,7 @@ if ((hostent = gethostbyname(s))) { if (memcmp((char*)connectionAddress->data, hostent->h_addr, hostent->h_length) != 0) { - LogError("Possible DNS spoof attempt."); + LogError("Possible DNS spoof attempt.\n"); hostent = NULL; /* so it enters next if() */ } else { local_name = hostent->h_name;