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
Segfault/assert fail while requiring IO::File in an attempt to resolve a missing method on a hash, hv_common expects SVt_PVHV but got SVt_PV #14939
Comments
From @dcollinsnGreetings Porters, I have compiled bleadperl with the afl-gcc compiler using: ./Configure -Dusedevel -Dprefix='/usr/local/perl-afl' -Dcc='ccache afl-gcc' -Duselongdouble -Duse64bitint -Doptimize=-g -Uversiononly -Uman1dir -Uman3dir -des And then fuzzed the resulting binary using: AFL_NO_VAR_CHECK=1 afl-fuzz -i in -o out bin/perl @@ After reducing testcases using `afl-tmin` and filtering out testcases that are merely iterations of "#!perl -u", I have located the following testcase that triggers a segmentation fault in the perl interpreter. The testcase is the 19-character file: %0=f fffff%::=fffff which was further manually reduced to the 8-character file: f f%::=f Debugging perls instead report: miniperl: hv.c:355: Perl_hv_common: Assertion `((svtype)((hv)->sv_flags & 0xff)) == SVt_PVHV' failed. Expected behavior is the same as the similar test 'f f$::=f', which crashes with "Can't locate object method "f" via package "f" (perhaps you forgot to load "f"?)". Once upon a time that happened, however, interestingly, that changed when xdg added code to automatically require IO::File when a filehandle method call would fail because the method would not be found (see bisect). What's more, I tested: dcollins@nightshade:/usr/local/perl-afl/out$ ../bin/perl -e 'f f%::=f' So it seems like this is some weird case of an error while loading the module in this way, or loading it while this odd construct is on the stack. **GDB** dcollins@nightshade:~/perl$ gdb --args ./perl ../crash Program received signal SIGSEGV, Segmentation fault. Inferior 1 [process 6902] will be killed. Quit anyway? (y or n) y 'entry' is set to this value on line 637, entry = (HvARRAY(hv))[hash & (I32) HvMAX(hv)]; sv_flags decodes to 0x10004403, SVf_IsCOW | SVp_POK | SVf_POK | SVt_PV. I'm not sure if sv_flags is corrupted here or if sv_u is, but entry is getting "CORE" written to it (0x45524f43 decodes to "EROC") instead of a pointer value. **VALGRIND** dcollins@nightshade:~/perl$ valgrind ./perl ../crash **BISECT** 15e6cdd is the first bad commit Filehandle method calls load IO::File on demand :100644 100644 5ddf5ccc2d313c25b50eebbb6f75cc6bdf8b2e8c d9281f462a045d2bbe376d81a8b86a974032156c M MANIFEST **PERL -V** dcollins@nightshade:~/perl$ ./perl -Ilib -V Characteristics of this binary (from libperl): |
From @tonycozOn Fri Sep 25 10:32:29 2015, dcollinsn@gmail.com wrote:
What's happening is the assignment: %::=f is releasing the sv PL_globalstash points at, which is then re-used when an overload for require is checked for, setting it to "CORE". Modifying hv_clear() to reinitialize PL_globalstash gets past that bug, but fails further on (trashing the symbol table is bad.) Tony |
The RT System itself - Status changed from 'new' to 'open' |
From @geeknikTriggered in v5.25.5 (v5.25.4-130-g7aa7bbc) w/ AFL + ASAN. ./perl -e '*0=d$^$^=%0=*0=$0=$^=$0=*0=$0=$V' |
From @geeknikTriggered in Perl v5.25.6 (v5.25.5-76-g91dca83) with AFL+ASAN. Odd number of elements in hash assignment at test113 line 1. The attached doesn't always trigger this assertion failure failure though, Odd number of elements in hash assignment at test113 line 1. and Odd number of elements in hash assignment at test113 line 1. and Odd number of elements in hash assignment at test113 line 1. |
From @geeknik |
From @hvdsThis reduces to: % PERL_HASH_SEED=1 ./miniperl -e '%::=(); /$^D \PX/' (The HASH_SEED determines the order the %:: keys are freed, and thus whether it fails; you may need a different value to reproduce.) This appears to happen because PL_globalstash gets freed when all its references disappear during the '%:: = ()', and gets recreated only as a PVAV. Giving it an artificial SvREFCNT_inc in S_init_main_stash() stops the coredump, but I'm not sure there's any sane situation it'd be needed, nor that it'd be the right answer if there is. Hugo |
The RT System itself - Status changed from 'new' to 'open' |
From @dur-randir
This is a duplicate of https://rt.perl.org/Public/Bug/Display.html?id=126188 |
From [Unknown Contact. See original ticket]
This is a duplicate of https://rt.perl.org/Public/Bug/Display.html?id=126188 |
From @dur-randir
This is a duplicate of https://rt.perl.org/Public/Bug/Display.html?id=126188 |
From [Unknown Contact. See original ticket]
This is a duplicate of https://rt.perl.org/Public/Bug/Display.html?id=126188 |
Migrated from rt.perl.org#126188 (status was 'open')
Searchable as RT126188$
The text was updated successfully, but these errors were encountered: