read_gitfile_gently: fix use-after-free

The "dir" variable is a pointer into the "buf" array. When we hit the cleanup_return path, the first thing we do is free(buf); but one of the error messages prints "dir", which will access the memory after the free. We can fix this by reorganizing the error path a little. We act on the fatal, error-printing conditions first, as they want to access memory and do not care about freeing. Then we free any memory, and finally return. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Jun 26, 2015 at 05:03 UTC 38ae8784074852c8e7b651f4f6e44e07466da7e1
1 file changed +5 -9
setup.c
+5 -9
@@ -479,19 +479,14 @@ const char *read_gitfile_gently(const char *path, int *return_error_code)
479 path = real_path(dir);
480
481 cleanup_return:
482 - free(buf);
483 -
482 if (return_error_code)
483 *return_error_code = error_code;
486 -
487 - if (error_code) {
488 - if (return_error_code)
489 - return NULL;
490 -
484 + else if (error_code) {
485 switch (error_code) {
486 case READ_GITFILE_ERR_STAT_FAILED:
487 case READ_GITFILE_ERR_NOT_A_FILE:
494 - return NULL;
488 + /* non-fatal; follow return path */
489 + break;
490 case READ_GITFILE_ERR_OPEN_FAILED:
491 die_errno("Error opening '%s'", path);
492 case READ_GITFILE_ERR_TOO_LARGE:
@@ -509,7 +504,8 @@ cleanup_return:
504 }
505 }
506
512 - return path;
507 + free(buf);
508 + return error_code ? NULL : path;
509 }
510
511 static const char *setup_explicit_git_dir(const char *gitdirenv,