From nobody@FreeBSD.org  Wed Feb 11 07:31:56 2004
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id F384716A4CE
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 11 Feb 2004 07:31:55 -0800 (PST)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id DA55143D2F
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 11 Feb 2004 07:31:55 -0800 (PST)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.12.10/8.12.10) with ESMTP id i1BFVt72026188
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 11 Feb 2004 07:31:55 -0800 (PST)
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.12.10/8.12.10/Submit) id i1BFVtNO026187;
	Wed, 11 Feb 2004 07:31:55 -0800 (PST)
	(envelope-from nobody)
Message-Id: <200402111531.i1BFVtNO026187@www.freebsd.org>
Date: Wed, 11 Feb 2004 07:31:55 -0800 (PST)
From: moulin p <moulin.p@calyopea.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [PATCH] /usr/src/lib/libc/locale/ldpart.c  buffer overflow
X-Send-Pr-Version: www-2.0

>Number:         62694
>Category:       kern
>Synopsis:       [PATCH] /usr/src/lib/libc/locale/ldpart.c  buffer overflow
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Feb 11 07:40:18 PST 2004
>Closed-Date:    Tue Aug 24 04:57:57 GMT 2004
>Last-Modified:  Tue Aug 24 04:57:57 GMT 2004
>Originator:     moulin p
>Release:        5.1-RELEASE-p11
>Organization:
calyopea.com
>Environment:
FreeBSD dev 5.1-RELEASE-p11 FreeBSD 5.1-RELEASE-p11 #5: Thu Dec 25 17:32:30 CET 2003     root@dev:/usr/src/sys/i386/compile/Athlon  i386

>Description:
Under certain circumstances, using setlocale() may cause software crashes.

The patch attached solve :

in /usr/src/lib/libc/locale/ldpart.c
 - *locale_buf was tested without prior checked if locale_buf 
   was NULL or not => sigvec under certain circumstances.
 - a strchr was used on an non '\0' terminated buffer => crash


other minor things:

in /usr/src/lib/libc/locale/srune.c (with gcc's -Werror flag)
  - memcpy needs <string.h> to be properly prototyped.

in /usr/src/lib/libc/locale/wcstold.c (with gcc's -Werror flag)
 - two unused variables.



>How-To-Repeat:
Using a bound-checker enabled gcc 3.3.2
(see http://web.inter.nl.net/hcc/Haj.Ten.Brugge/)

int main()
{
char *locale_test;

    locale_test=setlocale(C_TIME,"en_US.ISO8859-1");
    if (locale_test==NULL) return 1

return 0;
}

>Fix:




diff -ur /usr/src/lib/libc/locale_ORIGINAL/ldpart.c /usr/src/lib/libc/locale/ldpart.c
--- /usr/src/lib/libc/locale_ORIGINAL/ldpart.c  Thu Jun 26 12:46:16 2003
+++ /usr/src/lib/libc/locale/ldpart.c Wed Feb 11 15:20:28 2004
@@ -69,7 +69,7 @@
  /*
   * If the locale name is the same as our cache, use the cache.
   */
- if (*locale_buf != NULL && strcmp(name, *locale_buf) == 0) {
+ if (locale_buf != NULL && *locale_buf != NULL && strcmp(name, *locale_buf) == 0) {
    *using_locale = 1;
    return (_LDP_CACHE);
  }
@@ -106,12 +106,15 @@
  if (_read(fd, p, (size_t) st.st_size) != st.st_size)
    goto bad_lbuf;
  /*
-  * Parse the locale file into localebuf.
+  * check ending '\n' in freshly loaded locale.
   */
  if (plim[-1] != '\n') {
    errno = EFTYPE;
    goto bad_lbuf;
  }
+ /*
+  * Parse the locale file into localebuf.
+  */
  num_lines = split_lines(p, plim);
  if (num_lines >= locale_buf_size_max)
    num_lines = locale_buf_size_max;
@@ -151,12 +154,15 @@
 static int
 split_lines(char *p, const char *plim)
 {
- int i;
+  int i=0;
 
- for (i = 0; p < plim; i++) {
-   p = strchr(p, '\n');
-   *p++ = '\0';
- }
- return (i);
+  while (p < plim) {
+    if (*p == '\n') {
+      *p = '\0';
+      i++;
+    }
+    p++;
+  }
+  return (i);
 }
 
diff -ur /usr/src/lib/libc/locale_ORIGINAL/srune.c /usr/src/lib/libc/locale/srune.c
--- /usr/src/lib/libc/locale_ORIGINAL/srune.c Sat Nov  1 06:13:13 2003
+++ /usr/src/lib/libc/locale/srune.c  Wed Feb 11 12:31:41 2004
@@ -28,6 +28,7 @@
 __FBSDID("$FreeBSD: src/lib/libc/locale/srune.c,v 1.1 2003/11/01 05:13:13 tjr Exp $");
 
 #include <limits.h>
+#include <string.h>
 #include <rune.h>
 #include <wchar.h>
 
diff -ur /usr/src/lib/libc/locale_ORIGINAL/wcstold.c /usr/src/lib/libc/locale/wcstold.c
--- /usr/src/lib/libc/locale_ORIGINAL/wcstold.c Fri Oct 31 14:29:00 2003
+++ /usr/src/lib/libc/locale/wcstold.c  Wed Feb 11 12:32:37 2004
@@ -38,9 +38,9 @@
 wcstold(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr)
 {
  long double val;
- char *buf, *end, *p;
+ char *buf, *end;
  const wchar_t *wcp;
- size_t clen, len;
+ size_t len;
 
  while (iswspace(*nptr))
    nptr++;

>Release-Note:
>Audit-Trail:

From: David Schultz <das@FreeBSD.ORG>
To: moulin p <moulin.p@calyopea.com>
Cc: phantom@FreeBSD.ORG, ache@FreeBSD.ORG,
	freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: misc/62694: [PATCH] /usr/src/lib/libc/locale/ldpart.c  buffer overflow
Date: Sat, 24 Apr 2004 23:21:45 -0700

 On Wed, Feb 11, 2004, moulin p wrote:
 > in /usr/src/lib/libc/locale/ldpart.c
 >  - *locale_buf was tested without prior checked if locale_buf 
 >    was NULL or not => sigvec under certain circumstances.
 
 If you look at the callers of this (private) function, you'll
 notice that this can't happen.  Although locale_buf can be a
 pointer to NULL, it is never NULL itself.
 
 >  - a strchr was used on an non '\0' terminated buffer => crash
 
 This appears to be a legitimate concern.  Moreover, it appears
 that split_lines() may write a '\0' one byte beyond the end of the
 buffer.  I've CC'd the original author and ache@, and hopefully
 one of them will take care of the problems.
 
 > in /usr/src/lib/libc/locale/srune.c (with gcc's -Werror flag)
 >   - memcpy needs <string.h> to be properly prototyped.
 > 
 > in /usr/src/lib/libc/locale/wcstold.c (with gcc's -Werror flag)
 >  - two unused variables.
 
 It looks like these were already fixed.
State-Changed-From-To: open->closed 
State-Changed-By: tjr 
State-Changed-When: Tue Aug 24 04:57:09 GMT 2004 
State-Changed-Why:  
Patch committed to -current and -stable a while ago by ache@; thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=62694 
>Unformatted:
