NetBSD Problem Report #38482

From steve@mctavish.co.uk  Mon Apr 21 20:56:23 2008
Return-Path: <steve@mctavish.co.uk>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by narn.NetBSD.org (Postfix) with ESMTP id 44DD063B293
	for <gnats-bugs@gnats.NetBSD.org>; Mon, 21 Apr 2008 20:56:23 +0000 (UTC)
Message-Id: <20080421205613.A2E59CC6F5@oor-wullie.mctavish.co.uk>
Date: Mon, 21 Apr 2008 21:56:13 +0100 (BST)
To: gnats-bugs@gnats.NetBSD.org
Subject: C compiler can generate non-restartable code within a RAS
X-Send-Pr-Version: 3.95

>Number:         38482
>Category:       lib
>Synopsis:       C compiler can generate non-restartable code within a RAS.
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    lib-bug-people
>State:          analyzed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Apr 21 21:00:00 +0000 2008
>Closed-Date:    
>Last-Modified:  Thu Jun 03 10:29:50 +0000 2021
>Originator:     Steve Woodford
>Release:        NetBSD 4.99.60
>Organization:
>Environment:
Architecture: arm, hppa, m68000, mips, sh3, sparc, vax
Machine: arm, hppa, m68000, mips, sh3, sparc, vax
>Description:
I've recently noticed occasional SEGVs with threaded programs on ARM.
This turns out to be caused by dereferencing a bad pointer value in the
code between the RAS_START and RAS_END in
common/lib/libc/atomic/atomic_init_testset.c:_atomic_cas_up().

Examining the assembly code produced by Gcc shows the reason:

 108:   e1a03000        mov     r3, r0
0000010c <_atomic_cas_ras_start>:
 10c:   e5900000        ldr     r0, [r0]
 110:   e1500001        cmp     r0, r1
 114:   11a0f00e        movne   pc, lr
 118:   e5832000        str     r2, [r3]
0000011c <_atomic_cas_ras_end>:
 11c:   e1a0f00e        mov     pc, lr

Register r0 is modified within the sequence, therefore a bogus pointer
dereference is almost inevitable if the sequence is restarted.

It is likely all other archs which lack native CAS are at risk from
similar lossage. A quick check shows arm, hppa, m68000, mips, sh3, sparc,
and vax all use atomic_init_testset.c. I've only examined the compiled
code on ARM so I can't verify the other archs are similarly affected.
Even if an arch isn't currently affected, any future toolchain update or
minor change to the source for _atomic_cas_up() could easily break it.

>How-To-Repeat:
Run threaded code on affected archs (ARM in my case).
Observe occasional, seemingly random, SEGVs.

>Fix:
Rather than fighting the compiler, I propose we implement _atomic_cas_up()
in asm code for each affected arch. I can do ARM and m68000.

In addition, the rasctl(2) manual page should be updated to strongly
recommend that RASs are implemented in asm code only. Perhaps we should go
so far as removing the RAS_START/RAS_END macros from the API, though that
may preclude using in-line asm...

An audit of the tree for similar code sequences would also be a good idea.
For example: pthread_lock.c.

>Release-Note:

>Audit-Trail:
From: Steve Woodford <scw@netbsd.org>
To: gnats-bugs@netbsd.org
Cc: lib-bug-people@netbsd.org,
 gnats-admin@netbsd.org,
 netbsd-bugs@netbsd.org
