bugGnash - The GNU Flash player - Bugs: bug #40315, tummy_trouble.swf segfaults

 
 

bug #40315: tummy_trouble.swf segfaults

Submitted by:  Sandro Santilli <strk>
Submitted on:  Sun 20 Oct 2013 03:08:20 PM UTC  
 
Category: render-aggSeverity: 6 - Security
Release: NoneStatus: Fixed
Privacy: PublicAssigned to: Bastiaan Jacques <bjacques>
Open/Closed: Closed

Add a New Comment(Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

(Jump to the original submission Jump to the original submission)

Fri 18 Apr 2014 04:31:13 PM UTC, comment #11:

So, after adding -fsanitize=address to the CXXFLAGS I can confirm that the DrawingApiTest.swf can crash gnash until fixed by your commit f84af61ed7e9.

Good work!

Sandro Santilli <strk>
Project Member
Fri 18 Apr 2014 04:04:49 PM UTC, comment #10:

I cant' reproduce the tummy_trouble.swf crash anymore with master-21950-b4018a1

But I'm not sure if the testcase you added is really guarding against that crash because I can't get a crash playing DrawingTestApi.swf with master-21911-0df2a46, which instead crashes with tummy_trouble.swf

Sandro Santilli <strk>
Project Member
Fri 18 Apr 2014 12:27:18 AM UTC, comment #9:

Fix attempt: f84af61ed7e9.

Bastiaan Jacques <bjacques>
Project MemberIn charge of this item.
Thu 17 Apr 2014 11:06:38 PM UTC, comment #8:

The source of the problem is in DynamicShape::finalize(). The current (temporary) subshape is copied into the shape, and then the subshape is cleared. However, _currpath, _currline and _currfill are not reset. Then, when later the DynamicShape is reused to draw a line without adding a new line style, _currline refers to a nonexistent line style.

Bastiaan Jacques <bjacques>
Project MemberIn charge of this item.
Thu 16 Jan 2014 01:40:51 PM UTC, comment #7:

The problem was introduced this summer (June) when adding subshape support, and was not present ion 0.8.10. See also bug #39989 for a related problem introduced by the subshape support.

Petter Reinholdtsen <pere>
Project Member
Fri 10 Jan 2014 08:00:28 AM UTC, comment #6:

I tested the tummy_trouble.swf flash with the current HEAD
(1eaf85f95a8aabb0275447df9500357081bd333a) using valgrind, and got
this crash after playing and entering and exiting rooms.

pere@minerva:/scratch/pere/src/gnash$ ./gui/gnash tummy_trouble.swf
==25928== Memcheck, a memory error detector
==25928== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==25928== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==25928== Command: /scratch/pere/src/gnash/gui/.libs/lt-gtk-gnash tummy_trouble.swf
==25928==

    • (lt-gtk-gnash:25928): WARNING **: Couldn't find pixmap file: GnashG.png

==25928== Invalid read of size 2
==25928== at 0x4EF6924: gnash::DynamicShape::lineTo(int, int, int) (DynamicShape.cpp:207)
==25928== by 0x4FC7228: gnash::(anonymous namespace)::movieclip_lineTo(gnash::fn_call const&) (MovieClip_as.cpp:1459)
==25928== by 0x4FA3EC4: gnash::NativeFunction::call(gnash::fn_call const&) (NativeFunction.h:65)
==25928== by 0x506F307: gnash::(anonymous namespace)::ActionCallMethod(gnash::ActionExec&) (ASHandlers.cpp:2811)
==25928== by 0x50651E9: gnash::SWF::SWFHandlers::execute(gnash::SWF::ActionType, gnash::ActionExec&) const (ASHandlers.cpp:432)
==25928== by 0x5078064: gnash::ActionExec::operator()() (ActionExec.cpp:260)
==25928== by 0x4F5F609: gnash::Function2::call(gnash::fn_call const&) (Function2.cpp:219)
==25928== by 0x506F307: gnash::(anonymous namespace)::ActionCallMethod(gnash::ActionExec&) (ASHandlers.cpp:2811)
==25928== by 0x50651E9: gnash::SWF::SWFHandlers::execute(gnash::SWF::ActionType, gnash::ActionExec&) const (ASHandlers.cpp:432)
==25928== by 0x5078064: gnash::ActionExec::operator()() (ActionExec.cpp:260)
==25928== by 0x4F5EE49: gnash::Function::call(gnash::fn_call const&) (Function.cpp:145)
==25928== by 0x4EDB936: gnash::invoke(gnash::as_value const&, gnash::as_environment const&, gnash::as_object, gnash::FunctionArgs<gnash::as_value>&, gnash::as_object, gnash::movie_definition const*) (Global_as.h:185)
==25928== Address 0x18435814 is not stack'd, malloc'd or (recently) free'd
==25928==
==25928== Invalid read of size 1
==25928== at 0x548D069: gnash::Renderer_agg<agg::pixfmt_alpha_blend_rgba<agg::blender_rgba_pre<agg::rgba8, agg::order_bgra>, agg::row_accessor<unsigned char>, unsigned int> >::buildPaths_rounded(std::vector<agg::path_base<agg::vertex_block_storage<double, 8u, 256u> >, std::allocator<agg::path_base<agg::vertex_block_storage<double, 8u, 256u> > > >&, std::vector<gnash::Path, std::allocator<gnash::Path> > const&, std::vector<gnash::LineStyle, std::allocator<gnash::LineStyle> > const&) (Renderer_agg.cpp:2208)
==25928== by 0x54C9687: gnash::Renderer_agg<agg::pixfmt_alpha_blend_rgba<agg::blender_rgba_pre<agg::rgba8, agg::order_bgra>, agg::row_accessor<unsigned char>, unsigned int> >::drawShape(std::vector<gnash::FillStyle, std::allocator<gnash::FillStyle> > const&, std::vector<gnash::LineStyle, std::allocator<gnash::LineStyle> > const&, std::vector<gnash::Path, std::allocator<gnash::Path> > const&, gnash::SWFMatrix const&, gnash::SWFCxForm const&) (Renderer_agg.cpp:1180)
==25928== by 0x54CFE4A: gnash::Renderer_agg<agg::pixfmt_alpha_blend_rgba<agg::blender_rgba_pre<agg::rgba8, agg::order_bgra>, agg::row_accessor<unsigned char>, unsigned int> >::drawShape(gnash::SWF::ShapeRecord const&, gnash::Transform const&) (Renderer_agg.cpp:1141)
==25928== by 0x4F2E068: gnash::MovieClip::draw(gnash::Renderer&, gnash::Transform const&) (MovieClip.cpp:1201)
==25928== by 0x4F2E111: gnash::MovieClip::display(gnash::Renderer&, gnash::Transform const&) (MovieClip.cpp:1216)
==25928== by 0x4F66662: gnash::DisplayList::display(gnash::Renderer&, gnash::Transform const&) (DisplayList.cpp:593)
==25928== by 0x4F2E07A: gnash::MovieClip::draw(gnash::Renderer&, gnash::Transform const&) (MovieClip.cpp:1202)
==25928== by 0x4F2E111: gnash::MovieClip::display(gnash::Renderer&, gnash::Transform const&) (MovieClip.cpp:1216)
==25928== by 0x4F66662: gnash::DisplayList::display(gnash::Renderer&, gnash::Transform const&) (DisplayList.cpp:593)
==25928== by 0x4F2E07A: gnash::MovieClip::draw(gnash::Renderer&, gnash::Transform const&) (MovieClip.cpp:1202)
==25928== by 0x4F2E111: gnash::MovieClip::display(gnash::Renderer&, gnash::Transform const&) (MovieClip.cpp:1216)
==25928== by 0x4F66662: gnash::DisplayList::display(gnash::Renderer&, gnash::Transform const&) (DisplayList.cpp:593)
==25928== Address 0x8 is not stack'd, malloc'd or (recently) free'd
==25928==
==25928==
==25928== Process terminating with default action of signal 11 (SIGSEGV)
==25928== Access not within mapped region at address 0x8
==25928== at 0x548D069: gnash::Renderer_agg<agg::pixfmt_alpha_blend_rgba<agg::blender_rgba_pre<agg::rgba8, agg::order_bgra>, agg::row_accessor<unsigned char>, unsigned int> >::buildPaths_rounded(std::vector<agg::path_base<agg::vertex_block_storage<double, 8u, 256u> >, std::allocator<agg::path_base<agg::vertex_block_storage<double, 8u, 256u> > > >&, std::vector<gnash::Path, std::allocator<gnash::Path> > const&, std::vector<gnash::LineStyle, std::allocator<gnash::LineStyle> > const&) (Renderer_agg.cpp:2208)
==25928== by 0x54C9687: gnash::Renderer_agg<agg::pixfmt_alpha_blend_rgba<agg::blender_rgba_pre<agg::rgba8, agg::order_bgra>, agg::row_accessor<unsigned char>, unsigned int> >::drawShape(std::vector<gnash::FillStyle, std::allocator<gnash::FillStyle> > const&, std::vector<gnash::LineStyle, std::allocator<gnash::LineStyle> > const&, std::vector<gnash::Path, std::allocator<gnash::Path> > const&, gnash::SWFMatrix const&, gnash::SWFCxForm const&) (Renderer_agg.cpp:1180)
==25928== by 0x54CFE4A: gnash::Renderer_agg<agg::pixfmt_alpha_blend_rgba<agg::blender_rgba_pre<agg::rgba8, agg::order_bgra>, agg::row_accessor<unsigned char>, unsigned int> >::drawShape(gnash::SWF::ShapeRecord const&, gnash::Transform const&) (Renderer_agg.cpp:1141)
==25928== by 0x4F2E068: gnash::MovieClip::draw(gnash::Renderer&, gnash::Transform const&) (MovieClip.cpp:1201)
==25928== by 0x4F2E111: gnash::MovieClip::display(gnash::Renderer&, gnash::Transform const&) (MovieClip.cpp:1216)
==25928== by 0x4F66662: gnash::DisplayList::display(gnash::Renderer&, gnash::Transform const&) (DisplayList.cpp:593)
==25928== by 0x4F2E07A: gnash::MovieClip::draw(gnash::Renderer&, gnash::Transform const&) (MovieClip.cpp:1202)
==25928== by 0x4F2E111: gnash::MovieClip::display(gnash::Renderer&, gnash::Transform const&) (MovieClip.cpp:1216)
==25928== by 0x4F66662: gnash::DisplayList::display(gnash::Renderer&, gnash::Transform const&) (DisplayList.cpp:593)
==25928== by 0x4F2E07A: gnash::MovieClip::draw(gnash::Renderer&, gnash::Transform const&) (MovieClip.cpp:1202)
==25928== by 0x4F2E111: gnash::MovieClip::display(gnash::Renderer&, gnash::Transform const&) (MovieClip.cpp:1216)
==25928== by 0x4F66662: gnash::DisplayList::display(gnash::Renderer&, gnash::Transform const&) (DisplayList.cpp:593)
==25928== If you believe this happened as a result of a stack
==25928== overflow in your program's main thread (unlikely but
==25928== possible), you can try to increase the size of the
==25928== main thread stack using the --main-stacksize= flag.
==25928== The main thread stack size used in this run was 8388608.
==25928==
==25928== HEAP SUMMARY:
==25928== in use at exit: 16,224,662 bytes in 109,400 blocks
==25928== total heap usage: 3,900,169 allocs, 3,790,769 frees, 2,374,121,314 bytes allocated
==25928==
==25928== LEAK SUMMARY:
==25928== definitely lost: 20,736 bytes in 8 blocks
==25928== indirectly lost: 11,392 bytes in 354 blocks
==25928== possibly lost: 3,059,977 bytes in 25,543 blocks
==25928== still reachable: 13,132,557 bytes in 83,495 blocks
==25928== suppressed: 0 bytes in 0 blocks
==25928== Rerun with --leak-check=full to see details of leaked memory
==25928==
==25928== For counts of detected and suppressed errors, rerun with: -v
==25928== ERROR SUMMARY: 4 errors from 2 contexts (suppressed: 75 from 10)
Killed

