From 0f994de2f29baf608f4addc841acd31fd7f6f3c6 Mon Sep 17 00:00:00 2001 From: Keith Marshall Date: Sat, 11 May 2013 20:17:42 +0100 Subject: [PATCH] Avoid a potential SIGSEGV crash on CRT start-up. --- ChangeLog | 13 +++++++++++++ src/libcrt/crt/init.c | 22 ++++++---------------- src/libcrt/misc/glob.c | 19 ++++++++++++++++--- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index ef61b49..d095d98 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2013-05-11 Keith Marshall + Avoid a potential SIGSEGV crash on CRT start-up. + + * src/libcrt/misc/glob.c (glob_signed): Check only for pointer + aliasing, when validating a glob_t signature; checking signature + content via an uninitialised pointer may segfault. + + * src/libcrt/crt/init.c (__mingw_setargv): Call __mingw_glob() + directly, then set GLOB_APPEND for later calls; do not delegate to... + (do_glob): ...this; it uselessly attempted to set GLOB_APPEND on the + basis of an uninitialised counter. Function now unused; delete it. + +2013-05-11 Keith Marshall + Install non-executable files with proper attributes. * Makefile.in (INSTALL_DATA): New macro; define it per AC_SUBST; diff --git a/src/libcrt/crt/init.c b/src/libcrt/crt/init.c index d452763..46a7646 100644 --- a/src/libcrt/crt/init.c +++ b/src/libcrt/crt/init.c @@ -1,6 +1,6 @@ /** * @file init.c - * Copyright (C) 2012 MinGW.org project + * Copyright (C) 1997-1999, 2004, 2012-2013, MinGW.org Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -30,7 +30,7 @@ * Updated by Mumit Khan , * Earnie Boyd , and * Keith Marshall - * Copyright (C) 1997, 1998, 1999, 2004, 2012, MinGW Project + * Copyright (C) 1997-1999, 2004, 2012-2013, MinGW.org Project * * This file was formerly #included by both crt1.c and dllcrt1.c; * it is now used only by crt1.c @@ -70,18 +70,6 @@ extern void __getmainargs( int *, char ***, char ***, int, _startupinfo * ); #define ARGV_NOGROUP __CRT_GLOB_BRACKET_GROUPS__ ARGV_INLINE -int do_glob( const char *pattern, int flags, int (*errfn)(), glob_t *gl_buf ) -{ - /* Helper used by the MinGW replacement command line globbing handler, - * to invoke the glob() function, while ensuring that the GLOB_APPEND - * option is enabled at the appropriate time. - */ - if( gl_buf->gl_pathc > 0 ) - flags |= GLOB_APPEND; - return __mingw_glob( pattern, flags, errfn, gl_buf ); -} - -ARGV_INLINE char *backslash( int count, char *buf ) { /* Helper used by the MinGW replacement command line globbing handler, @@ -223,7 +211,8 @@ void __mingw_setargv( const char *cmdline ) * now add it to the globbed argument vector. */ *argptr = '\0'; - do_glob( argptr = cmdbuf, gl_opts, NULL, &gl_argv ); + __mingw_glob( argptr = cmdbuf, gl_opts, NULL, &gl_argv ); + gl_opts |= GLOB_APPEND; gotarg = 0; } } @@ -249,7 +238,8 @@ void __mingw_setargv( const char *cmdline ) /* ...and add any final pending argument to the globbed vector. */ *argptr = '\0'; - do_glob( argptr = cmdbuf, gl_opts, NULL, &gl_argv ); + __mingw_glob( argptr = cmdbuf, gl_opts, NULL, &gl_argv ); + gl_opts |= GLOB_APPEND; } /* ...and store the resultant globbed vector into the "argc" and "argv" * variables to be passed to main(); note that this allows us to safely diff --git a/src/libcrt/misc/glob.c b/src/libcrt/misc/glob.c index f4d04ae..a41c620 100644 --- a/src/libcrt/misc/glob.c +++ b/src/libcrt/misc/glob.c @@ -1,6 +1,6 @@ /** * @file glob.c - * Copyright (C) 2012 MinGW.org project. + * Copyright (C) 2011-2013, MinGW.org project. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -27,7 +27,7 @@ * globfree() API functions. * * Written by Keith Marshall - * Copyright (C) 2011, 2012, MinGW Project. + * Copyright (C) 2011-2013, MinGW.org Project. * --------------------------------------------------------------------------- */ #include @@ -936,8 +936,21 @@ GLOB_INLINE int glob_signed( const char *check, const char *magic ) /* Inline helper function, used exclusively by the glob_registry() * function, to confirm that the gl_magic field within a glob_t data * structure has been set, to indicate a properly initialised state. + * + * FIXME: we'd like to be able to verify the content at "check" + * against the signature at "magic", but "check" is likely to be + * an uninitialised pointer, and MS-Windows lamely crashes when the + * memory it might appear to address cannot be read. There may be a + * way we could trap, and effectively handle, the resulting access + * violation, (likely restricted to WinXP and later); in the absence + * of a suitable handler, we must restrict our check to require that + * "check" is a strict alias for "magic". This will lose, if we have + * multiple copies of "glob" loaded via distinct DLLs, and we pass a + * "glob_t" entity which has been initialised in one DLL across the + * boundary of another; for now, however, checking for strict pointer + * aliasing seems to be the only reliably safe option available. */ - return (check == magic) ? 0 : (check != NULL) ? strcmp( check, magic ) : 1; + return (check == magic) ? 0 : 1; } static glob_t *glob_registry( int request, glob_t *gl_data ) -- 2.11.0