NetBSD Problem Report #57594

From martin@duskware.de  Mon Aug 28 16:26:41 2023
Return-Path: <martin@duskware.de>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id DB0981A9238
	for <gnats-bugs@gnats.NetBSD.org>; Mon, 28 Aug 2023 16:26:41 +0000 (UTC)
From: martin@NetBSD.org
Reply-To: martin@NetBSD.org
To: gnats-bugs@NetBSD.org
Subject: openssl speed crashes on sparcv8
X-Send-Pr-Version: 3.95

>Number:         57594
>Category:       port-sparc
>Synopsis:       openssl speed crashes on sparcv8
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    port-sparc-maintainer
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Aug 28 16:30:00 +0000 2023
>Closed-Date:    Thu Sep 21 15:30:42 +0000 2023
>Last-Modified:  Thu Sep 21 15:30:42 +0000 2023
>Originator:     Martin Husemann
>Release:        NetBSD 10.99.7
>Organization:
The NetBSD Foundation, Inc.
>Environment:
System: NetBSD somnambulist.duskware.de 10.99.7 NetBSD 10.99.7 (SOMNA) #18: Mon Aug 28 12:28:48 CEST 2023 martin@seven-days-to-the-wolves.aprisoft.de:/work/src/sys/arch/sparc/compile/SOMNA sparc
Architecture: sparc
Machine: sparc
>Description:

Running "openssl speed" crashes after some time:

[..]
Doing 192 bits  ecdh's for 10s: 18 192-bits ECDH ops in 10.22s
Doing 224 bits  ecdh's for 10s: 12 224-bits ECDH ops in 9.71s
Doing 256 bits  ecdh's for 10s: 8 256-bits ECDH ops in 10.68s
Illegal instruction (core dumped)

and gdb shows it is here:

Program terminated with signal SIGILL, Illegal instruction.
#0  0x00212650 in OPENSSL_cleanse ()
(gdb) x/i $pc
=> 0x212650 <OPENSSL_cleanse+112>:      unknown

which is with a bit more context:

   0x212638 <OPENSSL_cleanse+88>:       be  0x212650 <OPENSSL_cleanse+112>
   0x21263c <OPENSSL_cleanse+92>:       nop 
   0x212640 <OPENSSL_cleanse+96>:       clrb  [ %o0 ]
   0x212644 <OPENSSL_cleanse+100>:      dec  %o1
   0x212648 <OPENSSL_cleanse+104>:      b  0x212634 <OPENSSL_cleanse+84>
   0x21264c <OPENSSL_cleanse+108>:      inc  %o0
=> 0x212650 <OPENSSL_cleanse+112>:      unknown
   0x212654 <OPENSSL_cleanse+116>:      sub  %o1, 8, %o1
   0x212658 <OPENSSL_cleanse+120>:      btst  -8, %o1

and the source is crypto/external/bsd/openssl/dist/crypto/sparccpuid.S
line 406: the "stx" encoded as .word   0xc0720000:

.Lot:
#ifndef ABI64
        subcc   %g0,1,%g1
        ! see above for explanation
        .word   0x83408000      !rd     %ccr,%g1
        cmp     %g1,0x99
        bne     .v8lot
        nop
#endif

.v9lot: andcc   %o0,7,%g0
        bz      .v9aligned
        nop
        stb     %g0,[%o0]
        sub     %o1,1,%o1
        ba      .v9lot
        add     %o0,1,%o0
.align  16,0x01000000
.v9aligned:
        .word   0xc0720000      !stx    %g0,[%o0]
        sub     %o1,8,%o1
        andcc   %o1,-8,%g0
#ifdef ABI64
        .word   0x126ffffd      !bnz    %xcc,.v9aligned
#else
        .word   0x124ffffd      !bnz    %icc,.v9aligned
#endif

I totally fail to see why this can be used w/o #ifdef ABI64 here
(and obviously it can't). Merge botch?


>How-To-Repeat:
s/a

>Fix:
n/a

>Release-Note:

>Audit-Trail:
From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-sparc/57594: openssl speed crashes on sparcv8
Date: Tue, 29 Aug 2023 20:30:45 +0200

 It seems I can only reproduce this when running with ASLR enabled.
 Starting openssl from gdb makes it work.

 The upstream code has a minor bug and fixing that seems to avoid the
 problem, but I'm not really clear why... (changing condition codes in
 the branch delay slot of a conditional branch considered evil?)

 Martin

 Index: sparccpuid.S
 ===================================================================
 RCS file: /cvsroot/src/crypto/external/bsd/openssl/dist/crypto/sparccpuid.S,v
 retrieving revision 1.10
 diff -u -r1.10 sparccpuid.S
 --- sparccpuid.S	7 May 2023 18:40:16 -0000	1.10
 +++ sparccpuid.S	29 Aug 2023 18:19:28 -0000
 @@ -364,12 +364,12 @@
  .align	32
  OPENSSL_cleanse:
  	cmp	%o1,14
 -	nop
  #ifdef ABI64
  	bgu	%xcc,.Lot
  #else
  	bgu	.Lot
  #endif
 +	nop
  	cmp	%o1,0
  	bne	.Little
  	nop