The crash is due to the line_styles vector passed to the
buildPaths_rounded() function being empty when its first element is
accessed. The first invalid read happen just before the crash, after
playing a bit and moving the player into the next room, back to the
initial room and re-entering the next room again.

Perhaps an assert like this is better than the crash to document the
problem better?

--- a/librender/agg/Renderer_agg.cpp
+++ b/librender/agg/Renderer_agg.cpp
@@ -1265,6 +1265,7 @@ public:
bool hinting=false, closed=false, hairline=false;

if (this_path.m_line) {
+ assert(line_styles.size() > 0);
const LineStyle& lstyle = line_styles[this_path.m_line-1];

hinting = lstyle.doPixelHinting();

This change get rid of the invalid read of 2 bytes. It seem to be
caused by the DynamicShape code assuming all subshapes have a list of
line styles, which is false when re-entering the second room. The
crash still happen after this change.

--- a/libcore/DynamicShape.cpp
+++ b/libcore/DynamicShape.cpp
@@ -204,7 +204,7 @@ DynamicShape::lineTo(boost::int32_t x, boost::int32_t y, in
SWFRect bounds = _shape.getBounds();

unsigned thickness = _currline ?
- _currsubshape.lineStyles().back().getThickness() : 0;
+ (_currsubshape.lineStyles().size() > 0 ? _currsubshape.lineStyles().b

if (_currpath->size() == 1) {
_currpath->expandBounds(bounds, thickness, swfVersion);

--
Happy hacking
Petter Reinholdtsen

Petter Reinholdtsen <pere>
Project Member
Sun 20 Oct 2013 06:59:48 PM UTC, comment #5:

The first bad commit could be any of:
22eac818afa08d15c55ae03091ea5a8d576dea20
31ce0628c76253052579065a0c2bf944357452b1
368216f46f76b7efeeafcf84d061857277ab7bcd
73da624b50cf46cba878143d7a2acf6f8b8de981
1fe4c1d27afd9fa97741df52c543382d94bc9be2
We cannot bisect more!

Sandro Santilli <strk>
Project Member
Sun 20 Oct 2013 05:26:48 PM UTC, comment #4:

# good: [51959a760e5ca622f88373f5476031d75bfb8a3e] Tidy up.
# skip: [368216f46f76b7efeeafcf84d061857277ab7bcd] Update
# bad: [439df46da3c8c037e34e6762f3751f4fc94dff42] cppcheck: remove useless #if which breaks {} pair.

Sandro Santilli <strk>
Project Member
Sun 20 Oct 2013 05:18:19 PM UTC, comment #3:

# bad: [ee880c6bfc28b71e0a760c6d484acba30524636f] cppcheck:
# good: [51959a760e5ca622f88373f5476031d75bfb8a3e] Tidy up.

Sandro Santilli <strk>
Project Member
Sun 20 Oct 2013 03:41:03 PM UTC, comment #2:

Just tried 0.8.10 and can confirm there's no bug there.
To reproduce with master: start playing, enter one room and exit again.

Sandro Santilli <strk>
Project Member
Sun 20 Oct 2013 03:09:19 PM UTC, comment #1:

http://strk.keybit.net/tmp/tummy_trouble.swf

Sandro Santilli <strk>
Project Member
Sun 20 Oct 2013 03:08:20 PM UTC, original submission:

Sounds like an infinite recursion. This movie (7db88c39605740feeb9a0890f8669886 tummy_truble.swf) used to work just fine some time ago (0.8.10 ?). Now (master, 0d46c8830264ba86abb9041cff04297e02968516) it segfaults:

Program terminated with signal 11, Segmentation fault.
#0 operator[] (__n=0, this=<optimized out>) at /usr/src/gnash/gnash-head/librender/agg/Renderer_agg.cpp:2207
2207 } // end of namespace gnash
(gdb)
(gdb) bt
#0 operator[] (__n=0, this=<optimized out>) at /usr/src/gnash/gnash-head/librender/agg/Renderer_agg.cpp:2207
#1 gnash::Renderer_agg<agg::pixfmt_alpha_blend_rgba<agg::blender_rgba_pre<agg::rgba8, agg::order_bgra>, agg::row_accessor<unsigned char>, unsigned int> >::buildPaths_rounded (this=this@entry=0x7f3e6b748540, dest=..., paths=..., line_styles=...)
at /usr/src/gnash/gnash-head/librender/agg/Renderer_agg.cpp:1268
#2 0x00007f3e69b6cdd8 in gnash::Renderer_agg<agg::pixfmt_alpha_blend_rgba<agg::blender_rgba_pre<agg::rgba8, agg::order_bgra>, agg::row_accessor<unsigned char>, unsigned int> >::drawShape (this=this@entry=0x7f3e6b748540, FillStyles=..., line_styles=..., objpaths=..., mat=..., cx=...)
at /usr/src/gnash/gnash-head/librender/agg/Renderer_agg.cpp:1180
#3 0x00007f3e69b7349b in gnash::Renderer_agg<agg::pixfmt_alpha_blend_rgba<agg::blender_rgba_pre<agg::rgba8, agg::order_bgra>, agg::row_accessor<unsigned char>, unsigned int> >::drawShape (this=0x7f3e6b748540, shape=..., xform=...)
at /usr/src/gnash/gnash-head/librender/agg/Renderer_agg.cpp:1141
#4 0x00007f3e69eafbc9 in gnash::MovieClip::draw (this=this@entry=0x7f3e6b98a9c0, renderer=..., xform=...)
at /usr/src/gnash/gnash-head/libcore/MovieClip.cpp:1201
#5 0x00007f3e69eafc72 in gnash::MovieClip::display (this=0x7f3e6b98a9c0, renderer=..., base=...)
at /usr/src/gnash/gnash-head/libcore/MovieClip.cpp:1216
#6 0x00007f3e69ee82e3 in gnash::DisplayList::display (this=this@entry=0x7f3e6b98a438, renderer=..., base=...)
at /usr/src/gnash/gnash-head/libcore/DisplayList.cpp:593
#7 0x00007f3e69eafbdb in gnash::MovieClip::draw (this=this@entry=0x7f3e6b98a320, renderer=..., xform=...)
at /usr/src/gnash/gnash-head/libcore/MovieClip.cpp:1202
#8 0x00007f3e69eafc72 in gnash::MovieClip::display (this=0x7f3e6b98a320, renderer=..., base=...)
at /usr/src/gnash/gnash-head/libcore/MovieClip.cpp:1216
#9 0x00007f3e69ee82e3 in gnash::DisplayList::display (this=this@entry=0x7f3e6b86dd98, renderer=..., base=...)
at /usr/src/gnash/gnash-head/libcore/DisplayList.cpp:593
#10 0x00007f3e69eafbdb in gnash::MovieClip::draw (this=this@entry=0x7f3e6b86dc80, renderer=..., xform=...)
at /usr/src/gnash/gnash-head/libcore/MovieClip.cpp:1202
#11 0x00007f3e69eafc72 in gnash::MovieClip::display (this=0x7f3e6b86dc80, renderer=..., base=...)
at /usr/src/gnash/gnash-head/libcore/MovieClip.cpp:1216

Sandro Santilli <strk>
Project Member

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach File(s):
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by pere (Posted a comment)
  • -unavailable- added by bjacques (Updated the item)
  • -unavailable- added by strk (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follow 6 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Fri 18 Apr 2014 04:31:13 PM UTCstrkStatusReady For Test=>Fixed
      Open/ClosedOpen=>Closed
    Fri 18 Apr 2014 12:27:18 AM UTCbjacquesStatusNone=>Ready For Test
    Sun 20 Oct 2013 04:57:44 PM UTCstrkAssigned toNone=>bjacques
    Sun 20 Oct 2013 03:41:03 PM UTCstrkAssigned tobjacques=>None
    Sun 20 Oct 2013 03:27:07 PM UTCbjacquesAssigned toNone=>bjacques

    Back to the top


    Powered by Savane 3.1-cleanup1