This is the mail archive of the cygwin-patches@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch]: sys_mount_table_counters


This patch implements a more secure method to signal that
the system mounts have changed. Instead of writing to the
cygwin shared, a flag is set directly in the mount tables
of the active users (which requires the previous patch).
It eliminates a source of DOS attack and takes a step toward
the demise of the cygwin shared.

Pierre

2004-02-06  Pierre Humblet <pierre.humblet@ieee.org>

	* path.cc (mount_info::conv_to_win32_path): Use
	sys_mount_table_update instead of the sys_mount_table_counters.
	(mount_info::send_update_sys_mounts): New.
	(mount_info::add_reg_mount): Call send_update_sys_mounts 
	instead of updating the sys_mount_table_counters.
	(mount_info::del_reg_mount): Ditto.
	(mount_info::write_cygdrive_info_to_registry): Ditto.
	(mount_info::remove_cygdrive_info_from_registry): Ditto.
	* shared_info.h (class_mountinfo::sys_mount_table_counter): Delete.
	(class_mountinfo::sys_mount_table_update): New member.
	(class_mountinfo::send_update_sys_mounts): New declaration.
	(class_mountinfo::got_update_sys_mounts): New method.
Index: path.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/path.cc,v
retrieving revision 1.286
diff -u -p -r1.286 path.cc
--- path.cc	26 Dec 2003 18:26:17 -0000	1.286
+++ path.cc	6 Feb 2004 01:42:08 -0000
@@ -74,6 +74,7 @@ details. */
 #include "registry.h"
 #include "cygtls.h"
 #include <assert.h>
+#include "pwdgrp.h"
 
 static int normalize_win32_path (const char *src, char *dst);
 static void slashify (const char *src, char *dst, int trailing_slash_p);
@@ -1321,10 +1322,10 @@ mount_info::conv_to_win32_path (const ch
 				unsigned *flags, bool no_normalize)
 {
   bool chroot_ok = !cygheap->root.exists ();
-  while (sys_mount_table_counter < cygwin_shared->sys_mount_table_counter)
+  while (sys_mount_table_update)
     {
+      sys_mount_table_update = false;
       init ();
-      sys_mount_table_counter++;
     }
   int src_path_len = strlen (src_path);
   MALLOC_CHECK;
@@ -1763,6 +1764,47 @@ mount_info::from_registry ()
   read_mounts (r1);
 }
 
+void
+mount_info::send_update_sys_mounts (unsigned int flags)
+{
+  if (!(flags & MOUNT_SYSTEM) || !wincap.has_security ())
+    return;
+
+  char map_buf[CYG_MAX_PATH], sid_string[128];
+  user_info * uid_info;
+  winpids pids;
+  cygsid sid;
+  HANDLE h;
+
+  for (unsigned i = 0; i < pids.npids; i++)
+    {
+      if (pids[i]->uid == myself->uid)
+	goto next;
+      for (unsigned j = 0; j < i; j++)
+	if (pids[i]->uid == pids[j]->uid)
+	  goto next;
+      sid.getfrompw (internal_getpwuid (pids[i]->uid));
+      if (!(sid.string (sid_string)))
+	goto next;
+      
+      if ((h = OpenFileMapping (FILE_MAP_READ|FILE_MAP_WRITE, FALSE,
+				shared_name (map_buf, sid_string, USER_VERSION)))
+	  && (uid_info = (user_info *) MapViewOfFileEx (h, 
+							FILE_MAP_READ|FILE_MAP_WRITE,
+							0, 0, 0, 0))) 
+	{
+	  debug_printf("Telling %u", pids[i]->uid);
+	  uid_info->mountinfo.got_update_sys_mounts ();
+	  UnmapViewOfFile (uid_info);
+	}
+      else
+	debug_printf("Open file mapping uid %u: %E", pids[i]->uid);
+      if (h)
+	CloseHandle (h);
+    next: ;
+    }
+}
+
 /* add_reg_mount: Add mount item to registry.  Return zero on success,
    non-zero on failure. */
 /* FIXME: Need a mutex to avoid collisions with other tasks. */
