Bug 188556 - [JSC] Should not rotate constant with 64
Summary: [JSC] Should not rotate constant with 64
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Yusuke Suzuki
URL:
Keywords: InRadar
Depends on: 188736
Blocks:
  Show dependency treegraph
 
Reported: 2018-08-14 09:11 PDT by Yusuke Suzuki
Modified: 2018-08-21 22:03 PDT (History)
9 users (show)

See Also:


Attachments
Patch (2.78 KB, patch)
2018-08-14 09:13 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (2.85 KB, patch)
2018-08-19 18:03 PDT, Yusuke Suzuki
saam: review+
ews-watchlist: commit-queue-
Details | Formatted Diff | Diff
Archive of layout-test-results from ews206 for win-future (12.92 MB, application/zip)
2018-08-19 20:39 PDT, EWS Watchlist
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Yusuke Suzuki 2018-08-14 09:11:08 PDT
[JSC] Should not rotate constant with 64
Comment 1 Yusuke Suzuki 2018-08-14 09:13:13 PDT
Created attachment 347080 [details]
Patch
Comment 2 Don Olmstead 2018-08-14 09:47:31 PDT
Comment on attachment 347080 [details]
Patch

Informal review is r+. This issue was found within a run of ARES6 using UBSan. This will prevent the undefined behavior.
Comment 3 Mark Lam 2018-08-14 10:12:26 PDT
Comment on attachment 347080 [details]
Patch