Subject: Re: lib/38482: C compiler can generate non-restartable code within a RAS
Date: Mon, 21 Apr 2008 22:38:52 +0100

 --Boundary-00=_tlQDInHx5ZUGTgu
 Content-Type: text/plain;
   charset="iso-8859-1"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline

 A patch which addresses this problem for ARM and m68000 is attached.

 The patch adds -D__HAVE_ASM_ATOMIC_CAS_UP to CPPFLAGS in the ARM and 
 m68000 Makefile.inc fragments, which atomic_init_testset.c uses to 
 determine if an asm version of atomic_cas_up() is present.

 Once all affected archs have been fixed, -D__HAVE_ASM_ATOMIC_CAS_UP can 
 be removed.

 The namespace police may want to give this the once-over. Unless I hear 
 any objections, I'll commit it in a few days.

 Cheers, Steve

 --Boundary-00=_tlQDInHx5ZUGTgu
 Content-Type: text/x-diff;
   charset="iso-8859-1";
   name="atomic_cas.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
 	filename="atomic_cas.diff"

 diff -ruN -x CVS /export/netbsd/pristine/common/lib/libc/arch/arm/atomic/Makefile.inc common/lib/libc/arch/arm/atomic/Makefile.inc
 --- /export/netbsd/pristine/common/lib/libc/arch/arm/atomic/Makefile.inc	2008-04-21 22:26:12.000000000 +0100
 +++ common/lib/libc/arch/arm/atomic/Makefile.inc	2008-04-21 22:12:51.000000000 +0100
 @@ -12,5 +12,7 @@
  .if defined(LIB) && (${LIB} == "c")

  SRCS+=	atomic_init_testset.c
 +SRCS+=	atomic_cas_up.S
 +CPPFLAGS+= -D__HAVE_ASM_ATOMIC_CAS_UP

  .endif
 diff -ruN -x CVS /export/netbsd/pristine/common/lib/libc/arch/arm/atomic/atomic_cas_up.S common/lib/libc/arch/arm/atomic/atomic_cas_up.S
 --- /export/netbsd/pristine/common/lib/libc/arch/arm/atomic/atomic_cas_up.S	1970-01-01 01:00:00.000000000 +0100
 +++ common/lib/libc/arch/arm/atomic/atomic_cas_up.S	2008-04-21 22:11:57.000000000 +0100
 @@ -0,0 +1,54 @@
 +/*	$NetBSD$	*/
 +
 +/*-
 + * Copyright (c) 2008 The NetBSD Foundation, Inc.
 + * All rights reserved.
 + *
 + * This code is derived from software contributed to The NetBSD Foundation
 + * by Steve C. Woodford.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + * 3. All advertising materials mentioning features or use of this software
 + *    must display the following acknowledgement:
 + *        This product includes software developed by the NetBSD
 + *        Foundation, Inc. and its contributors.
 + * 4. Neither the name of The NetBSD Foundation nor the names of its
 + *    contributors may be used to endorse or promote products derived
 + *    from this software without specific prior written permission.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 + * POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#include <machine/asm.h>
 +
 +	.globl	_C_LABEL(_atomic_cas_ras_start)
 +	.type	_C_LABEL(_atomic_cas_ras_start),_ASM_TYPE_FUNCTION
 +
 +	.globl	_C_LABEL(_atomic_cas_ras_end)
 +	.type	_C_LABEL(_atomic_cas_ras_end),_ASM_TYPE_FUNCTION
 +
 +ENTRY_NP(_atomic_cas_up)
 +	mov	r3, r0
 +_C_LABEL(_atomic_cas_ras_start):
 +	ldr	r0, [r3]
 +	cmp	r0, r1
 +	streq	r2, [r3]
 +_C_LABEL(_atomic_cas_ras_end):
 +	RET
 diff -ruN -x CVS /export/netbsd/pristine/common/lib/libc/arch/m68k/atomic/Makefile.inc common/lib/libc/arch/m68k/atomic/Makefile.inc
 --- /export/netbsd/pristine/common/lib/libc/arch/m68k/atomic/Makefile.inc	2008-04-21 22:26:12.000000000 +0100
 +++ common/lib/libc/arch/m68k/atomic/Makefile.inc	2008-04-21 22:13:04.000000000 +0100
 @@ -33,6 +33,8 @@
  .else

  SRCS+=	atomic_init_testset.c
 +SRCS+=	atomic_cas_68000.S
 +CPPFLAGS+= -D__HAVE_ASM_ATOMIC_CAS_UP

  .endif
  .endif
 diff -ruN -x CVS /export/netbsd/pristine/common/lib/libc/arch/m68k/atomic/atomic_cas_68000.S common/lib/libc/arch/m68k/atomic/atomic_cas_68000.S
 --- /export/netbsd/pristine/common/lib/libc/arch/m68k/atomic/atomic_cas_68000.S	1970-01-01 01:00:00.000000000 +0100
 +++ common/lib/libc/arch/m68k/atomic/atomic_cas_68000.S	2008-04-21 22:14:12.000000000 +0100
 @@ -0,0 +1,56 @@
 +/*	$NetBSD$	*/
 +
 +/*-
 + * Copyright (c) 2008 The NetBSD Foundation, Inc.
 + * All rights reserved.
 + *
 + * This code is derived from software contributed to The NetBSD Foundation
 + * by Steve C. Woodford.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + * 3. All advertising materials mentioning features or use of this software
 + *    must display the following acknowledgement:
 + *	This product includes software developed by the NetBSD
 + *	Foundation, Inc. and its contributors.
 + * 4. Neither the name of The NetBSD Foundation nor the names of its
 + *    contributors may be used to endorse or promote products derived
 + *    from this software without specific prior written permission.
 + *      
 + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 + * POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#include "atomic_op_asm.h"
 +
 +	.text
 +
 +	.globl	_C_LABEL(_atomic_cas_ras_start)
 +	.globl	_C_LABEL(_atomic_cas_ras_end)
 +
 +ENTRY_NOPROFILE(_atomic_cas_up)
 +	movl	%sp@(4), %a0		/* Fetch ptr */
 +
 +_C_LABEL(_atomic_cas_ras_start):
 +	movl	%a0@, d0		/* d0 = *ptr */
 +	cmp	%sp@(8), d0		/* Same as old? */
 +	jne	1f			/* Nope */
 +	movl	%sp@(12), %a0@		/* *ptr = new */
 +_C_LABEL(_atomic_cas_ras_end):
 +1:	rts
 +
 diff -ruN -x CVS /export/netbsd/pristine/common/lib/libc/atomic/atomic_init_testset.c common/lib/libc/atomic/atomic_init_testset.c
 --- /export/netbsd/pristine/common/lib/libc/atomic/atomic_init_testset.c	2008-04-21 22:26:12.000000000 +0100
 +++ common/lib/libc/atomic/atomic_init_testset.c	2008-04-21 22:13:38.000000000 +0100
 @@ -66,6 +66,9 @@

  RAS_DECL(_atomic_cas);

 +#ifdef	__HAVE_ASM_ATOMIC_CAS_UP
 +extern uint32_t _atomic_cas_up(volatile uint32_t *, uint32_t, uint32_t);
 +#else
  static uint32_t
  _atomic_cas_up(volatile uint32_t *ptr, uint32_t old, uint32_t new)
  {
 @@ -81,6 +84,7 @@

  	return ret;
  }
 +#endif

  static uint32_t
  _atomic_cas_mp(volatile uint32_t *ptr, uint32_t old, uint32_t new)

 --Boundary-00=_tlQDInHx5ZUGTgu--

