Description of problem: While investigating a different bug (bug # 810992), we discoverd that openssl's 32-bit libcrypto library is apparently using certain instructions on the ppc64 platform incorrectly. In the following file: http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/crypto/external/bsd/openssl/lib/libcrypto/arch/powerpc/ppccpuid.S there is the following procedure: ------------------------------------ .globl OPENSSL_ppc64_probe .type OPENSSL_ppc64_probe,@function .align 4 OPENSSL_ppc64_probe: fcfid 1,1 rldicl 0,0,32,32 blr .long 0 .byte 0,12,0x14,0,0,0,0,0 ------------------------------------ Further, this procedure is called from the following piece of code: if (sigsetjmp(ill_jmp,1) == 0) { OPENSSL_ppc64_probe(); OPENSSL_ppccap_P |= PPC_FPU64; } } This code incorrectly assumes that either the fcfid or rldicl instruction in the OPENSSL_ppc64_probe procedure may generate a SIGILL under certain situations. This is not the case in current POWER7 implementation. The rldicl instruction is of the 64-bit Category in the Power ISA, but neverthless, it is implemented and can be executed even in a 32-bit program, even though the ISA states that instructions in the 64-bit Category "may" result in an unsupported operation exception when run in 32-bit mode. It's our belief that the libcrypto library made the assumption that executing this instruction in 32-bit mode would cause a SIGILL. But since it does not, the behavior of OR'ing PPC_FPU64 to the OPENSSL_ppccap_P variable appears to be erroneous. Version-Release number of selected component (if applicable): 1.0.1c.7.fc18 How reproducible: See bug #810992, comment 5. Steps to Reproduce: 1. 2. 3. Actual results: Expected results: Additional info:
Please report the issue to the openssl upstream bug tracker: rt What do you propose as a fix? Just removing the whole if() block above?
An email has been sent to rt explaining the situation. They should inspect the aux vector to ascertain h/w capabilities rather than trying to pick certain instructions that they hope will give them a SIGILL. Since the rldicl instruction is officially not supported in 32-bit mode (according to the ISA), we will probably change Valgrind to fail with an "unhandled instruction" error. So (as described in bug # 810992) the "ppc-koji build --scratch f18 curl-7.25.0-1.fc18.src.rpm" will still bomb until libcrypto stops using unsupported instructions.
The response below was received from openssl contact, Andy Polyakov. The upshot is that openssl's use of rldicl in 32-bit mode is intentional. But as a workaround for the valgrind issue that is choking on the rldicl (see bug # 810992), try setting OPENSSL_ppccap environment variable to 0 prior running the application under valgrind's control. This bug should be closed as NOTABUG. On Mon, 2012-10-15 at 17:22 +0200, Andy Polyakov via RT wrote: > > The OpenSSL library on Fedora 18 appears to use the routine > > > > .globl OPENSSL_ppc64_probe > > .type OPENSSL_ppc64_probe,@function > > .align 4 > > OPENSSL_ppc64_probe: > > fcfid 1,1 > > rldicl 0,0,32,32 > > blr > > .long 0 > > .byte 0,12,0x14,0,0,0,0,0 > > > > to try and determine if the hardware is 32-bit or 64-bit. The rldicl is > > a 64-bit class instruction. On a 32-bit power processor it will > > generate a SIGILL when the instruction is executed. The belief is that > > the error handler then catches this and thus the OpenSSL package knows > > it is running on a 32-bit platform. However, when the library is > > compiled as a 32-bit library running on a 64-bit system the instruction > > will execute without generating a SIGILL exception. Thus the library > > might think it is running on a 64-bit system in 64-bit mode when it is > > actually running in 32-bit mode. > > Yes, and this is totally intentional. As long as a) CPU is 64-bit and b) > kernel is 64-bit, even 32-bit processes can use 64-bit instructions such > as rldicl. Yes, they actually *can* do so, but *only* as long as they > are not hit by asynchronous signal. The thing is that 64-bit kernel > preserves full 64-bit registers even for 32-bit processes upon context > switch, but *not* upon signal delivery. Which is why you can observe > sigprocmask in bn_mul_mont in the beginning of crypto/ppccap.c. See even > "December 2009" comment in crypto/bn/asm/ppc64-mont.pl for why it's > interesting to do that. > > > The concern is that the probe test may > > not work as expected for a 32-bit binary running on a 64-bit system and > > thus may give erroneous results. > > It shouldn't. What would be appropriate for Linux kernel to do is to > arrange so that upper halves of 64-bit GP registers even upon signal > delivery [which would allow to get rid of expensive setprocmask calls]. > It's done on s390x platforms and one can do same even on PPC. For > backward compatibility you'd have to save upper halves separately, but > it can be done without having to recompile all the applications. > > > Note, this issue was seen on a Fedora release 18 (Spherical Cow). It > > does not occur on the RedHat 6.3 release. > > 6.3 has 1.0.0, which doesn't perform the probe in question. > > > The issue was found when > > running a test program using valgrind as valgrind detected a type > > conflict. > > > > Maynard Johnson on the cc list can provide additional details if needed. > > You should be able to avoid this by setting OPENSSL_ppccap environment > variable to 0 prior running the application under valgrid's control. > This way you'll avoid the trouble with rldilc and have valgrind catch > eventual problems. >