Bug 99243 - FEImage::m_document is never cleared. Why not?
Summary: FEImage::m_document is never cleared. Why not?
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: SVG (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Stephen Chenney
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-10-13 00:35 PDT by Adam Barth
Modified: 2012-11-01 06:57 PDT (History)
15 users (show)

See Also:


Attachments
Patch (1.64 KB, patch)
2012-10-17 12:58 PDT, Stephen Chenney
no flags Details | Formatted Diff | Diff
Patch (1.39 KB, patch)
2012-10-30 10:10 PDT, Stephen Chenney
no flags Details | Formatted Diff | Diff
Patch (1.35 KB, patch)
2012-10-30 10:17 PDT, Stephen Chenney
krit: review+
krit: commit-queue-
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Adam Barth 2012-10-13 00:35:49 PDT
As far as I can tell, there's no mechanism for clearing FEImage::m_document after the Document has been destroyed.  Given that FEImage is RefCounted, it seems very likely that FEImage can be kept alive after the Document is destroyed.  I tried to chase down how we might be able to do that, but I got lost in SVG filter land.
Comment 1 Stephen Chenney 2012-10-15 10:28:16 PDT
I'm in that space now. It's a complete disaster area. I'll try to figure this one out too.
Comment 2 Stephen Chenney 2012-10-15 10:50:55 PDT
I don't think this is a problem. The document is only used when the filter is actually applied, and as far as I know you cannot apply a filter unless it is in the document. Furthermore, if the filter leaves the document the FilterEffect objects will be destroyed or marked dirty (forcing regeneration).

The RefCounted on such objects does not indicate that they are held outside of FilterData objects, rather it seems to be to simplify management of pointers in SVGFilterBuilder. The FEImage filter effect is SVG-only and is only held inside SVGFilterBuilder.
Comment 3 Adam Barth 2012-10-15 14:55:36 PDT
Thanks for investigating this issue!  Would you be willing to add a comment explaining this to the m_document declaration so that we won't get scared the next time we audit this code?
Comment 4 Stephen Chenney 2012-10-15 15:17:46 PDT
Reopened to comment appropriately.
Comment 5 Stephen Chenney 2012-10-17 12:58:23 PDT
Created attachment 169239 [details]
Patch

Is this what you had in mind?
Comment 6 Adam Barth 2012-10-17 13:14:03 PDT
Comment on attachment 169239 [details]
Patch

Yes, great.  I'll leave this patch for someone who can verify the comment to review.  Thanks!
Comment 7 Stephen Chenney 2012-10-30 08:52:47 PDT
I added an assert to the destructor for the FEImage filter effect and verified that it is destructed when it's target is removed from the document. These tests demonstrate the behavior. The assert stacks show the FEImage being destructed whenever its target (the thing that will try to use it) is detached.

To summarize: Only a target renderer ever tries to use the m_document in the filter effect. When the target is added to the document the filter is created. When the target is removed from the document the filters are destroyed. JS cannot hold references to this data - it is entirely internal. Hence, there is no point at which a filter can exist without a valid document.

svg/filters/feImage-remove-target.svg
svg/filters/feImage-target-reappend-to-document.svg
svg/filters/feImage-target-remove-from-document.svg
svg/filters/feImage-target-add-to-document.svg
svg/filters/feImage-target-attribute-change-with-use-indirection.svg

Is that sufficient verification to R+ the comment?
Comment 8 Dirk Schulze 2012-10-30 09:36:36 PDT
If it is wrong, why not fixing it? The comment is not really helpful. Make this bug no security bug anymore and fix it.
Comment 9 Maciej Stachowiak 2012-10-30 09:55:44 PDT
If this pointer is not actually a dangling reference hazard, then there is nothing to fix. I can see the value of adding a comment explaining that, so no one goes on a wild goose chase, but it seems a bit verbose for WebKit style. Is there a way to get the point across more concisely? I think the comment can just state that the pointer can't be used to access free memory despite never being cleared, without giving the full detailed explanation.
Comment 10 Stephen Chenney 2012-10-30 10:10:07 PDT
Created attachment 171475 [details]
Patch
Comment 11 Stephen Chenney 2012-10-30 10:15:03 PDT
Maciej is right that this is never dangling and there's no point in fixing it. The only possible code change would be to explicitly set m_document to null before destroying the object, but there's no point at all in that.

I've come up with a one line comment (a bit longer). Actually, it just occurred to me that I should reference this bug, so I'll give it another pass.

Also, there is no need for this to be a security issue.
Comment 12 Stephen Chenney 2012-10-30 10:17:30 PDT
Created attachment 171478 [details]
Patch

Much more concise, yet still informative.
Comment 13 Eric Seidel (no email) 2012-10-30 10:44:23 PDT
Comment on attachment 171478 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=171478&action=review

> Source/WebCore/svg/graphics/filters/SVGFEImage.h:58
> +    // m_document will never be a dangling reference. See https://bugs.webkit.org/show_bug.cgi?id=99243

Better justification would be to explain why here as well.  This is not an Element, so it doesn't keep the document alive.  I assume this is held off of a renderer?  Can this also be held off of a CSSValue?
Comment 14 Stephen Chenney 2012-10-30 11:04:13 PDT
Comment on attachment 171478 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=171478&action=review

>> Source/WebCore/svg/graphics/filters/SVGFEImage.h:58
>> +    // m_document will never be a dangling reference. See https://bugs.webkit.org/show_bug.cgi?id=99243
> 
> Better justification would be to explain why here as well.  This is not an Element, so it doesn't keep the document alive.  I assume this is held off of a renderer?  Can this also be held off of a CSSValue?

This object is only held by a SVGFilterBuilder which in turn is held by a RenderSVGResourceFilter::FilterData object, which in turn is held by a RenderSVGResourceFilter object which is a renderer. Nothing else at all holds references to FEImage. Any changes to CSS properties (including SVG attributes) that affect the filter cause the FilterData and hence FEImage object to be destroyed and recreated. CSS Filters cannot use SVGFEImage.

The only way that FEImage::m_document is used is to look up the renderer for the image it is drawing. It will only do that during applyResource, which is only called when the target for the filter (the thing that will draw it) is painted, which only happens if the target is in the document. If the target is in the document then FEImage::m_document is valid. If the target is not in the document then it both cannot be painted and there is no FEImage object to have a dangling reference.
Comment 15 Dirk Schulze 2012-10-30 16:18:29 PDT
Comment on attachment 171478 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=171478&action=review

> Source/WebCore/ChangeLog:8
> +        Adding a comment to explain why the failure to clear m_document is not a problem.

Please say that this will be refactored with another patch.

>>> Source/WebCore/svg/graphics/filters/SVGFEImage.h:58
>>> +    // m_document will never be a dangling reference. See https://bugs.webkit.org/show_bug.cgi?id=99243
>> 
>> Better justification would be to explain why here as well.  This is not an Element, so it doesn't keep the document alive.  I assume this is held off of a renderer?  Can this also be held off of a CSSValue?
> 
> This object is only held by a SVGFilterBuilder which in turn is held by a RenderSVGResourceFilter::FilterData object, which in turn is held by a RenderSVGResourceFilter object which is a renderer. Nothing else at all holds references to FEImage. Any changes to CSS properties (including SVG attributes) that affect the filter cause the FilterData and hence FEImage object to be destroyed and recreated. CSS Filters cannot use SVGFEImage.
> 
> The only way that FEImage::m_document is used is to look up the renderer for the image it is drawing. It will only do that during applyResource, which is only called when the target for the filter (the thing that will draw it) is painted, which only happens if the target is in the document. If the target is in the document then FEImage::m_document is valid. If the target is not in the document then it both cannot be painted and there is no FEImage object to have a dangling reference.

Please add a link to this bug report, and open the bug report after landing again. Can be dependent on your refactoring patch later. After refactoring you just close it.
Comment 16 Stephen Chenney 2012-10-30 16:47:04 PDT
Comment on attachment 171478 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=171478&action=review

>> Source/WebCore/ChangeLog:8
>> +        Adding a comment to explain why the failure to clear m_document is not a problem.
> 
> Please say that this will be refactored with another patch.

But it won't be refactored, at least not to my knowledge. The comment exists so that _if_ there is ever a patch that changes the behavior the patch author will know the situation. Or if anyone, like Adam, is doing a security review they will have context in which to understand why this is not a security problem.

>>>> Source/WebCore/svg/graphics/filters/SVGFEImage.h:58
>>>> +    // m_document will never be a dangling reference. See https://bugs.webkit.org/show_bug.cgi?id=99243
>>> 
>>> Better justification would be to explain why here as well.  This is not an Element, so it doesn't keep the document alive.  I assume this is held off of a renderer?  Can this also be held off of a CSSValue?
>> 
>> This object is only held by a SVGFilterBuilder which in turn is held by a RenderSVGResourceFilter::FilterData object, which in turn is held by a RenderSVGResourceFilter object which is a renderer. Nothing else at all holds references to FEImage. Any changes to CSS properties (including SVG attributes) that affect the filter cause the FilterData and hence FEImage object to be destroyed and recreated. CSS Filters cannot use SVGFEImage.
>> 
>> The only way that FEImage::m_document is used is to look up the renderer for the image it is drawing. It will only do that during applyResource, which is only called when the target for the filter (the thing that will draw it) is painted, which only happens if the target is in the document. If the target is in the document then FEImage::m_document is valid. If the target is not in the document then it both cannot be painted and there is no FEImage object to have a dangling reference.
> 
> Please add a link to this bug report, and open the bug report after landing again. Can be dependent on your refactoring patch later. After refactoring you just close it.

There is a link to this bug report. Did you mean something else?

Again, there is no plan for a future patch at this time.
Comment 17 Dirk Schulze 2012-10-31 18:04:32 PDT
(In reply to comment #16)
> (From update of attachment 171478 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=171478&action=review
> 
> >> Source/WebCore/ChangeLog:8
> >> +        Adding a comment to explain why the failure to clear m_document is not a problem.
> > 
> > Please say that this will be refactored with another patch.
> 
> But it won't be refactored, at least not to my knowledge. The comment exists so that _if_ there is ever a patch that changes the behavior the patch author will know the situation. Or if anyone, like Adam, is doing a security review they will have context in which to understand why this is not a security problem.
> 
> >>>> Source/WebCore/svg/graphics/filters/SVGFEImage.h:58
> >>>> +    // m_document will never be a dangling reference. See https://bugs.webkit.org/show_bug.cgi?id=99243
> >>> 
> >>> Better justification would be to explain why here as well.  This is not an Element, so it doesn't keep the document alive.  I assume this is held off of a renderer?  Can this also be held off of a CSSValue?
> >> 
> >> This object is only held by a SVGFilterBuilder which in turn is held by a RenderSVGResourceFilter::FilterData object, which in turn is held by a RenderSVGResourceFilter object which is a renderer. Nothing else at all holds references to FEImage. Any changes to CSS properties (including SVG attributes) that affect the filter cause the FilterData and hence FEImage object to be destroyed and recreated. CSS Filters cannot use SVGFEImage.
> >> 
> >> The only way that FEImage::m_document is used is to look up the renderer for the image it is drawing. It will only do that during applyResource, which is only called when the target for the filter (the thing that will draw it) is painted, which only happens if the target is in the document. If the target is in the document then FEImage::m_document is valid. If the target is not in the document then it both cannot be painted and there is no FEImage object to have a dangling reference.
> > 
> > Please add a link to this bug report, and open the bug report after landing again. Can be dependent on your refactoring patch later. After refactoring you just close it.
> 
> There is a link to this bug report. Did you mean something else?
> 
> Again, there is no plan for a future patch at this time.

Hm, ok. Then land it :P
Comment 18 Stephen Chenney 2012-11-01 06:57:37 PDT
Committed r133158: <http://trac.webkit.org/changeset/133158>