View Issue Details

IDProjectCategoryView StatusLast Update
0000487LDMud 3.5Runtimepublic2017-09-30 18:46
ReporterGnomi Assigned ToGnomi  
PrioritynormalSeveritycrashReproducibilityalways
Status resolvedResolutionfixed 
Platformi686OSDebian GNU/LinuxOS Version3.1
Fixed in Version3.5.0 
Summary0000487: Protected lvalues are copied without their protectors
DescriptionThe following LPC code crashes the driver:

     mapping m=([]);
     funcall(lambda(0,({#'=,'a,({#'copy,({#'&,({#'[,m,0})})})})));

2006.09.14 16:22:00 Ref count in freed hash mapping: -1
2006.09.14 16:22:00 Current object was w/gnomi/LPC_zst

2006.09.14 16:21:59 free_protector_mapping() : no hash reference

w/gnomi/LPC_zst w/gnomi/LPC_zst.c line 8
92996a6: 171 previous_object0 (0: 14) line 8
92996a7: 38 7 && (1: 15)
92996a9: 205 this_interactive (0: 14)
92996aa: 60 ! (1: 15)
92996ab: 39 3 || (1: 15)
92996ad: 205 this_interactive (0: 14) line 9
92996ae: 207 this_player (1: 15)
92996af: 51 == (2: 16)
92996b0: 38 7 && (1: 15)
92996b2: 171 previous_object0 (0: 14) line 10
92996b3: 256 27 geteuid (1: 15)
92996b5: 207 this_player (1: 15)
92996b6: 256 27 geteuid (2: 16)
92996b8: 51 == (2: 16)
92996b9: 38 7 && (1: 15)
92996bb: 207 this_player (0: 14) line 11
92996bc: 256 27 geteuid (1: 15)
92996be: 206 this_object (1: 15)
92996bf: 256 27 geteuid (2: 16)
92996c1: 51 == (2: 16)
92996c2: 106 56 branch_when_zero (1: 15)
92996c4: 96 256 clear_locals (0: 14) line 15
92996c7: 168 256 m_caggregate (0: 14)
92996ca: 123 0 push_local_variable_lvalue (1: 15)
92996cc: 41 (void)= (2: 16)
92996cd: 97 save_arg_frame (0: 14)
92996ce: 15 const0 (1: 15)
92996cf: 22 61480 closure (2: 16)
92996d4: 10 2 cstring0 (3: 17)
92996d6: 294 65 quote (4: 18)
92996d8: 22 61679 closure (4: 18)
92996dd: 22 61494 closure (5: 19)
92996e2: 22 61501 closure (6: 20)
92996e7: 30 0 local (7: 21)
92996e9: 15 const0 (8: 22)
92996ea: 166 3 aggregate (9: 23)
92996ed: 166 2 aggregate (7: 21)
92996f0: 166 2 aggregate (6: 20)
92996f3: 166 3 aggregate (5: 19)
92996f6: 350 17 lambda (3: 17)
92996f8: 416 funcall (2: 16)
w/gnomi/LPC_zst <lambda ?> line 0
8b1056b: 172 0 lambda_cconstant (0: 17) line 0
8b1056d: 15 const0 (1: 18)
8b1056e: 144 push_protected_indexed_lvalue (2: 19)
8b1056f: 239 10 copy (1: 18)
8b10571: 123 0 push_local_variable_lvalue (1: 18)
8b10573: 40 = (2: 19)
8b10574: 24 return (1: 18)
w/gnomi/LPC_zst w/gnomi/LPC_zst.c line 15
92996fa: 98 restore_arg_frame (2: 16) line 15
92996fb: 92 pop_value (1: 15)
92996fc: 25 0 0 0 164 69 41 9
' z_lpc' in 'i/zauberstab/zauberstab.c (/i/zauberstab/zmarker.inc)' (' obj/zauberstab#9') line 495
' start_lpc' in 'i/zauberstab/zauberstab.c (/i/zauberstab/zmarker.inc)' (' obj/zauberstab#9') line 404
' fun' in ' w/gnomi/LPC_zst.c' (' w/gnomi/LPC_zst') line 15
2006.09.14 16:22:00 LDMud aborting on fatal error.

Program terminated with signal 8, Arithmetic exception.
#0 0x08108cd3 in dump_core () at simulate.c:586
586 *((char*)0) = 0/a;
(gdb) bt
#0 0x08108cd3 in dump_core () at simulate.c:586
0000001 0x08108ca5 in fatal (
    fmt=0x813dcc8 "Ref count in freed hash mapping: %ld\n") at simulate.c:649
0000002 0x080c3225 in _free_mapping (m=0x9296900, no_data=0) at mapping.c:631
0000003 0x080c34bb in free_protector_mapping (m=0x9296900) at mapping.c:723
0000004 0x0808dfe3 in free_protector_svalue (v=0x835af5c) at interpret.c:1069
0000005 0x0808e2c2 in int_free_svalue (v=0x8174140) at interpret.c:1156
0000006 0x0808e5b1 in free_svalue (v=0x8174140) at interpret.c:1271
0000007 0x080a40fd in eval_instruction (
    first_instruction=0x92996a6 "?&\a?'\003?3&\a?\003\033?003\0333&\a?003\033?003\0333j8`", initial_sp=0x8174138) at interpret.c:13031
0000008 0x080adc6d in apply_low (fun=0x9049354, ob=0x92d6ba4, num_arg=0,
    b_ign_prot=0, allowRefs=0) at interpret.c:16811
0000009 0x080ade64 in int_apply (fun=0x9049354, ob=0x92d6ba4, num_arg=0,
    b_ign_prot=0, b_use_default=1) at interpret.c:16889
0000010 0x080a8e2a in eval_instruction (
    first_instruction=0x92b8c12 "`\001\002a\017\003@\036",
    initial_sp=0x81740e0) at interpret.c:16159
0000011 0x080adc6d in apply_low (fun=0x924bf5c, ob=0x92b2ab0, num_arg=1,
    b_ign_prot=0, allowRefs=0) at interpret.c:16811
0000012 0x080ade64 in int_apply (fun=0x924bf5c, ob=0x92b2ab0, num_arg=1,
    b_ign_prot=0, b_use_default=1) at interpret.c:16889
0000013 0x080ae2ce in sapply_int (fun=0x924bf5c, ob=0x92b2ab0, num_arg=1,
    b_find_static=0, b_use_default=1) at interpret.c:17050
#14 0x0804c9ce in parse_command (
    buff=0xbfb662c0 "zlpc mapping m=([]); funcall(lambda(0,({#'=,'a,({#'copy,({#'&,({#'[,m,0})})})})));", from_efun=0) at actions.c:1094
#15 0x0804cf41 in execute_command (
    str=0xbfb662c0 "zlpc mapping m=([]); funcall(lambda(0,({#'=,'a,({#'copy,({#'&,({#'[,m,0})})})})));", ob=0x91f7e58) at actions.c:1258
#16 0x08054999 in backend () at backend.c:671
#17 0x080c02c9 in main (argc=16, argv=0xbfb67c74) at main.c:615
(gdb)

The reason is, that assign_svalue(_no_free) does copy the T_LVALUE svalue structure, but not the corresponding protector structure. So the protector structure will be freed twice (each time one of the svalues will be freed), resulting in the negative hash ref. (If this hash ref wouldn't be checked, xfree would later complain about freeing a block twice.)

I used a lambda closure and the copy efun to circumvent several lvalue restrictions. But even if these restrictions were extended to cover such a lambda, the problem would still exist with simul_efuns, which have to deal with lvalues in vararg arguments:

nomask varargs void printf(varargs mixed *args)
{
    if (this_player())
        write(apply(#'sprintf,args));
}

nomask varargs void sefun(varargs mixed *args)
{
    args[0];
}

The first is a real world simul efun, the second just for demonstration.
With these simul efuns the following code crashes the driver in the same way:

     mapping m=([]);
     printf("%O\n", &(m[0]));
     sefun(&(m[0]));

Here apply() or F_INDEX just copy the protected lvalue without their protectors.
Can these protectors be given ref counts?

Greetings,
Gnomi.
TagsNo tags attached.

Relationships

child of 0000650 resolvedGnomi lvalue 2: Give variable references unlimited lifespan 

Activities

lars

2007-10-14 03:12

reporter   ~0000574

Note to self: It's not just adding refcounts - assignments of a PROTECTED_LVALUE will have to create
a regular LVALUE in the destination pointing to the PROTECTED_LVALUE. Reason is that protected_lvalue structures are larger than regular svalues.

Gnomi

2008-06-30 05:04

manager   ~0000623

This one is for the next unstable branch.

Issue History

Date Modified Username Field Change
2006-09-14 09:58 Gnomi New Issue
2007-10-14 03:01 lars Status new => acknowledged
2007-10-14 03:02 lars Assigned To => lars
2007-10-14 03:02 lars Status acknowledged => assigned
2007-10-14 03:12 lars Note Added: 0000574
2008-06-30 05:04 Gnomi Note Added: 0000623
2008-06-30 05:04 Gnomi Assigned To lars => Gnomi
2008-07-02 03:13 Gnomi Project LDMud => LDMud 3.5
2008-07-02 08:13 Gnomi Relationship added child of 0000546
2009-06-03 14:30 Gnomi Relationship added child of 0000650
2009-06-03 14:30 Gnomi Relationship deleted child of 0000546
2017-09-30 18:46 Gnomi Status assigned => resolved
2017-09-30 18:46 Gnomi Resolution open => fixed
2017-09-30 18:46 Gnomi Fixed in Version => 3.5.0