wineps.drv: Use locale aware variants _sprintf_l and _sscanf_l. (ASan)

Currently are the macros push_lc_numeric/pop_lc_numeric in place
to temporary switch locale for sprintf and sscanf calls.

This macros retrieve current locale, save it to a temporary
variable "tmplocale", in between is the call to sprintf or sscanf,
and restore the old locale from the temproary variable.

But in the second setlocale call the pointer in tmplocale gets freed.

Therefore ASan gets triggered in the third setlocale call when it
attempts to read the already freed memory.

This patch avoids this by removing this switching altogether.
This commit is contained in:
Bernhard Übelacker 2024-11-05 17:40:00 +01:00
parent 11e7024c52
commit 481ddf9798
5 changed files with 14 additions and 32 deletions

View file

@ -21,6 +21,7 @@
#include <stdarg.h>
#include <string.h>
#include <locale.h>
#include "windef.h"
#include "winbase.h"
@ -87,6 +88,7 @@ static const PSDRV_DEVMODE DefaultDevmode =
HINSTANCE PSDRV_hInstance = 0;
HANDLE PSDRV_Heap = 0;
_locale_t c_locale;
static BOOL import_ntf_from_reg(void)
{
@ -294,6 +296,7 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
PSDRV_hInstance = hinst;
DisableThreadLibraryCalls(hinst);
c_locale = _create_locale( LC_ALL, "C" );
if (__wine_init_unix_call())
return FALSE;
@ -319,6 +322,7 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
case DLL_PROCESS_DETACH:
if (reserved) break;
WINE_UNIX_CALL(unix_free_printer_info, NULL);
_free_locale( c_locale );
HeapDestroy( PSDRV_Heap );
break;
}

View file

@ -884,10 +884,7 @@ PPD *PSDRV_ParsePPD( const WCHAR *fname, HANDLE printer )
#define PIA page->ImageableArea
if(!PIA) {
PIA = HeapAlloc( PSDRV_Heap, 0, sizeof(*PIA) );
push_lc_numeric("C");
sscanf(tuple.value, "%f%f%f%f", &PIA->llx, &PIA->lly,
&PIA->urx, &PIA->ury);
pop_lc_numeric();
_sscanf_l(tuple.value, "%f%f%f%f", c_locale, &PIA->llx, &PIA->lly, &PIA->urx, &PIA->ury);
}
#undef PIA
}
@ -908,9 +905,7 @@ PPD *PSDRV_ParsePPD( const WCHAR *fname, HANDLE printer )
#define PD page->PaperDimension
if(!PD) {
PD = HeapAlloc( PSDRV_Heap, 0, sizeof(*PD) );
push_lc_numeric("C");
sscanf(tuple.value, "%f%f", &PD->x, &PD->y);
pop_lc_numeric();
_sscanf_l(tuple.value, "%f%f", c_locale, &PD->x, &PD->y);
}
#undef PD
}

View file

@ -625,9 +625,7 @@ BOOL PSDRV_WriteArc(print_ctx *ctx, INT x, INT y, INT w, INT h, double ang1,
/* Make angles -ve and swap order because we're working with an upside
down y-axis */
push_lc_numeric("C");
sprintf(buf, psarc, x, y, w, h, -ang2, -ang1);
pop_lc_numeric();
_sprintf_l(buf, psarc, c_locale, x, y, w, h, -ang2, -ang1);
return PSDRV_WriteSpool(ctx, buf, strlen(buf));
}
@ -678,16 +676,11 @@ BOOL PSDRV_WriteSetColor(print_ctx *ctx, PSCOLOR *color)
switch(color->type) {
case PSCOLOR_RGB:
push_lc_numeric("C");
sprintf(buf, pssetrgbcolor, color->value.rgb.r, color->value.rgb.g,
color->value.rgb.b);
pop_lc_numeric();
_sprintf_l(buf, pssetrgbcolor, c_locale, color->value.rgb.r, color->value.rgb.g, color->value.rgb.b);
return PSDRV_WriteSpool(ctx, buf, strlen(buf));
case PSCOLOR_GRAY:
push_lc_numeric("C");
sprintf(buf, pssetgray, color->value.gray.i);
pop_lc_numeric();
_sprintf_l(buf, pssetgray, c_locale, color->value.gray.i);
return PSDRV_WriteSpool(ctx, buf, strlen(buf));
default:
@ -786,9 +779,7 @@ BOOL PSDRV_WriteRotate(print_ctx *ctx, float ang)
{
char buf[256];
push_lc_numeric("C");
sprintf(buf, psrotate, ang);
pop_lc_numeric();
_sprintf_l(buf, psrotate, c_locale, ang);
return PSDRV_WriteSpool(ctx, buf, strlen(buf));
}

View file

@ -544,13 +544,7 @@ extern DWORD ASCII85_encode(BYTE *in_buf, DWORD len, BYTE *out_buf);
extern void passthrough_enter(print_ctx *ctx);
extern void passthrough_leave(print_ctx *ctx);
#define push_lc_numeric(x) do { \
const char *tmplocale = setlocale(LC_NUMERIC,NULL); \
setlocale(LC_NUMERIC,x);
#define pop_lc_numeric() \
setlocale(LC_NUMERIC,tmplocale); \
} while (0)
extern _locale_t c_locale;
static inline WCHAR *strdupW( const WCHAR *str )
{

View file

@ -203,11 +203,9 @@ TYPE42 *T42_download_header(print_ctx *ctx, char *ps_name,
buf = HeapAlloc(GetProcessHeap(), 0, sizeof(start) + strlen(ps_name) +
100);
push_lc_numeric("C");
sprintf(buf, start, ps_name,
_sprintf_l(buf, start, c_locale, ps_name,
(float)bbox->left / emsize, (float)bbox->bottom / emsize,
(float)bbox->right / emsize, (float)bbox->top / emsize);
pop_lc_numeric();
PSDRV_WriteSpool(ctx, buf, strlen(buf));