Index: lib/sanitizer_common/sanitizer_common_interceptors.inc =================================================================== --- lib/sanitizer_common/sanitizer_common_interceptors.inc +++ lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -3077,17 +3077,28 @@ #endif #if SANITIZER_INTERCEPT_GETPEERNAME -INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { +INTERCEPTOR(int, getpeername, int sockfd, void *addr, + __sanitizer_socklen_t *addrlen) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); - unsigned addr_sz; - if (addrlen) addr_sz = *addrlen; - // FIXME: under ASan the call below may write to freed memory and corrupt - // its metadata. See - // https://github.com/google/sanitizers/issues/321. - int res = REAL(getpeername)(sockfd, addr, addrlen); - if (!res && addr && addrlen) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); + __sanitizer_socklen_t taddrlen; + if (addrlen) + taddrlen = *addrlen; + else + taddrlen = 0; + __sanitizer_sockaddr_storage taddr; + int res = REAL(getpeername)(sockfd, addr ? &taddr : 0, + addrlen ? &taddrlen : 0); + if (!res) { + if (addr && addrlen) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, taddrlen); + if (addrlen) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addrlen, sizeof(*addrlen)); + } + if (addr && addrlen) + memcpy(addr, &taddr, taddrlen); + if (addrlen) + *addrlen = taddrlen; return res; } #define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);