https://bugs.winehq.org/show_bug.cgi?id=40330
Bug ID: 40330 Summary: Build fails with AddressSanitizer. Product: Wine Version: 1.9.5 Hardware: x86 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: -unknown Assignee: wine-bugs@winehq.org Reporter: adam.buchbinder@gmail.com Distribution: ---
https://wiki.winehq.org/Building_Wine#Memory_.26_Address_Checkers describes using AddressSanitizer with Wine. It seems not to compile. I'm using:
$ gcc --version gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
A short excerpt:
$ ./configure --enable-win64 CFLAGS="-g -O1 -fsanitize=address" ... $ make ... make[1]: Entering directory `/home/abuchbinder/software/wine/tools' LC_ALL=C sed -e 's,@bindir@,/usr/local/bin,g' -e 's,@dlldir@,/usr/local/lib64/wine,g' -e 's,@PACKAGE_STRING@,Wine 1.9.6,g' -e 's,@PACKAGE_VERSION@,1.9.6,g' wineapploader.in >wineapploader || (rm -f wineapploader && false) gcc -m64 -c -o make_xftmpl.o make_xftmpl.c -I. -I../include -D__WINESRC__ -Wall -pipe -fno-strict-aliasing \ -Wdeclaration-after-statement -Wempty-body -Wignored-qualifiers -Wstrict-prototypes -Wtype-limits \ -Wunused-but-set-parameter -Wvla -Wwrite-strings -Wpointer-arith -Wlogical-op -gdwarf-2 \ -gstrict-dwarf -g -O1 -fsanitize=address -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 gcc -m64 -o make_xftmpl make_xftmpl.o ../libs/port/libwine_port.a make_xftmpl.o: In function `exit_on_signal': /home/abuchbinder/software/wine/tools/make_xftmpl.c:413: undefined reference to `__asan_handle_no_return' make_xftmpl.o: In function `fatal_error': /home/abuchbinder/software/wine/tools/make_xftmpl.c:127: undefined reference to `__asan_handle_no_return' ...
and so on. The problem here is that the command:
gcc -m64 -o make_xftmpl make_xftmpl.o ../libs/port/libwine_port.a
should be:
gcc -m64 -o make_xftmpl make_xftmpl.o ../libs/port/libwine_port.a -fsanitize=address
I can work around this in part with:
$ find . -name Makefile|xargs perl -pi -e 's/^(CC = gcc -m64)$/\1 -fsanitize=address/'
... but that's probably not the right way to do this, and it only works for tools/ and not dlls/ anyway. My Makefile-fu is not strong; I'm sure I'm missing something about how the configuration system works, but I'm equally sure that this is something worth reporting even if I'm not entirely certain what's going on.
https://bugs.winehq.org/show_bug.cgi?id=40330
--- Comment #1 from Adam Buchbinder adam.buchbinder@gmail.com --- Update: it gets much further with:
$ ./configure --enable-win64 CFLAGS="-g -O1 -fsanitize=address" LDFLAGS="-fsanitize=address"
But still fails at the DLL stage:
make[1]: Entering directory `/home/abuchbinder/software/wine/dlls/acledit' ../../tools/winegcc/winegcc -o acledit.dll.so -B../../tools/winebuild -m64 -fasynchronous-unwind-tables -shared acledit.spec \ main.o ../../libs/port/libwine_port.a -fsanitize=address main.o: In function `DllMain': /home/abuchbinder/software/wine/dlls/acledit/main.c:38: undefined reference to `__asan_report_load1' ...
https://bugs.winehq.org/show_bug.cgi?id=40330
Rosanne DiMesio dimesio@earthlink.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |kyle.auble@zoho.com
https://bugs.winehq.org/show_bug.cgi?id=40330
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |austinenglish@gmail.com
https://bugs.winehq.org/show_bug.cgi?id=40330
--- Comment #2 from Adam Buchbinder adam.buchbinder@gmail.com --- This appears to compile almost everything:
$ ./configure --enable-win64 CFLAGS="-g -O1 -fsanitize=address -fno-omit-frame-pointer" LDFLAGS="-fsanitize=address -lasan -lpthread"
However, make then fails on an execution of sfnt2fon, which may be a FreeType problem, but I'm not sure; the code in sfnt2fon.c is pretty involved. It seems to be complaining about memory allocated by FreeType, which the program then goes past the end of. I've attached the report, though it only identified the line in sfnt2fon.c, not anything before that.
Failures are seen on: sseriffe.fon, smae1257.fon, and smallee.fon.
https://bugs.winehq.org/show_bug.cgi?id=40330
--- Comment #3 from Adam Buchbinder adam.buchbinder@gmail.com --- Created attachment 53999 --> https://bugs.winehq.org/attachment.cgi?id=53999 ASan output for sfnt2fon trying to generate sserifee.fon.
https://bugs.winehq.org/show_bug.cgi?id=40330
--- Comment #4 from Kyle Auble kyle.auble@zoho.com --- Hi Adam,
First let me apologize for not responding sooner. I just stumbled across this bug report while checking for any old bugs I was subscribed to. I honestly don't remember getting a notice; it probably came right when I was dropping off the internet for a while.
Anyways, by now you've probably either moved on or upgraded to newer versions that work, but I have an idea about what might be happening. My best guess is that if you follow the new instructions on the wiki, passing the "-Og" compiler flag rather than "-g -O1" (even if you still use GCC v4.8), it should work.
I see you figured out that you need to pass "-fsanitize=address" to the linker in addition to the compiler. That was an omission from the Building Wine page that has since been fixed. The problems you saw after that though may have come from not passing all 3 of the "-fno-..." flags mentioned on the wiki.
I think "-lasan -lthread" is completely redundant as long as you also pass "-fsanitize=address" to the linker, but without all 3 "-fno-..." flags, it's very possible the compiler optimized away something ASan would require to hook into Wine at execution.
The "-Og" flag is nice since it asks the compiler (so essentially the compiler devs) to select exactly the optimizations you need for debugging tools. That way you don't have to worry about any of the "-fno-..." flags anymore.
Of course, if you (or anyone else) still has this problem, and the new instructions don't fix it, definitely update us here. I'll try to keep a closer eye on the report and look into it more if needed.
https://bugs.winehq.org/show_bug.cgi?id=40330
tokktokk fdsfgs@krutt.org changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |fdsfgs@krutt.org
https://bugs.winehq.org/show_bug.cgi?id=40330
Kristján Gerhardsson fluffy@fluffy.is changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |fluffy@fluffy.is
--- Comment #5 from Kristján Gerhardsson fluffy@fluffy.is --- For anyone else stumbling over the sfnt2fon problem, here is a quick workaround.
Compile wine normally (without asan), then make a copy of sfnt2fon. Then compile wine with asan. Once the compilation fails, replace the sfnt2fon version compiled with asan with the one compiled without asan, which you copied earlier. The compilation should complete without any further errors.
Obviously this isn't a proper fix, but it's at least a workaround to get the asan compilation to work.
https://bugs.winehq.org/show_bug.cgi?id=40330
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Status|UNCONFIRMED |NEW
--- Comment #6 from Austin English austinenglish@gmail.com --- (In reply to Kyle Auble from comment #4)
Of course, if you (or anyone else) still has this problem, and the new instructions don't fix it, definitely update us here. I'll try to keep a closer eye on the report and look into it more if needed.
Hi Kyle,
I hadn't tried this in a while, but just did with 7.3.0.
Doing: ./configure CFLAGS="-Og -fsanitize=address" LDFLAGS="-fsanitize=address" make -j $(nproc)
failed. I need to add -lasan -pthread.
After that, fails when it tries to make fonts with output similar to attachment 53999. I'll attach a patch that avoids it, but it's a hack.
https://bugs.winehq.org/show_bug.cgi?id=40330
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |download, source
--- Comment #7 from Austin English austinenglish@gmail.com --- Also updated https://wiki.winehq.org/index.php?title=Building_Wine
https://bugs.winehq.org/show_bug.cgi?id=40330
--- Comment #8 from Austin English austinenglish@gmail.com --- Created attachment 61743 --> https://bugs.winehq.org/attachment.cgi?id=61743 hack
https://bugs.winehq.org/show_bug.cgi?id=40330
--- Comment #9 from Kyle Auble kyle.auble@zoho.com --- (In reply to Austin English from comment #6)
Hi Kyle,
I hadn't tried this in a while, but just did with 7.3.0.
Doing: ./configure CFLAGS="-Og -fsanitize=address" LDFLAGS="-fsanitize=address" make -j $(nproc)
failed. I need to add -lasan -pthread.
After that, fails when it tries to make fonts with output similar to attachment 53999 [details]. I'll attach a patch that avoids it, but it's a hack.
Hey Austin, thanks for testing it hands-on and updating the wiki too.
I'm actually going to be moving on from Wine, but I wanted to keep an eye on the few bugs I've been involved with. Anyways, I don't have any triage permissions so I can't update the bug itself, but it sounds like there are actually two issues:
1. From researching the docs, there are a few linker flags (like "--no-undefined" and "-z,defs") that are conceptually incompatible with ASan. AFAICT though, wine's build configuration doesn't use them. Clang also has some kinks that apparently require you to link in ASan differently, but this report discusses GCC.
Just skimming the actual ASan documentation and bug tracker, they seem pretty adamant that manually calling any flags besides "-fsanitize=address" is deprecated and shouldn't be necessary. There are still lots of people using it though, and it's obviously important here so I'm thinking this deserves a bug-report with ASan. Besides documenting it in our building instructions, I suspect this isn't ultimately Wine's bug.
2. Now as for the sfnt2fon problem, it looks like that actually may just be ASan doing its job. At least their documented example of a heap-overflow at compile-time is also a fatal error: https://github.com/google/sanitizers/wiki/AddressSanitizerExampleHeapOutOfBo...
I definitely don't know the code well enough to say for sure, but unless it's a false positive, for now I would interpret it as a legitimate overflow. You said you got a similar log to the original reporter, but there are gaps in his call-stack trace. Any guesses at if/where sfnt2fon might be acting funny?
https://bugs.winehq.org/show_bug.cgi?id=40330
--- Comment #10 from Austin English austinenglish@gmail.com --- (In reply to Kyle Auble from comment #9)
- From researching the docs, there are a few linker flags (like
"--no-undefined" and "-z,defs") that are conceptually incompatible with ASan. AFAICT though, wine's build configuration doesn't use them. Clang also has some kinks that apparently require you to link in ASan differently, but this report discusses GCC.
Yeah, I later ran into that as well. I worked around it with: sed -i -e 's/-fsanitize=address//' -e 's/-lasan//' loader/Makefile
long term, if this proves usable, it shouldn't be too hard to add a configure option so that the Makefile are properly generated without sed.
Just skimming the actual ASan documentation and bug tracker, they seem pretty adamant that manually calling any flags besides "-fsanitize=address" is deprecated and shouldn't be necessary. There are still lots of people using it though, and it's obviously important here so I'm thinking this deserves a bug-report with ASan. Besides documenting it in our building instructions, I suspect this isn't ultimately Wine's bug.
Agreed.
- Now as for the sfnt2fon problem, it looks like that actually may just be
ASan doing its job. At least their documented example of a heap-overflow at compile-time is also a fatal error: https://github.com/google/sanitizers/wiki/ AddressSanitizerExampleHeapOutOfBounds
I definitely don't know the code well enough to say for sure, but unless it's a false positive, for now I would interpret it as a legitimate overflow. You said you got a similar log to the original reporter, but there are gaps in his call-stack trace. Any guesses at if/where sfnt2fon might be acting funny?
I ran sfnt2fon under valgrind, which showed some more info, see bug 45422.
https://bugs.winehq.org/show_bug.cgi?id=40330
--- Comment #11 from Austin English austinenglish@gmail.com --- Short answer is https://source.winehq.org/git/wine.git/blob/HEAD:/tools/sfnt2fon/sfnt2fon.c#...
https://bugs.winehq.org/show_bug.cgi?id=40330
--- Comment #12 from Austin English austinenglish@gmail.com --- Though after getting it to build, running wine fails; looks like the preloader interferes with ASAN: ==9822==Shadow memory range interleaves with an existing memory mapping. ASan cannot proceed correctly. ABORTING. ==9822==ASan shadow was supposed to be located in the [0x1ffff000-0x3fffffff] range. ==9822==Process memory map follows: 0x00010000-0x68000000 0x7c000000-0x7c002000 /var/lib/jenkins/home/workspace/wine-gcc-asan/loader/wine 0x7c002000-0x7c003000 /var/lib/jenkins/home/workspace/wine-gcc-asan/loader/wine 0x7c003000-0x7c004000 /var/lib/jenkins/home/workspace/wine-gcc-asan/loader/wine 0x7c400000-0x7c402000 /var/lib/jenkins/home/workspace/wine-gcc-asan/loader/wine-preloader 0x7c403000-0x7c404000 /var/lib/jenkins/home/workspace/wine-gcc-asan/loader/wine-preloader
I tried the LD_PRELOAD workaround: export ASAN_OPTIONS=halt_on_error=0 export LD_PRELOAD="/usr/lib64/gcc/x86_64-pc-linux-gnu/7.3.0/libasan.so.4 /usr/lib64/gcc/x86_64-pc-linux-gnu/7.3.0/32/libasan.so.4"
as well as -fsanitize-recover=address, but none of those helped. From a quick glance at ASAN bugs, sounds like it's a WONTFIX.
https://bugs.winehq.org/show_bug.cgi?id=40330
--- Comment #13 from Kyle Auble kyle.auble@zoho.com --- Ah, this bug is a veritable hydra!
I was just thinking some, and I realized that in addition to the sfnt2fon and memory conflicts, the Wine preloader is linked statically. Is that possibly causing any problems, or are ASan and Wine's configure smart enough to ignore the "fsanitize" flag when building the preloader?
(In reply to Austin English from comment #11)
Short answer is https://source.winehq.org/git/wine.git/blob/HEAD:/tools/sfnt2fon/sfnt2fon. c#l577
I wasn't sure how accurate the line-numbers for ASan were, but that's nice that it lands close to the actual problem.
(In reply to Austin English from comment #12)
Though after getting it to build, running wine fails; looks like the preloader interferes with ASAN: ==9822==Shadow memory range interleaves with an existing memory mapping.
...
I tried the LD_PRELOAD workaround: export ASAN_OPTIONS=halt_on_error=0 export LD_PRELOAD="/usr/lib64/gcc/x86_64-pc-linux-gnu/7.3.0/libasan.so.4 /usr/lib64/gcc/x86_64-pc-linux-gnu/7.3.0/32/libasan.so.4"
as well as -fsanitize-recover=address, but none of those helped. From a quick glance at ASAN bugs, sounds like it's a WONTFIX.
I guess this is the real essence of the bug; maybe we should note the runtime conflict with the preloader in the title? You're probably right that working around the preloader would probably qualify as WONTFIX for the ASan team.
However, setting aside practicality for a second and looking at it as "do the right thing," couldn't the Wine preloader and ASan theoretically respect each other? Doesn't Wine need the preloader to reserve specific memory addresses whereas ASan only needs to preemptively reserve some range for shadow memory? Or am I completely misunderstanding?