"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Omar Polo <op@omarpolo.com>
Subject:
Re: gotwebd: leaks in blame page
To:
Stefan Sperling <stsp@stsp.name>
Cc:
gameoftrees@openbsd.org
Date:
Sat, 03 Sep 2022 12:51:12 +0200

Download raw body.

Thread
On 2022/09/03 09:31:45 +0200, Stefan Sperling <stsp@stsp.name> wrote:
> On Fri, Sep 02, 2022 at 05:20:09PM +0200, Omar Polo wrote:
> > however, the blame page still leaks like crazy.  There's some serious
> > leak between got_gotweb_blame_cb and got_output_file_blame that I'm
> > just not seeing.
> > 
> > In a controlled environment (localhost) after 1K requests to a blame
> > page (always the same to rule out the cache) gotwebd' RES is 24M.  If
> > I comment the call to got_blame then it's "just" ~5M.  So, it leaks
> > both outside got_output_file_blame but the more serious leak is
> > inside.
> 
> Is this easy to trigger via a reproducer hacked into got/got.c?

it seems so!

it's an hack of a diff but then `got blame Makefile' starts leaking
memory quite fast.

diff /home/op/w/got
commit - 06edcc519b27fc4831d2583a8dd10c7d2ab61e10
path + /home/op/w/got
blob - 64ef5fc0ef4b1bd3dce557f8ecb20c5f2946dee6
file + got/got.c
--- got/got.c
+++ got/got.c
@@ -5402,7 +5402,7 @@ done:
 }
 
 static const struct got_error *
-cmd_blame(int argc, char *argv[])
+i_cmd_blame(int argc, char *argv[])
 {
 	const struct got_error *error;
 	struct got_repository *repo = NULL;
@@ -5426,11 +5426,11 @@ cmd_blame(int argc, char *argv[])
 
 	memset(&bca, 0, sizeof(bca));
 
-#ifndef PROFILE
-	if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil",
-	    NULL) == -1)
-		err(1, "pledge");
-#endif
+/* #ifndef PROFILE */
+/* 	if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil", */
+/* 	    NULL) == -1) */
+/* 		err(1, "pledge"); */
+/* #endif */
 
 	while ((ch = getopt(argc, argv, "c:r:")) != -1) {
 		switch (ch) {
@@ -5510,11 +5510,11 @@ cmd_blame(int argc, char *argv[])
 			goto done;
 		}
 		free(p);
-		error = apply_unveil(got_repo_get_path(repo), 1, NULL);
+		/* error = apply_unveil(got_repo_get_path(repo), 1, NULL); */
 	} else {
-		error = apply_unveil(got_repo_get_path(repo), 1, NULL);
-		if (error)
-			goto done;
+		/* error = apply_unveil(got_repo_get_path(repo), 1, NULL); */
+		/* if (error) */
+			/* goto done; */
 		error = got_repo_map_path(&in_repo_path, repo, path);
 	}
 	if (error)
@@ -5678,6 +5678,18 @@ done:
 	return error;
 }
 
+static const struct got_error *
+cmd_blame(int argc, char **argv)
+{
+	const struct got_error *error;
+
+	for (;;) {
+		error = i_cmd_blame(argc, argv);
+		if (error)
+			return error;
+	}
+}
+
 __dead static void
 usage_tree(void)
 {