From efc41b2bb1affbfb33eb6de1071e7ffa3a083a3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sun, 16 Feb 2014 13:08:43 +0000 Subject: [PATCH] check length of unix domain socket filenames MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Stefan Bühler git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2958 152afb58-edef-0310-8abb-c4023f1b3aa9 --- NEWS | 1 + src/mod_fastcgi.c | 17 +++++++++++++++-- src/mod_scgi.c | 17 +++++++++++++++-- src/network.c | 11 +++++++++-- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 01f3a1b7..d288c020 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,7 @@ NEWS * [network] check return value of lseek() * fix unchecked return values from stream_open/stat_cache_get_entry * [mod_webdav] fix logic error in handling file creation error + * check length of unix domain socket filenames - 1.4.34 * [mod_auth] explicitly link ssl for SHA1 (fixes #2517) diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c index 641cf0fa..ad1ec183 100644 --- a/src/mod_fastcgi.c +++ b/src/mod_fastcgi.c @@ -873,7 +873,13 @@ static int fcgi_spawn_connection(server *srv, #ifdef HAVE_SYS_UN_H fcgi_addr_un.sun_family = AF_UNIX; - strcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr); + if (proc->unixsocket->used > sizeof(fcgi_addr_un.sun_path)) { + log_error_write(srv, __FILE__, __LINE__, "sB", + "ERROR: Unix Domain socket filename too long:", + proc->unixsocket); + return -1; + } + memcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr, proc->unixsocket->used); #ifdef SUN_LEN servlen = SUN_LEN(&fcgi_addr_un); @@ -1670,7 +1676,14 @@ static connection_result_t fcgi_establish_connection(server *srv, handler_ctx *h #ifdef HAVE_SYS_UN_H /* use the unix domain socket */ fcgi_addr_un.sun_family = AF_UNIX; - strcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr); + if (proc->unixsocket->used > sizeof(fcgi_addr_un.sun_path)) { + log_error_write(srv, __FILE__, __LINE__, "sB", + "ERROR: Unix Domain socket filename too long:", + proc->unixsocket); + return -1; + } + memcpy(fcgi_addr_un.sun_path, proc->unixsocket->ptr, proc->unixsocket->used); + #ifdef SUN_LEN servlen = SUN_LEN(&fcgi_addr_un); #else diff --git a/src/mod_scgi.c b/src/mod_scgi.c index af81c000..1c16c2d4 100644 --- a/src/mod_scgi.c +++ b/src/mod_scgi.c @@ -670,7 +670,13 @@ static int scgi_spawn_connection(server *srv, #ifdef HAVE_SYS_UN_H scgi_addr_un.sun_family = AF_UNIX; - strcpy(scgi_addr_un.sun_path, proc->socket->ptr); + if (proc->socket->used > sizeof(scgi_addr_un.sun_path)) { + log_error_write(srv, __FILE__, __LINE__, "sB", + "ERROR: Unix Domain socket filename too long:", + proc->socket); + return -1; + } + memcpy(scgi_addr_un.sun_path, proc->socket->ptr, proc->socket->used); #ifdef SUN_LEN servlen = SUN_LEN(&scgi_addr_un); @@ -1340,7 +1346,14 @@ static int scgi_establish_connection(server *srv, handler_ctx *hctx) { #ifdef HAVE_SYS_UN_H /* use the unix domain socket */ scgi_addr_un.sun_family = AF_UNIX; - strcpy(scgi_addr_un.sun_path, proc->socket->ptr); + if (proc->socket->used > sizeof(scgi_addr_un.sun_path)) { + log_error_write(srv, __FILE__, __LINE__, "sB", + "ERROR: Unix Domain socket filename too long:", + proc->socket); + return -1; + } + memcpy(scgi_addr_un.sun_path, proc->socket->ptr, proc->socket->used); + #ifdef SUN_LEN servlen = SUN_LEN(&scgi_addr_un); #else diff --git a/src/network.c b/src/network.c index 3c7dcc12..ebde43bc 100644 --- a/src/network.c +++ b/src/network.c @@ -349,14 +349,21 @@ static int network_server_init(server *srv, buffer *host_token, specific_config break; case AF_UNIX: + { + size_t hostlen = strlen(host) + 1; + if (hostlen > sizeof(srv_socket->addr.un.sun_path)) { + log_error_write(srv, __FILE__, __LINE__, "sS", "unix socket filename too long:", host); + goto error_free_socket; + } + memcpy(srv_socket->addr.un.sun_path, host, hostlen); + } srv_socket->addr.un.sun_family = AF_UNIX; - strcpy(srv_socket->addr.un.sun_path, host); #ifdef SUN_LEN addr_len = SUN_LEN(&srv_socket->addr.un); #else /* stevens says: */ - addr_len = strlen(host) + 1 + sizeof(srv_socket->addr.un.sun_family); + addr_len = hostlen + sizeof(srv_socket->addr.un.sun_family); #endif /* check if the socket exists and try to connect to it. */