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 | f594b2bf6dbb49f5e2bc27cc3f27f272a7f95c1c (patch) | |
tree | e3fb4537c60c2cb17c828dac9a5d7971074f16f8 /src | |
parent | 4c4fdc475450d4faa5a996ff0087ef005ee8a232 (diff) | |
download | nginx-f594b2bf6dbb49f5e2bc27cc3f27f272a7f95c1c.tar.gz nginx-f594b2bf6dbb49f5e2bc27cc3f27f272a7f95c1c.zip |
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.
Diffstat (limited to 'src')
-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 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; } |