Closed Bug 280522 Opened 20 years ago Closed 20 years ago

Possible Buffer overflow due to missing terminating null [windows/nsToolkit.cpp:ConvertWtoA()]

Categories

(Core :: Widget: Win32, defect)

x86
Windows XP
defect
Not set
critical

Tracking

()

RESOLVED FIXED

People

(Reporter: Franke, Assigned: dveditz)

References

Details

(Keywords: fixed-aviary1.0.1, fixed1.7.6, Whiteboard: [sg:fix] ready to land)

Attachments

(3 files)

User-Agent:       Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.8a5) Gecko/20041122
Build Identifier: Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.8a5) Gecko/20041122

windows/nsToolkit.cpp:ConvertWtoA() does not append a null byte if the string
exceeds buffer size.

Win32 function WideCharToMultiByte() returns 0 on buffer overflow, but fills the
buffer to the end, without trailing null byte. This behaviour is undocumented in
Win32 API documentation.


Reproducible: Always

Steps to Reproduce:
1. Call ConvertWtoA() with a too small buffer, e.g. via a call to
nsWindow::SetTitle("some string exceeding 127 chars")
2. Examine returned string, e.g. see Bug 244674 for a visible result.
Actual Results:  
ConvertWtoA() produces a non-null terminated string, and all 16 call sites do
not check the return value.

Expected Results:  
ConvertWToA() should always produce a null terminated string, or call sites
should check for return value 0.

This is the reason for Bug 244674.

Missing trailing null byte may lead to a buffer overflow in further processing.
=> Setting Security flag.
Note that ConvertWToA() returns 0 even if the output string fits exactly
(size==11).
The extra null Termination by ConvertWtoA() in the non-overflow case is not
necessary. WideCharToMultiByte() returns #bytes *including* terminating null.
Added missing trailing null on overflow. Kept adding extra null in non-overflow
case, don't know if this is necessary.

Also fixes passing a too small buffersize (MAX_CLASS_NAME instead of MAX_PATH)
in nsSendMessage(). The small size (<160) resulted in visibility of this bug in
window title (bug 244674).
Attachment #172962 - Flags: review?(win32)
Similar problem setting menu items
http://lxr.mozilla.org/mozilla/source/xpfe/bootstrap/nsNativeAppSupportWin.cpp#117

I don't see any actual overflow--something that *writes* outside the buffer--but
clearly extra garbage is getting included in strings sent to windows.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: blocking1.7.6?
Flags: blocking-aviary1.1?
Flags: blocking-aviary1.0.1?
Whiteboard: [sg:fix]
Comment on attachment 172962 [details] [diff] [review]
Patch for ConvertWtoA() and nsSendMessage()

r=dveditz
Attachment #172962 - Flags: superreview?(dbaron)
Attachment #172962 - Flags: review?(win32)
Attachment #172962 - Flags: review+
Attachment #172962 - Flags: approval1.7.6?
Attachment #172962 - Flags: approval-aviary1.0.1?
Never mind comment about GetACPString(), missed the equals in 'outlen >= 0': if
the converted string is too long we'll end up with an empty string. Since
WideCharToMultiByte never returns negative the check is kind of pointless.
Flags: blocking-aviary1.1? → blocking-aviary1.1+
Attachment #172962 - Flags: superreview?(dbaron) → superreview+
Assignee: win32 → dveditz
Flags: blocking1.7.6?
Flags: blocking1.7.6+
Flags: blocking-aviary1.0.1?
Flags: blocking-aviary1.0.1+
(In reply to comment #5)
> Never mind comment about GetACPString(), missed the equals ...
> ...WideCharToMultiByte never returns negative the check is kind of pointless.

Even worse: Unlike ConvertWtoA(), GetACPString() definitely has a write behind
buffer issue: WideCharToMultibyte() returns the chars written, not the string
length. On exact fit, outlen == acplen => acp[acplen] = '\0' => *Overflow*

Suggest at least the following quick fix (untested blind patch, sorry):

...
  if( acp ) {
    int outlen = ::WideCharToMultiByte( CP_ACP, 0, aStr.get(),aStr.Length(),
                                        acp, acplen, NULL, NULL );
-   if ( outlen >= 0)
-     acp[ outlen ] = '\0';  // null terminate
+   if (outlen == 0)
+     acp[acplen-1] = '\0';  // null terminate on overflow
   }

This does not handle other conversion errors correctly, but avoids overflow.
Again note that null termination is not necessary in the non-overflow case.
The null termination is necessary because they're not converting the null in
WideCharToMultiByte. We could change that and go more your way, or just do
this.
Attachment #173302 - Flags: superreview?(bzbarsky)
Attachment #173302 - Flags: review?(bzbarsky)
Attachment #173302 - Flags: approval1.7.6?
Attachment #173302 - Flags: approval-aviary1.0.1?
Comment on attachment 173302 [details] [diff] [review]
fix GetACPString()

No, this is wrong.  What happens for negative values of outlen?

Maybe you want to null terminate at PR_MAX(0, outlen) ?
Attachment #173302 - Flags: superreview?(bzbarsky)
Attachment #173302 - Flags: superreview-
Attachment #173302 - Flags: review?(bzbarsky)
Attachment #173302 - Flags: review-
Comment on attachment 172962 [details] [diff] [review]
Patch for ConvertWtoA() and nsSendMessage()

a=mkaply for both
Attachment #172962 - Flags: approval1.7.6?
Attachment #172962 - Flags: approval1.7.6+
Attachment #172962 - Flags: approval-aviary1.0.1?
Attachment #172962 - Flags: approval-aviary1.0.1+
Comment on attachment 173302 [details] [diff] [review]
fix GetACPString()

Never mind me.	I misunderstood the patch.  r+sr=bzbarsky
Attachment #173302 - Flags: superreview-
Attachment #173302 - Flags: superreview+
Attachment #173302 - Flags: review-
Attachment #173302 - Flags: review+
Comment on attachment 173302 [details] [diff] [review]
fix GetACPString()

a=chofmann for the branches
Attachment #173302 - Flags: approval1.7.6?
Attachment #173302 - Flags: approval1.7.6+
Attachment #173302 - Flags: approval-aviary1.0.1?
Attachment #173302 - Flags: approval-aviary1.0.1+
(In reply to comment #7)
> Created an attachment (id=173302) [edit]
> ... We could change that and go more your way, or just do this.

Looks good ;-)
BTW: Could you possibly give me access (add as CC:) to the dependent Bugs?
> BTW: Could you possibly give me access (add as CC:) to the dependent Bugs?

They're completely unrelated, just tracking bugs predating the creation of the
blocking-aviary1.0.1 flag.
Whiteboard: [sg:fix] → [sg:fix] ready to land
Landed on trunk
Status: NEW → RESOLVED
Closed: 20 years ago
Resolution: --- → FIXED
Group: security
*** Bug 244674 has been marked as a duplicate of this bug. ***
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: