From: Junio C Hamano Date: Tue, 19 Sep 2017 01:47:55 +0000 (+0900) Subject: Merge branch 'jk/leak-checkers' X-Git-Tag: v2.15.0-rc0~83 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/09595ab3818619a34281b85e1fb98802182e12a2?ds=inline;hp=-c Merge branch 'jk/leak-checkers' Many of our programs consider that it is OK to release dynamic storage that is used throughout the life of the program by simply exiting, but this makes it harder to leak detection tools to avoid reporting false positives. Plug many existing leaks and introduce a mechanism for developers to mark that the region of memory pointed by a pointer is not lost/leaking to help these tools. * jk/leak-checkers: add UNLEAK annotation for reducing leak false positives set_git_dir: handle feeding gitdir to itself repository: free fields before overwriting them reset: free allocated tree buffers reset: make tree counting less confusing config: plug user_config leak update-index: fix cache entry leak in add_one_file() add: free leaked pathspec after add_files_to_cache() test-lib: set LSAN_OPTIONS to abort by default test-lib: --valgrind should not override --verbose-log --- 09595ab3818619a34281b85e1fb98802182e12a2 diff --combined Makefile index 68948dfbf3,c052f09bba..ed5960e6b3 --- a/Makefile +++ b/Makefile @@@ -162,11 -162,6 +162,11 @@@ all: # algorithm. This is slower, but may detect attempted collision attacks. # Takes priority over other *_SHA1 knobs. # +# Define DC_SHA1_EXTERNAL in addition to DC_SHA1 if you want to build / link +# git with the external SHA1 collision-detect library. +# Without this option, i.e. the default behavior is to build git with its +# own built-in code (or submodule). +# # Define DC_SHA1_SUBMODULE in addition to DC_SHA1 to use the # sha1collisiondetection shipped as a submodule instead of the # non-submodule copy in sha1dc/. This is an experimental option used @@@ -1041,6 -1036,9 +1041,9 @@@ BASIC_CFLAGS += -fno-omit-frame-pointe ifneq ($(filter undefined,$(SANITIZERS)),) BASIC_CFLAGS += -DNO_UNALIGNED_LOADS endif + ifneq ($(filter leak,$(SANITIZERS)),) + BASIC_CFLAGS += -DSUPPRESS_ANNOTATED_LEAKS + endif endif ifndef sysconfdir @@@ -1480,15 -1478,6 +1483,15 @@@ ifdef APPLE_COMMON_CRYPT BASIC_CFLAGS += -DSHA1_APPLE else DC_SHA1 := YesPlease + BASIC_CFLAGS += -DSHA1_DC + LIB_OBJS += sha1dc_git.o +ifdef DC_SHA1_EXTERNAL + ifdef DC_SHA1_SUBMODULE +$(error Only set DC_SHA1_EXTERNAL or DC_SHA1_SUBMODULE, not both) + endif + BASIC_CFLAGS += -DDC_SHA1_EXTERNAL + EXTLIBS += -lsha1detectcoll +else ifdef DC_SHA1_SUBMODULE LIB_OBJS += sha1collisiondetection/lib/sha1.o LIB_OBJS += sha1collisiondetection/lib/ubc_check.o @@@ -1498,15 -1487,17 +1501,15 @@@ els LIB_OBJS += sha1dc/ubc_check.o endif BASIC_CFLAGS += \ - -DSHA1_DC \ -DSHA1DC_NO_STANDARD_INCLUDES \ -DSHA1DC_INIT_SAFE_HASH_DEFAULT=0 \ -DSHA1DC_CUSTOM_INCLUDE_SHA1_C="\"cache.h\"" \ - -DSHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_C="\"sha1dc_git.c\"" \ - -DSHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_H="\"sha1dc_git.h\"" \ -DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C="\"git-compat-util.h\"" endif endif endif endif +endif ifdef SHA1_MAX_BLOCK_SIZE LIB_OBJS += compat/sha1-chunked.o diff --combined builtin/reset.c index f1af9345e4,0295c961a3..9cd89b2305 --- a/builtin/reset.c +++ b/builtin/reset.c @@@ -44,10 -44,11 +44,11 @@@ static inline int is_merge(void static int reset_index(const struct object_id *oid, int reset_type, int quiet) { - int nr = 1; + int i, nr = 0; struct tree_desc desc[2]; struct tree *tree; struct unpack_trees_options opts; + int ret = -1; memset(&opts, 0, sizeof(opts)); opts.head_idx = 1; @@@ -75,23 -76,32 +76,32 @@@ struct object_id head_oid; if (get_oid("HEAD", &head_oid)) return error(_("You do not have a valid HEAD.")); - if (!fill_tree_descriptor(desc, &head_oid)) + if (!fill_tree_descriptor(desc + nr, &head_oid)) return error(_("Failed to find tree of HEAD.")); nr++; opts.fn = twoway_merge; } - if (!fill_tree_descriptor(desc + nr - 1, oid)) - return error(_("Failed to find tree of %s."), oid_to_hex(oid)); + if (!fill_tree_descriptor(desc + nr, oid)) { + error(_("Failed to find tree of %s."), oid_to_hex(oid)); + goto out; + } + nr++; + if (unpack_trees(nr, desc, &opts)) - return -1; + goto out; if (reset_type == MIXED || reset_type == HARD) { tree = parse_tree_indirect(oid); prime_cache_tree(&the_index, tree); } - return 0; + ret = 0; + + out: + for (i = 0; i < nr; i++) + free((void *)desc[i].buffer); + return ret; } static void print_new_head_line(struct commit *commit) @@@ -367,8 -377,8 +377,8 @@@ int cmd_reset(int argc, const char **ar die_if_unmerged_cache(reset_type); if (reset_type != SOFT) { - struct lock_file *lock = xcalloc(1, sizeof(*lock)); - hold_locked_index(lock, LOCK_DIE_ON_ERROR); + struct lock_file lock = LOCK_INIT; + hold_locked_index(&lock, LOCK_DIE_ON_ERROR); if (reset_type == MIXED) { int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN; if (read_from_tree(&pathspec, &oid, intent_to_add)) @@@ -384,7 -394,7 +394,7 @@@ die(_("Could not reset index file to revision '%s'."), rev); } - if (write_locked_index(&the_index, lock, COMMIT_LOCK)) + if (write_locked_index(&the_index, &lock, COMMIT_LOCK)) die(_("Could not write new index file.")); } diff --combined builtin/update-index.c index 655e6d60d3,d955cd56b3..bf7420b808 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@@ -287,8 -287,10 +287,10 @@@ static int add_one_path(const struct ca } option = allow_add ? ADD_CACHE_OK_TO_ADD : 0; option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0; - if (add_cache_entry(ce, option)) + if (add_cache_entry(ce, option)) { + free(ce); return error("%s: cannot add to the index - missing --add option?", path); + } return 0; } @@@ -915,7 -917,7 +917,7 @@@ int cmd_update_index(int argc, const ch struct refresh_params refresh_args = {0, &has_errors}; int lock_error = 0; int split_index = -1; - struct lock_file *lock_file; + struct lock_file lock_file = LOCK_INIT; struct parse_opt_ctx_t ctx; strbuf_getline_fn getline_fn; int parseopt_state = PARSE_OPT_UNKNOWN; @@@ -1014,8 -1016,11 +1016,8 @@@ git_config(git_default_config, NULL); - /* We can't free this memory, it becomes part of a linked list parsed atexit() */ - lock_file = xcalloc(1, sizeof(struct lock_file)); - /* we will diagnose later if it turns out that we need to update it */ - newfd = hold_locked_index(lock_file, 0); + newfd = hold_locked_index(&lock_file, 0); if (newfd < 0) lock_error = errno; @@@ -1150,11 -1155,11 +1152,11 @@@ exit(128); unable_to_lock_die(get_index_file(), lock_error); } - if (write_locked_index(&the_index, lock_file, COMMIT_LOCK)) + if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK)) die("Unable to write new index file"); } - rollback_lock_file(lock_file); + rollback_lock_file(&lock_file); return has_errors ? 1 : 0; }