New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 614648 link

Starred by 0 users

Issue metadata

Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Jun 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux
Pri: 2
Type: Bug



Sign in to add a comment

Undefined-shift in mem_get_be32_as_int

Project Member Reported by ClusterFuzz, May 25 2016

Issue description

Detailed report: https://cluster-fuzz.appspot.com/testcase?key=4625337657065472

Fuzzer: libfuzzer_media_vpx_video_decoder_fuzzer
Job Type: libfuzzer_chrome_ubsan
Platform Id: linux

Crash Type: Undefined-shift
Crash Address: 
Crash State:
  mem_get_be32_as_int
  get_tile_buffer
  get_tile_buffers
  
Regressed: https://cluster-fuzz.appspot.com/revisions?job=libfuzzer_chrome_ubsan&range=392658:393412

Minimized Testcase (0.07 Kb): https://cluster-fuzz.appspot.com/download/AMIfv97atwO5TR1bi_VAy0YZtOHtPwSnGAxfSFhq3BchsVtl_flNLsL2z44pkuLPi8eDb9jLZNmFAGkhPY9dqMWLBKUkYtJp5Bik7Sobdef5kdAhSWu88auYm55L4Qb4wLiOZd8tSw87JlAmTtYq4x9d8eQW-Kq0sA

Filer: mmoroz

See https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/reproducing.md for more information.
 

Comment 1 by mmoroz@chromium.org, May 25 2016

Cc: marpan@chromium.org mmoroz@chromium.org kcc@chromium.org aizatsky@chromium.org
Components: Internals>Media>Codecs
Labels: -Pri-1 Pri-2
Owner: tomfinegan@chromium.org
tomfinegan@, could you please take a look? Who may be a good owner for this?
Am I going crazy here? The fuzzer/ubsan output seems off. Are unsigned integers not 32 bits on the target? Why can't we shift 145 left by 24 bits and store it in an unsigned int when it's valid to do so with 255?

Here's why I'm confused. I'm running a clang build here and I cannot repro this using a much larger value:

int main(int argc, char* argv[]) {
  unsigned char bytes[4] = {0xFF, 0xFF, 0xFF, 0xFF};
  unsigned int val = bytes[0] << 24;
  return 0;
}

My compile commands:
clang -o /tmp/blah /tmp/tmpubs.cc --std=c++11 -fsanitize=integer -fsanitize=undefined -fsanitize=address -m32
clang -o /tmp/blah /tmp/tmpubs.cc --std=c++11 -fsanitize=integer -fsanitize=undefined -fsanitize=address

Sanity checks (changing the code above to left shift bytes[0] by 25) show that ubsan is working:
/tmp/tmpubs.cc:3:24: runtime error: left shift of 255 by 25 places cannot be represented in type 'int'

Now back to the bug. Some more info. The offending line according to the report:
https://code.google.com/p/chromium/codesearch#chromium/src/third_party/libvpx/source/libvpx/vpx_ports/mem_ops.h&l=92

It's this:
val = mem[0] << 24;

mem type:
const MAU_T          *mem = (const MAU_T *)vmem;
MAU_T is unsigned char.

val type:
unsigned MEM_VALUE_T  val;
MEM_VALUE_T is int.

Maybe I need more coffee. UBSAN confusion due to preproc stuff? Any ideas? 
It seems that UBSAN checks for the high bit set. Relevant bit of assembly:

.text:00000000007024FE loc_7024FE:                             ; CODE XREF: get_tile_buffers+1EEj
.text:00000000007024FE                 mov     rsi, [rbp+data]
.text:0000000000702502                 movzx   ebx, byte ptr [rsi]
.text:0000000000702505                 test    bl, bl
.text:0000000000702507                 mov     r15, [rbp+var_50]
.text:000000000070250B                 js      handle_ubsan_error_7027FB
.text:0000000000702511                 mov     eax, cs:cov_1D40864
.text:0000000000702517                 test    eax, eax
.text:0000000000702519                 jle     record_cov_702705
.text:000000000070251F
.text:000000000070251F loc_70251F:                             ; CODE XREF: get_tile_buffers+477j
.text:000000000070251F                 inc     cs:byte_1D41268
.text:0000000000702525
.text:0000000000702525 loc_702525:                             ; CODE XREF: get_tile_buffers+585j
.text:0000000000702525                 movzx   r12d, byte ptr [rsi+2]
.text:000000000070252A                 shl     rbx, 18h
.text:000000000070252E                 movzx   eax, byte ptr [rsi+1]
.text:0000000000702532                 shl     rax, 10h
.text:0000000000702536                 shl     r12, 8
.text:000000000070253A                 movzx   ecx, byte ptr [rsi+3]
.text:000000000070253E                 or      r12, rbx
.text:0000000000702541                 or      r12, rax
.text:0000000000702544                 or      r12, rcx

Will try to understand why such code is generated.
I just contacted Richard Smith for standard clarification. Here's his answer:

---- cut ----

