/* My free translation of
 * https://bugzilla.altlinux.org/show_bug.cgi?id=10911 */

i586-alt-linux-gcc (GCC) 4.1.1 20070105 (ALT Linux, build
4.1.1-alt11)
glibc 2.5 (glibc-2_5-branch snapshot 20070112)

Vim built with CFLAGS containing -fstack-protector (turned on by
default in gcc).

All Vim flavors dies when trying to execute example from ":help
self":

        :function Mylen() dict
        :   return len(self.data)
        :endfunction
        :let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
        :echo mydict.len()

#0  0x00002aaaacd333a5 in raise () from /lib64/libc.so.6
#1  0x00002aaaacd34730 in abort () from /lib64/libc.so.6
#2  0x00002aaaacd68ebb in __fsetlocking () from /lib64/libc.so.6
#3  0x00002aaaacdd04ff in __chk_fail () from /lib64/libc.so.6
#4  0x0000000000457a64 in call_func (name=0x857e90 "Mylen", len=Variable "len" 
is not available.) at eval.c:19832
#5  0x000000000045a8dc in get_func_tv (name=0x857e90 "Mylen", len=5, 
rettv=0x7fff452d7cd0, arg=0x7fff452d7ce8, firstline=494, 
    lastline=494, doesrange=0x7fff452d77fc, evaluate=1, selfdict=0x921410) at 
eval.c:7411
#6  0x000000000045aacb in handle_subscript (arg=0x7fff452d7ce8, 
rettv=0x7fff452d7cd0, evaluate=1, verbose=1) at eval.c:17185
#7  0x000000000045be48 in eval7 (arg=0x7fff452d7ce8, rettv=0x7fff452d7cd0, 
evaluate=1) at eval.c:4701
#8  0x000000000045c6a4 in eval6 (arg=0x7fff452d7ce8, rettv=0x7fff452d7cd0, 
evaluate=1) at eval.c:4442
#9  0x000000000045927f in eval5 (arg=0x7fff452d7ce8, rettv=0x7fff452d7cd0, 
evaluate=1) at eval.c:4311
#10 0x00000000004594f6 in eval4 (arg=0x7fff452d7ce8, rettv=0x7fff452d7cd0, 
evaluate=1) at eval.c:4043
#11 0x0000000000459c24 in eval3 (arg=0x7fff452d7ce8, rettv=0x7fff452d7cd0, 
evaluate=1) at eval.c:3955
#12 0x0000000000459d74 in eval1 (arg=0x7fff452d7ce8, rettv=0x7fff452d7cd0, 
evaluate=1) at eval.c:3884
#13 0x000000000045a042 in ex_echo (eap=0x7fff452d7e50) at eval.c:18150
#14 0x000000000047d974 in do_one_cmd (cmdlinep=0x7fff452d8068, sourcing=0, 
cstack=0x7fff452d8070, fgetline=0x48bad0 <getexline>, 
    cookie=0x0) at ex_docmd.c:2616
#15 0x000000000047eda9 in do_cmdline (cmdline=Variable "cmdline" is not 
available.) at ex_docmd.c:1098
#16 0x00000000004e8352 in nv_colon (cap=0x7fff452d85b0) at normal.c:5161
#17 0x00000000004ea9d3 in normal_cmd (oap=0x7fff452d8650, toplevel=1) at 
normal.c:1136
#18 0x00000000004affbf in main_loop (cmdwin=0, noexmode=0) at main.c:1154
#19 0x00000000004b301a in main (argc=Variable "argc" is not available.) at 
main.c:934

There's a compiler warning while building vim:

eval.c: In function 'call_func':
eval.c:19832: warning: call to __builtin___strcpy_chk will always overflow
destination buffer

Situation id: dictitem_T declared as:

/*
 * Structure to hold an item of a Dictionary.
 * Also used for a variable.
 * The key is copied into "di_key" to avoid an extra alloc/free for it.
 */
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!) */
};

typedef struct dictitem_S dictitem_T;

eval.c:call_user_func() have code:

    funccall_T  fc;
    dictitem_T  *v;
    char_u      *name;
...
        /* Set l:self to "selfdict".  Use "name" to avoid a warning from
         * some compiler that checks the destination size. */
        v = &fc.fixvar[fixvar_idx++].var;
        name = v->di_key;
        STRCPY(name, "self");

Using "name" can't help to hide copying to di_key, which is one
element char array.  funccall_S is declared as:

struct funccall_S
{
...
    struct                      /* fixed variables for arguments */
    {
        dictitem_T      var;            /* variable (without room for name) */
        char_u  room[VAR_SHORT_LEN];    /* room for the name */
    } fixvar[FIXVAR_CNT];
...
};

So var.di_name will be always overflowed, filling "room".


OpenSUSE, which also have -fstack-protector turned on by default,
is using attached patch...

-- 
Regards,
Sir Raorn.
--- src/structs.h.sav   2007-02-02 11:31:05.000000000 +0100
+++ src/structs.h       2007-02-02 11:31:14.000000000 +0100
@@ -1082,7 +1082,7 @@
 {
     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!) */
+    char_u     di_key[];       /* key (actually longer!) */
 };
 
 typedef struct dictitem_S dictitem_T;

Attachment: signature.asc
Description: Digital signature

Reply via email to