From: Junio C Hamano Date: Wed, 25 Apr 2018 04:29:03 +0000 (+0900) Subject: Merge branch 'bp/fsmonitor-bufsize-fix' X-Git-Tag: v2.18.0-rc0~112 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/beed7e22fdc81ba325c4bfaadf84d23f5c697d93?ds=inline;hp=-c Merge branch 'bp/fsmonitor-bufsize-fix' Fix an unexploitable (because the oversized contents are not under attacker's control) buffer overflow. * bp/fsmonitor-bufsize-fix: fsmonitor: fix incorrect buffer size when printing version number --- beed7e22fdc81ba325c4bfaadf84d23f5c697d93 diff --combined fsmonitor.c index 6d7bcd5d0e,512615eef5..eb4e642256 --- a/fsmonitor.c +++ b/fsmonitor.c @@@ -26,6 -26,7 +26,6 @@@ int read_fsmonitor_extension(struct ind uint32_t hdr_version; uint32_t ewah_size; struct ewah_bitmap *fsmonitor_dirty; - int i; int ret; if (sz < sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint32_t)) @@@ -48,25 -49,31 +48,25 @@@ ewah_free(fsmonitor_dirty); return error("failed to parse ewah bitmap reading fsmonitor index extension"); } - - if (git_config_get_fsmonitor()) { - /* Mark all entries valid */ - for (i = 0; i < istate->cache_nr; i++) - istate->cache[i]->ce_flags |= CE_FSMONITOR_VALID; - - /* Mark all previously saved entries as dirty */ - ewah_each_bit(fsmonitor_dirty, fsmonitor_ewah_callback, istate); - - /* Now mark the untracked cache for fsmonitor usage */ - if (istate->untracked) - istate->untracked->use_fsmonitor = 1; - } - ewah_free(fsmonitor_dirty); + istate->fsmonitor_dirty = fsmonitor_dirty; trace_printf_key(&trace_fsmonitor, "read fsmonitor extension successful"); return 0; } +void fill_fsmonitor_bitmap(struct index_state *istate) +{ + int i; + istate->fsmonitor_dirty = ewah_new(); + for (i = 0; i < istate->cache_nr; i++) + if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID)) + ewah_set(istate->fsmonitor_dirty, i); +} + void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate) { uint32_t hdr_version; uint64_t tm; - struct ewah_bitmap *bitmap; - int i; uint32_t ewah_start; uint32_t ewah_size = 0; int fixup = 0; @@@ -80,9 -87,12 +80,9 @@@ strbuf_add(sb, &ewah_size, sizeof(uint32_t)); /* we'll fix this up later */ ewah_start = sb->len; - bitmap = ewah_new(); - for (i = 0; i < istate->cache_nr; i++) - if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID)) - ewah_set(bitmap, i); - ewah_serialize_strbuf(bitmap, sb); - ewah_free(bitmap); + ewah_serialize_strbuf(istate->fsmonitor_dirty, sb); + ewah_free(istate->fsmonitor_dirty); + istate->fsmonitor_dirty = NULL; /* fix up size field */ put_be32(&ewah_size, sb->len - ewah_start); @@@ -104,14 -114,13 +104,14 @@@ static int query_fsmonitor(int version if (!(argv[0] = core_fsmonitor)) return -1; - snprintf(ver, sizeof(version), "%d", version); + snprintf(ver, sizeof(ver), "%d", version); snprintf(date, sizeof(date), "%" PRIuMAX, (uintmax_t)last_update); argv[1] = ver; argv[2] = date; argv[3] = NULL; cp.argv = argv; cp.use_shell = 1; + cp.dir = get_git_work_tree(); return capture_command(&cp, query_result, 1024); } @@@ -130,7 -139,7 +130,7 @@@ static void fsmonitor_refresh_callback( * as it could be a new untracked file. */ trace_printf_key(&trace_fsmonitor, "fsmonitor_refresh_callback '%s'", name); - untracked_cache_invalidate_path(istate, name); + untracked_cache_invalidate_path(istate, name, 0); } void refresh_fsmonitor(struct index_state *istate) @@@ -229,29 -238,7 +229,29 @@@ void remove_fsmonitor(struct index_stat void tweak_fsmonitor(struct index_state *istate) { - switch (git_config_get_fsmonitor()) { + int i; + int fsmonitor_enabled = git_config_get_fsmonitor(); + + if (istate->fsmonitor_dirty) { + if (fsmonitor_enabled) { + /* Mark all entries valid */ + for (i = 0; i < istate->cache_nr; i++) { + istate->cache[i]->ce_flags |= CE_FSMONITOR_VALID; + } + + /* Mark all previously saved entries as dirty */ + ewah_each_bit(istate->fsmonitor_dirty, fsmonitor_ewah_callback, istate); + + /* Now mark the untracked cache for fsmonitor usage */ + if (istate->untracked) + istate->untracked->use_fsmonitor = 1; + } + + ewah_free(istate->fsmonitor_dirty); + istate->fsmonitor_dirty = NULL; + } + + switch (fsmonitor_enabled) { case -1: /* keep: do nothing */ break; case 0: /* false */