> Is this kind of shift indeed an undefined behavior? Is this a false positive?

It depends on which language mode you're in. In C and C++98, it is undefined behavior. 145 * 2**24 does not fit in an int (the C / C++98 rule is that you cannot shift a 1 into the sign bit).

In C++11, this case has defined behavior, but left-shifting by 25 places would have undefined behavior (you cannot shift a 1 out of the sign bit in C++11).


> Is the value promoted to signed type somewhere?

Yes, the integral promotions are performed on the left-hand side, so we're left-shifting a value of type 'int'. (Otherwise this would be unconditionally undefined behavior because 24 is greater than the bit-width of 'unsigned char'.) 

---- end cut ----

If you compile your sample in C mode, then ubsan correctly complains:

$ cat tmpubs.cc && clang++ -o tmpubs -x c tmpubs.cc -fsanitize=integer -fsanitize=undefined && ./tmpubs
int main(int argc, char* argv[]) {
  volatile unsigned char bytes[4] = {0xFF, 0xFF, 0xFF, 0xFF};
  volatile unsigned int val = bytes[0] << 24;
  return 0;
}
tmpubs.cc:3:40: runtime error: left shift of 255 by 24 places cannot be represented in type 'int'


The correct solution is to explicitly cast unsigned bytes to unsigned ints. 
Project Member

Comment 5 by ClusterFuzz, May 26 2016

ClusterFuzz has detected this testcase as flaky and is unable to reproduce it in the original crash revision. Skipping fixed testing check and marking it as potentially fixed.

Detailed report: https://cluster-fuzz.appspot.com/testcase?key=4625337657065472

Fuzzer: libfuzzer_media_vpx_video_decoder_fuzzer
Job Type: libfuzzer_chrome_ubsan
Platform Id: linux

Crash Type: Undefined-shift
Crash Address: 
Crash State:
  mem_get_be32_as_int
  get_tile_buffer
  get_tile_buffers
  
Regressed: https://cluster-fuzz.appspot.com/revisions?job=libfuzzer_chrome_ubsan&range=392658:393412

Minimized Testcase (0.07 Kb): https://cluster-fuzz.appspot.com/download/AMIfv97atwO5TR1bi_VAy0YZtOHtPwSnGAxfSFhq3BchsVtl_flNLsL2z44pkuLPi8eDb9jLZNmFAGkhPY9dqMWLBKUkYtJp5Bik7Sobdef5kdAhSWu88auYm55L4Qb4wLiOZd8tSw87JlAmTtYq4x9d8eQW-Kq0sA

See https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/reproducing.md for more information.

If you suspect that the result above is incorrect, try re-doing that job on the test case report page.
@aizatsky

Thanks for the detailed explanation. I thought all of chrome was compiled with C++11 enabled (i.e. --std=c++11), so this situation is something of a surprise... Not that chrome's use of C++11 excuses the issue entirely considering that the upstream code is typically compiled as C. Will look into fixing this upstream.

Comment 7 by kcc@chromium.org, May 26 2016

