Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Aug 1996 00:55:22 +0900 (JST)
From:      Ikuo Nakagawa <ikuo@isl.intec.co.jp>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/1488: /sys/i386/isa/spkr.c does not check the length of a string
Message-ID:  <199608101555.AAA00789@pawn.isl.intec.co.jp>
Resent-Message-ID: <199608101620.JAA06042@freefall.freebsd.org>

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

>Number:         1488
>Category:       kern
>Synopsis:       /sys/i386/isa/spkr.c does not check the length of a string
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Aug 10 09:20:01 PDT 1996
>Last-Modified:
>Originator:     Ikuo Nakagawa
>Organization:
INTEC Inc.
>Release:        FreeBSD 2.2-960801-SNAP i386
>Environment:
System: FreeBSD 2.2-960801-SNAP
Architecture: i386

>Description:
Playstring() function in /sys/i386/isa/spkr.c has two arguments,
  `cp'    ... a string to play,
  `slen'  ... the length of the string pointed by `cp'.
But, codes like { cp++; slen--; } are evaluated WITHOUT checking
the value of `slen'.

>How-To-Repeat:
Following code MAY cause kernel panic...
{
  int fd = open("/dev/speaker", O_WRONLY);
  write(fd, "T120O3A8.", 9);
}

>Fix:
*** spkr.c.orig	Sat Aug 10 23:07:28 1996
--- spkr.c	Sat Aug 10 23:07:28 1996
***************
*** 281,287 ****
  {
      int		pitch, oldfill, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
  
! #define GETNUM(cp, v)	for(v=0; isdigit(cp[1]) && slen > 0; ) \
  				{v = v * 10 + (*++cp - '0'); slen--;}
      for (; slen--; cp++)
      {
--- 281,287 ----
  {
      int		pitch, oldfill, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
  
! #define GETNUM(cp, v)	for(v=0; slen && isdigit(cp[1]); ) \
  				{v = v * 10 + (*++cp - '0'); slen--;}
      for (; slen--; cp++)
      {
***************
*** 300,312 ****
  	    pitch = notetab[c - 'A'] + octave * OCTAVE_NOTES;
  
  	    /* this may be followed by an accidental sign */
! 	    if (cp[1] == '#' || cp[1] == '+')
  	    {
  		++pitch;
  		++cp;
  		slen--;
  	    }
! 	    else if (cp[1] == '-')
  	    {
  		--pitch;
  		++cp;
--- 300,312 ----
  	    pitch = notetab[c - 'A'] + octave * OCTAVE_NOTES;
  
  	    /* this may be followed by an accidental sign */
! 	    if (slen && (cp[1] == '#' || cp[1] == '+'))
  	    {
  		++pitch;
  		++cp;
  		slen--;
  	    }
! 	    else if (slen && cp[1] == '-')
  	    {
  		--pitch;
  		++cp;
***************
*** 341,347 ****
  		timeval = value;
  
  	    /* ...and/or sustain dots */
! 	    for (sustain = 0; cp[1] == '.'; cp++)
  	    {
  		slen--;
  		sustain++;
--- 341,347 ----
  		timeval = value;
  
  	    /* ...and/or sustain dots */
! 	    for (sustain = 0; slen && cp[1] == '.'; cp++)
  	    {
  		slen--;
  		sustain++;
***************
*** 349,355 ****
  
  	    /* ...and/or a slur mark */
  	    oldfill = fill;
! 	    if (cp[1] == '_')
  	    {
  		fill = LEGATO;
  		++cp;
--- 349,355 ----
  
  	    /* ...and/or a slur mark */
  	    oldfill = fill;
! 	    if (slen && cp[1] == '_')
  	    {
  		fill = LEGATO;
  		++cp;
***************
*** 363,375 ****
  	    break;
  
  	case 'O':
! 	    if (cp[1] == 'N' || cp[1] == 'n')
  	    {
  		octprefix = octtrack = FALSE;
  		++cp;
  		slen--;
  	    }
! 	    else if (cp[1] == 'L' || cp[1] == 'l')
  	    {
  		octtrack = TRUE;
  		++cp;
--- 363,375 ----
  	    break;
  
  	case 'O':
! 	    if (slen && (cp[1] == 'N' || cp[1] == 'n'))
  	    {
  		octprefix = octtrack = FALSE;
  		++cp;
  		slen--;
  	    }
! 	    else if (slen && (cp[1] == 'L' || cp[1] == 'l'))
  	    {
  		octtrack = TRUE;
  		++cp;
***************
*** 398,410 ****
  
  	case 'N':
  	    GETNUM(cp, pitch);
! 	    for (sustain = 0; cp[1] == '.'; cp++)
  	    {
  		slen--;
  		sustain++;
  	    }
  	    oldfill = fill;
! 	    if (cp[1] == '_')
  	    {
  		fill = LEGATO;
  		++cp;
--- 398,410 ----
  
  	case 'N':
  	    GETNUM(cp, pitch);
! 	    for (sustain = 0; slen && cp[1] == '.'; cp++)
  	    {
  		slen--;
  		sustain++;
  	    }
  	    oldfill = fill;
! 	    if (slen && cp[1] == '_')
  	    {
  		fill = LEGATO;
  		++cp;
***************
*** 426,432 ****
  	    GETNUM(cp, timeval);
  	    if (timeval <= 0 || timeval > MIN_VALUE)
  		timeval = value;
! 	    for (sustain = 0; cp[1] == '.'; cp++)
  	    {
  		slen--;
  		sustain++;
--- 426,432 ----
  	    GETNUM(cp, timeval);
  	    if (timeval <= 0 || timeval > MIN_VALUE)
  		timeval = value;
! 	    for (sustain = 0; slen && cp[1] == '.'; cp++)
  	    {
  		slen--;
  		sustain++;
***************
*** 442,460 ****
  	    break;
  
  	case 'M':
! 	    if (cp[1] == 'N' || cp[1] == 'n')
  	    {
  		fill = NORMAL;
  		++cp;
  		slen--;
  	    }
! 	    else if (cp[1] == 'L' || cp[1] == 'l')
  	    {
  		fill = LEGATO;
  		++cp;
  		slen--;
  	    }
! 	    else if (cp[1] == 'S' || cp[1] == 's')
  	    {
  		fill = STACCATO;
  		++cp;
--- 442,460 ----
  	    break;
  
  	case 'M':
! 	    if (slen && (cp[1] == 'N' || cp[1] == 'n'))
  	    {
  		fill = NORMAL;
  		++cp;
  		slen--;
  	    }
! 	    else if (slen && (cp[1] == 'L' || cp[1] == 'l'))
  	    {
  		fill = LEGATO;
  		++cp;
  		slen--;
  	    }
! 	    else if (slen && (cp[1] == 'S' || cp[1] == 's'))
  	    {
  		fill = STACCATO;
  		++cp;

>Audit-Trail:
>Unformatted:



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