John Little wrote:

> I've been running a debug build of vim for a while,
> and while diagnosing a slowness problem noticed
> that it was much slower than the version I get with
> my distro (Kubuntu 14.04, 7.4.52), so I changed
> my compiler flags to add -O2 and recompiled.
>
> The resulting executable aborted instantly:
> *** buffer overflow detected ***: vim terminated
> and splurges out a backtrace and about 300 lines of memory map.
> The version of gcc is 4.8.2.
>
> Getting a core dump, I see that gcc is doing a checked strcpy and aborting.  
> This occurs at my line 874 of eval.c:
>
>         STRCPY(p->vv_di.di_key, p->vv_name);
>
> p is pointing at the first element of vimvars:
>
> static struct vimvar
> {
>     char        *vv_name;       /* name of variable, without v: */
>     dictitem_T  vv_di;          /* value and name for key */
>     char        vv_filler[16];  /* space for LONGEST name below!!! */
>     char        vv_flags;       /* VV_COMPAT, VV_RO, VV_RO_SBX */
> } vimvars[VV_LEN] =
>
> and vv_di is a
> struct dictitem_S
> {
>     typval_T    di_tv;          /* type and value of the variable */
>     char_u      di_flags;       /* flags (only used for variable) */
>     char_u      di_key[1];      /* key (actually longer!) */
> }
>
> This is done to avoid a allocation for di_key.  I think gcc
> is complaining that di_key has only room for one char,
> and doesn't realize that we've allowed space in vv_filler
> for the data.
>
> Why it should do that with -O2 and not without has me
> wondering, perhaps the members of struct vimvar are
> being reordered?
>
> Anyway, if I add  -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
> to the compile flags (gcc is using a default of 2) the abort
> goes away, but this leaves an uneasy feeling.


Hi John

I'm guessing you're using Ubuntu.  Ubuntu modified
their version of gcc to default to -D_FORTITY_SOURCE=2.

See "man gcc" on Ubuntu which says:

=== BEGIN QUOTE ===
NOTE: In Ubuntu 8.10 and later versions,
-D_FORTIFY_SOURCE=2 is set by default,
and is activated when -O is set to 2 or higher.
This enables additional compile-time and
run-time checks for several libc functions.
To disable, specify either -U_FORTIFY_SOURCE
or -D_FORTIFY_SOURCE=0.
=== END QUOTE ===

This is done to harden Ubuntu distribution and find
some buffer overflows. As far as I know, only Ubuntu
did that to their gcc by default. The problem with that,
-D_FORTIFY_SOURCE=2 (which kicks in when using
-O2 or -O3) can break a few valid C programs, such as
Vim.

See:
http://manpages.ubuntu.com/manpages/jaunty/man7/feature_test_macros.7.html

=== BEGIN QUOTE ===
If  _FORTIFY_SOURCE is set to 1,  with compiler
optimization level 1 (gcc -O1) and above, checks
that shouldn’t change the behavior of  conforming
programs are performed. With _FORTIFY_SOURCE
set to 2 some more checking is added, but some
conforming  programs might fail.
=== END QUOTE ===

To compile Vim with optimizations, you *must*
override the default setting with -D_FORTIFY_SOURCE=1
or else Vim with crash.  -D_FORTIFY_SOURCE=1 will still
detect overflow bugs, but only those that are
definitely bugs.  Normally Vim configure and Makefile
takes care of that automatically, so it's odd that
you have this problem.

It's not a bug in Vim.  Vim use a pattern, common in
C programs, especially networking code, where the
last element of a struct is an array of size 1, but
extra size is allocated when calling malloc and
it's allowed to to more than 1 element in the array.
An -D_FORTIFY_SOURCE=2 wrongly considers
it as an overflow.

gcc has a C extension (zero size array) where it
makes it more explicity that the intent to use
more elements in the array than what is declared:

https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

When using zero size array, -D_FORTIFY_SOURCE=2
would then not cause crashes.  The problem is that zero
size array are not portable so Vim does not use that.

If you still worry about corruptions, you can try using
valgrind or the address sanitizer aka ASAN (by compiling
with "-fsanitize=address" available recent versions of gcc
or clang). This will detect some bugs, if any, without false
positive. Valgrind or ASAN find many more bugs than
-D_FORTIFY_SOURCE=... at the cost of being slower,
so valgrind or ASAN are only OK for debug purpose,
whereas -D_FORTIFY_SOURCE=1 is OK by default
(no noticeable slow down).

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.

Raspunde prin e-mail lui