http-backend: Protect GIT_PROJECT_ROOT from /../ requests
[gitweb.git] / http-backend.c
index 902126675a04d13aa18a24aea29230433eb0a0b1..f8ea9d7faa0494375d3d5413e91869d74252d649 100644 (file)
@@ -209,7 +209,7 @@ static void send_strbuf(const char *type, struct strbuf *buf)
        safe_write(1, buf->buf, buf->len);
 }
 
-static void send_file(const char *the_type, const char *name)
+static void send_local_file(const char *the_type, const char *name)
 {
        const char *p = git_path("%s", name);
        size_t buf_alloc = 8192;
@@ -247,28 +247,28 @@ static void get_text_file(char *name)
 {
        select_getanyfile();
        hdr_nocache();
-       send_file("text/plain", name);
+       send_local_file("text/plain", name);
 }
 
 static void get_loose_object(char *name)
 {
        select_getanyfile();
        hdr_cache_forever();
-       send_file("application/x-git-loose-object", name);
+       send_local_file("application/x-git-loose-object", name);
 }
 
 static void get_pack_file(char *name)
 {
        select_getanyfile();
        hdr_cache_forever();
-       send_file("application/x-git-packed-objects", name);
+       send_local_file("application/x-git-packed-objects", name);
 }
 
 static void get_idx_file(char *name)
 {
        select_getanyfile();
        hdr_cache_forever();
-       send_file("application/x-git-packed-objects-toc", name);
+       send_local_file("application/x-git-packed-objects-toc", name);
 }
 
 static int http_config(const char *var, const char *value, void *cb)
@@ -559,7 +559,13 @@ static char* getdir(void)
        if (root && *root) {
                if (!pathinfo || !*pathinfo)
                        die("GIT_PROJECT_ROOT is set but PATH_INFO is not");
+               if (daemon_avoid_alias(pathinfo))
+                       die("'%s': aliased", pathinfo);
                strbuf_addstr(&buf, root);
+               if (buf.buf[buf.len - 1] != '/')
+                       strbuf_addch(&buf, '/');
+               if (pathinfo[0] == '/')
+                       pathinfo++;
                strbuf_addstr(&buf, pathinfo);
                return strbuf_detach(&buf, NULL);
        } else if (path && *path) {