From 1c45ee343ee5e503faddbe8f2b17084b39da292e Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 10 Oct 2016 16:15:41 +0300 Subject: [PATCH] Core: sockaddr lengths now respected by ngx_cmp_sockaddr(). Linux can return AF_UNIX sockaddrs with partially filled sun_path, resulting in spurious comparison failures and failed binary upgrades. Added proper checking of the lengths provided. Reported by Jan Seda, http://mailman.nginx.org/pipermail/nginx-devel/2016-September/008832.html. --- src/core/ngx_inet.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c index dbd1f4611..3bcd3e799 100644 --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -1364,6 +1364,7 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, socklen_t slen1, struct sockaddr_in6 *sin61, *sin62; #endif #if (NGX_HAVE_UNIX_DOMAIN) + size_t len; struct sockaddr_un *saun1, *saun2; #endif @@ -1393,15 +1394,21 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, socklen_t slen1, #if (NGX_HAVE_UNIX_DOMAIN) case AF_UNIX: - /* TODO length */ - saun1 = (struct sockaddr_un *) sa1; saun2 = (struct sockaddr_un *) sa2; - if (ngx_memcmp(&saun1->sun_path, &saun2->sun_path, - sizeof(saun1->sun_path)) - != 0) - { + if (slen1 < slen2) { + len = slen1 - offsetof(struct sockaddr_un, sun_path); + + } else { + len = slen2 - offsetof(struct sockaddr_un, sun_path); + } + + if (len > sizeof(saun1->sun_path)) { + len = sizeof(saun1->sun_path); + } + + if (ngx_memcmp(&saun1->sun_path, &saun2->sun_path, len) != 0) { return NGX_DECLINED; }