diff options
author | Maxim Dounin <mdounin@mdounin.ru> | 2016-10-10 16:15:41 +0300 |
---|---|---|
committer | Maxim Dounin <mdounin@mdounin.ru> | 2016-10-10 16:15:41 +0300 |
commit | 4891ba59d809133470636671f6714733b9484899 (patch) | |
tree | 10607a36e89e00c13d0514e9c34d5d48c8bfecbc | |
parent | e19481f35e45dc6a0016dc11b63095d88137b719 (diff) |
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.
-rw-r--r-- | src/core/ngx_inet.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c index 33b303dd0..404f7635d 100644 --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -1213,6 +1213,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 @@ -1242,15 +1243,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; } |