Description of problem: I received an email with the following: Certificate for hostname 'iridium', in file (or by nickname): /etc/pki/tls/certs/localhost.crt The certificate needs to be renewed; this can be done using the 'genkey' program. When attempting to run genkey --days 365 localhost (this is a workstation using a self signed key) I get an error about a /etc/pki/tls/private/localhost.key existing, to remove it first and then re-run genkey. Once removed if I re-run genkey I get an immediate segfault. I just ran this on a CentOS 5.4 box moments before without a problem. Version-Release number of selected component (if applicable): How reproducible: Always Steps to Reproduce: 1. genkey --days 365 servername 2. 3. Actual results: segfault Expected results: New cert Additional info:
Also, genkey --gdb servername is of no help as it just segfaults anyway before getting into gdb
Thanks for the report.
The segfault occurs on F-13 but not on F-12. The code is the same in both Fedoras. It happens inside RunForm in the line ($reason, $data) = $panel->Run(); genkey has been using NSS under the covers since F-10. F-9 has the old code, the one that works fine in RHEL-4. I recompiled the F-9 tools and ran the version for F-9 I ran ./genkey --days 365 myservername and other commands and had the segfault. Could the problem be with perl-Newt?
On the other hand, perl-Newt is at the same version on F-12 and F-13.
Created attachment 424474 [details] HelloWorld-like script that segfaults This is the aame script as the one in Bug 600670 that this one blocks. Will reassign to perlNewt.
Created attachment 424486 [details] minimal repro case
This one will segfault on exit.
I looked and perl-Newt F-13 (with segfault) and F-12 (no segfault) have the same code but I did find this difference. $ diff F-12/perl-Newt.spec F-13/perl-Newt.spec 4c4 < Release: 24%{?dist} --- > Release: 25%{?dist} 62a63,65 > * Mon Dec 7 2009 Stepan Kasal <skasal> - 1.08-25 > - rebuild against perl 5.10.1 >
This is more minimal test case: #!/usr/bin/perl -w use Newt; Newt::Init(); #my $ok = Newt::Button("OK", 0); my $panel = Newt::Panel(1, 1, "Panel example"); Newt::Finished(); If you create Newt::Panel, it will segfault. If you create Newt::Button instead, it will not.
This is trace from Perl debugger: Package ./newt-reproducer. in .=Newt::Init() from ./newt-reproducer:4 out .=Newt::Init() from ./newt-reproducer:4 in $=Newt::Panel(1, 1, 'Panel example') from ./newt-reproducer:7 in $=Newt::Form() from /usr/lib64/perl5/Newt.pm:342 in $=Newt::newtForm() from /usr/lib64/perl5/Newt.pm:250 out $=Newt::newtForm() from /usr/lib64/perl5/Newt.pm:250 scalar context return from Newt::newtForm: -> 20259296 out $=Newt::Form() from /usr/lib64/perl5/Newt.pm:342 scalar context return from Newt::Form: 'co' => newtComponent=SCALAR(0x13508e8) -> 20259296 in $=Newt::newtCreateGrid(1, 1) from /usr/lib64/perl5/Newt.pm:343 out $=Newt::newtCreateGrid(1, 1) from /usr/lib64/perl5/Newt.pm:343 scalar context return from Newt::newtCreateGrid: -> 17667664 out $=Newt::Panel(1, 1, 'Panel example') from ./newt-reproducer:7 scalar context return from Newt::Panel: 'co' => newtComponent=SCALAR(0x13508e8) -> 20259296 'g' => newtGrid=SCALAR(0x13254a0) -> 17667664 'refs' => HASH(0x131e138) empty hash 'title' => 'Panel example' in .=Newt::Finished() from ./newt-reproducer:9 out .=Newt::Finished() from ./newt-reproducer:9 It segfaults after Newt::Finished(). Thus it's definitively memory corruption shooting Perl deinitializer. Lets use gdb to figure out what happens.
Yet shorter reproducer: #!/usr/bin/perl -w use Newt; Newt::Init(); my $form = Newt::Form(); $form->DESTROY(); sleep 2; Newt::Finished(); If you run this under debugger, you will get segfault in free(3) called from newt dynamic library: (gdb) bt full #0 0x000000385ac7a83c in __libc_free (mem=0x69e1e0) at malloc.c:3724 ar_ptr = <value optimized out> p = 0x69e1d0 hook = <value optimized out> #1 0x00007ffff1d1e6e6 in newtFormDestroy (co=0x6bd290) at form.c:828 form = 0x636db0 i = <value optimized out> #2 0x00007ffff1f37c90 in XS_Newt_newtFormDestroy (my_perl=<value optimized out>, cv=<value optimized out>) at Newt.c:3136 Perl_form_nocontext = <value optimized out> sp = <value optimized out> ax = <value optimized out> mark = <value optimized out> #3 0x0000003fb7ca6375 in Perl_pp_entersub (my_perl=0x603010) at pp_hot.c:2888 markix = 0 sp = <value optimized out> sv = 0x70b750 gv = 0x6c5220 cv = 0x70b768 cx = <value optimized out> gimme = 128 hasargs = 0 '\000' #4 0x0000003fb7ca4666 in Perl_runops_standard (my_perl=0x603010) at run.c:40 No locals. [...] If you remove the explicit $form->DESTROY(), it segfaults too but in perl itself: (gdb) run newt-reproducer arg Starting program: /usr/bin/perl newt-reproducer arg [Thread debugging using libthread_db enabled] Program received signal SIGSEGV, Segmentation fault. 0x0000003fb7cb89ec in Perl_sv_clear (my_perl=0x603010, sv=0x606d48) at sv.c:5422 5422 || CvSTART(destructor)->op_next->op_type != OP_LEAVESUB)) And if you run the code with explicit DESTROY() with non-empty command line argument AND in UTF-8 locale, you get beautiful invalid-pointer free() abort initiated by glibc: $ LANG=en_US.UTF-8 ./newt-reproducer arg *** glibc detected *** /usr/bin/perl: free(): invalid pointer: 0x000000385af7af68 *** ======= Backtrace: ========= /lib64/libc.so.6[0x385ac75726] /usr/lib64/libnewt.so.0.52(newtFormDestroy+0x56)[0x7f48c98416e6] /usr/lib64/perl5/auto/Newt/Newt.so(XS_Newt_newtFormDestroy+0x130)[0x7f48c9a5ac90] /usr/lib64/perl5/CORE/libperl.so(Perl_pp_entersub+0x5a5)[0x3fb7ca6375] /usr/lib64/perl5/CORE/libperl.so(Perl_runops_standard+0x16)[0x3fb7ca4666] /usr/lib64/perl5/CORE/libperl.so(Perl_call_sv+0x4cf)[0x3fb7c4c6af] /usr/lib64/perl5/CORE/libperl.so(Perl_sv_clear+0xb6)[0x3fb7cb8916] /usr/lib64/perl5/CORE/libperl.so(Perl_sv_free2+0x52)[0x3fb7cb9112] /usr/lib64/perl5/CORE/libperl.so(Perl_leave_scope+0xe45)[0x3fb7cd5bf5] /usr/lib64/perl5/CORE/libperl.so(Perl_pp_leave+0x105)[0x3fb7ca5c85] /usr/lib64/perl5/CORE/libperl.so(Perl_runops_standard+0x16)[0x3fb7ca4666] /usr/lib64/perl5/CORE/libperl.so(perl_run+0x338)[0x3fb7c4d1a8] /usr/bin/perl(main+0xdc)[0x400c5c] /lib64/libc.so.6(__libc_start_main+0xfd)[0x385ac1ec5d] /usr/bin/perl[0x400ab9] ======= Memory map: ======== 00400000-00401000 r-xp 00000000 fd:02 10077 /usr/bin/perl 00601000-00603000 rw-p 00001000 fd:02 10077 /usr/bin/perl 01aac000-01bf5000 rw-p 00000000 00:00 0 [heap] 385a800000-385a81e000 r-xp 00000000 fd:02 4525 /lib64/ld-2.12.so 385aa1e000-385aa1f000 r--p 0001e000 fd:02 4525 /lib64/ld-2.12.so 385aa1f000-385aa20000 rw-p 0001f000 fd:02 4525 /lib64/ld-2.12.so 385aa20000-385aa21000 rw-p 00000000 00:00 0 <== 385ac00000-385ad75000 r-xp 00000000 fd:02 6828 /lib64/libc-2.12.so 385ad75000-385af75000 ---p 00175000 fd:02 6828 /lib64/libc-2.12.so 385af75000-385af79000 r--p 00175000 fd:02 6828 /lib64/libc-2.12.so 385af79000-385af7a000 rw-p 00179000 fd:02 6828 /lib64/libc-2.12.so 385af7a000-385af7f000 rw-p 00000000 00:00 0 385b000000-385b002000 r-xp 00000000 fd:02 21846 /lib64/libdl-2.12.so [...]
If explicit form->DESTROY() is called, it is killed by glibc because Newt::Form::Destroy → Newt::newtFormDestroy($self->{co}) → XS_Newt_newtFormDestroy → newtFormDestroy(co) → free() is called twice on the same co. First time by explicit DESTROY, second time by Perl on object destruction (second time `co' structure members points to different memory and thus it's killed by glibc or kernel depending on target address). I checked newt C library and there are no checks for NULL pointers, any free() is not followed by assigning NULL to freed pointer. Thus it's application (perl-Newt) responsibility not use destroyed newt components. However I don't understand the Perl XS magic. Thus I can not say what's bad in perl-Newt XS wrapper now.
If explicit form->DESTROY() is NOT called, it segfaults in perl before calling any {XS_Newt_,}newtFormDestroy(). It seems like Newt::Form constructor not registering destructor for Newt::Form properly and that explicit DESTROY() corrects destructor handler.
Yep, if I remove Newt::newtFormDestroy() call from Newt.pm: sub Newt::Form::DESTROY { my $self = shift; # Newt::newtFormDestroy($self->{co}); } I get segfault without explicit DESTROY() call only.
If I remove complete destructor sub Newt::Form::DESTROY {} definition, then Perl does not crash. And Perl destroys it on interpret termination automatically via XS_Newt_newtFormDestroy wrapper. Of course if I call destructor explicitly, it will crash because it will try to free already freed memory. So the problem has been introduced by this upstream Changelog entry probably: Mon Oct 26 18:04:51 1998 Alejandro Escalante Medina <amedina.mx> * Newt.pm: Added DESTROY to forms
Excellent, that works here too. Thanks a lot Petr!
*** Bug 604635 has been marked as a duplicate of this bug. ***
*** Bug 625005 has been marked as a duplicate of this bug. ***
perl-Newt-1.08-25.fc13.1 has been submitted as an update for Fedora 13. https://admin.fedoraproject.org/updates/perl-Newt-1.08-25.fc13.1
perl-Newt-1.08-27.fc14 has been submitted as an update for Fedora 14. https://admin.fedoraproject.org/updates/perl-Newt-1.08-27.fc14
perl-Newt-1.08-25.fc13.1 has been pushed to the Fedora 13 testing repository. If problems still persist, please make note of it in this bug report. If you want to test the update, you can install it with su -c 'yum --enablerepo=updates-testing update perl-Newt'. You can provide feedback for this update here: https://admin.fedoraproject.org/updates/perl-Newt-1.08-25.fc13.1
perl-Newt-1.08-25.fc13.1 has been pushed to the Fedora 13 stable repository. If problems still persist, please make note of it in this bug report.
perl-Newt-1.08-27.fc14 has been pushed to the Fedora 14 stable repository. If problems still persist, please make note of it in this bug report.