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.
This commit is contained in:
parent
0ed3b2a38b
commit
1c45ee343e
1 changed files with 13 additions and 6 deletions
|
@ -1364,6 +1364,7 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, socklen_t slen1,
|
||||||
struct sockaddr_in6 *sin61, *sin62;
|
struct sockaddr_in6 *sin61, *sin62;
|
||||||
#endif
|
#endif
|
||||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||||
|
size_t len;
|
||||||
struct sockaddr_un *saun1, *saun2;
|
struct sockaddr_un *saun1, *saun2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1393,15 +1394,21 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, socklen_t slen1,
|
||||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||||
case AF_UNIX:
|
case AF_UNIX:
|
||||||
|
|
||||||
/* TODO length */
|
|
||||||
|
|
||||||
saun1 = (struct sockaddr_un *) sa1;
|
saun1 = (struct sockaddr_un *) sa1;
|
||||||
saun2 = (struct sockaddr_un *) sa2;
|
saun2 = (struct sockaddr_un *) sa2;
|
||||||
|
|
||||||
if (ngx_memcmp(&saun1->sun_path, &saun2->sun_path,
|
if (slen1 < slen2) {
|
||||||
sizeof(saun1->sun_path))
|
len = slen1 - offsetof(struct sockaddr_un, sun_path);
|
||||||
!= 0)
|
|
||||||
{
|
} 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;
|
return NGX_DECLINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue