From 4ae95682694a1cd05ee2029fe241ad90d43c8c0e Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 26 Sep 2005 19:10:55 -0700 Subject: [PATCH 1/4] Support a modicum of path validation, and allow an export all trees option. --- daemon.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 5 deletions(-) diff --git a/daemon.c b/daemon.c index fe46d3e4c6..0ca6cef939 100644 --- a/daemon.c +++ b/daemon.c @@ -12,7 +12,13 @@ static int log_syslog; static int verbose; -static const char daemon_usage[] = "git-daemon [--verbose] [--syslog] [--inetd | --port=n]"; +static const char daemon_usage[] = "git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all] [directory...]"; + +/* List of acceptable pathname prefixes */ +static char **ok_paths = NULL; + +/* If this is set, git-daemon-export-ok is not required */ +static int export_all_trees = 0; static void logreport(int priority, const char *err, va_list params) @@ -69,15 +75,61 @@ void loginfo(const char *err, ...) va_end(params); } +static int path_ok(const char *dir) +{ + const char *p = dir; + char **pp; + int sl = 1, ndot = 0; + + for (;;) { + if ( *p == '.' ) { + ndot++; + } else if ( *p == '/' || *p == '\0' ) { + if ( sl && ndot > 0 && ndot < 3 ) + return 0; /* . or .. in path */ + sl = 1; + if ( *p == '\0' ) + break; /* End of string and all is good */ + } else { + sl = ndot = 0; + } + p++; + } + + if ( ok_paths && *ok_paths ) { + int ok = 0; + int dirlen = strlen(dir); /* read_packet_line can return embedded \0 */ + + for ( pp = ok_paths ; *pp ; pp++ ) { + int len = strlen(*pp); + if ( len <= dirlen && + !strncmp(*pp, dir, len) && + (dir[len] == '/' || dir[len] == '\0') ) { + ok = 1; + break; + } + } + + if ( !ok ) + return 0; /* Path not in whitelist */ + } + + return 1; /* Path acceptable */ +} static int upload(char *dir, int dirlen) { loginfo("Request for '%s'", dir); + + if (!path_ok(dir)) { + logerror("Forbidden directory: %s\n", dir); + return -1; + } + if (chdir(dir) < 0) { logerror("Cannot chdir('%s'): %s", dir, strerror(errno)); return -1; } - chdir(".git"); /* * Security on the cheap. @@ -86,10 +138,10 @@ static int upload(char *dir, int dirlen) * a "git-daemon-export-ok" flag that says that the other side * is ok with us doing this. */ - if (access("git-daemon-export-ok", F_OK) || + if ((!export_all_trees && access("git-daemon-export-ok", F_OK)) || access("objects/00", X_OK) || access("HEAD", R_OK)) { - logerror("Not a valid gitd-enabled repository: '%s'", dir); + logerror("Not a valid git-daemon-enabled repository: '%s'", dir); return -1; } @@ -441,7 +493,6 @@ int main(int argc, char **argv) continue; } } - if (!strcmp(arg, "--inetd")) { inetd_mode = 1; continue; @@ -455,6 +506,17 @@ int main(int argc, char **argv) openlog("git-daemon", 0, LOG_DAEMON); continue; } + if (!strcmp(arg, "--export-all")) { + export_all_trees = 1; + continue; + } + if (!strcmp(arg, "--")) { + ok_paths = &argv[i+1]; + break; + } else if (arg[0] != '-') { + ok_paths = &argv[i]; + break; + } usage(daemon_usage); } From 47888f0f3188c39e13e02ad8442c5e785d2ebcdd Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 27 Sep 2005 08:49:40 -0700 Subject: [PATCH 2/4] Restore chdir(".git") --- daemon.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/daemon.c b/daemon.c index 0ca6cef939..a369ce527e 100644 --- a/daemon.c +++ b/daemon.c @@ -131,6 +131,8 @@ static int upload(char *dir, int dirlen) return -1; } + chdir(".git"); + /* * Security on the cheap. * From 8fc7ba85c9f6f3d599e9f81cf9fbd0d014b5dad4 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 27 Sep 2005 09:01:08 -0700 Subject: [PATCH 3/4] Parallelize the build --- git-core.spec.in | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/git-core.spec.in b/git-core.spec.in index 6af5103ee6..e8cc6afe53 100644 --- a/git-core.spec.in +++ b/git-core.spec.in @@ -23,12 +23,12 @@ elsewhere for tools for ordinary humans layered on top of this. %setup -q %build -make COPTS="$RPM_OPT_FLAGS" WITH_OWN_SUBPROCESS_PY=YesPlease \ +make %{_smp_mflags} COPTS="$RPM_OPT_FLAGS" WITH_OWN_SUBPROCESS_PY=YesPlease \ prefix=%{_prefix} all %{!?_without_docs: doc} %install rm -rf $RPM_BUILD_ROOT -make DESTDIR=$RPM_BUILD_ROOT WITH_OWN_SUBPROCESS_PY=YesPlease \ +make %{_smp_mflags} DESTDIR=$RPM_BUILD_ROOT WITH_OWN_SUBPROCESS_PY=YesPlease \ prefix=%{_prefix} mandir=%{_mandir} \ install %{!?_without_docs: install-doc} @@ -45,6 +45,9 @@ rm -rf $RPM_BUILD_ROOT %{!?_without_docs: %{_mandir}/man7/*.7*} %changelog +* Tue Sep 27 2005 H. Peter Anvin +- parallelize build + * Fri Sep 16 2005 Chris Wright 0.99.6-1 - update to 0.99.6 From e8f71fce3720016d1e9ae3070a8774c19888dc59 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 27 Sep 2005 09:02:24 -0700 Subject: [PATCH 4/4] COPTS -> CFLAGS --- git-core.spec.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/git-core.spec.in b/git-core.spec.in index e8cc6afe53..8763069442 100644 --- a/git-core.spec.in +++ b/git-core.spec.in @@ -23,7 +23,7 @@ elsewhere for tools for ordinary humans layered on top of this. %setup -q %build -make %{_smp_mflags} COPTS="$RPM_OPT_FLAGS" WITH_OWN_SUBPROCESS_PY=YesPlease \ +make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" WITH_OWN_SUBPROCESS_PY=YesPlease \ prefix=%{_prefix} all %{!?_without_docs: doc} %install @@ -47,6 +47,7 @@ rm -rf $RPM_BUILD_ROOT %changelog * Tue Sep 27 2005 H. Peter Anvin - parallelize build +- COPTS -> CFLAGS * Fri Sep 16 2005 Chris Wright 0.99.6-1 - update to 0.99.6