Christian Brabandt wrote:

> Bram,
> I tend to abort long running z= commands by pressing <Ctrl-C>. This
> randomly crashed Vim for me, but until now, I couldn't reliably
> reproduce it, possibly it is timing dependent or influenced by some
> setting, I don't know.
>
> However, I could just get a stacktrace as well as some valgrind logfiles
> (see attached tar.xz file). Both logfiles are not very helpful. It seems
> like Vim is allocating a lot of memory and finally gets killed. The
> problem lies in the the add_sound_suggest() function and it seems, wlen
> runs over. When gdb caught SEGV, it was at some value of above 21000.
>
> Here is a patch, that makes sure, wlen doesn't increment over MAXWLEN
> and fixes it for me. So please include it.
>
>
> diff --git a/src/spell.c b/src/spell.c
> --- a/src/spell.c
> +++ b/src/spell.c
> @@ -13382,6 +13382,10 @@
>         wordcount = 0;
>         for (;;)
>         {
> +           if (wlen > MAXWLEN)
> +               /* safety check */
> +               break;
> +
>             i = 1;
>             if (wordcount == orgnr && byts[n + 1] == NUL)
>                 break;  /* found end of word */


Trying to press CTRL-C right after  z=  as you describe, it
did not take me long to get a crash as well using vim-7.4.92
on Linux x86_84. This is the error I got with valgrind, which
is different than yours:

==3900== Memcheck, a memory error detector
==3900== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3900== Using Valgrind-3.9.0.SVN and LibVEX; rerun with -h for copyright info
==3900== Command: ./vim spell.c
==3900== Parent PID: 3839
==3900==
==3900== Invalid read of size 1
==3900==    at 0x56CE37: spell_edit_score (spell.c:15072)
==3900==    by 0x571913: suggest_trie_walk (spell.c:13504)
==3900==    by 0x568365: spell_find_suggest (spell.c:13277)
==3900==    by 0x566F3E: spell_suggest (spell.c:10245)
==3900==    by 0x4DDD8D: nv_zet (normal.c:5272)
==3900==    by 0x4D4460: normal_cmd (normal.c:1200)
==3900==    by 0x5C1872: main_loop (main.c:1329)
==3900==    by 0x5C0DF1: main (main.c:1020)
==3900==  Address 0xf00000001 is not stack'd, malloc'd or (recently) free'd
==3900==

It happened with  spelllang=fr, when pressing z= on the
word  x  (only one letter x).

It does not happen all the time, but it's easy to reproduce
after trying several times, always with the same stack trace
as above and with the same invalid address 0xf00000001

Code where it crashes:

15048     static int
15049 spell_edit_score(slang, badword, goodword)
.....
15069         for (p = badword, badlen = 0; *p != NUL; )
15070             wbadword[badlen++] = mb_cptr2char_adv(&p);

It must be p which is wrong (i.e. parameter badword).


Trying also with clang-3.4 address sanitizer and undefined
sanitizer (clang -fsanituze=address,undefined) shows a
stack buffer overflow (such stack overflows can't be detected
by valgrind but are detected by the address sanitizer):

==4531==ERROR: AddressSanitizer: stack-buffer-overflow on address
0x7fff0f0404ba at pc 0x1a05fd3 bp 0x7fff0f03f970 sp 0x7fff0f03f968
WRITE of size 1 at 0x7fff0f0404ba thread T0
    #0 0x1a05fd2 in add_sound_suggest /home/pel/sb/vim/src/spell.c:13429
    #1 0x19c7ab7 in suggest_trie_walk /home/pel/sb/vim/src/spell.c:11729
    #2 0x19b6121 in suggest_try_soundalike /home/pel/sb/vim/src/spell.c:13277
    #3 0x198b7c5 in spell_suggest_intern /home/pel/sb/vim/src/spell.c:10876
    #4 0x1947750 in spell_find_suggest /home/pel/sb/vim/src/spell.c:10711
    #5 0x193d3b8 in spell_suggest /home/pel/sb/vim/src/spell.c:10245
    #6 0x127a543 in nv_zet /home/pel/sb/vim/src/normal.c:5272
    #7 0x119fb5b in normal_cmd /home/pel/sb/vim/src/normal.c:1200
    #8 0x1fcbb64 in main_loop /home/pel/sb/vim/src/main.c:1329
    #9 0x1faa79c in main /home/pel/sb/vim/src/main.c:1020
    #10 0x7fba1dd10de4 in __libc_start_main
/build/buildd/eglibc-2.17/csu/libc-start.c:260
    #11 0x4a880c in _start (/home/pel/sb/vim/src/vim+0x4a880c)

Address 0x7fff0f0404ba is located in stack of thread T0 at offset 794 in frame
    #0 0x1a0273f in add_sound_suggest /home/pel/sb/vim/src/spell.c:13328

  This frame has 26 object(s):
    [32, 40) 'su.addr'
    [96, 104) 'goodword.addr'
    [160, 164) 'score.addr'
    [224, 232) 'lp.addr'
    [288, 296) 'slang'
    [352, 356) 'sfwordnr'
    [416, 424) 'nrline'
    [480, 484) 'orgnr'
    [544, 794) 'theword' <== Memory access at offset 794 overflows this variable
    [832, 836) 'i'
    [896, 900) 'wlen'
    [960, 968) 'byts'
    [1024, 1032) 'idxs'
    [1088, 1092) 'n'
    [1152, 1156) 'wordcount'
    [1216, 1220) 'wc'
    [1280, 1284) 'goodscore'
    [1344, 1352) 'hash'
    [1408, 1416) 'hi'
    [1472, 1480) 'sft'
    [1536, 1540) 'bc'
    [1600, 1604) 'gc'
    [1664, 1668) 'limit'
    [1728, 1978) 'cword'
    [2016, 2024) 'p'
    [2080, 2084) 'flags'
HINT: this may be a false positive if your program uses some custom
stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow
/home/pel/sb/vim/src/spell.c:13429 add_sound_suggest
Shadow bytes around the buggy address:
  0x100061e00040: 00 f4 f4 f4 f2 f2 f2 f2 04 f4 f4 f4 f2 f2 f2 f2
  0x100061e00050: 00 f4 f4 f4 f2 f2 f2 f2 00 f4 f4 f4 f2 f2 f2 f2
  0x100061e00060: 04 f4 f4 f4 f2 f2 f2 f2 00 f4 f4 f4 f2 f2 f2 f2
  0x100061e00070: 04 f4 f4 f4 f2 f2 f2 f2 00 00 00 00 00 00 00 00
  0x100061e00080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100061e00090: 00 00 00 00 00 00 00[02]f2 f2 f2 f2 04 f4 f4 f4
  0x100061e000a0: f2 f2 f2 f2 04 f4 f4 f4 f2 f2 f2 f2 00 f4 f4 f4
  0x100061e000b0: f2 f2 f2 f2 00 f4 f4 f4 f2 f2 f2 f2 04 f4 f4 f4
  0x100061e000c0: f2 f2 f2 f2 04 f4 f4 f4 f2 f2 f2 f2 04 f4 f4 f4
  0x100061e000d0: f2 f2 f2 f2 04 f4 f4 f4 f2 f2 f2 f2 00 f4 f4 f4
  0x100061e000e0: f2 f2 f2 f2 00 f4 f4 f4 f2 f2 f2 f2 00 f4 f4 f4
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:     fa
  Heap right redzone:    fb
  Freed heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==4531==ABORTING

13322     static void
13323 add_sound_suggest(su, goodword, score, lp)
13324     suginfo_T   *su;
13325     char_u      *goodword;
13326     int         score;          /* soundfold score  */
13327     langp_T     *lp;
13328 {
13329     slang_T     *slang = lp->lp_slang;  /* language for sound folding */
13330     int         sfwordnr;
13331     char_u      *nrline;
13332     int         orgnr;
13333     char_u      theword[MAXWLEN];
13334     int         i;
13335     int         wlen;
13336     char_u      *byts;
13337     idx_T       *idxs;
13338     int         n;
13339     int         wordcount;
13340     int         wc;
13341     int         goodscore;
13342     hash_T      hash;
13343     hashitem_T  *hi;
13344     sftword_T   *sft;
13345     int         bc, gc;
13346     int         limit;
......
13429             theword[wlen++] = byts[n + i];
13430             n = idxs[n + i];

So it looks theword[wlen++] writes more than 250 bytes
in a 250 byte array in the stack.

But in your patch, I think that the  line "if (wlen > MAXWLEN)"
should really be ""if (wlen >= MAXWLEN - 1)".  That seems to
fix it:

$ hg diff spell.c
diff -r 0c37f66b4f3b src/spell.c
--- a/src/spell.c    Thu Nov 14 05:48:46 2013 +0100
+++ b/src/spell.c    Mon Nov 18 22:28:25 2013 +0100
@@ -13402,6 +13402,10 @@
     wordcount = 0;
     for (;;)
     {
+            if (wlen >= MAXWLEN - 1)
+                /* safety check */
+                break;
+
         i = 1;
         if (wordcount == orgnr && byts[n + 1] == NUL)
         break;    /* found end of word */


The question remains: what is wlen so large when
pressing CTRL-C?  I do not know yet.

Regards
Dominique

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Raspunde prin e-mail lui