comparison src/event/ngx_event_accept.c @ 7119:fef61d26da39

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).
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 04 Oct 2017 21:19:33 +0300
parents 3e2d90073adf
children d0b897c0bb5b
comparison
equal deleted inserted replaced
7118:b6dc472299da 7119:fef61d26da39
162 if (c->pool == NULL) { 162 if (c->pool == NULL) {
163 ngx_close_accepted_connection(c); 163 ngx_close_accepted_connection(c);
164 return; 164 return;
165 } 165 }
166 166
167 if (socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
168 socklen = sizeof(ngx_sockaddr_t);
169 }
170
167 c->sockaddr = ngx_palloc(c->pool, socklen); 171 c->sockaddr = ngx_palloc(c->pool, socklen);
168 if (c->sockaddr == NULL) { 172 if (c->sockaddr == NULL) {
169 ngx_close_accepted_connection(c); 173 ngx_close_accepted_connection(c);
170 return; 174 return;
171 } 175 }
438 442
439 c->shared = 1; 443 c->shared = 1;
440 c->type = SOCK_DGRAM; 444 c->type = SOCK_DGRAM;
441 c->socklen = msg.msg_namelen; 445 c->socklen = msg.msg_namelen;
442 446
447 if (c->socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
448 c->socklen = sizeof(ngx_sockaddr_t);
449 }
450
443 #if (NGX_STAT_STUB) 451 #if (NGX_STAT_STUB)
444 (void) ngx_atomic_fetch_add(ngx_stat_active, 1); 452 (void) ngx_atomic_fetch_add(ngx_stat_active, 1);
445 #endif 453 #endif
446 454
447 c->pool = ngx_create_pool(ls->pool_size, ev->log); 455 c->pool = ngx_create_pool(ls->pool_size, ev->log);