Bug 96272 - NPN_InitializeVariantWithStringCopy is wrong for platforms that return NULL from malloc(0)
Summary: NPN_InitializeVariantWithStringCopy is wrong for platforms that return NULL f...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Plug-ins (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Major
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-09-10 07:29 PDT by Julien Brianceau
Modified: 2013-01-24 16:57 PST (History)
3 users (show)

See Also:


Attachments
NPN_InitializeVariantWithStringCopy patch (1.80 KB, patch)
2012-09-10 08:39 PDT, Julien Brianceau
jbriance: review-
jbriance: commit-queue-
Details | Formatted Diff | Diff
NPN_InitializeVariantWithStringCopy patch (2) (1.79 KB, patch)
2012-09-10 08:55 PDT, Julien Brianceau
no flags Details | Formatted Diff | Diff
NPN_InitializeVariantWithStringCopy patch (3) (2.12 KB, patch)
2013-01-24 02:57 PST, Julien Brianceau
darin: review+
darin: commit-queue-
Details | Formatted Diff | Diff
NPN_InitializeVariantWithStringCopy patch (4) (2.12 KB, patch)
2013-01-24 10:21 PST, Julien Brianceau
no flags Details | Formatted Diff | Diff
NPN_InitializeVariantWithStringCopy patch (5) (1.73 KB, patch)
2013-01-24 14:51 PST, Julien Brianceau
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Julien Brianceau 2012-09-10 07:29:39 PDT
NPN_InitializeVariantWithStringCopy function call CRASH macro when NPString passed in parameters has a null length and malloc(0) returns NULL.
CRASH should only be called in this function for malloc failures with NPString length greater than 0.
Comment 1 Julien Brianceau 2012-09-10 08:39:13 PDT
Created attachment 163139 [details]
NPN_InitializeVariantWithStringCopy patch
Comment 2 WebKit Review Bot 2012-09-10 08:46:14 PDT
Attachment 163139 [details] did not pass style-queue:

Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'Source/WebCore/ChangeLog', u'Source/WebCor..." exit_code: 1
Source/WebCore/bridge/npruntime.cpp:95:  One line control clauses should not use braces.  [whitespace/braces] [4]
Total errors found: 1 in 2 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 3 Julien Brianceau 2012-09-10 08:55:34 PDT
Created attachment 163142 [details]
NPN_InitializeVariantWithStringCopy patch (2)
Comment 4 Alexey Proskuryakov 2012-09-10 09:47:24 PDT
Comment on attachment 163142 [details]
NPN_InitializeVariantWithStringCopy patch (2)

I wonder if we can just switch to fastMalloc/fastFree here. It doesn't look like a plug-in could directly invoke free() on the pointer.

Unlike malloc/free, fastMalloc has well defined behavior when size is 0.
Comment 5 Julien Brianceau 2012-09-10 09:54:32 PDT
(In reply to comment #4)
I don't know if we can switch to fastMalloc/fastFree here.
Perhaps it would be good to propose this switch in a separate new changeset ?
Comment 6 Darin Adler 2013-01-16 14:18:21 PST
(In reply to comment #5)
> I don't know if we can switch to fastMalloc/fastFree here.

I think we can.

> Perhaps it would be good to propose this switch in a separate new changeset ?

Perhaps, but maybe you misunderstand what Alexey meant.

Alexey’s point is that changing to fastMalloc/fastFree would be an alternate way to fix this very bug. Not that it would be an interesting bug unrelated change.

That fix would not require adding a special case for empty strings. Since we don’t have a good reason to optimize empty strings, it would be nice to fix this in a way that would not require making this otherwise-simple function more complex.
Comment 7 Julien Brianceau 2013-01-17 03:13:25 PST
Comment on attachment 163142 [details]
NPN_InitializeVariantWithStringCopy patch (2)

Ok, I'll provide a new patch to use fastMalloc allocator for NPN objects and string variants, and perform few tests.
But I see that even fastMalloc can return 0 when USE_SYSTEM_MALLOC define is set in Source/WTF/wtf/Platform.h. Should we handle this case ?
Comment 8 Darin Adler 2013-01-17 09:37:26 PST
(In reply to comment #7)
> But I see that even fastMalloc can return 0 when USE_SYSTEM_MALLOC define is set in Source/WTF/wtf/Platform.h.

That is incorrect.

Here is the code from FastMalloc.cpp (I removed the WTF_MALLOC_VALIDATION #if for clarity):

    void* fastMalloc(size_t n) 
    {
        ASSERT(!isForbidden());
        void* result = malloc(n);
        if (!result)
            CRASH();
        return result;
    }

The function will crash if malloc returns zero. So this implementation is not compatible with systems where the system malloc can return 0 when the passed-in size is 0. If someone needs to use USE_SYSTEM_MALLOC on a system like that, they’ll need to fix that in FastMalloc.cpp; it’s not something we have to worry about elsewhere.
Comment 9 Julien Brianceau 2013-01-17 09:45:00 PST
(In reply to comment #8)
> (In reply to comment #7)
> > But I see that even fastMalloc can return 0 when USE_SYSTEM_MALLOC define is set in Source/WTF/wtf/Platform.h.
> 
> That is incorrect.
> 

Aw yes you're right. I looked at tryFastMalloc implementation thinking it was fastMalloc, my mistake.
Comment 10 Julien Brianceau 2013-01-21 03:37:19 PST
Mmmh this seems to be more complex that I thought.

If I understand correctly NetScape plugins, a plugin can allocate its own String variant through NPN_InitializeVariantWithString call. In this case, the caller allocate the String, and this String will be released through NPReleaseVariantValue.

I'm clearly not an expert in NetScape plugins but I'm pretty sure that I'll introduce side effects crashes if I switch this to fastMalloc/fastFree.
Comment 11 Darin Adler 2013-01-21 17:01:22 PST
(In reply to comment #4)
> I wonder if we can just switch to fastMalloc/fastFree here.

Given Julien’s most recent comment, it seems we can’t.
Comment 12 Alexey Proskuryakov 2013-01-22 09:50:04 PST
> If I understand correctly NetScape plugins, a plugin can allocate its own String variant through NPN_InitializeVariantWithString call.

Do we implement that in WebKit? I could not find it anywhere in source code, only NPN_InitializeVariantWithStringCopy, which of course copies the string with any WebKit provided allocator.
Comment 13 Darin Adler 2013-01-22 10:21:11 PST
(In reply to comment #12)
> > If I understand correctly NetScape plugins, a plugin can allocate its own String variant through NPN_InitializeVariantWithString call.
> 
> Do we implement that in WebKit? I could not find it anywhere in source code, only NPN_InitializeVariantWithStringCopy, which of course copies the string with any WebKit provided allocator.

Lets get to the bottom of this. Either fix (fastMalloc, or adding zero check) seems OK, but we should do the fastMalloc fix if we can.
Comment 14 Julien Brianceau 2013-01-23 00:17:09 PST
(In reply to comment #13)
> 
> Lets get to the bottom of this. Either fix (fastMalloc, or adding zero check) seems OK, but we should do the fastMalloc fix if we can.

I agree. I removed obsolete flag on my patch and let someone more skilled than me in NPAPI decide what to do here. Of course I won't be offended at all if this patch is dropped to switch to fastMalloc :-)
Comment 15 Alexey Proskuryakov 2013-01-23 08:31:20 PST
Julien, can you please elaborate on your comment 10? I think that this is what preventing us from using fastMalloc to solve this siiue.
Comment 16 Julien Brianceau 2013-01-23 15:09:30 PST
(In reply to comment #15)
> Julien, can you please elaborate on your comment 10? I think that this is what preventing us from using fastMalloc to solve this siiue.

I didn't find an implementation of NPN_InitializeVariantWithString in current versions of WebKit, so my comment #10 is useless.

However there is still "STRINGZ_TO_NPVARIANT" macro (in Source/WebCore/plugins/npruntime.h), and I read this: http://stackoverflow.com/questions/1431409/firefox-npapi-plugin-development-firefox-freeze-when-calling-a-method
So I thought that we could perhaps switch to NPN_MemAlloc/NPN_MemFree calls, then switch these 2 functions' implementation to fastMalloc/fastFree (in Source/WebCore/plugins/npapi.cpp).

But it seems that there's quite an history for this: https://bugs.webkit.org/show_bug.cgi?id=20566, and I still can see this kind of comment (FIXME: This should really call NPN_MemAlloc but that's in WebKit) in Source/WebCore/bridge/NP_jsobject.cpp
Comment 17 Alexey Proskuryakov 2013-01-23 16:35:40 PST
Oh, interesting. So plug-ins can get their own data into a variant with STRINGZ_TO_NPVARIANT. The contract is that they use NPN_MemAlloc, but we don't really want to rely on that, as a comment in npnMemAlloc explains:

void* npnMemAlloc(uint32_t size)
{
    // We could use fastMalloc here, but there might be plug-ins that mix NPN_MemAlloc/NPN_MemFree with malloc and free,
    // so having them be equivalent seems like a good idea.
    return malloc(size);
}

This means that it's undesirable to switch NPN_InitializeVariantWithStringCopy to fastMalloc indeed. But we also need a comment explaining this, so that the next time someone looks at this code, they could find the explanation more easily.
Comment 18 Julien Brianceau 2013-01-24 02:57:27 PST
Created attachment 184453 [details]
NPN_InitializeVariantWithStringCopy patch (3)

Comment added in the code + ChangeLog update
Comment 19 Darin Adler 2013-01-24 09:31:05 PST
Comment on attachment 184453 [details]
NPN_InitializeVariantWithStringCopy patch (3)

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

> Source/WebCore/ChangeLog:10
> +        No new tests. This is platform dependant.

Spelling error: dependent is not spelled with an "a"

> Source/WebCore/bridge/npruntime.cpp:90
> +        // switching to fastMalloc would be better to avoid length check but this is not desirable
> +        // as NPN_MemAlloc is using malloc and there might be plugins that mix NPN_MemAlloc and malloc too

WebKit comment coding style is “sentence style”. First letter capitalized, period at end of sentence.
Comment 20 Julien Brianceau 2013-01-24 10:21:58 PST
Created attachment 184523 [details]
NPN_InitializeVariantWithStringCopy patch (4)
Comment 21 Alexey Proskuryakov 2013-01-24 11:29:30 PST
Comment on attachment 184523 [details]
NPN_InitializeVariantWithStringCopy patch (4)

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

This is going for way too long already, but I have additional comments, sorry about that.

> Source/WebCore/ChangeLog:8
> +        See bug 96272 comments for further information.

This is not helpful - the bug number is the same as above, so of course one would go there for additional information.

> Source/WebCore/bridge/npruntime.cpp:91
> +        variant->value.stringValue.UTF8Characters = (NPUTF8 *)malloc(sizeof(NPUTF8) * value->UTF8Length);

This is a pre-existing error, but WebKit style is to put star next to C++ class name (so it would be "(NPUTF8*)). It's also WebKit style to use static_cast over C-style casts, although I personally don't see that as beneficial in cases like this.

> Source/WebCore/bridge/npruntime.cpp:93
> +        if (!variant->value.stringValue.UTF8Characters)
> +            CRASH();

Can't we just change this check to the one below?

if (value->UTF8Length && !variant->value.stringValue.UTF8Characters)
    CRASH();

That would be a much smaller change, and more readable code, I think.
Comment 22 Julien Brianceau 2013-01-24 14:51:17 PST
Created attachment 184586 [details]
 NPN_InitializeVariantWithStringCopy patch (5)

Changes performed as requested excepting for the static_cast instead of C-style cast (because there are others C-style cast in this file for malloc/free calls and I'd prefer that we don't mix the bug fix with style changes).
Comment 23 WebKit Review Bot 2013-01-24 16:57:47 PST
Comment on attachment 184586 [details]
 NPN_InitializeVariantWithStringCopy patch (5)

Clearing flags on attachment: 184586

Committed r140751: <http://trac.webkit.org/changeset/140751>
Comment 24 WebKit Review Bot 2013-01-24 16:57:52 PST
All reviewed patches have been landed.  Closing bug.