2016-01-10 21:21 GMT+03:00 Dominique Pellé <[email protected]>:

> Hi
>
> afl-fuzz found another memory error in vim-7.4.1082 (and older).
> Using the attached non sensical 'crash.vim' file:
>
> $ valgrind vim -u NONE -N  -S crash.vim 2> log
>
> And log file contains:
>
> ==15151== Memcheck, a memory error detector
> ==15151== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
> ==15151== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright
> info
> ==15151== Command: ./vim -u NONE -N -S crash.vim
> ==15151==
> ==15151== Invalid write of size 1
> ==15151==    at 0x409847: buflist_list (buffer.c:2801)
> ==15151==    by 0x45FECD: do_one_cmd (ex_docmd.c:2962)
> ==15151==    by 0x45B9B0: do_cmdline (ex_docmd.c:1133)
> ==15151==    by 0x459AD1: do_source (ex_cmds2.c:3396)
> ==15151==    by 0x4592A3: cmd_source (ex_cmds2.c:3005)
> ==15151==    by 0x45FECD: do_one_cmd (ex_docmd.c:2962)
> ==15151==    by 0x45B9B0: do_cmdline (ex_docmd.c:1133)
> ==15151==    by 0x5B9EBC: exe_commands (main.c:2928)
> ==15151==    by 0x5B9EBC: main (main.c:962)
> ==15151==  Address 0x759d0e4 is 20 bytes after a block of size 1,040
> in arena "client"
> ==15151==
> ==15151== Invalid write of size 1
> ==15151==    at 0x4C2F673: memcpy@GLIBC_2.2.5 (in
> /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==15151==    by 0x4AFCD6: vim_vsnprintf (message.c:4152)
> ==15151==    by 0x4B51CC: vim_snprintf (message.c:4106)
> ==15151==    by 0x409968: buflist_list (buffer.c:2803)
> ==15151==    by 0x45FECD: do_one_cmd (ex_docmd.c:2962)
> ==15151==    by 0x45B9B0: do_cmdline (ex_docmd.c:1133)
> ==15151==    by 0x459AD1: do_source (ex_cmds2.c:3396)
> ==15151==    by 0x4592A3: cmd_source (ex_cmds2.c:3005)
> ==15151==    by 0x45FECD: do_one_cmd (ex_docmd.c:2962)
> ==15151==    by 0x45B9B0: do_cmdline (ex_docmd.c:1133)
> ==15151==    by 0x5B9EBC: exe_commands (main.c:2928)
> ==15151==    by 0x5B9EBC: main (main.c:962)
> ==15151==  Address 0x759d0e5 is 21 bytes after a block of size 1,040
> in arena "client"
> ==15151==
>
> The problem happens because code in buffer.c
> wrongly assumes that when vim_snprintf(...) truncates its output,
> it returns the truncated number of bytes.  This is incorrect as it
> returns the number of bytes that would have been written if there
> was no truncation.  See man snprintf(...):
>

​`man snprintf` is irrelevant, vim_snprintf is a complete reimplementation
that only follows same conventions (but actually does not have to). It is
only correct to refer to documentation in comments in message.c, which are
similar.​



>
> === BEGIN [man snprintf] ===
> If the output was truncated due to this limit then the return
> value is the number of characters (excluding the terminating
> null byte) which would have been written  to  the  final
> string if enough space had been available.  Thus, a return
> value of size or more means that the output was truncated.
> (See also below under NOTES.)
> ...snip...
> NOTES
> ..snip...
> The glibc implementation of the functions snprintf() and vsnprintf()
> conforms to the C99 standard, that is, behaves as  described
> above,  since  glibc version 2.1.  Until glibc 2.0.6 they would
> return -1 when the output was truncated.
> ==== END [man snprintf] ===
>
> Attached patch fixes the bug. However:
>
> * I wonder whether there are other similar bugs elsewhere.
>   I see that returned value of vim_snprintf(...) is used in a
>   few places which look suspicious in message.c and
>   eval.c
> * also, since old version of glibc could return -1, there might
>   be a portability bug there too.  I'm not sure whether configure
>   checks for that.
>

In file `message.c` which defines the function in question there are
exactly zero references to snprintf that do not live in comments. So no
portatibility bugs may arise from any glibc implementation.

---

Relevant documentation in message.c:

 * This code was included to provide a portable vsnprintf() and snprintf().
 * Some systems may provide their own, but we always use this one for
 * consistency.​
…
 * The return value is the number of characters which would be generated
 * for the given input, excluding the trailing NUL. If this value
 * is greater or equal to "str_m", not all characters from the result
 * have been stored in str, output bytes beyond the ("str_m"-1) -th
character
 * are discarded. If "str_m" is greater than zero it is guaranteed
 * the resulting string will be NUL-terminated.




>
> 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/d/optout.
>

-- 
-- 
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/d/optout.

Raspunde prin e-mail lui