Skip to content

Commit 64f1e65

Browse files
ttaylorrpeff
authored andcommitted
contrib/credential: avoid fixed-size buffer in libsecret
The libsecret credential helper reads the newline-delimited protocol stream one line at a time by repeatedly calling fgets() into a fixed-size buffer, and is thus affected by the vulnerability described in the previous commit. To mitigate this attack, avoid using a fixed-size buffer, and instead rely on getline() to allocate a buffer as large as necessary to fit the entire content of the line, preventing any protocol injection. In most parts of Git we don't assume that every platform has getline(). But libsecret is primarily used on Linux, where we do already assume it (using a knob in config.mak.uname). POSIX also added getline() in 2008, so we'd expect other recent Unix-like operating systems to have it (e.g., FreeBSD also does). Note that the buffer was already allocated on the heap in this case, but we'll swap `g_free()` for `free()`, since it will now be allocated by the system `getline()`, rather than glib's `g_malloc()`. Tested-by: Jeff King <[email protected]> Co-authored-by: Jeff King <[email protected]> Signed-off-by: Jeff King <[email protected]> Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent de2fb99 commit 64f1e65

File tree

1 file changed

+7
-8
lines changed

1 file changed

+7
-8
lines changed

contrib/credential/libsecret/git-credential-libsecret.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -244,17 +244,16 @@ static void credential_clear(struct credential *c)
244244

245245
static int credential_read(struct credential *c)
246246
{
247-
char *buf;
248-
size_t line_len;
247+
char *buf = NULL;
248+
size_t alloc;
249+
ssize_t line_len;
249250
char *key;
250251
char *value;
251252

252-
key = buf = g_malloc(1024);
253+
while ((line_len = getline(&buf, &alloc, stdin)) > 0) {
254+
key = buf;
253255

254-
while (fgets(buf, 1024, stdin)) {
255-
line_len = strlen(buf);
256-
257-
if (line_len && buf[line_len-1] == '\n')
256+
if (buf[line_len-1] == '\n')
258257
buf[--line_len] = '\0';
259258

260259
if (!line_len)
@@ -298,7 +297,7 @@ static int credential_read(struct credential *c)
298297
*/
299298
}
300299

301-
g_free(buf);
300+
free(buf);
302301

303302
return 0;
304303
}

0 commit comments

Comments
 (0)