Subject: Re: buffer overflows in libsa
To: None <tech-kern@NetBSD.org>
From: Roland Illig <rillig@NetBSD.org>
List: tech-kern
Date: 08/23/2005 09:01:45
This is a multi-part message in MIME format.
--------------060800090106010201010003
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Bill Studenmund wrote:
> I wouldn't object to you coming up with a getsn() or some such that took a
> buffer length and assumed standard in. Or getsl().
Here it is.
Roland
--------------060800090106010201010003
Content-Type: text/plain;
name="libsa-gets.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="libsa-gets.patch"
? libsa-gets.patch
Index: Makefile
===================================================================
RCS file: /cvsroot/src/sys/lib/libsa/Makefile,v
retrieving revision 1.56
diff -u -p -r1.56 Makefile
--- Makefile 13 Jun 2005 12:11:07 -0000 1.56
+++ Makefile 23 Aug 2005 07:00:06 -0000
@@ -17,8 +17,8 @@ CPPFLAGS= -I${SADIR} ${SACPPFLAGS} ${SAM
.PATH.c: ${SADIR}
# stand routines
-SRCS+= alloc.c bcopy.c bzero.c errno.c exit.c exec.c files.c \
- getfile.c gets.c globals.c memcmp.c memcpy.c memmove.c memset.c \
+SRCS+= alloc.c bcopy.c bzero.c errno.c exit.c exec.c files.c getfile.c \
+ gets.c getsl.c globals.c memcmp.c memcpy.c memmove.c memset.c \
panic.c printf.c qsort.c snprintf.c sprintf.c strerror.c subr_prf.c \
twiddle.c vsprintf.c checkpasswd.c
Index: gets.c
===================================================================
RCS file: /cvsroot/src/sys/lib/libsa/gets.c,v
retrieving revision 1.8
diff -u -p -r1.8 gets.c
--- gets.c 7 Aug 2003 16:32:27 -0000 1.8
+++ getsl.c 23 Aug 2005 07:00:06 -0000
@@ -1,4 +1,5 @@
-/* $NetBSD: gets.c,v 1.8 2003/08/07 16:32:27 agc Exp $ */
+/* $NetBSD$ */
+/* From NetBSD: gets.c,v 1.8 2003/08/07 16:32:27 agc Exp */
/*-
* Copyright (c) 1993
@@ -33,14 +34,21 @@
#include "stand.h"
+#define CTRL(key) ((key) & 037)
+
+/* gets(3)-like function with bounds checking */
void
-gets(buf)
- char *buf;
+getsl(char *buf, size_t bufsize)
{
int c;
- char *lp;
+ char *lp, *bufend;
+
+ /* assert(bufsize != 0); */
+
+ /* leave enough room for the terminating null character */
+ bufend = buf + bufsize - 1;
- for (lp = buf;;)
+ for (lp = buf;;) {
switch (c = getchar() & 0177) {
case '\n':
case '\r':
@@ -62,7 +70,7 @@ gets(buf)
--lp;
break;
#endif
- case 'r'&037: {
+ case CTRL('r'): {
char *p;
putchar('\n');
@@ -73,14 +81,18 @@ gets(buf)
#if AT_ERASE
case '@':
#endif
- case 'u'&037:
- case 'w'&037:
+ case CTRL('u'):
+ case CTRL('w'):
lp = buf;
putchar('\n');
break;
default:
- *lp++ = c;
- putchar(c);
+ if (lp < bufend) {
+ *lp++ = c;
+ putchar(c);
+ } else
+ putchar('\a');
}
+ }
/*NOTREACHED*/
}
--------------060800090106010201010003--