Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Jan 2016 22:40:10 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 206177] Out-of-bounds read in wcsncat(3)
Message-ID:  <bug-206177-8@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=206177

            Bug ID: 206177
           Summary: Out-of-bounds read in wcsncat(3)
           Product: Base System
           Version: 11.0-CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: bin
          Assignee: freebsd-bugs@FreeBSD.org
          Reporter: cherepan@mccme.ru

Created attachment 165467
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=165467&action=edit
Patch

The wcsncat function could read several bytes behind the end of its input
buffer. This could lead to a crash if the buffer happens to immediately precede
an unmapped page.

According to C11, 7.29.4.3.2, wcsncat(s1, s2, n) will append s2 to s1 but will
stop as soon as null wide char is met or n wide chars are read. In particular,
s2 is not required to be a null-terminated wide string.
(The man page[1] for wcsncat refers to the man page[2] for strncat which
erroneously talks about strings only. I filed [3] about it.)

When s2 is an array containing exactly n non-null wide chars, FreeBSD
implementation of wcsncat will read one extra wide char. The code[4] for
traversing the source array:

50              r = s2;
51              while (*r && n) {
52                      *q++ = *r++;
53                      n--;
54              }

"n" in the loop controlling expression makes sure that the loop is terminated
after n chars are copied but the dereference in "*r" happens before the "n"
check. For example, there would be one dereference when n=0.
Calling the function as wcsncat(s1, NULL, 0) will crash. (Formally speaking,
passing NULL as s2 is invalid in C11, a valid crashing testcase is attached.)

To fix it, it's enough to swap the checks in the while loop (patch attached).
Or all the code could be changed to match strncat.

The issue has security consequences but the function is rarely used so severity
seems very low.

Other BSDs are affected.

[1]
https://svnweb.freebsd.org/base/head/lib/libc/string/wmemchr.3?revision=251069&view=markup
[2]
https://svnweb.freebsd.org/base/head/lib/libc/string/strcat.3?revision=262890&view=markup
[3] https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=206176
[4]
https://svnweb.freebsd.org/base/head/lib/libc/string/wcsncat.c?revision=188080&view=markup#l50

-- 
You are receiving this mail because:
You are the assignee for the bug.


Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-206177-8>