From 7a4078ee340b7f15c839257d6fa895d92abe0224 Mon Sep 17 00:00:00 2001
From: Christopher Faylor <me@cgf.cx>
Date: Thu, 28 Jun 2001 02:19:57 +0000
Subject: [PATCH] Change check_null_empty_path* to check_null_empty_str*
 throughout. * path.cc (path_conv::check): Add signal protection here since
 retrieving info about remote shares can take some time. * path.h
 (check_null_empty_str_errno): Convert to a function prototype. * path.cc
 (check_null_empty_str): Move to miscfuncs.cc. * miscfuncs.cc
 (check_null_empty_str_errno): New function. (__check_null_invalid_struct):
 Ditto. (__check_null_invalid_struct_errno): Ditto. (check_null_empty_str):
 Change from VirtualQuery to IsBadWritePtr. * thread.cc (check_valid_pointer):
 Ditto. * resource.cc (getrlimit): Use check_null_invalid_struct macro for
 checking validity of pointer. (setrlimit): Ditto.

---
 winsup/cygwin/ChangeLog     | 20 ++++++++++++++++++
 winsup/cygwin/environ.cc    |  6 +++---
 winsup/cygwin/exceptions.cc |  2 +-
 winsup/cygwin/miscfuncs.cc  | 41 +++++++++++++++++++++++++++++++++++++
 winsup/cygwin/path.cc       | 29 ++++++--------------------
 winsup/cygwin/path.h        | 10 ---------
 winsup/cygwin/resource.cc   | 16 ++++-----------
 winsup/cygwin/syscalls.cc   |  4 ++--
 winsup/cygwin/thread.cc     |  4 +---
 winsup/cygwin/winsup.h      | 10 +++++++++
 10 files changed, 88 insertions(+), 54 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index a04141e66..0aa24996d 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,23 @@
