From: Omar Polo Subject: Re: gotwebd: leaks in blame page To: Stefan Sperling Cc: gameoftrees@openbsd.org Date: Sat, 03 Sep 2022 12:51:12 +0200 On 2022/09/03 09:31:45 +0200, Stefan Sperling 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) {