From archie@whistle.com  Wed Nov  4 19:17:35 1998
Received: from whistle.com (s205m131.whistle.com [207.76.205.131])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id TAA05433
          for <FreeBSD-gnats-submit@freebsd.org>; Wed, 4 Nov 1998 19:17:35 -0800 (PST)
          (envelope-from archie@whistle.com)
Received: (from smap@localhost) by whistle.com (8.7.5/8.6.12) id TAA04251 for <FreeBSD-gnats-submit@freebsd.org>; Wed, 4 Nov 1998 19:17:25 -0800 (PST)
Received: from bubba.whistle.com(207.76.205.7) by whistle.com via smap (V1.3)
	id sma004247; Wed Nov  4 19:17:23 1998
Received: (from archie@localhost) by bubba.whistle.com (8.8.7/8.6.12) id TAA03886; Wed, 4 Nov 1998 19:17:23 -0800 (PST)
Message-Id: <199811050317.TAA03886@bubba.whistle.com>
Date: Wed, 4 Nov 1998 19:17:23 -0800 (PST)
From: Archie Cobbs <archie@whistle.com>
Reply-To: archie@whistle.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: Request [v]snprintf() in the kernel
X-Send-Pr-Version: 3.2

>Number:         8577
>Category:       kern
>Synopsis:       Request [v]snprintf() in the kernel
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Nov  4 19:20:00 PST 1998
>Closed-Date:    Sun Dec 6 21:45:28 PST 1998
>Last-Modified:  Sun Dec  6 21:46:14 PST 1998
>Originator:     Archie Cobbs
>Release:        FreeBSD 2.2.6-RELEASE i386
>Organization:
Whistle Communications, Inc.
>Environment:

	FreeBSD 3.0-current

>Description:

	Request that snprintf() and vsnprintf() functions
	be added to the kernel. This would enable us to change
	kernel code that uses sprintf() for:

	 - Greater safety from buffer overflows

	 - Eliminate code that does manual bounds checking,
	   ie, the equivalent of what snprintf() does automatically

	Also, the amount of code to add to the kernel is just
	a few lines.

>How-To-Repeat:


>Fix:

This patch is a start.. it enable the aforementioned cleanups
to start happening.

Index: kern/subr_prf.c
===================================================================
RCS file: /cvs/freebsd/src/sys/kern/subr_prf.c,v
retrieving revision 1.50
diff -u -r1.50 subr_prf.c
--- subr_prf.c	1998/09/06 06:25:04	1.50
+++ subr_prf.c	1998/11/05 03:10:12
@@ -68,6 +68,8 @@
 struct putchar_arg {int flags; struct tty *tty; };
 static void  putchar __P((int ch, void *arg));
 static char *ksprintn __P((u_long num, int base, int *len));
+static void snprintf_func __P((int ch, void *arg));
+struct snprintf_arg { char *buf; size_t remain; };
 
 static int consintr = 1;		/* Ok to handle console interrupts? */
 static int msgbufmapped;		/* Set when safe to use msgbuf */
@@ -326,6 +328,47 @@
 	retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
 	buf[retval] = '\0';
 	return retval;
+}
+
+/*
+ * Scaled down version of snprintf(3).
+ */
+int
+snprintf(char *buf, size_t max, const char *cfmt, ...)
+{
+	int retval;
+	va_list ap;
+
+	va_start(ap, cfmt);
+	retval = vsnprintf(buf, max, cfmt, ap);
+	va_end(ap);
+	return retval;
+}
+
+/*
+ * Scaled down version of vsnprintf(3).
+ */
+int
+vsnprintf(char *buf, size_t size, const char *cfmt, va_list ap)
+{
+	struct snprintf_arg info = { buf, size };
+	int retval;
+
+	retval = kvprintf(cfmt, snprintf_func, &info, 10, ap);
+	if (info.remain >= 1)
+		*info.buf++ = '\0';
+	return retval;
+}
+
+static void
+snprintf_func(int ch, void *arg)
+{
+	struct snprintf_arg *const info = (struct snprintf_arg *) arg;
+
+	if (info->remain >= 2) {
+		*info->buf++ = ch;
+		info->remain--;
+	}
 }
 
 /*
Index: sys/systm.h
===================================================================
RCS file: /cvs/freebsd/src/sys/sys/systm.h,v
retrieving revision 1.78
diff -u -r1.78 systm.h
--- systm.h	1998/10/30 05:41:15	1.78
+++ systm.h	1998/11/05 03:10:13
@@ -108,6 +108,8 @@
 void	logwakeup __P((void));
 int	printf __P((const char *, ...)) __printflike(1, 2);
 int	sprintf __P((char *buf, const char *, ...)) __printflike(2, 3);
+int	snprintf __P((char *, size_t, const char *, ...)) __printflike(3, 4);
+int	vsnprintf __P((char *, size_t, const char *, _BSD_VA_LIST_)) __printflike(3, 0);
 void	uprintf __P((const char *, ...)) __printflike(1, 2);
 void	vprintf __P((const char *, _BSD_VA_LIST_)) __printflike(1, 0);
 int     vsprintf __P((char *buf, const char *, _BSD_VA_LIST_)) __printflike(2, 0);
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: archie 
State-Changed-When: Sun Dec 6 21:45:28 PST 1998 
State-Changed-Why:  
[v]snprintf() added by me :) 
>Unformatted:
