Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undefined behavior in wuffs-v0.4.c #152

Closed
tksuoran opened this issue Jul 26, 2024 · 6 comments
Closed

Undefined behavior in wuffs-v0.4.c #152

tksuoran opened this issue Jul 26, 2024 · 6 comments

Comments

@tksuoran
Copy link

This could be somehow my own bad, as I've just started testing wuffs, but I decided to report this anyway:
When I run my code with ubsan, I get this kind of reports:

wuffs-v0.4.c:17220:14: runtime error: call to function wuffs_png__decoder__decode_image_config through pointer to incorrect function type 'wuffs_base__status__struct (*)(void *, wuffs_base__image_config__struct *, wuffs_base__io_buffer__struct *)'
wuffs-v0.4.c:61835: note: wuffs_png__decoder__decode_image_config defined here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior wuffs-v0.4.c:17220:14
wuffs-v0.4.c:17188:14: runtime error: call to function wuffs_png__decoder__decode_frame_config through pointer to incorrect function type 'wuffs_base__status__struct (*)(void *, wuffs_base__frame_config__struct *, wuffs_base__io_buffer__struct *)'
wuffs-v0.4.c:64123: note: wuffs_png__decoder__decode_frame_config defined here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior wuffs-v0.4.c:17188:14
wuffs-v0.4.c:17515:14: runtime error: call to function wuffs_png__decoder__workbuf_len through pointer to incorrect function type 'wuffs_base__range_ii_u64__struct (*)(const void *)'
wuffs-v0.4.c:65979: note: wuffs_png__decoder__workbuf_len defined here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior wuffs-v0.4.c:17515:14
wuffs-v0.4.c:17156:14: runtime error: call to function wuffs_png__decoder__decode_frame through pointer to incorrect function type 'wuffs_base__status__struct (*)(void *, wuffs_base__pixel_buffer__struct *, wuffs_base__io_buffer__struct *, unsigned char, wuffs_base__slice_u8, wuffs_base__decode_frame_options__struct *)'
wuffs-v0.4.c:64611: note: wuffs_png__decoder__decode_frame defined here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior wuffs-v0.4.c:17156:14
@tksuoran
Copy link
Author

I can work around the issue by this:

#pragma clang attribute push (__attribute__((no_sanitize("undefined"))), apply_to=function)
#include "wuffs-v0.4.c"
#pragma clang attribute pop

but I think this is less than ideal.

@nigeltao
Copy link
Collaborator

Can you share the ubsan-using command line that triggers this?

@tksuoran
Copy link
Author

While investigating another issue - gabime/spdlog#3145 - I run Microsoft Visual C++ Redistributable repair, and after that, I can no longer reproduce this undefined behavior. This suggests the issue was in somehow caused by old or broken Microsoft Visual C++ Redistributable.

I wish Microsoft would have added some sort of version check when they did breaking change (microsoft/STL#4730).

@nigeltao
Copy link
Collaborator

OK, not reproducible.

Still, you mentioned "Microsoft Visual C++ Redistributable" but also #pragma clang. Out of curiosity: were you compiling with MSVC or with clang?

@nigeltao
Copy link
Collaborator

And, in case this gets re-opened later, I am unable to reproduce any ubsan warnings. With this patch:

$ git diff
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 1a197f73..9b7019d0 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -1,6 +1,9 @@
 #ifndef WUFFS_INCLUDE_GUARD
 #define WUFFS_INCLUDE_GUARD
 
+#include <stdio.h>
+int trigger_ubsan = 0x7fffffff;
+
 // Wuffs ships as a "single file C library" or "header file library" as per
 // https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
 //
@@ -17181,6 +17184,7 @@ wuffs_base__image_decoder__decode_frame_config(
     wuffs_base__image_decoder* self,
     wuffs_base__frame_config* a_dst,
     wuffs_base__io_buffer* a_src) {
+fprintf(stderr, "wuffs_base__image_decoder__decode_frame_config\n");
   if (!self) {
     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
   }
@@ -64136,6 +64140,8 @@ wuffs_png__decoder__decode_frame_config(
     wuffs_png__decoder* self,
     wuffs_base__frame_config* a_dst,
     wuffs_base__io_buffer* a_src) {
+fprintf(stderr, "wuffs_png__decoder__decode_frame_config\n");
+if (trigger_ubsan++ == 123456) { fprintf(stderr, "undefined behavior! (int overflow)\n"); }
   if (!self) {
     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
   }

I get this output:

$ clang-14 -fsanitize=undefined test/c/std/png.c && ./a.out
wuffs_base__image_decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
test/c/std/../../../release/c/wuffs-unsupported-snapshot.c:64144:18: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior test/c/std/../../../release/c/wuffs-unsupported-snapshot.c:64144:18 in 
wuffs_base__image_decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_base__image_decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
wuffs_png__decoder__decode_frame_config
std/png         clang14 PASS (12 tests)

So, ubsan is triggering, but if I take out the trigger_ubsan++ == 123456 line, ubsan is no longer triggered. I don't get the test/c/std/... runtime error: signed integer overflow... SUMMARY: UndefinedBehaviorSanitizer... lines.

@tksuoran
Copy link
Author

OK, not reproducible.

Still, you mentioned "Microsoft Visual C++ Redistributable" but also #pragma clang. Out of curiosity: were you compiling with MSVC or with clang?

I was compiling in msys2 clang64 environment using clang:

$ clang++ --version
clang version 18.1.8
Target: x86_64-w64-windows-gnu
Thread model: posix
InstalledDir: C:/msys64/clang64/bin

AFAIK, msvc does not support ubsan currently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants