On Fri, Jun 13, 2014 at 12:32 AM, Yann Ylavic <ylavic....@gmail.com> 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]

Reply via email to