r=me
Comment 4 Yusuke Suzuki 2018-08-14 10:14:26 PDT
(In reply to Don Olmstead from comment #2)
> Comment on attachment 347080 [details]
> Patch
> 
> Informal review is r+. This issue was found within a run of ARES6 using
> UBSan. This will prevent the undefined behavior.

Yeah, this is nice.

(In reply to Mark Lam from comment #3)
> Comment on attachment 347080 [details]
> Patch
> 
> r=me

Thanks :)
Comment 5 Yusuke Suzuki 2018-08-14 10:16:38 PDT
Committed r234852: <https://trac.webkit.org/changeset/234852>
Comment 6 Radar WebKit Bug Importer 2018-08-14 10:17:46 PDT
<rdar://problem/43291961>
Comment 7 WebKit Commit Bot 2018-08-19 17:22:41 PDT
Re-opened since this is blocked by bug 188736
Comment 8 Darin Adler 2018-08-19 17:41:15 PDT
Comment on attachment 347080 [details]
Patch

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

> Source/JavaScriptCore/assembler/MacroAssembler.h:1298
> +        // Generate the seed in [0, widthInBits). We should not generate widthInBits
> +        // since it leads to `<< widthInBits`, which is an undefined behavior.
> +        return random() % (widthInBits - 1);

I don’t understand the original bug, nor do I understand how this change will fix it.

The comment doesn’t agree with the code.

Let’s consider the case where widthInBits is 64. This code then does (u % 63), where u is a 32-bit unsigned integer. That operation should result in an integer in the range [0, 63). The existing code that does (u % 64) already should yield a number in the range [0, 64). The theory of the bug doesn’t make sense. The result of (u % 64) should not ever be 64.

Is there a bug here in the original code? How did we come to suspect there was?
Comment 9 Darin Adler 2018-08-19 17:41:40 PDT
(In reply to Don Olmstead from comment #2)
> This issue was found within a run of ARES6 using
> UBSan. This will prevent the undefined behavior.

I’d like to know more about exactly what UBSan reported.
Comment 10 Saam Barati 2018-08-19 17:45:30 PDT
Comment on attachment 347080 [details]
Patch

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

>> Source/JavaScriptCore/assembler/MacroAssembler.h:1298
>> +        return random() % (widthInBits - 1);
> 
> I don’t understand the original bug, nor do I understand how this change will fix it.
> 
> The comment doesn’t agree with the code.
> 
> Let’s consider the case where widthInBits is 64. This code then does (u % 63), where u is a 32-bit unsigned integer. That operation should result in an integer in the range [0, 63). The existing code that does (u % 64) already should yield a number in the range [0, 64). The theory of the bug doesn’t make sense. The result of (u % 64) should not ever be 64.
> 
> Is there a bug here in the original code? How did we come to suspect there was?

Isn't the bug here just that a shift by a number >= 64 UB?
Comment 11 Saam Barati 2018-08-19 17:49:25 PDT
Comment on attachment 347080 [details]
Patch

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

>>> Source/JavaScriptCore/assembler/MacroAssembler.h:1298
>>> +        return random() % (widthInBits - 1);
>> 
>> I don’t understand the original bug, nor do I understand how this change will fix it.
>> 
>> The comment doesn’t agree with the code.
>> 
>> Let’s consider the case where widthInBits is 64. This code then does (u % 63), where u is a 32-bit unsigned integer. That operation should result in an integer in the range [0, 63). The existing code that does (u % 64) already should yield a number in the range [0, 64). The theory of the bug doesn’t make sense. The result of (u % 64) should not ever be 64.
>> 
>> Is there a bug here in the original code? How did we come to suspect there was?
> 
> Isn't the bug here just that a shift by a number >= 64 UB?

I just read the original code. I also don't see how there is a bug. Since we already were doing % 64, we'd end up with a number in the range of [0, 63].
Comment 12 Darin Adler 2018-08-19 17:51:58 PDT
(In reply to Saam Barati from comment #11)
> I just read the original code. I also don't see how there is a bug. Since we
> already were doing % 64, we'd end up with a number in the range of [0, 63].

Yes, that matches my understanding.

Since UBSan complained, I would like to know what it complained about. If it complained about a shift of 64, then I would like to know the details because the results of a % 64 should never be 64.
Comment 13 Yusuke Suzuki 2018-08-19 17:55:34 PDT
Comment on attachment 347080 [details]
Patch

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

>>>> Source/JavaScriptCore/assembler/MacroAssembler.h:1298
>>>> +        return random() % (widthInBits - 1);
>>> 
>>> I don’t understand the original bug, nor do I understand how this change will fix it.
>>> 
>>> The comment doesn’t agree with the code.
>>> 
>>> Let’s consider the case where widthInBits is 64. This code then does (u % 63), where u is a 32-bit unsigned integer. That operation should result in an integer in the range [0, 63). The existing code that does (u % 64) already should yield a number in the range [0, 64). The theory of the bug doesn’t make sense. The result of (u % 64) should not ever be 64.
>>> 
>>> Is there a bug here in the original code? How did we come to suspect there was?
>> 
>> Isn't the bug here just that a shift by a number >= 64 UB?
> 
> I just read the original code. I also don't see how there is a bug. Since we already were doing % 64, we'd end up with a number in the range of [0, 63].

Yeah, the problem is, >> 64 AND << 64 are both undefined behavior.
https://wiki.sei.cmu.edu/confluence/display/c/INT34-C.+Do+not+shift+an+expression+by+a+negative+number+of+bits+or+by+greater+than+or+equal+to+the+number+of+bits+that+exist+in+the+operand
We should generate a seed [1, 63] to make `value = (value << rotation) | (value >> (sizeof(void*) * 8 - rotation));` safe.
Comment 14 Yusuke Suzuki 2018-08-19 17:57:02 PDT
Comment on attachment 347080 [details]
Patch

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

>>>>> Source/JavaScriptCore/assembler/MacroAssembler.h:1298
>>>>> +        return random() % (widthInBits - 1);
>>>> 
>>>> I don’t understand the original bug, nor do I understand how this change will fix it.
>>>> 
>>>> The comment doesn’t agree with the code.
>>>> 
>>>> Let’s consider the case where widthInBits is 64. This code then does (u % 63), where u is a 32-bit unsigned integer. That operation should result in an integer in the range [0, 63). The existing code that does (u % 64) already should yield a number in the range [0, 64). The theory of the bug doesn’t make sense. The result of (u % 64) should not ever be 64.
>>>> 
>>>> Is there a bug here in the original code? How did we come to suspect there was?
>>> 
>>> Isn't the bug here just that a shift by a number >= 64 UB?
>> 
>> I just read the original code. I also don't see how there is a bug. Since we already were doing % 64, we'd end up with a number in the range of [0, 63].
> 
> Yeah, the problem is, >> 64 AND << 64 are both undefined behavior.
> https://wiki.sei.cmu.edu/confluence/display/c/INT34-C.+Do+not+shift+an+expression+by+a+negative+number+of+bits+or+by+greater+than+or+equal+to+the+number+of+bits+that+exist+in+the+operand
> We should generate a seed [1, 63] to make `value = (value << rotation) | (value >> (sizeof(void*) * 8 - rotation));` safe.

The first fix was wrong, since it does not produce 64 without this patch. I thought the UB is caused by `value << 64`. But in fact, it is caused by `value >> (sizeof(void*) * 8 - rotation)` part if `rotation` is 0.
I'll upload a patch, which generates a seed within [1, 63].
Comment 15 Yusuke Suzuki 2018-08-19 18:03:22 PDT
Created attachment 347474 [details]
Patch
Comment 16 EWS Watchlist 2018-08-19 20:39:17 PDT
Comment on attachment 347474 [details]
Patch

Attachment 347474 [details] did not pass win-ews (win):
Output: https://webkit-queues.webkit.org/results/8913070

New failing tests:
http/tests/security/contentSecurityPolicy/video-with-https-url-allowed-by-csp-media-src-star.html
Comment 17 EWS Watchlist 2018-08-19 20:39:30 PDT
Created attachment 347478 [details]
Archive of layout-test-results from ews206 for win-future

The attached test failures were seen while running run-webkit-tests on the win-ews.
Bot: ews206  Port: win-future  Platform: CYGWIN_NT-6.1-2.9.0-0.318-5-3-x86_64-64bit
Comment 18 Yusuke Suzuki 2018-08-21 22:03:01 PDT
Committed r235160: <https://trac.webkit.org/changeset/235160>