From: matthew green <mrg@eterna.com.au>
To: gnats-bugs@netbsd.org
Cc: port-sparc-maintainer@netbsd.org, gnats-admin@netbsd.org,
    netbsd-bugs@netbsd.org, martin@NetBSD.org
Subject: re: port-sparc/57594: openssl speed crashes on sparcv8
Date: Thu, 31 Aug 2023 05:47:13 +1000

 martin and i figured out what is going on here.

 basically, the rd on sparc ends up reading from th %y register,
 and if it just happens to have 0x99 value already, then the
 test for v9 will false-positively pass and we fault.

 must be something in newer openssl that ends up leaving %y with
 0x99 and wasn't hit before, as this bug is old.


 .mrg.

From: Martin Husemann <martin@duskware.de>
To: matthew green <mrg@eterna.com.au>
Cc: gnats-bugs@netbsd.org
Subject: Re: port-sparc/57594: openssl speed crashes on sparcv8
Date: Wed, 30 Aug 2023 23:00:28 +0200

 On Thu, Aug 31, 2023 at 05:47:13AM +1000, matthew green wrote:
 > must be something in newer openssl that ends up leaving %y with
 > 0x99 and wasn't hit before, as this bug is old.

 It is mostly random - and may only hit on some CPU implementations.
 I have a patch (and an upstream bug report/pull request) that I will
 commit soonish. With that I have been unable to reproduce the crash
 in several runs.

 Martin

From: matthew green <mrg@eterna.com.au>
To: Martin Husemann <martin@duskware.de>
Cc: gnats-bugs@netbsd.org
Subject: re: port-sparc/57594: openssl speed crashes on sparcv8
Date: Thu, 31 Aug 2023 08:12:16 +1000

 Martin Husemann writes:
 > On Thu, Aug 31, 2023 at 05:47:13AM +1000, matthew green wrote:
 > > must be something in newer openssl that ends up leaving %y with
 > > 0x99 and wasn't hit before, as this bug is old.
 >
 > It is mostly random - and may only hit on some CPU implementations.
 > I have a patch (and an upstream bug report/pull request) that I will
 > commit soonish. With that I have been unable to reproduce the crash
 > in several runs.

 i wrote a simple program that reproduces it immediately:

 #include <stdio.h>
 #include <openssl/crypto.h>

 int
 main(void)
 {
         char largeish[32];

         printf("testing with 0 in %y\n");
         __asm __volatile("wr 0, %y");
         OPENSSL_cleanse(largeish, sizeof largeish);

         printf("testing with 0x99 in %y\n");
         __asm __volatile("wr 0x99, %y");
         OPENSSL_cleanse(largeish, sizeof largeish);
 }

 this patch fixes it:


 fix v8/v9 detection code for openssl.

 this code uses a trick where the encoding on both v8 and v9 are
 the same, and are not illegal instructions, but that the v9 one
 has a detectable difference than v8.

 the idea is that we perform a "subcc" (set condition codes) which
 sets "%ccr" on v9, which is an unimplemented "%asr2" on v8, then
 we read %ccr (v9) or %asr2 (v8), which will always be 0x99 on v9,
 and .. is non-trapping but impleentation defined on v8.

 for most implementations this returns the value of the %y reg.

 as nothing actually sets %y in this path, it remains the value it
 was most recently set to by something (anything), and if it just
 happens to be 0x99 then the v9 paths will be taken on v8.

 fix this by clearing the %y register before the potential read.

 fixes PR#57594.


 Index: crypto/external/bsd/openssl/dist/crypto/sparccpuid.S
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: /cvsroot/src/crypto/external/bsd/openssl/dist/crypto/sparccpuid.=
 S,v
 retrieving revision 1.10
 diff -p -u -r1.10 sparccpuid.S
 --- crypto/external/bsd/openssl/dist/crypto/sparccpuid.S	7 May 2023 18:40:=
 16 -0000	1.10
 +++ crypto/external/bsd/openssl/dist/crypto/sparccpuid.S	30 Aug 2023 21:04=
 :12 -0000
 @@ -51,6 +51,10 @@ OPENSSL_wipe_cpu:
  	! to determine if the CPU the code is executing on is V8- or
  	! V9-compliant, as V9 returns a distinct value of 0x99,
  	! "negative" and "borrow" bits set in both %icc and %xcc.
 +	! XXXNETBSD PR#57594
 +	! we clear %y here in case it just happens to have 0x99 in it
 +	! and the v8 host takes the v9 path and faults.
 +	wr	0, %y
  	.word	0x91408000	!rd	%ccr,%o0
  	cmp	%o0,0x99
  	bne	.v8
 @@ -178,6 +182,10 @@ walk_reg_wins:
  OPENSSL_atomic_add:
  #ifndef ABI64
  	subcc	%g0,1,%o2
 +	! XXXNETBSD PR#57594
 +	! we clear %y here in case it just happens to have 0x99 in it
 +	! and the v8 host takes the v9 path and faults.
 +	wr	0, %y
  	.word	0x95408000	!rd	%ccr,%o2, see comment above
  	cmp	%o2,0x99
  	be	.v9
 @@ -226,6 +234,10 @@ OPENSSL_atomic_add:
  .align	32
  _sparcv9_rdtick:
  	subcc	%g0,1,%o0
 +	! XXXNETBSD PR#57594
 +	! we clear %y here in case it just happens to have 0x99 in it
 +	! and the v8 host takes the v9 path and faults.
 +	wr	0, %y
  	.word	0x91408000	!rd	%ccr,%o0
  	cmp	%o0,0x99
  	bne	.notick
 @@ -387,6 +399,10 @@ OPENSSL_cleanse:
  .Lot:
  #ifndef ABI64
  	subcc	%g0,1,%g1
 +	! XXXNETBSD PR#57594
 +	! we clear %y here in case it just happens to have 0x99 in it
 +	! and the v8 host takes the v9 path and faults.
 +	wr	0, %y
  	! see above for explanation
  	.word	0x83408000	!rd	%ccr,%g1
  	cmp	%g1,0x99

