OSDN Git Service

Avoid a potential SIGSEGV crash on CRT start-up.
authorKeith Marshall <keithmarshall@users.sourceforge.net>
Sat, 11 May 2013 19:17:42 +0000 (20:17 +0100)
committerKeith Marshall <keithmarshall@users.sourceforge.net>
Sat, 11 May 2013 19:17:42 +0000 (20:17 +0100)
ChangeLog
src/libcrt/crt/init.c
src/libcrt/misc/glob.c

index ef61b49..d095d98 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2013-05-11  Keith Marshall  <keithmarshall@users.sourceforge.net>
 
+       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  <keithmarshall@users.sourceforge.net>
+
        Install non-executable files with proper attributes.
 
        * Makefile.in (INSTALL_DATA): New macro; define it per AC_SUBST;
index d452763..46a7646 100644 (file)
@@ -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 <khan@xraylith.wisc.edu>,
  *   Earnie Boyd <earnie@users.sourceforge.net>, and
  *   Keith Marshall <keithmarshall@users.sourceforge.net>
- * 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
index f4d04ae..a41c620 100644 (file)
@@ -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 <keithmarshall@users.sourceforge.net>
- * Copyright (C) 2011, 2012, MinGW Project.
+ * Copyright (C) 2011-2013, MinGW.org Project.
  * ---------------------------------------------------------------------------
  */
 #include <glob.h>
@@ -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 )