daemon: detect and reject too-long paths
authorJeff King <peff@peff.net>
Sat, 22 Oct 2016 04:59:38 +0000 (00:59 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 24 Oct 2016 16:59:29 +0000 (09:59 -0700)
When we are checking the path via path_ok(), we use some
fixed PATH_MAX buffers. We write into them via snprintf(),
so there's no possibility of overflow, but it does mean we
may silently truncate the path, leading to potentially
confusing errors when the partial path does not exist.

We're better off to reject the path explicitly.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
daemon.c
index 8d45c336f5f816768962c39e8af6b10e0bb0e21e..72f6ad3c0d5faccfb845f7181331e621454376da 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -161,6 +161,7 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)
 {
        static char rpath[PATH_MAX];
        static char interp_path[PATH_MAX];
+       size_t rlen;
        const char *path;
        const char *dir;
 
@@ -188,8 +189,12 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)
                        namlen = slash - dir;
                        restlen -= namlen;
                        loginfo("userpath <%s>, request <%s>, namlen %d, restlen %d, slash <%s>", user_path, dir, namlen, restlen, slash);
-                       snprintf(rpath, PATH_MAX, "%.*s/%s%.*s",
-                                namlen, dir, user_path, restlen, slash);
+                       rlen = snprintf(rpath, sizeof(rpath), "%.*s/%s%.*s",
+                                       namlen, dir, user_path, restlen, slash);
+                       if (rlen >= sizeof(rpath)) {
+                               logerror("user-path too large: %s", rpath);
+                               return NULL;
+                       }
                        dir = rpath;
                }
        }
@@ -208,7 +213,15 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)
 
                strbuf_expand(&expanded_path, interpolated_path,
                              expand_path, &context);
-               strlcpy(interp_path, expanded_path.buf, PATH_MAX);
+
+               rlen = strlcpy(interp_path, expanded_path.buf,
+                              sizeof(interp_path));
+               if (rlen >= sizeof(interp_path)) {
+                       logerror("interpolated path too large: %s",
+                                interp_path);
+                       return NULL;
+               }
+
                strbuf_release(&expanded_path);
                loginfo("Interpolated dir '%s'", interp_path);
 
@@ -220,7 +233,11 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)
                        logerror("'%s': Non-absolute path denied (base-path active)", dir);
                        return NULL;
                }
-               snprintf(rpath, PATH_MAX, "%s%s", base_path, dir);
+               rlen = snprintf(rpath, sizeof(rpath), "%s%s", base_path, dir);
+               if (rlen >= sizeof(rpath)) {
+                       logerror("base-path too large: %s", rpath);
+                       return NULL;
+               }
                dir = rpath;
        }