Welcome! Log In Create A New Profile

Advanced

[nginx] Fixed buffer overread with unix sockets after accept().

Maxim Dounin
October 17, 2017 09:08AM
details: http://hg.nginx.org/nginx/rev/83600ce25995
branches: stable-1.12
changeset: 7145:83600ce25995
user: Maxim Dounin <mdounin@mdounin.ru>
date: Wed Oct 04 21:19:33 2017 +0300
description:
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).

diffstat:

src/core/ngx_connection.c | 4 ++++
src/event/ngx_event_accept.c | 8 ++++++++
2 files changed, 12 insertions(+), 0 deletions(-)

diffs (39 lines):

diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -165,6 +165,10 @@ ngx_set_inherited_sockets(ngx_cycle_t *c
continue;
}

+ if (ls[i].socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
+ ls[i].socklen = sizeof(ngx_sockaddr_t);
+ }
+
switch (ls[i].sockaddr->sa_family) {

#if (NGX_HAVE_INET6)
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -164,6 +164,10 @@ ngx_event_accept(ngx_event_t *ev)
return;
}

+ if (socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
+ socklen = sizeof(ngx_sockaddr_t);
+ }
+
c->sockaddr = ngx_palloc(c->pool, socklen);
if (c->sockaddr == NULL) {
ngx_close_accepted_connection(c);
@@ -440,6 +444,10 @@ ngx_event_recvmsg(ngx_event_t *ev)
c->type = SOCK_DGRAM;
c->socklen = msg.msg_namelen;

+ if (c->socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
+ c->socklen = sizeof(ngx_sockaddr_t);
+ }
+
#if (NGX_STAT_STUB)
(void) ngx_atomic_fetch_add(ngx_stat_active, 1);
#endif
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[nginx] Fixed buffer overread with unix sockets after accept().

Maxim Dounin 283 October 17, 2017 09:08AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 306
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready