Subject: bin/22394: [rkb] radioctl(1) -w gets SIGBUS on strict-alignment LP64 archs
To: None <gnats-bugs@gnats.netbsd.org>
From: None <rafal@netbsd.org>
List: netbsd-bugs
Date: 08/07/2003 13:32:33
>Number: 22394
>Category: bin
>Synopsis: radioctl(1) -w gets SIGBUS on strict-alignment LP64 archs
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Aug 07 17:33:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: Rafal Boni
>Release: NetBSD 1.6W
>Organization:
Lacking
>Environment:
System: NetBSD fearless-vampire-killer.waterside.net 1.6W NetBSD 1.6W (FEARLESS_VAMPIRE_KILLER) #6: Thu Aug 7 12:24:53 EDT 2003 rafal@fearless-vampire-killer.waterside.net:/extra/sparc64/obj/sys/arch/sparc64/compile/FEARLESS_VAMPIRE_KILLER sparc64
Architecture: sparc64
Machine: sparc64
>Description:
On sparc64 (or any LP64 strict-aligning arch), run the following
command, and watch it fall over with a SIGBUS:
radioctl -w frequency=88.1 (or any other frequency)
The issue is that even though the fields of the radio_info structure
are either int's or u_int32_t's, the radioctl(1) code that sets them
passes a u_long pointer and a u_long value to the update function.
A secondary issue is that the radioio.h interface uses pure `int'
in some places and `u_int32_t' in others... it should probably be
made to just use u_int32_t's everywhere to make like simpler.
>How-To-Repeat:
Run the following on a sparc64 with a radio tuner (like a DLink
USB radio):
radioctl -w frequency=88.1 (or any other frequency)
Watch SIGBUS happen and the value not get updated.
>Fix:
Here's some cleanup to radioctl(1); as I mentioned, the radioio.h
interface should probably *also* be changed to use fixed-size-types
everywhere (I don't think this is an ABI issue).
Index: radioctl.c
===================================================================
RCS file: /cvsroot/src/usr.bin/radioctl/radioctl.c,v
retrieving revision 1.5
diff -u -r1.5 radioctl.c
--- radioctl.c 2003/06/23 13:05:51 1.5
+++ radioctl.c 2003/08/07 17:16:20
@@ -91,7 +91,7 @@
static void print_value(int);
static void change_value(const struct opt_t);
-static void update_value(int, u_long *, u_long);
+static void update_value(int, u_int32_t *, u_int32_t);
static void warn_unsupported(int);
static void usage(void);
@@ -260,14 +260,14 @@
switch (o.option) {
case OPTION_VOLUME:
- update_value(o.sign, (u_long *)&ri.volume, o.value);
+ update_value(o.sign, &ri.volume, o.value);
break;
case OPTION_FREQUENCY:
- update_value(o.sign, (u_long *)&ri.freq, o.value);
+ update_value(o.sign, &ri.freq, o.value);
break;
case OPTION_REFERENCE:
if (ri.caps & RADIO_CAPS_REFERENCE_FREQ)
- update_value(o.sign, (u_long *)&ri.rfreq, o.value);
+ update_value(o.sign, &ri.rfreq, o.value);
else
unsupported++;
break;
@@ -281,7 +281,7 @@
break;
case OPTION_SENSITIVITY:
if (ri.caps & RADIO_CAPS_LOCK_SENSITIVITY)
- update_value(o.sign, (u_long *)&ri.lock, o.value);
+ update_value(o.sign, &ri.lock, o.value);
else
unsupported++;
break;
@@ -320,7 +320,7 @@
}
static void
-update_value(int sign, u_long *value, u_long update)
+update_value(int sign, u_int32_t *value, u_int32_t update)
{
switch (sign) {
case SIGN_NONE:
>Release-Note:
>Audit-Trail:
>Unformatted:
Sources from Aug 6th, 2003