misc/77369: [PATCH] strnstr(3) can read beyond specified length

Ed Maste emaste at phaedrus.sandvine.ca
Thu Feb 10 17:50:20 PST 2005


>Number:         77369
>Category:       misc
>Synopsis:       [PATCH] strnstr(3) can read beyond specified length
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Feb 11 01:50:19 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Ed Maste
>Release:        5.3-RELEASE-p2
>Organization:
Sandvine Inc.
>Environment:
>Description:
strstr(3) states
The strnstr() function locates the first occurrence of the null-terminated string little in the string big, where not more than len characters are searched.

(It does not explicitly mention whether string big must be null terminated or not.)  However, strnstr may actually read one character more than len if the string is not null-terminated.
>How-To-Repeat:
strnstrtest.c:
#include <stdio.h>
#include <string.h>
#define PAGE_SIZE 4096
int main(int argc, char *argv[])
{
    char *str;
    char *buf=malloc(PAGE_SIZE);
    memset(buf, '-', PAGE_SIZE);
    str=strnstr(buf, "little", PAGE_SIZE);
    printf("strnstr returned %p\n", str);
}

$ cc -g strnstrtest.c -o strnstrtest
$ ./strnstrtest
Segmentation fault (core dumped)

>Fix:
--- src/lib/libc/string/strnstr.c.orig
+++ src/lib/libc/string/strnstr.c
@@ -60,7 +60,7 @@
                len = strlen(find);
                do {
                        do {
-                               if ((sc = *s++) == '\0' || slen-- < 1)
+                               if (slen-- < 1 || (sc = *s++) == '\0')
                                        return (NULL);
                        } while (sc != c);
                        if (len > slen)

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list