bin/52691: str[n][case]cmp may cause segmentation violation with NULL pointers passed

Seva Gluschenko gvs at rinet.ru
Mon May 26 04:40:19 PDT 2003


>Number:         52691
>Category:       bin
>Synopsis:       str[n][case]cmp may cause segmentation violation with NULL pointers passed
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon May 26 04:40:17 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Seva Gluschenko
>Release:        FreeBSD 4.8-RC i386
>Organization:
JSC Demos-Internet
>Environment:
System: FreeBSD road.demos.su 4.8-RC FreeBSD 4.8-RC #2: Tue Mar 4 15:43:13 MSK 2003 gvs at road.demos.su:/usr/local/obj/usr/local/src/sys/ROAD i386


	
>Description:
	Using libc's implementation of case-insensitive string comparison (str[n][case]cmp)
	is possible to have the segmentation violation because NULL pointers aren't checked
	and *p++ is used blindly. Any occasional call to these functions with one of string
	pointers is equal to NULL may catch signal 11 and cause program to die.
>How-To-Repeat:

	create the simplest test:

#include <string.h>

int main() {

	char *s1 = NULL, *s2 = NULL;

	return strcmp(s1, s2);
}

	> gcc -o test test.c
	> ./test
	Segmentation fault (core dumped)
>Fix:
	Apply patch below, rebuild and reinstall libc. Don't use
	str[n][case]cmp from libc until it's fixed unless you want your
	projects to die unexpectedly.

--- /usr/src/lib/libc/string/strcmp.c.orig	Mon May 26 15:35:59 2003
+++ /usr/src/lib/libc/string/strcmp.c	Mon May 26 15:37:05 2003
@@ -52,6 +52,8 @@
 strcmp(s1, s2)
 	register const char *s1, *s2;
 {
+	if (s1 == NULL || s2 == NULL)
+		return (0);
 	while (*s1 == *s2++)
 		if (*s1++ == 0)
 			return (0);
--- /usr/src/lib/libc/string/strncmp.c.orig	Mon May 26 15:35:52 2003
+++ /usr/src/lib/libc/string/strncmp.c	Mon May 26 15:36:36 2003
@@ -48,7 +48,7 @@
 	register size_t n;
 {
 
-	if (n == 0)
+	if (n == 0 || s1 == NULL || s2 == NULL)
 		return (0);
 	do {
 		if (*s1 != *s2++)
--- /usr/src/lib/libc/string/strcasecmp.c.orig	Mon May 26 15:01:42 2003
+++ /usr/src/lib/libc/string/strcasecmp.c	Mon May 26 15:03:54 2003
@@ -49,6 +49,7 @@
 strcasecmp(s1, s2)
 	const char *s1, *s2;
 {
+    if (s1 != NULL || s2 != NULL) {
 	register const u_char
 			*us1 = (const u_char *)s1,
 			*us2 = (const u_char *)s2;
@@ -57,6 +58,9 @@
 		if (*us1++ == '\0')
 			return (0);
 	return (tolower(*us1) - tolower(*--us2));
+    }
+    return 0;
+
 }
 
 int
@@ -64,7 +68,7 @@
 	const char *s1, *s2;
 	register size_t n;
 {
-	if (n != 0) {
+	if (s1 != NULL && s2 != NULL && n != 0) {
 		register const u_char
 				*us1 = (const u_char *)s1,
 				*us2 = (const u_char *)s2;
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list