/* 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;
signature.asc
Description: Digital signature