In general you can not compile a C code with --std=c++11 :( 
Project Member

Comment 8 by ClusterFuzz, May 27 2016

Detailed report: https://cluster-fuzz.appspot.com/testcase?key=5047822600896512

Fuzzer: libfuzzer_media_vpx_video_decoder_fuzzer
Job Type: libfuzzer_chrome_ubsan
Platform Id: linux

Crash Type: Undefined-shift
Crash Address: 
Crash State:
  mem_get_be32_as_int
  get_tile_buffer
  get_tile_buffers
  
Regressed: https://cluster-fuzz.appspot.com/revisions?job=libfuzzer_chrome_ubsan&range=392658:393412

Minimized Testcase (0.07 Kb): https://cluster-fuzz.appspot.com/download/AMIfv958YtLCQIf2uLDAV9HPadK3QYz9dM3HgBEIrdxo0RLJcEv4bXRsdRuHp1ij-gcQJUM_rnPgKpIZr5hyWr6tnzTS_rSic5VvTgdIFMDqhfxNRKJlCDw6Xse-ojVMicjIjthCyk84Uz295AZcTA-n2kAOma_zmA

Filer: mmoroz

See https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/reproducing.md for more information.
Project Member

Comment 9 by bugdroid1@chromium.org, May 27 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/webm/libvpx/+/f1de6226176ff90552ebe7473d8a76e388685053

commit f1de6226176ff90552ebe7473d8a76e388685053
Author: Tom Finegan <tomfinegan@google.com>
Date: Fri May 27 16:16:35 2016

vpx_ports/mem_ops.h: cast the lhs of bitwise shifts of 24.

C does not allow for shifting into the sign bit of a signed
integer, and the two instances here become signed ints via
promotion. Explcitly cast them to unsigned MEM_VALUE_T to
avoid the problem.

BUG=https://bugs.chromium.org/p/chromium/issues/detail?id=614648

Change-Id: I51165361a8c6cbb5c378cf7e4e0f4b80b3ad9a6e

[modify] https://crrev.com/f1de6226176ff90552ebe7473d8a76e388685053/vpx_ports/mem_ops.h

Will roll early next week. Rolling before a long weekend sets the tree on fire. :(
Project Member

Comment 11 by bugdroid1@chromium.org, Jun 1 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d

commit dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d
Author: marpan <marpan@chromium.org>
Date: Wed Jun 01 15:55:23 2016

Roll src/third_party/libvpx/source/libvpx/ 4f774ac50..f80d8011a (12 commits).

https://chromium.googlesource.com/webm/libvpx.git/+log/4f774ac50e4d..f80d8011a014

$ git log 4f774ac50..f80d8011a --date=short --no-merges --format='%ad %ae %s'
2016-05-27 jzern acm_random,Rand9Signed: correct cast
2016-05-17 linfengz Upgrade fwht4x4_mmx() to fwht4x4_sse2() for vp9 and vp10.
2016-05-27 tomfinegan vpx_ports/mem_ops.h: cast the lhs of bitwise shifts of 24.
2016-05-19 linfengz Upgrade vpx_lpf_{vertical,horizontal}_4 mmx to sse2
2016-05-25 yaowu Convert to unsigned int before left shift
2016-05-25 marpan vp9: Add datarate test for 1 pass VBR mode.
2016-05-24 yaowu Fix comments in build_intra_predictors_high()
2016-05-25 yaowu Prevent read to invalid RefBuffer
2016-05-24 bvibber Move git version extras out of iOS shared framework bundle version
2016-05-24 jzern remove vp9_diamond_search_sad_avx.c
2016-05-24 slavarnway Code clean of sub_pixel_variance4xh -- 2
2016-05-20 jackychen vp9: Remove a redundent condition in sub-pixel filter choosing.

R=johannkoenig@google.com
BUG= 614701 ,  614648 ,  615046 

Review-Url: https://codereview.chromium.org/2027703002
Cr-Commit-Position: refs/heads/master@{#397153}

[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/DEPS
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/BUILD.gn
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/README.chromium
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/generate_gypi.sh
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/libvpx.gyp
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/libvpx_srcs.gni
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/libvpx_srcs_x86.gypi
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/libvpx_srcs_x86_64.gypi
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/libvpx_srcs_x86_64_intrinsics.gypi
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/libvpx_srcs_x86_intrinsics.gypi
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/source/config/linux/ia32/vp9_rtcd.h
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/source/config/linux/ia32/vpx_dsp_rtcd.h
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/source/config/linux/x64/vp9_rtcd.h
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/source/config/linux/x64/vpx_dsp_rtcd.h
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/source/config/mac/ia32/vp9_rtcd.h
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/source/config/mac/ia32/vpx_dsp_rtcd.h
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/source/config/mac/x64/vp9_rtcd.h
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/source/config/mac/x64/vpx_dsp_rtcd.h
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/source/config/vpx_version.h
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/source/config/win/ia32/vp9_rtcd.h
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/source/config/win/ia32/vpx_dsp_rtcd.h
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/source/config/win/x64/vp9_rtcd.h
[modify] https://crrev.com/dfb18ad9f81978e1beccc6ba528acf6d9ee9f07d/third_party/libvpx/source/config/win/x64/vpx_dsp_rtcd.h

Project Member

Comment 12 by ClusterFuzz, Jun 2 2016

ClusterFuzz has detected this issue as fixed in range 397093:397165.

Detailed report: https://cluster-fuzz.appspot.com/testcase?key=5047822600896512

Fuzzer: libfuzzer_media_vpx_video_decoder_fuzzer
Job Type: libfuzzer_chrome_ubsan
Platform Id: linux

Crash Type: Undefined-shift
Crash Address: 
Crash State:
  mem_get_be32_as_int
  get_tile_buffer
  get_tile_buffers
  
Regressed: https://cluster-fuzz.appspot.com/revisions?job=libfuzzer_chrome_ubsan&range=392658:393412
Fixed: https://cluster-fuzz.appspot.com/revisions?job=libfuzzer_chrome_ubsan&range=397093:397165

Minimized Testcase (0.07 Kb): https://cluster-fuzz.appspot.com/download/AMIfv958YtLCQIf2uLDAV9HPadK3QYz9dM3HgBEIrdxo0RLJcEv4bXRsdRuHp1ij-gcQJUM_rnPgKpIZr5hyWr6tnzTS_rSic5VvTgdIFMDqhfxNRKJlCDw6Xse-ojVMicjIjthCyk84Uz295AZcTA-n2kAOma_zmA

See https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/reproducing.md for more information.

If you suspect that the result above is incorrect, try re-doing that job on the test case report page.
Status: Fixed (was: Available)
Project Member

Comment 14 by sheriffbot@chromium.org, Nov 22 2016

Labels: -Restrict-View-EditIssue
Removing EditIssue view restrictions from ClusterFuzz filed bugs. If you believe that this issue should still be restricted, please reapply the label.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot

Sign in to add a comment