git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: git-daemon --inetd

From
Linus Torvalds <torvalds@osdl.org>
Date
Sep 15, 2005, 16:03 UTC
Message-ID
<Pine.LNX.4.58.0509150829090.26803@g5.osdl.org>
In-Reply-To
<43290EFF.3070604@zytor.com>
On Wed, 14 Sep 2005, H. Peter Anvin wrote:
> 
> On that note, though, it would be very nice if there was a way to run 
> git-daemon in a chroot, or otherwise restrict it to a specific 
> subhierarchy of the filesystem.

Hmm.. That should work fine. You can already just run it that way by just wrapping it in "chroot", but if you don't want that for some reason, how about a patch like this?

It compiles. That's just about all I can say about it.
		Linus
---
diff --git a/daemon.c b/daemon.c
--- a/daemon.c
+++ b/daemon.c
@@ -1,11 +1,19 @@
+/* setresuid/setresgid. GNU? Who are you kidding, glibc? */
+#define _GNU_SOURCE
+
 #include "cache.h"
 #include "pkt-line.h"
 #include <signal.h>
 #include <sys/wait.h>
 #include <sys/socket.h>
 #include <sys/time.h>
+#include <sys/types.h>
 #include <netdb.h>
 #include <netinet/in.h>
+#include <unistd.h>
+
+#include <pwd.h>
+#include <grp.h>
 
 static const char daemon_usage[] = "git-daemon [--inetd | --port=n]";
 
@@ -326,10 +334,50 @@ static int serve(int port)
 	}
 }
 
+/*
+ * This will drop our effective uid/gid to the real one,
+ * even if no "--user=" or "--group=" arguments were used.
+ *
+ * So it's not a no-op even without that.
+ */
+static void set_user_group(const char *user, const char *group)
+{
+	uid_t uid = getuid();
+	gid_t gid = getgid();
+	char *end;
+
+	if (user) {
+		struct passwd *pw = getpwnam(user);
+		if (pw) {
+			uid = pw->pw_uid;
+			gid = pw->pw_gid;
+		} else {
+			uid = strtol(user, &end, 10);
+			if (*end || end == user)
+				die("invalid user name '%s'", user);
+		}
+	}
+	if (group) {
+		struct group *grp = getgrnam(group);
+		if (grp) {
+			gid = grp->gr_gid;
+		} else {
+			gid = strtol(group, &end, 10);
+			if (*end || end == group)
+				die("invalid group name '%s'", group);
+		}
+	}
+	if (!uid || !gid)
+		die("I refuse to run as root");
+	if (setresgid(gid, gid, gid) || setresuid(uid, uid, uid))
+		die("I can't run as %d:%d", uid, gid);
+}
+
 int main(int argc, char **argv)
 {
 	int port = DEFAULT_GIT_PORT;
 	int inetd_mode = 0;
+	const char *user = NULL, *group = NULL;
 	int i;
 
 	for (i = 1; i < argc; i++) {
@@ -350,9 +398,32 @@ int main(int argc, char **argv)
 			continue;
 		}
 
+		if (!strncmp(arg, "--chroot=", 9)) {
+			if (chroot(arg+9) < 0)
+				die("unable to chroot to '%s': %s", arg+9, strerror(errno));
+			if (chdir("/") < 0)
+				die("unable to chdir to new root");
+
+			user = user ? user : "nobody";
+			group = group ? group : "nobody";
+			continue;
+		}
+
+		if (!strncmp(arg, "--user=", 7)) {
+			user = arg+7;
+			continue;
+		}
+
+		if (!strncmp(arg, "--group=", 8)) {
+			group = arg + 8;
+			continue;
+		}
+
 		usage(daemon_usage);
 	}
 
+	set_user_group(user, group);
+
 	if (inetd_mode) {
 		fclose(stderr); //FIXME: workaround
 		return execute();
Previous: H. Peter AnvinNext: H. Peter Anvin
Message 2 of 15 in “git-daemon --inetd”
  1. H. Peter AnvinSep 15, 2005
  2. Linus TorvaldsSep 15, 2005
  3. H. Peter AnvinSep 15, 2005
  4. Linus TorvaldsSep 15, 2005
  5. H. Peter AnvinSep 15, 2005
  6. Linus TorvaldsSep 15, 2005
  7. Martin LanghoffSep 15, 2005
  8. Jon SeymourOct 22, 2005
  9. Linus TorvaldsOct 22, 2005
  10. Junio C HamanoSep 15, 2005
  11. Junio C HamanoSep 16, 2005
  12. Junio C HamanoSep 16, 2005
  13. H. Peter AnvinSep 16, 2005
  14. Linus TorvaldsSep 16, 2005
  15. H. Peter AnvinSep 16, 2005

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.