From: Alan Barrett <apb@cequrux.com>
To: gnats-bugs@NetBSD.org
Cc: netbsd-bugs@NetBSD.org
Subject: Re: lib/38482: C compiler can generate non-restartable code within
	a RAS
Date: Tue, 22 Apr 2008 11:08:29 +0200

 On Mon, 21 Apr 2008, scw@NetBSD.org wrote:
 > I've recently noticed occasional SEGVs with threaded programs on ARM.
 > This turns out to be caused by dereferencing a bad pointer value in the
 > code between the RAS_START and RAS_END in
 > common/lib/libc/atomic/atomic_init_testset.c:_atomic_cas_up().

 Does it help to declare "volatile uint32_t ret;" ?

 --apb (Alan Barrett)

From: Steve Woodford <scw@netbsd.org>
To: gnats-bugs@netbsd.org
Cc: lib-bug-people@netbsd.org,
 gnats-admin@netbsd.org,
 netbsd-bugs@netbsd.org
Subject: Re: lib/38482: C compiler can generate non-restartable code within  a RAS
Date: Tue, 22 Apr 2008 10:15:24 +0100

 On Tuesday 22 April 2008 10:10:05 Alan Barrett wrote:

 >  Does it help to declare "volatile uint32_t ret;" ?

 It does, on ARM, with the current toolchain. But 1) it generates less 
 efficient code, and 2) the next version of Gcc may well break it again.

 Cheers, Steve

