Red Hat Bugzilla – Bug 865124
openssl libcrypto using 64-bit Category instruction incorrectly
Last modified: 2012-10-17 15:39:31 EDT
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:
there is the following procedure:
Further, this procedure is called from the following piece of code:
if (sigsetjmp(ill_jmp,1) == 0)
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):
See bug #810992, comment 5.
Steps to Reproduce:
Please report the issue to the openssl upstream bug tracker: email@example.com
What do you propose as a fix? Just removing the whole if() block above?
An email has been sent to firstname.lastname@example.org 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.