+Wed Jun 27 22:19:07 2001  Christopher Faylor <cgf@cygnus.com>
+
+	* path.cc (path_conv::check): Add signal protection here since
+	retrieving info about remote shares can take some time.
+
+Wed Jun 27 23:30:00 2001  Robert Collins <rbtcollins@hotmail.com>
+                          Christopher Faylor <cgf@cygnus.com>
+   
+	Change check_null_empty_path* to check_null_empty_str* throughout.
+	* path.h (check_null_empty_str_errno): Convert to a function prototype.
+	* path.cc (check_null_empty_str): Move to miscfuncs.cc.
+	* miscfuncs.cc (check_null_empty_str_errno): New function.
+	(__check_null_invalid_struct): Ditto.
+	(__check_null_invalid_struct_errno): Ditto.
+	(check_null_empty_str): Change from VirtualQuery to IsBadWritePtr.
+	* thread.cc (check_valid_pointer): Ditto.
+	* resource.cc (getrlimit): Use check_null_invalid_struct macro for
+	checking validity of pointer.
+	(setrlimit): Ditto.
+
 Tue Jun 26 16:59:16 2001  Christopher Faylor <cgf@cygnus.com>
 
 	* fhandler.cc (fhandler_disk_file::fstat): Don't rely on exactly 3
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index 47de60a51..1135bfbba 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -290,7 +290,7 @@ extern "C" int
 putenv (const char *str)
 {
   int res;
-  if ((res = check_null_empty_path (str)))
+  if ((res = check_null_empty_str (str)))
     {
       if (res == ENOENT)
 	return 0;
@@ -312,12 +312,12 @@ extern "C" int
 setenv (const char *name, const char *value, int overwrite)
 {
   int res;
-  if ((res = check_null_empty_path (value)) == EFAULT)
+  if ((res = check_null_empty_str (value)) == EFAULT)
     {
       set_errno (res);
       return  -1;
     }
-  if ((res = check_null_empty_path (name)))
+  if ((res = check_null_empty_str (name)))
     {
       if (res == ENOENT)
 	return 0;
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index cc69497b5..3c9198475 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -638,8 +638,8 @@ interruptible (DWORD pc, int testvalid = 0)
   else
     res = !strncasematch (windows_system_directory, checkdir,
 			  windows_system_directory_length);
+  sigproc_printf ("pc %p, h %p, interruptible %d, testvalid %d", pc, h, res, testvalid);
 # undef h
-  sigproc_printf ("h %p, interruptible %d", res);
   return res;
 }
 
diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc
index d66c22549..49e7cebd9 100644
--- a/winsup/cygwin/miscfuncs.cc
+++ b/winsup/cygwin/miscfuncs.cc
@@ -9,6 +9,8 @@ Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 details. */
 
 #include "winsup.h"
+#include "cygerrno.h"
+#include <sys/errno.h>
 
 /********************** String Helper Functions ************************/
 
@@ -112,3 +114,42 @@ strcasestr (const char *searchee, const char *lookfor)
 
   return NULL;
 }
+
+int __stdcall
+check_null_empty_str (const char *name)
+{
+  if (!name || IsBadStringPtr (name, MAX_PATH))
+    return EFAULT;
+
+  if (!*name)
+    return ENOENT;
+
+  return 0;
+}
+
+int __stdcall
+check_null_empty_str_errno (const char *name)
+{ 
+  int __err; 
+  if ((__err = check_null_empty_str (name))) 
+    set_errno (__err); 
+  return __err; 
+}
+
+int __stdcall
+__check_null_invalid_struct (const void *s, unsigned sz)
+{
+  if (!s || IsBadWritePtr ((void *) s, sz))
+    return EFAULT;
+
+  return 0;
+}
+
+int __stdcall
+__check_null_invalid_struct_errno (const void *s, unsigned sz)
+{ 
+  int __err; 
+  if ((__err = __check_null_invalid_struct (s, sz))) 
+    set_errno (__err); 
+  return __err; 
+}
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 20c71f58f..8c1469470 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -376,6 +376,7 @@ path_conv::check (const char *src, unsigned opt,
   bool need_directory = 0;
   bool saw_symlinks = 0;
   int is_relpath;
+  sigframe thisframe (mainthread);
 
 #if 0
   static path_conv last_path_conv;
@@ -403,7 +404,7 @@ path_conv::check (const char *src, unsigned opt,
 
   if (!(opt & PC_NULLEMPTY))
     error = 0;
-  else if ((error = check_null_empty_path (src)))
+  else if ((error = check_null_empty_str (src)))
     return;
 
   /* This loop handles symlink expansion.  */
@@ -2990,13 +2991,8 @@ getwd (char *buf)
 extern "C" int
 chdir (const char *in_dir)
 {
-  int dir_error = check_null_empty_path (in_dir);
-  if (dir_error)
-    {
-      syscall_printf ("NULL or invalid input to chdir");
-      set_errno (dir_error);
-      return -1;
-    }
+  if (check_null_empty_str_errno (in_dir))
+    return -1;
 
   syscall_printf ("dir '%s'", in_dir);
 
@@ -3141,7 +3137,7 @@ extern "C"
 int
 cygwin_conv_to_posix_path (const char *path, char *posix_path)
 {
-  if (check_null_empty_path_errno (path))
+  if (check_null_empty_str_errno (path))
     return -1;
   mount_table->conv_to_posix_path (path, posix_path, 1);
   return 0;
@@ -3151,7 +3147,7 @@ extern "C"
 int
 cygwin_conv_to_full_posix_path (const char *path, char *posix_path)
 {
-  if (check_null_empty_path_errno (path))
+  if (check_null_empty_str_errno (path))
     return -1;
   mount_table->conv_to_posix_path (path, posix_path, 0);
   return 0;
@@ -3354,19 +3350,6 @@ cygwin_split_path (const char *path, char *dir, char *file)
   file[end - last_slash - 1] = 0;
 }
 
-int __stdcall
-check_null_empty_path (const char *name)
-{
-  MEMORY_BASIC_INFORMATION m;
-  if (!name || !VirtualQuery (name, &m, sizeof (m)) || (m.State != MEM_COMMIT))
-    return EFAULT;
-
-  if (!*name)
-    return ENOENT;
-
-  return 0;
-}
-
 /*****************************************************************************/
 
 /* Return the hash value for the current win32 value.
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index b72a20c14..a3e94c18f 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -150,21 +150,11 @@ class path_conv
 
 int __stdcall get_device_number (const char *name, int &unit, BOOL from_conv = FALSE)  __attribute__ ((regparm(3)));
 int __stdcall slash_unc_prefix_p (const char *path) __attribute__ ((regparm(1)));
-int __stdcall check_null_empty_path (const char *name) __attribute__ ((regparm(1)));
 
 const char * __stdcall find_exec (const char *name, path_conv& buf, const char *winenv = "PATH=",
 			int null_if_notfound = 0, const char **known_suffix = NULL)  __attribute__ ((regparm(3)));
 
 /* Common macros for checking for invalid path names */
-
-#define check_null_empty_path_errno(src) \
-({ \
-  int __err; \
-  if ((__err = check_null_empty_path(src))) \
-    set_errno (__err); \
-  __err; \
-})
-
 #define isdrive(s) (isalpha (*(s)) && (s)[1] == ':')
 
 static inline bool
diff --git a/winsup/cygwin/resource.cc b/winsup/cygwin/resource.cc
index fbd335ae6..c56fb77fd 100644
--- a/winsup/cygwin/resource.cc
+++ b/winsup/cygwin/resource.cc
@@ -105,12 +105,8 @@ extern "C"
 int
 getrlimit (int resource, struct rlimit *rlp)
 {
-  MEMORY_BASIC_INFORMATION m;
-  if (!rlp || !VirtualQuery (rlp, &m, sizeof (m)) || (m.State != MEM_COMMIT))
-    {
-      set_errno (EFAULT);
-      return -1;
-    }
+  if (check_null_invalid_struct_errno (rlp))
+    return -1;
 
   rlp->rlim_cur = RLIM_INFINITY;
   rlp->rlim_max = RLIM_INFINITY;
@@ -141,12 +137,8 @@ extern "C"
 int
 setrlimit (int resource, const struct rlimit *rlp)
 {
-  MEMORY_BASIC_INFORMATION m;
-  if (!rlp || !VirtualQuery (rlp, &m, sizeof (m)) || (m.State != MEM_COMMIT))
-    {
-      set_errno (EFAULT);
-      return -1;
-    }
+  if (check_null_invalid_struct_errno (rlp))
+    return -1;
 
   struct rlimit oldlimits;
 
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 8b1a41e1e..7fc972e6c 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -445,7 +445,7 @@ _open (const char *unix_path, int flags, ...)
   sigframe thisframe (mainthread);
 
   syscall_printf ("open (%s, %p)", unix_path, flags);
-  if (!check_null_empty_path_errno (unix_path))
+  if (!check_null_empty_str_errno (unix_path))
     {
       SetResourceLock (LOCK_FD_LIST, WRITE_LOCK|READ_LOCK, " open ");
 
@@ -698,7 +698,7 @@ chown_worker (const char *name, unsigned fmode, uid_t uid, gid_t gid)
   uid_t old_uid;
   gid_t old_gid;
 
-  if (check_null_empty_path_errno (name))
+  if (check_null_empty_str_errno (name))
     return -1;
 
   if (os_being_run != winNT)    // real chown only works on NT
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 26c29c3f2..3c8f16e03 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -739,9 +739,7 @@ verifyable_object::~verifyable_object ()
 int __stdcall
 check_valid_pointer (void *pointer)
 {
-  MEMORY_BASIC_INFORMATION m;
-  if (!pointer || !VirtualQuery (pointer, &m, sizeof (m))
-      || (m.State != MEM_COMMIT))
+  if (!pointer || IsBadWritePtr (pointer, sizeof (verifyable_object)))
     return EFAULT;
   return 0;
 }
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index b725f8243..8beac76e6 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -190,6 +190,16 @@ long __stdcall to_time_t (FILETIME * ptr);
 void __stdcall set_console_title (char *);
 void set_console_handler ();
 
+int __stdcall check_null_empty_str (const char *name) __attribute__ ((regparm(1)));
+int __stdcall check_null_empty_str_errno (const char *name) __attribute__ ((regparm(1)));
+int __stdcall __check_null_invalid_struct (const void *s, unsigned sz) __attribute__ ((regparm(1)));
+int __stdcall __check_null_invalid_struct_errno (const void *s, unsigned sz) __attribute__ ((regparm(1)));
+
+#define check_null_invalid_struct(s) \
+  __check_null_invalid ((s), sizeof (*(s)))
+#define check_null_invalid_struct_errno(s) \
+  __check_null_invalid_struct_errno ((s), sizeof (*(s)))
+
 #define set_winsock_errno() __set_winsock_errno (__FUNCTION__, __LINE__)
 void __set_winsock_errno (const char *fn, int ln) __attribute__ ((regparm(2)));