Skip to content

Commit

Permalink
unix-socket: avoid leak when initialization fails
Browse files Browse the repository at this point in the history
When a Unix socket is initialized, the current directory's path is
stored so that the cleanup code can `chdir()` back to where it was
before exit.

If the path that needs to be stored exceeds the default size of the
`sun_path` attribute of `struct sockaddr_un` (which is defined as a
108-sized byte array on Linux), a larger buffer needs to be allocated so
that it can hold the path, and it is the responsibility of the
`unix_sockaddr_cleanup()` function to release that allocated memory.

In Git's CI, this stack allocation is not necessary because the code is
checked out to `/home/runner/work/git/git`. Concatenate the path
`t/trash directory.t0301-credential-cache/.cache/git/credential/socket`
and a terminating NUL, and you end up with 96 bytes, 12 shy of the
default `sun_path` size.

However, I use worktrees with slightly longer paths:
`/home/me/projects/git/yes/i/nest/worktrees/to/organize/them/` is more
in line with what I have. When I recently tried to locally reproduce a
failure of the `linux-leaks` CI job, this t0301 test failed (where it
had not failed in CI).

The reason: When `credential-cache` tries to reach its daemon initially
by calling `unix_sockaddr_init()`, it is expected that the daemon cannot
be reached (the idea is to spin up the daemon in that case and try
again). However, when this first call to `unix_sockaddr_init()` fails,
the code returns early from the `unix_stream_connect()` function
_without_ giving the cleanup code a chance to run, skipping the
deallocation of above-mentioned path.

The fix is easy: do not return early but instead go directly to the
cleanup code.

Signed-off-by: Johannes Schindelin <[email protected]>
  • Loading branch information
dscho committed Feb 6, 2025
1 parent a62f00c commit ee1479b
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion unix-socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ int unix_stream_connect(const char *path, int disallow_chdir)
struct unix_sockaddr_context ctx;

if (unix_sockaddr_init(&sa, path, &ctx, disallow_chdir) < 0)
return -1;
goto fail;
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
goto fail;
Expand Down

0 comments on commit ee1479b

Please sign in to comment.