From 4cdb0b68b9d7680e3c3f11f48b9e739c394a2a6a Mon Sep 17 00:00:00 2001 From: Sergei Trofimovich Date: Tue, 15 Aug 2017 09:45:29 +0100 Subject: [PATCH] src/nss.c: fix out-of-bounds memset() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit out-of-bounds access happens at memset() call site: @@ -272,9 +272,9 @@ enum nss_status _nss_mdns_gethostbyname4_r( // Copy address memcpy(&(tuple->addr), &(u.data.result[i].address), address_length); if(address_length < sizeof(ipv6_address_t)) { memset((&(tuple->addr) + address_length - sizeof(ipv6_address_t)), 0, (sizeof(ipv6_address_t) - address_length) ); } The problem here is in 'addr' type: struct gaih_addrtuple { ... uint32_t addr[4]; ... }; It means pointer addressing is not byte-based as offsets imply and memset() wipes 12 bytes in hearby memory (of stack in glibc case). valgrind detects the overflow as: ==12732== Invalid write of size 1 ==12732== at 0x4C11A29: memset (vg_replace_strmem.c:1239) ==12732== by 0x57FA348: _nss_mdns_minimal_gethostbyname4_r (nss.c:292) ==12732== by 0x4F016D8: gaih_inet.constprop.7 (getaddrinfo.c:806) ==12732== by 0x4F02673: getaddrinfo (getaddrinfo.c:2317) ==12732== by 0x4800B3B: main (a.c:34) The effect is SIGSEGV-ing getaddrinfo() call on systems with the following nsswitch.conf: hosts: files mdns_minimal [NOTFOUND=return] dns The fix is to simplify memset()/memcpy() sequence. Reported-by: Michał Górny Bug: https://bugs.gentoo.org/627770 Signed-off-by: Sergei Trofimovich --- src/nss.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/nss.c b/src/nss.c index ebb887c..1f50bad 100644 --- a/src/nss.c +++ b/src/nss.c @@ -271,12 +271,8 @@ enum nss_status _nss_mdns_gethostbyname4_r( tuple->family = u.data.result[i].af; // Copy address + memset(&(tuple->addr), 0, sizeof(ipv6_address_t)); memcpy(&(tuple->addr), &(u.data.result[i].address), address_length); - if(address_length < sizeof(ipv6_address_t)) { - memset((&(tuple->addr) + address_length - sizeof(ipv6_address_t)), 0, - (sizeof(ipv6_address_t) - address_length) - ); - } // Assign interface scope id tuple->scopeid = u.data.result[i].scopeid; -- 2.14.1