On Fri, Jun 13, 2014 at 12:32 AM, Yann Ylavic <[email protected]> wrote:
> The most important imho is to not truncate the length at sizeof(struct
> sockaddr_un) when the real sun_path is beyond sizeof(sun_path).
> The libc calls are probably bullet proof regarding NUL termination
> (eg. force ((char*)sun)[addrlen] = 0 and recompute the length like in
> the linux code from your link above), setting the NUL ourself at the
> good place seems reasonable though ;)
Hence I think the correct behaviour is in mod_cgid, and something like
the following patch should be applied :
Index: modules/proxy/mod_proxy_fdpass.c
===================================================================
--- modules/proxy/mod_proxy_fdpass.c (revision 1602309)
+++ modules/proxy/mod_proxy_fdpass.c (working copy)
@@ -103,7 +103,8 @@ static apr_status_t get_socket_from_path(apr_pool_
const char* path,
apr_socket_t **out_sock)
{
- struct sockaddr_un sa;
+ struct sockaddr_un *sa;
+ apr_socklen_t salen, len;
apr_socket_t *s;
apr_status_t rv;
*out_sock = NULL;
@@ -114,10 +115,14 @@ static apr_status_t get_socket_from_path(apr_pool_
return rv;
}
- sa.sun_family = AF_UNIX;
- apr_cpystrn(sa.sun_path, path, sizeof(sa.sun_path));
+ len = strlen(path);
+ salen = APR_OFFSETOF(struct sockaddr_un, sun_path) + len;
+ sa = (struct sockaddr_un *)apr_palloc(p, salen + 1);
+ sa->sun_family = AF_UNIX;
+ memcpy(sa->sun_path, path, len);
+ sa->sun_path[len] = '\0';
- rv = socket_connect_un(s, &sa);
+ rv = socket_connect_un(s, sa);
if (rv != APR_SUCCESS) {
return rv;
}
Index: modules/proxy/proxy_util.c
===================================================================
--- modules/proxy/proxy_util.c (revision 1602309)
+++ modules/proxy/proxy_util.c (working copy)
@@ -2623,7 +2623,8 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const
#if APR_HAVE_SYS_UN_H
if (conn->uds_path)
{
- struct sockaddr_un sa;
+ struct sockaddr_un *sa;
+ apr_socklen_t salen, len;
rv = apr_socket_create(&newsock, AF_UNIX, SOCK_STREAM, 0,
conn->scpool);
@@ -2638,10 +2639,14 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const
}
conn->connection = NULL;
- sa.sun_family = AF_UNIX;
- apr_cpystrn(sa.sun_path, conn->uds_path, sizeof(sa.sun_path));
+ len = strlen(conn->uds_path);
+ salen = APR_OFFSETOF(struct sockaddr_un, sun_path) + len;
+ sa = (struct sockaddr_un *)apr_palloc(conn->scpool, salen + 1);
+ sa->sun_family = AF_UNIX;
+ memcpy(sa->sun_path, conn->uds_path, len);
+ sa->sun_path[len] = '\0';
- rv = socket_connect_un(newsock, &sa);
+ rv = socket_connect_un(newsock, sa);
if (rv != APR_SUCCESS) {
apr_socket_close(newsock);
ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(02454)
[EOS]