@@ -1820,11 +1862,9 @@ mount_info::add_reg_mount (const char *n
       if (res != ERROR_SUCCESS)
 	goto err;
       res = subkey.set_int ("flags", mountflags);
-
-      sys_mount_table_counter++;
-      cygwin_shared->sys_mount_table_counter++;
     }
 
+  send_update_sys_mounts (mountflags);
   return 0; /* Success */
  err:
   __seterrno_from_win_error (res);
@@ -1849,8 +1889,6 @@ mount_info::del_reg_mount (const char * 
     }
   else					/* Delete from system registry */
     {
-      sys_mount_table_counter++;
-      cygwin_shared->sys_mount_table_counter++;
       reg_key reg_sys (HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS, "SOFTWARE",
 		       CYGWIN_INFO_CYGNUS_REGISTRY_NAME, CYGWIN_REGNAME,
 		       CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME,
@@ -1864,6 +1902,7 @@ mount_info::del_reg_mount (const char * 
       return -1;
     }
 
+  send_update_sys_mounts (flags);
   return 0; /* Success */
 }
 
@@ -1914,12 +1953,6 @@ mount_info::write_cygdrive_info_to_regis
   /* Determine whether to modify user or system cygdrive path prefix. */
   HKEY top = (flags & MOUNT_SYSTEM) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
 
-  if (flags & MOUNT_SYSTEM)
-    {
-      sys_mount_table_counter++;
-      cygwin_shared->sys_mount_table_counter++;
-    }
-
   /* reg_key for user path prefix in HKEY_CURRENT_USER or system path prefix in
      HKEY_LOCAL_MACHINE.  */
   reg_key r (top, KEY_ALL_ACCESS, "SOFTWARE",
@@ -1961,6 +1994,7 @@ mount_info::write_cygdrive_info_to_regis
       mount_table->cygdrive_len = strlen (mount_table->cygdrive);
     }
 
+  send_update_sys_mounts (flags);
   return 0;
 }
 
@@ -1970,12 +2004,6 @@ mount_info::remove_cygdrive_info_from_re
   /* Determine whether to modify user or system cygdrive path prefix. */
   HKEY top = (flags & MOUNT_SYSTEM) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
 
-  if (flags & MOUNT_SYSTEM)
-    {
-      sys_mount_table_counter++;
-      cygwin_shared->sys_mount_table_counter++;
-    }
-
   /* reg_key for user path prefix in HKEY_CURRENT_USER or system path prefix in
      HKEY_LOCAL_MACHINE.  */
   reg_key r (top, KEY_ALL_ACCESS, "SOFTWARE",
@@ -1991,6 +2019,7 @@ mount_info::remove_cygdrive_info_from_re
      registry. */
   read_cygdrive_info_from_registry ();
 
+  send_update_sys_mounts (flags);
   return (res != ERROR_SUCCESS) ? res : res2;
 }
 
Index: shared_info.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/shared_info.h,v
retrieving revision 1.38
diff -u -p -r1.38 shared_info.h
--- shared_info.h	14 Nov 2003 23:40:05 -0000	1.38
+++ shared_info.h	6 Feb 2004 01:42:08 -0000
@@ -55,7 +55,6 @@ struct device;
 class mount_info
 {
  public:
-  DWORD sys_mount_table_counter;
   int nmounts;
   mount_item mount[MAX_MOUNTS];
 
@@ -68,6 +67,7 @@ class mount_info
  private:
   int posix_sorted[MAX_MOUNTS];
   int native_sorted[MAX_MOUNTS];
+  volatile bool sys_mount_table_update;
 
  public:
   /* Increment when setting up a reg_key if mounts area had to be
@@ -94,6 +94,8 @@ class mount_info
   int remove_cygdrive_info_from_registry (const char *cygdrive_prefix, unsigned flags);
   int get_cygdrive_info (char *user, char *system, char* user_flags,
 			 char* system_flags);
+  void send_update_sys_mounts (unsigned int flags);
+  void got_update_sys_mounts () { sys_mount_table_update = true; }
 
  private:
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]