From: Andrew Doran <ad@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: lib/38482: C compiler can generate non-restartable code within a RAS
Date: Tue, 22 Apr 2008 12:08:15 +0100

 On Mon, Apr 21, 2008 at 09:00:01PM +0000, scw@netbsd.org wrote:

 > Rather than fighting the compiler, I propose we implement _atomic_cas_up()
 > in asm code for each affected arch. I can do ARM and m68000.

 Yes please. I can do mips and perhaps alpha. IIRC the assembler should
 recognise the .hidden keyword so none of the symbols in the atomic CAS
 file need to be visible outside libc.

 > In addition, the rasctl(2) manual page should be updated to strongly
 > recommend that RASs are implemented in asm code only. Perhaps we should go
 > so far as removing the RAS_START/RAS_END macros from the API, though that
 > may preclude using in-line asm...

 I also agree with this. C is too hit-and-miss..

 > An audit of the tree for similar code sequences would also be a good idea.
 > For example: pthread_lock.c.

 I think we may already have assembly sequences in libpthread for some
 architectures.

 Thanks,
 Andrew

State-Changed-From-To: open->analyzed
State-Changed-By: scw@NetBSD.org
State-Changed-When: Tue, 29 Apr 2008 22:10:36 +0100
State-Changed-Why:
_atomic_cas_up() is in the process of being implemented in asm code for each
affected arch.


From: Steve Woodford <scw@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/38482 CVS commit: src/lib/libc/sys
Date: Tue, 29 Apr 2008 21:06:28 +0000 (UTC)

 Module Name:	src
 Committed By:	scw
 Date:		Tue Apr 29 21:06:28 UTC 2008

 Modified Files:
 	src/lib/libc/sys: rasctl.2

 Log Message:
 - Document RAS_START_ASM, RAS_END_ASM, RAS_START_ASM_HIDDEN, and
   RAS_END_ASM_HIDDEN.
 - Advise against implementing RASs in C.

 See PR lib/38482 for details.

 While here, remove clauses 3 and 4 from TNF license.


 To generate a diff of this commit:
 cvs rdiff -r1.12 -r1.13 src/lib/libc/sys/rasctl.2

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

From: Andrew Doran <ad@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/38482 CVS commit: src/common/lib/libc/arch/mips/atomic
Date: Wed, 30 Apr 2008 00:17:34 +0000 (UTC)

 Module Name:	src
 Committed By:	ad
 Date:		Wed Apr 30 00:17:34 UTC 2008

 Modified Files:
 	src/common/lib/libc/arch/mips/atomic: Makefile.inc
 Added Files:
 	src/common/lib/libc/arch/mips/atomic: atomic_cas_up.S

 Log Message:
 Assembly _atomic_cas_up() for mips. PR lib/38482.


 To generate a diff of this commit:
 cvs rdiff -r1.6 -r1.7 src/common/lib/libc/arch/mips/atomic/Makefile.inc
 cvs rdiff -r0 -r1.1 src/common/lib/libc/arch/mips/atomic/atomic_cas_up.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/38482 CVS commit: src/common/lib/libc/arch/sparc/atomic
Date: Wed, 28 Nov 2012 21:39:59 +0000

 Module Name:	src
 Committed By:	martin
 Date:		Wed Nov 28 21:39:59 UTC 2012

 Modified Files:
 	src/common/lib/libc/arch/sparc/atomic: Makefile.inc
 Added Files:
 	src/common/lib/libc/arch/sparc/atomic: atomic_cas_up.S

 Log Message:
 Provide an assembler version of _atomic_cas_up for sparc - the C code
 does not compile to something usable in a RAS. See PR 38482.


 To generate a diff of this commit:
 cvs rdiff -u -r1.14 -r1.15 src/common/lib/libc/arch/sparc/atomic/Makefile.inc
 cvs rdiff -u -r0 -r1.1 src/common/lib/libc/arch/sparc/atomic/atomic_cas_up.S

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

From: David Holland <dholland-bugs@netbsd.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: lib/38482: C compiler can generate non-restartable code within a
 RAS.
Date: Sat, 22 May 2021 03:47:23 +0000

 Though some the commits didn't make it to this PR, it looks like at
 this point only sh3 and vax are missing an atomic_cas_up.S.

 The mips code appears to be missing 16- and 8- bit CAS and be still
 using the C code from atomic_init_testset.c; path of least resistance
 is to use atomic_cas_by_cas32.c for both cases and not just mips64,
 but writing narrow RAS versions is straightforward.

 (also it seems like we ought to support real CAS for multiprocessor
 mips32+ targets, but that's a different issue)

 It would probably be good to get the missing bits written and remove
 the dodgy C-based RAS code.

 -- 
 David A. Holland
 dholland@netbsd.org

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.