On 4 October 2017 at 17:59, Thierry Vignaud <thierry.vign...@gmail.com> wrote: >>>>>>>>> The urpmi issue is when checking bogus pkgs. >>>>>>>>> The RPM4 issue is when traversing the transaction (not the rpmdb) >>>>>>>>> Attached are the valgrind outputs >>>>>>>>> >>>>>>>> >>>>>>>> So we have stuff like >>>>>>>> >>>>>>>> ==14087== Invalid write of size 4 >>>>>>>> ==14087== at 0x103AA6DD: headerUnlink (header.c:188) >>>>>>>> ==14087== by 0x103AA6DD: headerFree (header.c:194) >>>>>>>> ==14087== by 0xFF69314: XS_RPM4__Header_DESTROY (RPM4.xs:890) >>>>>>>> ==14087== by 0x3F512E2C40: Perl_pp_entersub (pp_hot.c:4231) >>>>>>>> ==14087== by 0x3F5125551E: Perl_call_sv (perl.c:2848) >>>>>>>> ==14087== by 0x3F512E7C09: S_curse (sv.c:6987) >>>>>>>> ==14087== by 0x3F512E84F7: Perl_sv_clear (sv.c:6591) >>>>>>>> ==14087== by 0x3F512E898D: Perl_sv_free2 (sv.c:7088) >>>>>>>> ==14087== by 0x3F513182E6: UnknownInlinedFun (inline.h:200) >>>>>>>> ==14087== by 0x3F513182E6: Perl_free_tmps (scope.c:212) >>>>>>>> ==14087== by 0x3F512DAD74: Perl_pp_nextstate (pp_hot.c:52) >>>>>>>> ==14087== by 0x3F512DAA55: Perl_runops_standard (run.c:41) >>>>>>>> ==14087== by 0x3F5125D236: S_run_body (perl.c:2524) >>>>>>>> ==14087== by 0x3F5125D236: perl_run (perl.c:2447) >>>>>>>> ==14087== by 0x400C79: main (perlmain.c:123) >>>>>>>> ==14087== Address 0xffeffef8c is on thread 1's stack >>>>>>>> ==14087== 396 bytes below stack pointer >>>>>>>> >>>>>>>> ...and all the failures are around headerFree(), but none of the >>>>>>>> traces >>>>>>>> go >>>>>>>> into rpm itself, so I dont really know what does "traversing the >>>>>>>> transaction" actually mean. >>>>>>> >>>>>>> >>>>>>> >>>>>>> in both URPM & RPM4 bindings, there's a family of traverse functions >>>>>>> that enable to execute a callback on each package of either: >>>>>>> - rpmdb >>>>>>> - the current transaction, >>>>>>> - pkgs header from an hdlist file >>>>>>> - synthetic metadata from a synthesis file >>>>>>> calling the callback on the currrent header >>>>>>> >>>>>>> See: >>>>>>> - Db_traverse*() & Trans_traverse() in perl-URPM/URPM.xs >>>>>>> - Ts_traverse() in RPM4-0.36/src/RPM4.xs >>>>>>> >>>>>>> It's loosely documented at >>>>>>> http://search.cpan.org/~tvignaud/URPM-5.12/URPM.pm or >>>>>>> >>>>>>> >>>>>>> http://search.cpan.org/~tvignaud/RPM4-0.36/lib/RPM4/Transaction.pm#Hdlist::Db-%3Etraverse_headers(sub) >>>>>>> (RPM4's doc is very incomplete -- I'm only maintaining this b/c other >>>>>>> tools depend on that and I cannot break them when upgrading rpm) >>>>>>> >>>>>>>> But the problem is simply with perl-RPM4 and >>>>>>>> urpmi passing uninitialized variables to headerFree(). >>>>>>>> >>>>>>>> What changed in rpm is that rpmReadPackageFile() no longer does this >>>>>>>> as >>>>>>>> the >>>>>>>> first thing: >>>>>>>> >>>>>>>> if (hdrp) >>>>>>>> *hdrp = NULL; >>>>>>>> >>>>>>>> Ie if you pass an uninitialized pointer as hdrp, it remains >>>>>>>> uninitialized >>>>>>>> unless rpmReadPackageFile() returns with a success code. >>>>>>>> Which is how I think it should be, but it does deserve a release note >>>>>>>> on >>>>>>>> the >>>>>>>> changed API. >>>>>>>> >>>>>>>> So the moral of the story is basically: if you depend on your >>>>>>>> variables >>>>>>>> being initialized, initialize them by yourself. It's a good practise >>>>>>>> anyway. >>>>>>> >>>>>>> >>>>>>> >>>>>>> I'll check for uninitialized variables later today >>>>>> >>>>>> >>>>>> >>>>>> Actually the bug happen when running the transaction >>>>>> >>>>> >>>>> Right, that makes sense, there's a second rpmReadPackageFile() inside >>>>> transaction run. >>>> >>>> >>>> Intestingly, perl-RPM4 no more segfaults (there still faillures >>>> though) if I alter the transrun() method (which calls rpmtsRun in >>>> rpmlib) 's perl callback to *not* call std rpmShowProgress()) >>>> See attached patch >>>> >>>> Aka previously it runs both the passed perl callback + rpmlib default >>>> callback which worked smoothly. >>>> But since rpm-4.14, calling std rpm callback results a segfault... >>>> I'm happy to not call that and I don't think we have any tool actually >>>> running transactions^W installing packages through RPM4 right now but >>>> still that's a regression in rpm... >>>> Maybe some new unlink call or sg like that >>>> >>> >>> Are you saying you still get that segfault with this fix? >>> https://github.com/rpm-software-management/rpm/commit/082e6e77dd613efa643b02ee0417c1382f520893 >> >> That fix was for URPM segfaulting while verifying bad rpms, here I'm >> talking about RPM4 segfaulting while installing packages >> (different binding, different issue) >> The URPM issue is fixed by the above commit (s/is/should/ - I hadn't >> actually tested your fix) >> The RPM4 issue is a different issue, even if both happen in headerFree() . >> You might get confused by the perl gdb traces that looks similar but >> the issues really are different. >> They show the point where the perl interpreter segfault, but not the >> point where the call in rpmlib has garbaged things as this action has >> finished and we'd return to the perl interpreter. >> >>> From the traceback you posted it was tripping on the uninitialized header >>> pointer as the other one. And if you disable the entire callback then there >>> are no open files returned and the whole error path is different. >> >> There's still a perl callback that's run. >> Actually there's a C/XS wrapper (transCallback()), running the >> optional pure perl callback if present >> Ts_transrun => rpmtsSetNotifyCallback with transCallback wrapper as >> callback and the actual perl callback as parameter >> (similar to what URPM is doing) >> Then during the actual installation, rpmlib calls the callback >> (transCallback) which set up the perl arg stack & calls the perl >> callback which itself used to call the rpmlib default callback. >> >> Here, the segfault is also in headerFree() but only happen in the >> install callback while installing pkgs and only if the perl callback >> calls the default rpmlib progress callback. >> >>> BTW, your workaround in >>> http://gitweb.mageia.org/software/rpm/perl-URPM/commit/?id=87dbde4f3b078173e53cd45cac000c2d2751b370 >>> is not the one you want: initialize to NULL instead >> >> Ack. Thx >> Though from what you said, I should be able to remove any >> initialization at all as the rpmReadPackageFile() regression is fixed >> and should now always set the return parameter. >> See you > > You can test by building the perl-RPM4 packages with the attached spec > file, w/o installing it. > Sources are at > http://search.cpan.org/CPAN/authors/id/T/TV/TVIGNAUD/RPM4-0.36.tar.gz > then in order to run the broken test with the just compiled module: > cd BUILD/RPM4-0.36/ > PERL_DL_NONLAZY=1 PERL_USE_UNSAFE_INC=1 gdb -q --args perl > "-MExtUtils::Command::MM" "-MTest::Harness" -Iblib/lib -Iblib/arch > t/05transaction.t > What's interesting is that: > - it segfaults on FC26 with rpm-4.13.0.1-7.fc26.x86_64 > - it doesn't segfaults but show failures on mga6 with rpm-4.13.0.1-3.1.mga6
One difference being that FC26 uses perl-5.24 whereas mga6 uses 5.22 > Some patch difference could explain that > I see that it hasn't been rebuild for rpm updates between > 4.13.0-0.rc1.32.mga6 & 4.13.0.1-3.mga6 and I guess the other > regressions weren't checked for after a signing segfault in the > testsuite due to rpm-4.13 was fixed _______________________________________________ Rpm-maint mailing list Rpm-maint@lists.rpm.org http://lists.rpm.org/mailman/listinfo/rpm-maint