From de94f97649cbf36a5d8ae805a0d211573fcb11be Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Sat, 31 Mar 2012 12:20:25 -0400 Subject: [PATCH] auth: Make sure we get AF_INET addresses from DNS The routines which do AFSDB and SRV lookups copy the results of gethostbyname directly into an afs_int32, and use the size of the result to limit the copy. If, for any reason, they get a result that isn't an int, then they will overflow this value. Check that the result we get from gethostbyname is in the INET address family, and also limit the size of the copy by the size of the destination, rather than that of the source. Caught by clang-analyzer Change-Id: Icf1426e090bc1ed382212d5de6c291d0816fb2c9 Reviewed-on: http://gerrit.openafs.org/7096 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/auth/cellconfig.c | 50 +++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/src/auth/cellconfig.c b/src/auth/cellconfig.c index a230cbb..bc9feef 100644 --- a/src/auth/cellconfig.c +++ b/src/auth/cellconfig.c @@ -1099,17 +1099,18 @@ afsconf_LookupServer(const char *service, const char *protocol, if ((afsdb_type == 1) && (server_num < MAXHOSTSPERCELL) && /* Do we want to get TTL data for the A record as well? */ (he = gethostbyname(host))) { - afs_int32 ipaddr; - memcpy(&ipaddr, he->h_addr, he->h_length); - cellHostAddrs[server_num] = ipaddr; - ports[server_num] = afsdbPort; - ipRanks[server_num] = 0; - strncpy(cellHostNames[server_num], host, - sizeof(cellHostNames[server_num])); - server_num++; - - if (!minttl || ttl < minttl) - minttl = ttl; + if (he->h_addrtype == AF_INET) { + afs_int32 ipaddr; + memcpy(&ipaddr, he->h_addr, sizeof(ipaddr)); + cellHostAddrs[server_num] = ipaddr; + ports[server_num] = afsdbPort; + ipRanks[server_num] = 0; + strncpy(cellHostNames[server_num], host, + sizeof(cellHostNames[server_num])); + server_num++; + if (!minttl || ttl < minttl) + minttl = ttl; + } } } if (type == T_SRV) { @@ -1132,18 +1133,21 @@ afsconf_LookupServer(const char *service, const char *protocol, if ((server_num < MAXHOSTSPERCELL) && /* Do we want to get TTL data for the A record as well? */ (he = gethostbyname(host))) { - afs_int32 ipaddr; - memcpy(&ipaddr, he->h_addr, he->h_length); - cellHostAddrs[server_num] = ipaddr; - ipRanks[server_num] = (p[0] << 8) | p[1]; - ports[server_num] = htons((p[4] << 8) | p[5]); - /* weight = (p[2] << 8) | p[3]; */ - strncpy(cellHostNames[server_num], host, - sizeof(cellHostNames[server_num])); - server_num++; - - if (!minttl || ttl < minttl) - minttl = ttl; + if (he->h_addrtype == AF_INET) { + afs_int32 ipaddr; + + memcpy(&ipaddr, he->h_addr, sizeof(ipaddr)); + cellHostAddrs[server_num] = ipaddr; + ipRanks[server_num] = (p[0] << 8) | p[1]; + ports[server_num] = htons((p[4] << 8) | p[5]); + /* weight = (p[2] << 8) | p[3]; */ + strncpy(cellHostNames[server_num], host, + sizeof(cellHostNames[server_num])); + server_num++; + + if (!minttl || ttl < minttl) + minttl = ttl; + } } } -- 1.9.4