Klaus Demo nginx / cb4dc27
Fixed buffer overread with unix sockets after accept(). Some OSes (notably macOS, NetBSD, and Solaris) allow unix socket addresses larger than struct sockaddr_un. Moreover, some of them (macOS, Solaris) return socklen of the socket address before it was truncated to fit the buffer provided. As such, on these systems socklen must not be used without additional check that it is within the buffer provided. Appropriate checks added to ngx_event_accept() (after accept()), ngx_event_recvmsg() (after recvmsg()), and ngx_set_inherited_sockets() (after getsockname()). We also obtain socket addresses via getsockname() in ngx_connection_local_sockaddr(), but it does not need any checks as it is only used for INET and INET6 sockets (as there can be no wildcard unix sockets). Maxim Dounin 4 years ago
2 changed file(s) with 12 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
162162 "socket #%d failed", ls[i].fd);
163163 ls[i].ignore = 1;
164164 continue;
165 }
166
167 if (ls[i].socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
168 ls[i].socklen = sizeof(ngx_sockaddr_t);
165169 }
166170
167171 switch (ls[i].sockaddr->sa_family) {
163163 return;
164164 }
165165
166 if (socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
167 socklen = sizeof(ngx_sockaddr_t);
168 }
169
166170 c->sockaddr = ngx_palloc(c->pool, socklen);
167171 if (c->sockaddr == NULL) {
168172 ngx_close_accepted_connection(c);
439443 c->type = SOCK_DGRAM;
440444 c->socklen = msg.msg_namelen;
441445
446 if (c->socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
447 c->socklen = sizeof(ngx_sockaddr_t);
448 }
449
442450 #if (NGX_STAT_STUB)
443451 (void) ngx_atomic_fetch_add(ngx_stat_active, 1);
444452 #endif