Subject: port-i386/2612: spkrwrite sometimes overruns given data and plays random music
To: None <gnats-bugs@NetBSD.ORG>
From: None <enami@ba2.so-net.or.jp>
List: netbsd-bugs
Date: 07/09/1996 21:25:07
>Number: 2612
>Category: port-i386
>Synopsis: spkrwrite sometimes overruns given data and plays random music
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: gnats-admin (GNATS administrator)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Jul 9 08:50:01 1996
>Last-Modified:
>Originator: enami tsugutomo
>Organization:
An individual
>Release: 1.2_ALPHA
>Environment:
System: NetBSD plants-doll.enami.ba2.so-net.or.jp 1.2_BETA NetBSD 1.2_BETA (PLANTS_DOLL) #170: Sat Jul 6 15:31:38 JST 1996 enami@plants-doll.enami.ba2.so-net.or.jp:/usr/src/sys/arch/i386/compile/PLANTS_DOLL i386
>Description:
The function spkrwrite in arch/i386/isa/spkr.c sometimes overruns
given data. In such case, speaker plays random music after palying
right one.
>How-To-Repeat:
Apply following patch to spkr.c. It fills a internal buffer with
wrong garbage before copy given data. Then do
echo -n o4cc >/dev/speaker.
This should only play two beep, but it may plays random music (and
may panic if DEV_BSZIE is exceeded).
Index: spkr.c
===================================================================
RCS file: /a/cvsroot/NetBSD/sys/arch/i386/isa/spkr.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 spkr.c
--- spkr.c 1996/05/07 02:40:14 1.1.1.5
+++ spkr.c 1996/07/09 11:39:54
@@ -503,8 +503,11 @@
return(ENXIO);
else
{
+ int i;
n = min(DEV_BSIZE, uio->uio_resid);
cp = spkr_inbuf->b_data;
+ for (i = 0; i < DEV_BSIZE; i++)
+ cp[i] = '#';
error = uiomove(cp, n, uio);
if (!error)
playstring(cp, n);
>Fix:
The problem is in a function playstring; it uses cp[1] without
checking slen > 0 and if garbage looks right data it decrements slen
over zero (it becomes very large integer because slen is size_t).
To fix the problem I think there is at lease two way:
a) Check if slen > 0 whenever uses cp[1].
or
b) Put a sentinel after given data so that random garbage in
buffer does not confuse the playstring.
Here is a patch for style b). It is shorter than a).
Index: spkr.c
===================================================================
RCS file: /a/cvsroot/NetBSD/sys/arch/i386/isa/spkr.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 spkr.c
--- spkr.c 1996/05/07 02:40:14 1.1.1.5
+++ spkr.c 1996/07/09 12:04:32
@@ -253,7 +253,7 @@
{
int pitch, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
-#define GETNUM(cp, v) for(v=0; isdigit(cp[1]) && slen > 0; ) \
+#define GETNUM(cp, v) for(v=0; isdigit(cp[1]); ) \
{v = v * 10 + (*++cp - '0'); slen--;}
for (; slen--; cp++)
{
@@ -503,11 +503,13 @@
return(ENXIO);
else
{
- n = min(DEV_BSIZE, uio->uio_resid);
+ n = min(DEV_BSIZE - 1, uio->uio_resid);
cp = spkr_inbuf->b_data;
error = uiomove(cp, n, uio);
- if (!error)
+ if (!error) {
+ cp[n] = '\0'; /* put a sentinel */
playstring(cp, n);
+ }
return(error);
}
}
>Audit-Trail:
>Unformatted: