summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2016-10-10 16:15:41 +0300
committerMaxim Dounin <mdounin@mdounin.ru>2016-10-10 16:15:41 +0300
commit4891ba59d809133470636671f6714733b9484899 (patch)
tree10607a36e89e00c13d0514e9c34d5d48c8bfecbc
parente19481f35e45dc6a0016dc11b63095d88137b719 (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.c19
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;
}