diff options
author | koeleck <779769+koeleck@users.noreply.github.com> | 2023-03-19 22:32:37 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-19 14:32:37 -0700 |
commit | 84027f7515b8ee6f818462f105882fc0052783c4 (patch) | |
tree | 9e48424644e31cd4af75714328a3be6d408f6910 | |
parent | ecc4d0e435d618828b938d78fbded7fbe1314760 (diff) | |
download | rneovim-84027f7515b8ee6f818462f105882fc0052783c4.tar.gz rneovim-84027f7515b8ee6f818462f105882fc0052783c4.tar.bz2 rneovim-84027f7515b8ee6f818462f105882fc0052783c4.zip |
fix: invalid buffer size argument to snprintf #22729
Problem:
Crash in findtags_add_match with FORTIFY_SOURCE=3.
Note: Fedora 38 packages are now built with -D_FORTIFY_SOURCE=3 by default.
1. Compile with overflow protection.
2. nvim --clean
3. :h <Space> <Tab>
4. `*** overflow detected ***: terminated`
The additional checks for the stated buffer size and the actual bounds
of the buffer do not match. See `___snprintf_chk` in the glibc sources:
https://sourceware.org/git/?p=glibc.git;a=blob;f=debug/snprintf_chk.c;h=59577de076c570b81307dd31c8c73e265808cf4c;hb=HEAD#l28
Solution:
Fix arithmetic error: The length of the previously written data is now
subtracted from the total size of the buffer, instead of added on top.
close #22718
-rw-r--r-- | src/nvim/tag.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 774157831d..852e7e6e7c 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -1947,6 +1947,7 @@ static void findtags_add_match(findtags_state_T *st, tagptrs_T *tagpp, findtags_ const bool name_only = (st->flags & TAG_NAMES); int mtt; size_t len = 0; + size_t mfp_size = 0; bool is_current; // file name matches bool is_static; // current tag line is static char *mfp; @@ -1990,13 +1991,14 @@ static void findtags_add_match(findtags_state_T *st, tagptrs_T *tagpp, findtags_ // The format is {tagname}@{lang}NUL{heuristic}NUL *tagpp->tagname_end = NUL; len = (size_t)(tagpp->tagname_end - tagpp->tagname); - mfp = xmalloc(sizeof(char) + len + 10 + ML_EXTRA + 1); + mfp_size = sizeof(char) + len + 10 + ML_EXTRA + 1; + mfp = xmalloc(mfp_size); p = mfp; STRCPY(p, tagpp->tagname); p[len] = '@'; STRCPY(p + len + 1, st->help_lang); - snprintf(p + len + 1 + ML_EXTRA, strlen(p) + len + 1 + ML_EXTRA, "%06d", + snprintf(p + len + 1 + ML_EXTRA, mfp_size - (len + 1 + ML_EXTRA), "%06d", help_heuristic(tagpp->tagname, margs->match_re ? margs->matchoff : 0, !margs->match_no_ic) + st->help_pri); |