It seems test_crypto_pin_token also fails time to time on s390x.
$ configure \
--enable-doc \
--disable-online-test \
--disable-static \
--enable-test \
--with-libcurl \
--disable-fatalwarnings
$ make -O -j3
$ make install DESTDIR=/home/yarda/rpmbuild/BUILDROOT/libdatovka-0.5.0-1.x86_64 INSTALL="/usr/bin/install -p"
$ make check -j3
FAIL: isds_load_erased_messages
===============================
../../test/offline/data/GetListOfErasedMessages-async-response-extracted.xml: Could not open file: No such file or directory
../../test/offline/data/GetListOfErasedMessages-missing-entries.xml: Could not open file: No such file or directory
Testing unit: isds_load_erased_messages
decompressed XML response: failed
reason: Could not load test data from `../../test/offline/data/GetListOfErasedMessages-async-response-extracted.xml' file
decompressed XML response with missing values: failed
reason: Could not load test data from `../../test/offline/data/GetListOfErasedMessages-missing-entries.xml' file
Test results: unit = isds_load_erased_messages, passed = 0, failed = 2, skipped = 0
FAIL isds_load_erased_messages (exit status: 1)
Fedora bugzilla (I guess it works also as the gcc upstream tracker): https://bugzilla.redhat.com/show_bug.cgi?id=2047715
It's tagged gcc-12.0.1, but it's probably a pre-release, it seems they are betatesting in the Fedora :D I don't get their release model. So I will create the bugzilla.
@kslany maybe it is result of some compiler optimization. Are you able to reproduce the problem/error in your environment?
Maybe it's potential problem, i.e. it is currently not visible in the valgrind, but it could manifest under some compilation conditions or maybe it's just gcc bug.
I think it can be reported even without the stripped down reproducer. The gcc guys have tools/knowhow how to quickly analyze it.
@kslany thanks for info. The use-after-free compiler error looks suspicious. Could you please open gcc bug about it? Or I can do, but I didn't review the code. I only noticed that the service_name_locale
is constructed from the service_name
which is used in the xmlNewNode()
call, thus I tried to destruct it in the opposite order without diving into details.
The patch solved just the use-after-free not the dangling-pointers problem.
I have trouble to do the merge-request - I cannot fork the project (you have reached the project limit) and my email MR was also rejected:
Unfortunately, your email message to GitLab could not be processed.
You are not allowed to perform this action. If you believe this is in error, contact a staff member.
so attaching the patch for the first part of the problem as a zip file
gcc-12.0.1
E.g.:
isds.c: In function 'build_send_check_dbdummy_request.part.0.constprop.0':
isds.c:6101:5: error: pointer 'request_37' used after 'free' [-Werror=use-after-free]
6101 | xmlFreeNode(request);
| ^~~~~~~~~~~~~~~~~~~~
isds.c:6100:5: note: call to 'free' here
6100 | free(service_name_locale);
| ^~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
and:
In file included from isds_PersonName_duplicate.c:1:
isds_PersonName_duplicate.c: In function 'test_isds_PersonName_duplicate':
../test.h:39:30: error: storing the address of local variable 'copy' in 'test_destructor_argument' [-Werror=dangling-pointer=]
39 | test_destructor_argument = argument; \
isds_PersonName_duplicate.c:6:29: note: 'copy' declared here
6 | struct isds_PersonName *copy = isds_PersonName_duplicate(origin);
| ^~~~
../test.h:21:14: note: 'test_destructor_argument' declared here
21 | extern void *test_destructor_argument;
| ^~~~~~~~~~~~~~~~~~~~~~~~
../test.h:39:30: error: storing the address of local variable 'copy' in 'test_destructor_argument' [-Werror=dangling-pointer=]
39 | test_destructor_argument = argument; \
isds_PersonName_duplicate.c:6:29: note: 'copy' declared here
6 | struct isds_PersonName *copy = isds_PersonName_duplicate(origin);
| ^~~~
../test.h:21:14: note: 'test_destructor_argument' declared here
21 | extern void *test_destructor_argument;
| ^~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
It has to be build with the --disable-fatalwarnings
.
On the s390x with the openssl-1.1.1 there is a garbage in the output buffer, but with the openssl-3.0.0 the buffer is empty. So probably something changed in the openssl. Maybe now for the short ciphertext the decryption happens in the EVP_EncryptFinal_ex, but only if there is no padding error. I haven't found anything related in the openssl docs (I haven't checked it thoroughly), but I think if openssl signals error, you shouldn't rely on the content of the output buffers.
After enabling the openssl error messages in the src/datovka_shared/crypto/crypto_pwd.c I can see the same openssl errors on all platforms, not just on the s390x:
40B91B34427F0000:error:1C800064:Provider routines:ossl_cipher_unpadblock:bad decrypt:providers/implementations/ciphers/ciphercommon_block.c:124:
It's with the openssl-3.0.0. Full test log:
********* Start testing of TestCryptoPinPwd *********
Config: Using QtTest library 5.15.2, Qt 5.15.2 (s390x-big_endian-lp64 shared (dynamic) release build; by GCC 11.2.1 20211019 (Red Hat 11.2.1-6)), fedora 36
PASS : TestCryptoPinPwd::initTestCase()
PASS : TestCryptoPinPwd::loadConfigPinDisabled()
40B91B34427F0000:error:1C800064:Provider routines:ossl_cipher_unpadblock:bad decrypt:providers/implementations/ciphers/ciphercommon_block.c:124:
FAIL! : TestCryptoPinPwd::loadConfigPinEnabled() '!acntSet.password().isEmpty()' returned FALSE. ()
Loc: [../tests/test_crypto_pin_pwd.cpp(208)]
40B91B34427F0000:error:1C800064:Provider routines:ossl_cipher_unpadblock:bad decrypt:providers/implementations/ciphers/ciphercommon_block.c:124:
FAIL! : TestCryptoPinPwd::enablePin() '!acntSet.password().isEmpty()' returned FALSE. ()
Loc: [../tests/test_crypto_pin_pwd.cpp(208)]
40B91B34427F0000:error:1C800064:Provider routines:ossl_cipher_unpadblock:bad decrypt:providers/implementations/ciphers/ciphercommon_block.c:124:
FAIL! : TestCryptoPinPwd::disablePin() '!acntSet.password().isEmpty()' returned FALSE. ()
Loc: [../tests/test_crypto_pin_pwd.cpp(208)]
PASS : TestCryptoPinPwd::cleanupTestCase()
Totals: 3 passed, 3 failed, 0 skipped, 0 blacklisted, 19ms
********* Finished testing of TestCryptoPinPwd *********
The openssl-1.1.1 has slightly different error:
4396807468320:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:crypto/evp/evp_enc.c:643:
But the meaning is probably the same.
The difference is that on the s390x in case of the error the final 'out' buffer is empty, but on the x86_64 there is some garbage. Maybe it's due to different implementation/optimization on the s390x - I didn't check it deeper. So I think you should deal with it in your code, i.e. in case of the openssl error you should handle it in the caller and mark the content of the object as invalid and you shouldn't rely that there will be some garbage which you are later checking with the isEmpty() test.
Downstream Fedora report: https://bugzilla.redhat.com/show_bug.cgi?id=2018900
********* Start testing of TestCryptoPinPwd *********
Config: Using QtTest library 5.15.2, Qt 5.15.2 (s390x-big_endian-lp64 shared (dynamic) release build; by GCC 11.2.1 20211019 (Red Hat 11.2.1-6)), fedora 36
PASS : TestCryptoPinPwd::initTestCase()
PASS : TestCryptoPinPwd::loadConfigPinDisabled()
FAIL! : TestCryptoPinPwd::loadConfigPinEnabled() '!acntSet.password().isEmpty()' returned FALSE. ()
Loc: [../tests/test_crypto_pin_pwd.cpp(208)]
FAIL! : TestCryptoPinPwd::enablePin() '!acntSet.password().isEmpty()' returned FALSE. ()
Loc: [../tests/test_crypto_pin_pwd.cpp(208)]
FAIL! : TestCryptoPinPwd::disablePin() '!acntSet.password().isEmpty()' returned FALSE. ()
Loc: [../tests/test_crypto_pin_pwd.cpp(208)]
PASS : TestCryptoPinPwd::cleanupTestCase()
Totals: 3 passed, 3 failed, 0 skipped, 0 blacklisted, 19ms
********* Finished testing of TestCryptoPinPwd *********