From: "matthew green" <mrg@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/57594 CVS commit: src/crypto/external/bsd/openssl/dist/crypto
Date: Sat, 2 Sep 2023 20:07:32 +0000

 Module Name:	src
 Committed By:	mrg
 Date:		Sat Sep  2 20:07:32 UTC 2023

 Modified Files:
 	src/crypto/external/bsd/openssl/dist/crypto: sparccpuid.S

 Log Message:
 fix SPARC v8/v9 detection code.

 this code uses a trick where the encoding on both v8 and v9 are
 the same, and are not illegal instructions, but that the v9 one
 has a detectable difference than v8.

 the idea is that we perform a "subcc" (set condition codes) which
 sets "%ccr" on v9, which is an unimplemented "%asr2" on v8, then
 we read %ccr (v9) or %asr2 (v8), which will always be 0x99 on v9,
 and .. is non-trapping but impleentation defined on v8.

 for many implementations this returns the value of the %y reg.

 as nothing actually sets %y in this path, it remains the value it
 was most recently set to by something (anything), and if it just
 happens to be 0x99 then the v9 paths will be taken on v8.

 fix this by clearing the %y register before the potential read.

 fixes PR port-sparc/57594.  tested on ss20 and in qemu.  this
 version of the patch has been submitted upstream.

 XXX: pullup-10, pullup-9, pullup-8.


 To generate a diff of this commit:
 cvs rdiff -u -r1.10 -r1.11 \
     src/crypto/external/bsd/openssl/dist/crypto/sparccpuid.S

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Martin Husemann" <martin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/57594 CVS commit: [netbsd-10] src/crypto/external/bsd/openssl/dist/crypto
Date: Wed, 6 Sep 2023 08:00:12 +0000

 Module Name:	src
 Committed By:	martin
 Date:		Wed Sep  6 08:00:12 UTC 2023

 Modified Files:
 	src/crypto/external/bsd/openssl/dist/crypto [netbsd-10]: sparccpuid.S

 Log Message:
 Pull up following revision(s) (requested by mrg in ticket #349):

 	crypto/external/bsd/openssl/dist/crypto/sparccpuid.S: revision 1.11

 fix SPARC v8/v9 detection code.

 this code uses a trick where the encoding on both v8 and v9 are
 the same, and are not illegal instructions, but that the v9 one
 has a detectable difference than v8.

 the idea is that we perform a "subcc" (set condition codes) which
 sets "%ccr" on v9, which is an unimplemented "%asr2" on v8, then
 we read %ccr (v9) or %asr2 (v8), which will always be 0x99 on v9,
 and .. is non-trapping but impleentation defined on v8.

 for many implementations this returns the value of the %y reg.

 as nothing actually sets %y in this path, it remains the value it
 was most recently set to by something (anything), and if it just
 happens to be 0x99 then the v9 paths will be taken on v8.

 fix this by clearing the %y register before the potential read.

 fixes PR port-sparc/57594.  tested on ss20 and in qemu.  this
 version of the patch has been submitted upstream.


 To generate a diff of this commit:
 cvs rdiff -u -r1.9.6.1 -r1.9.6.2 \
     src/crypto/external/bsd/openssl/dist/crypto/sparccpuid.S

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Martin Husemann" <martin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/57594 CVS commit: [netbsd-9] src/crypto/external/bsd/openssl/dist/crypto
Date: Wed, 6 Sep 2023 08:01:47 +0000

 Module Name:	src
 Committed By:	martin
 Date:		Wed Sep  6 08:01:47 UTC 2023

 Modified Files:
 	src/crypto/external/bsd/openssl/dist/crypto [netbsd-9]: sparccpuid.S

 Log Message:
 Pull up following revision(s) (requested by mrg in ticket #1727):

 	crypto/external/bsd/openssl/dist/crypto/sparccpuid.S: revision 1.11

 fix SPARC v8/v9 detection code.

 this code uses a trick where the encoding on both v8 and v9 are
 the same, and are not illegal instructions, but that the v9 one
 has a detectable difference than v8.

 the idea is that we perform a "subcc" (set condition codes) which
 sets "%ccr" on v9, which is an unimplemented "%asr2" on v8, then
 we read %ccr (v9) or %asr2 (v8), which will always be 0x99 on v9,
 and .. is non-trapping but impleentation defined on v8.

 for many implementations this returns the value of the %y reg.

 as nothing actually sets %y in this path, it remains the value it
 was most recently set to by something (anything), and if it just
 happens to be 0x99 then the v9 paths will be taken on v8.

 fix this by clearing the %y register before the potential read.

 fixes PR port-sparc/57594.  tested on ss20 and in qemu.  this
 version of the patch has been submitted upstream.


 To generate a diff of this commit:
 cvs rdiff -u -r1.8.2.1 -r1.8.2.2 \
     src/crypto/external/bsd/openssl/dist/crypto/sparccpuid.S

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Martin Husemann" <martin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/57594 CVS commit: [netbsd-8] src/crypto/external/bsd/openssl/dist/crypto
Date: Wed, 6 Sep 2023 08:03:45 +0000

 Module Name:	src
 Committed By:	martin
 Date:		Wed Sep  6 08:03:45 UTC 2023

 Modified Files:
 	src/crypto/external/bsd/openssl/dist/crypto [netbsd-8]: sparccpuid.S

 Log Message:
 Pull up following revision(s) (requested by mrg in ticket #1895):

 	crypto/external/bsd/openssl/dist/crypto/sparccpuid.S: revision 1.11

 fix SPARC v8/v9 detection code.

 this code uses a trick where the encoding on both v8 and v9 are
 the same, and are not illegal instructions, but that the v9 one
 has a detectable difference than v8.

 the idea is that we perform a "subcc" (set condition codes) which
 sets "%ccr" on v9, which is an unimplemented "%asr2" on v8, then
 we read %ccr (v9) or %asr2 (v8), which will always be 0x99 on v9,
 and .. is non-trapping but impleentation defined on v8.

 for many implementations this returns the value of the %y reg.

 as nothing actually sets %y in this path, it remains the value it
 was most recently set to by something (anything), and if it just
 happens to be 0x99 then the v9 paths will be taken on v8.

 fix this by clearing the %y register before the potential read.

 fixes PR port-sparc/57594.  tested on ss20 and in qemu.  this
 version of the patch has been submitted upstream.


 To generate a diff of this commit:
 cvs rdiff -u -r1.6 -r1.6.6.1 \
     src/crypto/external/bsd/openssl/dist/crypto/sparccpuid.S

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->closed
State-Changed-By: martin@NetBSD.org
State-Changed-When: Thu, 21 Sep 2023 15:30:42 +0000
State-Changed-Why:
fixed on all active branches


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2023 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.