public inbox for cygwin-cvs@sourceware.org
help / color / mirror / Atom feed
From: Corinna Vinschen <corinna@sourceware.org>
To: cygwin-cvs@sourceware.org
Subject: [newlib-cygwin] Cygwin: fix buffer overrun in cygwin_strcasecmp
Date: Mon,  6 Jul 2020 11:18:18 +0000 (GMT)	[thread overview]
Message-ID: <20200706111818.CDE263858D35@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=bb96bd03b0b9be5ed63127771687ac4877092ef8

commit bb96bd03b0b9be5ed63127771687ac4877092ef8
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Mon Jul 6 13:17:53 2020 +0200

    Cygwin: fix buffer overrun in cygwin_strcasecmp
    
    sys_mbstowcs is called with the destination buffer length
    set to MaximumLength from the receiving UNICODE_STRING buffer.
    This is twice as much as the actual size of the buffer in
    wchar_t units, which is the unit expected by sys_mbstowcs.
    
    sys_mbstowcs always attaches a NUL, within the destination
    buffersize given.  But if the string is exactly one wchar_t
    less than the actual buffer, and the buffersize is given too
    large, sys_mbstowcs writes a NUL one wchar_t beyond the buffer.
    
    This has only been exposed with Cygwin 3.1.5 because alloca
    on newer gcc 9 apparently allocates more tightly.  The alloca
    buffer here is requested with 16 bytes, which is exactly the
    number of bytes required for the string L"cmd.exe".  Older gcc
    apparently allocated a few more bytes on the stack, while gcc 9
    allocates in 16 byte granularity...
    
    Fix this by giving the correct destination buffer size to
    sys_mbstowcs.
    
    Fixes: https://cygwin.com/pipermail/cygwin/2020-June/245226.html
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/release/3.1.6 |  3 +++
 winsup/cygwin/strfuncs.cc   | 34 ++++++++++++++++++++--------------
 2 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/winsup/cygwin/release/3.1.6 b/winsup/cygwin/release/3.1.6
index d64ee4c92..e06c0bc9a 100644
--- a/winsup/cygwin/release/3.1.6
+++ b/winsup/cygwin/release/3.1.6
@@ -9,3 +9,6 @@ Bug Fixes:
 ----------
 
 - Fix IPPROTO_TCP option handling, especially in terms of TCP_MAXSEG.
+
+- Fix a buffer overrun in Cygwin-internal string comparison.
+  Fixes: https://cygwin.com/pipermail/cygwin/2020-June/245226.html
diff --git a/winsup/cygwin/strfuncs.cc b/winsup/cygwin/strfuncs.cc
index e0a4c7182..604d7611c 100644
--- a/winsup/cygwin/strfuncs.cc
+++ b/winsup/cygwin/strfuncs.cc
@@ -635,7 +635,7 @@ sys_cp_mbstowcs (mbtowc_p f_mbtowc, wchar_t *dst, size_t dlen,
 	  /* The technique is based on a discussion here:
 	     http://www.mail-archive.com/linux-utf8@nl.linux.org/msg00080.html
 
-	     Invalid bytes in a multibyte secuence are converted to
+	     Invalid bytes in a multibyte sequence are converted to
 	     the private use area which is already used to store ASCII
 	     chars invalid in Windows filenames.  This technque allows
 	     to store them in a symmetric way. */
@@ -801,14 +801,18 @@ extern "C" int __stdcall
 cygwin_strcasecmp (const char *cs, const char *ct)
 {
   UNICODE_STRING us, ut;
-  ULONG len;
-
-  len = (strlen (cs) + 1) * sizeof (WCHAR);
-  RtlInitEmptyUnicodeString (&us, (PWCHAR) alloca (len), len);
-  us.Length = sys_mbstowcs (us.Buffer, us.MaximumLength, cs) * sizeof (WCHAR);
-  len = (strlen (ct) + 1) * sizeof (WCHAR);
-  RtlInitEmptyUnicodeString (&ut, (PWCHAR) alloca (len), len);
-  ut.Length = sys_mbstowcs (ut.Buffer, ut.MaximumLength, ct) * sizeof (WCHAR);
+  ULONG len, ulen;
+
+  len = strlen (cs) + 1;
+  ulen = len * sizeof (WCHAR);
+  RtlInitEmptyUnicodeString (&us, (PWCHAR) alloca (ulen), ulen);
+  us.Length = sys_mbstowcs (us.Buffer, len, cs) * sizeof (WCHAR);
+
+  len = strlen (ct) + 1;
+  ulen = len * sizeof (WCHAR);
+  RtlInitEmptyUnicodeString (&ut, (PWCHAR) alloca (ulen), ulen);
+  ut.Length = sys_mbstowcs (ut.Buffer, len, ct) * sizeof (WCHAR);
+
   return RtlCompareUnicodeString (&us, &ut, TRUE);
 }
 
@@ -816,19 +820,21 @@ extern "C" int __stdcall
 cygwin_strncasecmp (const char *cs, const char *ct, size_t n)
 {
   UNICODE_STRING us, ut;
-  ULONG len;
+  ULONG ulen;
   size_t ls = 0, lt = 0;
 
   while (cs[ls] && ls < n)
     ++ls;
-  len = (ls + 1) * sizeof (WCHAR);
-  RtlInitEmptyUnicodeString (&us, (PWCHAR) alloca (len), len);
+  ulen = (ls + 1) * sizeof (WCHAR);
+  RtlInitEmptyUnicodeString (&us, (PWCHAR) alloca (ulen), ulen);
   us.Length = sys_mbstowcs (us.Buffer, ls + 1, cs, ls) * sizeof (WCHAR);
+
   while (ct[lt] && lt < n)
     ++lt;
-  len = (lt + 1) * sizeof (WCHAR);
-  RtlInitEmptyUnicodeString (&ut, (PWCHAR) alloca (len), len);
+  ulen = (lt + 1) * sizeof (WCHAR);
+  RtlInitEmptyUnicodeString (&ut, (PWCHAR) alloca (ulen), ulen);
   ut.Length = sys_mbstowcs (ut.Buffer, lt + 1, ct, lt)  * sizeof (WCHAR);
+
   return RtlCompareUnicodeString (&us, &ut, TRUE);
 }


                 reply	other threads:[~2020-07-06 11:18 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200706111818.CDE263858D35@sourceware.org \
    --to=corinna@sourceware.org \
    --cc=cygwin-cvs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).