Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Apr 1997 14:00:17 -0700 (PDT)
From:      brett@lariat.org
To:        freebsd-gnats-submit@freebsd.org
Subject:   i386/3309: /dev/spkr can crash system and may have serious security exploits
Message-ID:  <199704162100.OAA06608@freefall.freebsd.org>
Resent-Message-ID: <199704162110.OAA07966@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         3309
>Category:       i386
>Synopsis:       /dev/spkr can crash system and may have serious security exploits
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Apr 16 14:10:01 PDT 1997
>Last-Modified:
>Originator:     Brett Glass
>Organization:
InfoWorld
>Release:        2.1.0-R (source in 2.2 is similar or identical)
>Environment:
>Description:
The /dev/spkr driver apparently can corrupt kernel memory if noises
are made in rapid succession or if one is started before an earlier
one finishes. The Perl code below triggers the bug on my 2.1.0-R 
system quite reliably (the code for the driver doesn't seem to have 
changed since then).

The problem seems to have to do with a race condition and/or with kernel 
memory allocation. I'm not terribly familiar with BSD kernel 
programming, and there's no documentation on the full implications of 
some items in the driver code, so I'm not sure how to pinpoint 
the problem. A kernel hacker familiar with race conditions and memory
allocation in the kernel should be able to spot the problem.

Frequently (but not always), when code like the sample is executed, 
the speaker begins to play random noises after the second "print." It
doesn't stop. The process that's playing the sounds may hang, and the 
system can become unstable. Killing the hung process results in a wide 
range of awful noises -- and, at least on my machine -- a reboot 
without sync'ing the file system. (I had to do extensive reconstruction
of /dev after the crash.) There may also be a potential security 
exploit here, since the play string is copied into kernel memory.

An earlier bug fix to the driver appears not to have solved all of 
the potential problems with the driver.

Can someone help to identify the source of the problem and a fix 
for it?

--Brett Glass

>How-To-Repeat:
In Perl 5:

open (SPKR, ">/dev/speaker");
print SPKR "T120L8O4AF"; # Bing-bong!
close (SPKR);
open (SPKR, ">/dev/speaker");
print SPKR "T120L8O4AF"; # And again....
close (SPKR);

>Fix:
Would like to fix this myself, but don't know all the semantics and
meta-semantics of the routines called within FreeBSD device drivers.
(Would love to see a kernel-hacking manual that covers this!) I have
been able to work around the problem only by adding sleep() statements
that guarantee that every "play" string is played to completion and then
some. (For instance, in the above example, adding sleep(1) between the
first close and the second open seems to mask the bug. However,
this is only a workaround, NOT a fix! Given the possibility that
this could be a security exploit, a real fix is warranted.                                 
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199704162100.OAA06608>