locale: Fix for too small buffers

Vitaliy Margolen wine-devel at kievinfo.com
Sat Dec 13 12:03:49 CST 2003


Found yet one more case with heap corruption:

=>0 0x401c2369 (HEAP_CreateFreeBlock+0x104(subheap=0x40300000, ptr=0x40364b78, size=0xb488) [heap.c:429] in NTDLL.DLL) (ebp=408dfc14)
  1 0x401c242a (HEAP_MakeInUseBlockFree+0x7d(subheap=0x40300000, pArena=0x40364b78) [heap.c:466] in NTDLL.DLL) (ebp=408dfc3c)
  2 0x401c3c30 (RtlFreeHeap+0x12a(heap=0x40300000, flags=0x2, ptr=0x40364b80) [heap.c:1202] in NTDLL.DLL) (ebp=408dfc68)
  3 0x4047d7bc (HeapFree+0x1e(heap=0x40300000, flags=0x0, ptr=0x40364b80) [heap.c:284] in KERNEL32.DLL) (ebp=408dfc80)
  4 0x4048bef9 (get_registry_locale_info+0x25e(flags=0x0, value=0x40512302, buffer=0x0, len=0x0) [locale.c:822] in KERNEL32.DLL) (ebp=408dfcc8)
  5 0x4048c15c (GetLocaleInfoW+0xec(lcid=0x419, lctype=0x28, buffer=0x0, len=0x0) [locale.c:933] in KERNEL32.DLL) (ebp=408dfd20)
  6 0x4048bf5b (GetLocaleInfoA+0x54(lcid=0x419, lctype=0x28, buffer=0x408dfd70, len=0x100) [locale.c:859] in KERNEL32.DLL) (ebp=408dfd50)

The heap corruption happens here:
  ((WCHAR *)info->Data)[ret] = '\0';

Should we move it somewhere else? Because in this case this is the only one
thing, that's being executed (it's not a number nor buffer is set).

BTW reading MSDN it's clearly stated, that:
"lpLCData
    [out] Pointer to a buffer that receives the requested data. This pointer is
    not used if cchData is zero."

Why are we using !buffer as an indication for this not the !len ?

I'm not sure if I want to submit a patch for this. There few things that I don't
feel comfortable about. Attached is something that fixed the problem for me. But
I have a gut feeling this function needs to be redone.



Friday, December 5, 2003, 9:29:34 AM, you wrote:

> Yep that is the problem I was seeing with one program I'm running. And this
> patch took care of it. Thanks!

> Vitaliy Margolen

> Tuesday, December 2, 2003, 13:01:18, Vitaliy Margolen wrote:

>> Hi, found a problem with the latest locale changes. When it calls the 
>> GetLocaleInfoW() function, the attached error occurs.

>> This occurred because of the new code using the LOCALE_RETURN_NUMBER flag. The
>> problem is if the buffer supplied to get_registry_locale_info is quite small 
>> (say sizeof(INT)). The value returned by NtQueryValueKey() however, is for a 
>> string, and is much longer. As NtQueryValueKey updates the value of size, 
>> this caused other parts of the code to corrupt memory.
-------------- next part --------------
Index: locale.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/locale.c,v
retrieving revision 1.27
diff -u -r1.27 locale.c
--- locale.c	1 Dec 2003 22:46:19 -0000	1.27
+++ locale.c	13 Dec 2003 17:52:11 -0000
@@ -742,6 +742,7 @@
 static INT get_registry_locale_info( UINT flags, LPCWSTR value, LPWSTR buffer, INT len )
 {
     DWORD size;
+    DWORD resultSize;
     INT ret;
     HKEY hkey;
     NTSTATUS status;
@@ -761,8 +762,9 @@
         return 0;
     }
 
-    status = NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, info, size, &size );
+    status = NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, info, size, &resultSize );
     if (status == STATUS_BUFFER_OVERFLOW && !buffer) status = 0;
+    if (!(flags & LOCALE_RETURN_NUMBER)) size = info_size + resultSize;
 
     if (!status)
     {
@@ -772,7 +774,8 @@
         {
             if (ret < len || !buffer)
             {
-                ((WCHAR *)info->Data)[ret] = '\0';
+                if (buffer)
+		    ((WCHAR *)info->Data)[ret] = '\0';
                 ret++;
             }
             else


More information about the wine-devel mailing list