[ 
https://issues.apache.org/jira/browse/THRIFT-6332?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Jens Geyer resolved THRIFT-6332.
--------------------------------
    Fix Version/s: 0.26.0
         Assignee: Sylwester Lachiewicz
       Resolution: Fixed

> Graphviz generator crashes on struct, typedef and nested container constants
> ----------------------------------------------------------------------------
>
>                 Key: THRIFT-6332
>                 URL: https://issues.apache.org/jira/browse/THRIFT-6332
>             Project: Thrift
>          Issue Type: Bug
>          Components: Graphviz - Compiler
>    Affects Versions: 0.22.0, 0.23.0, 0.24.0, 0.25.0
>            Reporter: Sylwester Lachiewicz
>            Assignee: Sylwester Lachiewicz
>            Priority: Major
>             Fix For: 0.26.0
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> {{--gen gv}} crashes on a constant whose declared type is a struct, a 
> typedef, or a container nested in either. 
> {{t_gv_generator::print_const_value}} casts the declared type to {{t_map*}}, 
> {{t_list*}} or {{t_set*}} by the shape of the *value* without checking the 
> type: a struct literal is a {{CV_MAP}} value, so the cast reads a {{t_map}} 
> member out of a {{t_struct}} object, and a typedef of a container is a 
> {{t_typedef}} object cast the same way. An integer or string under the wrong 
> type survives because nothing dereferences the type; an enum identifier or a 
> nested container does not.
> Minimal reproducer, crashes on every run:
> {code}
> enum E { A = 1 }
> struct S { 1: E e }
> const S C = { "e": E.A }
> {code}
> {noformat}
> $ thrift --gen gv repro.thrift
> Segmentation fault: 11
> {noformat}
> Under AddressSanitizer (master at 43cd5e041, {{-fsanitize=address}}):
> {noformat}
> ==1556==ERROR: AddressSanitizer: heap-buffer-overflow ...
> READ of size 8 at 0x602000000c58 thread T0
>     #0 t_gv_generator::print_const_value(t_type*, t_const_value*) 
> t_gv_generator.cc:286
>     #1 t_gv_generator::print_const_value(t_type*, t_const_value*) 
> t_gv_generator.cc:263
>     #2 t_gv_generator::generate_const(t_const*) t_gv_generator.cc:171
> {noformat}
> Line 263 is {{((t_map*)type)->get_val_type()}} with {{type}} a {{t_struct}}; 
> line 286 then calls {{type->get_name()}} on the garbage pointer that returned.
> Other shapes that report the same overflow at lines 261/263, or segfault at 
> 286 through the {{t_set*}} branch: a typedef of {{map<string, E>}} with an 
> enum value, a typedef of {{list<E>}}, a struct constant holding a map, a 
> struct constant holding a struct. Only a flat {{{ "x": 1 }}} survives.
> In the shipped test suite, {{--gen gv}} on {{test/DebugProtoTest.thrift}} and 
> {{test/EnumTest.thrift}} crashes, as do 
> {{lib/go/test/ConstOptionalField.thrift}} and 
> {{lib/go/test/StructKeyTest.thrift}}: 18 of 20 runs of the last one segfault, 
> the rest print empty type names where the enum should be.
> Fix: resolve the declared type with {{get_true_type()}} for the shape 
> dispatch, and for a struct literal look each key up as a field name and print 
> the value with the field's type. Over every {{.thrift}} file in the 
> repository the fixed generator is sanitizer-clean, produces byte-identical 
> output for the 154 files that did not crash, and generates the 5 that did.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to