WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
171211
Image decoders must have private constructors to avoid refcount misuse: ASSERTION FAILED: m_deletionHasBegun when destroying ImageDecoder
https://bugs.webkit.org/show_bug.cgi?id=171211
Summary
Image decoders must have private constructors to avoid refcount misuse: ASSER...
Michael Catanzaro
Reported
2017-04-23 20:32:17 PDT
Created
attachment 307949
[details]
backtrace When loading
http://midori-browser.org/
ASSERTION FAILED: m_deletionHasBegun ../../Source/WTF/wtf/RefCounted.h(84) : WTF::RefCountedBase::~RefCountedBase() Backtrace attached
Attachments
backtrace
(15.77 KB, text/plain)
2017-04-23 20:32 PDT
,
Michael Catanzaro
no flags
Details
Patch
(6.67 KB, patch)
2017-04-24 07:37 PDT
,
Miguel Gomez
no flags
Details
Formatted Diff
Diff
Patch
(12.29 KB, patch)
2017-04-25 02:30 PDT
,
Miguel Gomez
no flags
Details
Formatted Diff
Diff
Show Obsolete
(1)
View All
Add attachment
proposed patch, testcase, etc.
Michael Catanzaro
Comment 1
2017-04-23 20:38:05 PDT
Note that this is a *UI process* assertion. Apparently image decoders are used in the UI process for the favicon database. This is surprising and unexpected to me, since I would not expect this security-critical code to be running in the UI process. I suppose we need to render those favicons somehow, but it should happen in a constrained secondary process where only the result is passed back to the UI process. This is what we do in gdk-pixbuf now, so that the image decoders can be sandboxed with seccomp filters. Of course, that's a much larger challenge for another bug report... in this bug we should just fix this assertion.
Michael Catanzaro
Comment 2
2017-04-23 20:48:37 PDT
So the problem here is that the PNGImageDecoder is being deleted before its refcount has fallen to zero, because it's being stored in a std::unique_ptr. That's wrong, it needs to be stored in a Ref or RefPtr.
Michael Catanzaro
Comment 3
2017-04-23 21:01:44 PDT
Also note that this was easily-preventable, it's why we require that refcounted objects have create functions and private constructors. It looks like all the image decoder classes violate this rule. Fixing this bug thoroughly would entail not just replacing the use of unique_ptr with Ref or RefPtr, but also adding create functions to all the image decoders and making the constructors private in order to ensure this never happens again.
Miguel Gomez
Comment 4
2017-04-24 00:32:39 PDT
Weird, I didn't know ICOImageDecoder would use a PNGImageDecoder inside. Anyway, we already have a create function in ImageDecoder that returns RefPtr, but ICOImageDecoder is not using it at the moment, but directly instantiates the PNGImageDecoder. Changing ICOImageDecoder to use ImageDecoder::create shouldn't be too complicated. I'll give it a look as soon as I can.
Miguel Gomez
Comment 5
2017-04-24 07:37:19 PDT
Created
attachment 307975
[details]
Patch
Carlos Garcia Campos
Comment 6
2017-04-24 08:18:52 PDT
Comment on
attachment 307975
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=307975&action=review
To prevent this from happening again, I would make all constructors private to force everybody to use the create() functions.
> Source/WebCore/platform/graphics/ImageTypes.h:82 > +enum class ImageFormat { > + ImageFormatGIF, > + ImageFormatPNG, > + ImageFormatICO, > + ImageFormatCUR, > + ImageFormatJPEG, > + ImageFormatWEBP, > + ImageFormatBMP
When using enum class, including the class name in the elements is redundant, ImageFormat::GIF, ImageFormat::PNG looks better, IMO.
> Source/WebCore/platform/image-decoders/ImageDecoder.cpp:149 > + default: > + return nullptr;
This should never happen, I think we should return the default and make this return a Ref<>
Michael Catanzaro
Comment 7
2017-04-24 08:55:02 PDT
Comment on
attachment 307975
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=307975&action=review
Thanks Miguel! Yeah, private constructors please.
>> Source/WebCore/platform/image-decoders/ImageDecoder.cpp:149 >> + return nullptr; > > This should never happen, I think we should return the default and make this return a Ref<>
What do you mean by "return the default"... is there a default image decoder? I would do RELEASE_ASSERT_NOT_REACHED().
> Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.h:142 > + typedef Vector<RefPtr<ImageDecoder>> PNGDecoders;
So if you take Carlos's suggestion, then this should use Ref rather than RefPtr.
Carlos Garcia Campos
Comment 8
2017-04-24 09:08:08 PDT
Comment on
attachment 307975
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=307975&action=review
>>> Source/WebCore/platform/image-decoders/ImageDecoder.cpp:149 >>> + return nullptr; >> >> This should never happen, I think we should return the default and make this return a Ref<> > > What do you mean by "return the default"... is there a default image decoder? I would do RELEASE_ASSERT_NOT_REACHED().
Oops, sorry I meant remove the default
Miguel Gomez
Comment 9
2017-04-24 09:10:53 PDT
> To prevent this from happening again, I would make all constructors private > to force everybody to use the create() functions.
Sure, I'll change that.
> > Source/WebCore/platform/graphics/ImageTypes.h:82 > > +enum class ImageFormat { > > + ImageFormatGIF, > > + ImageFormatPNG, > > + ImageFormatICO, > > + ImageFormatCUR, > > + ImageFormatJPEG, > > + ImageFormatWEBP, > > + ImageFormatBMP > > When using enum class, including the class name in the elements is > redundant, ImageFormat::GIF, ImageFormat::PNG looks better, IMO.
Indeed, and I had that until the style checker started to complain, that's why I added the ImageFormat thing.
> > Source/WebCore/platform/image-decoders/ImageDecoder.cpp:149 > > + default: > > + return nullptr; > > This should never happen, I think we should return the default and make this > return a Ref<>
mmmm actually Michael is right and there's no default, so an assertion makes more sense.
Carlos Garcia Campos
Comment 10
2017-04-24 09:22:25 PDT
(In reply to Miguel Gomez from
comment #9
)
> > To prevent this from happening again, I would make all constructors private > > to force everybody to use the create() functions. > > Sure, I'll change that. > > > > Source/WebCore/platform/graphics/ImageTypes.h:82 > > > +enum class ImageFormat { > > > + ImageFormatGIF, > > > + ImageFormatPNG, > > > + ImageFormatICO, > > > + ImageFormatCUR, > > > + ImageFormatJPEG, > > > + ImageFormatWEBP, > > > + ImageFormatBMP > > > > When using enum class, including the class name in the elements is > > redundant, ImageFormat::GIF, ImageFormat::PNG looks better, IMO. > > Indeed, and I had that until the style checker started to complain, that's > why I added the ImageFormat thing. > > > > Source/WebCore/platform/image-decoders/ImageDecoder.cpp:149 > > > + default: > > > + return nullptr; > > > > This should never happen, I think we should return the default and make this > > return a Ref<> > > mmmm actually Michael is right and there's no default, so an assertion makes > more sense.
I meant remove the default, because there's no default. If you remove the default it will fail at compile time if new type is added.
Miguel Gomez
Comment 11
2017-04-25 02:30:48 PDT
Created
attachment 308078
[details]
Patch
WebKit Commit Bot
Comment 12
2017-04-25 05:35:22 PDT
Comment on
attachment 308078
[details]
Patch Clearing flags on attachment: 308078 Committed
r215729
: <
http://trac.webkit.org/changeset/215729
>
WebKit Commit Bot
Comment 13
2017-04-25 05:35:23 PDT
All reviewed patches have been landed. Closing bug.
Michael Catanzaro
Comment 14
2017-04-25 07:30:47 PDT
Awesome, thanks!
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug