vos: fix crash when getting a non-loopback host address
authorMichael Meffie <mmeffie@sinenomine.net>
Thu, 20 Nov 2014 21:54:25 +0000 (16:54 -0500)
committerJeffrey Altman <jaltman@your-file-system.com>
Wed, 26 Nov 2014 14:38:18 +0000 (09:38 -0500)
Fix a crash in vos when trying to find a non loopback server address.

The struct hostent h_addr_list field is a null terminated array of
pointers to addresses, in network byte order.  The struct hostent length
field is not the length of the h_addr_list array (as one would expect),
but rather the length of an address in bytes, which is always 4 for IP
version 4 addresses.

Verify the returned addresses are IPv4 and take care to not iterate
beyond the end of the address pointer array.

The non-loopback address check was introduced
commit dc2a4fe4e949c250ca25708aa5a6dd575878fd7e.

Change-Id: I75dff5ed2a7dd3c4bd6605b375a7a2ffa91eff01
Reviewed-on: http://gerrit.openafs.org/11609
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>

src/volser/vos.c

index 8b08d37..a7299ab 100644 (file)
@@ -234,6 +234,7 @@ GetServer(char *aname)
     afs_uint32 addr; /* in network byte order */
     afs_int32 code;
     char hostname[MAXHOSTCHARS];
+    afs_uint32 **addr_list;
     int i;
 
     addr = GetServerNoresolve(aname);
@@ -245,10 +246,11 @@ GetServer(char *aname)
     }
 
     th = gethostbyname(aname);
-    if (th != NULL) {
-       for (i=0; i < th->h_length; i++) {
-           if (!rx_IsLoopbackAddr(ntohl(*(afs_uint32 *)th->h_addr_list[i]))) {
-               memcpy(&addr, th->h_addr_list[i], sizeof(addr));
+    if (th != NULL && th->h_addrtype == AF_INET) {
+       addr_list = (afs_uint32 **)th->h_addr_list;
+       for(i = 0; addr_list[i] != NULL; i++) {
+           if (!rx_IsLoopbackAddr(ntohl(*addr_list[i]))) {
+               memcpy(&addr, addr_list[i], sizeof(addr));
                return addr;
            }
        }
@@ -263,10 +265,11 @@ GetServer(char *aname)
        code = gethostname(hostname, MAXHOSTCHARS);
        if (code == 0) {
            th = gethostbyname(hostname);
-           if (th != NULL) {
-               for (i=0; i < th->h_length; i++) {
-                   if (!rx_IsLoopbackAddr(ntohl(*(afs_uint32 *)th->h_addr_list[i]))) {
-                       memcpy(&addr, th->h_addr_list[i], sizeof(addr));
+           if (th != NULL && th->h_addrtype == AF_INET) {
+               addr_list = (afs_uint32 **)th->h_addr_list;
+               for (i=0; addr_list[i] != NULL; i++) {
+                   if (!rx_IsLoopbackAddr(ntohl(*addr_list[i]))) {
+                       memcpy(&addr, addr_list[i], sizeof(addr));
                        return addr;
                    }
                }