* fhandler.h (-struct wsa_event): Move to wsa_event.h. Include
wsa_event.h instead. * fhandler_socket.cc (NUM_SOCKS): Move to wsa_event.h. (wsa_events): Move from DLL shared area to cygwin_shared shared memory. Accommodate throughout. (socket_serial_number): Ditto. * fhandler_tape.cc (mt): Ditto. (mtinfo_init): Remove. (mt): Define as cygwin_shared->mt. * flock.cc (FLOCK_PARENT_DIR_ACCESS): Remove. (FLOCK_INODE_DIR_ACCESS): Move up in file. (FLOCK_MUTANT_ACCESS): Ditto. (FLOCK_EVENT_ACCESS): Ditto. (get_lock_parent_dir): Remove. (inode_t::inode_t): Call get_shared_parent_dir to get parent dir handle. Add a "flock-" prefix to file's lock directory name for clarity. * mtinfo.h (mtinfo_init): Drop declaration. * net.cc (last_used_bindresvport): Move from DLL shared area to cygwin_shared shared memory. (cygwin_bindresvport_sa): Accommodate above change. * sec_helper.cc (_everyone_sd): Move here from flock.cc. * security.h (SD_MIN_SIZE): Ditto. (everyone_sd): Ditto. * shared.cc (cygwin_shared_area): Remove. (cygwin_shared_h): New handle. (get_shared_parent_dir): New static function. (shared_name): Drop session_local argument. Call get_shared_parent_dir here. Add cygwin-shared subdir to object name. (offsets): Reinstantiate SH_CYGWIN_SHARED member. (open_shared): Revert change from 2007-03-29 for systems supporting SeCreateGlobalPrivilege. (shared_info::initialize): Call mtinfo's initialize here. (memory_init): Drop call to mtinfo_init. * shared_info.h (SHARED_INFO_CB): Accommodate change to shared_info. (CURR_SHARED_MAGIC): Ditto. (class shared_info): Add members for global socket and tape info sharing. (enum shared_locations): Reinstantiate SH_CYGWIN_SHARED. (get_shared_parent_dir): Declare. (shared_name): Drop session_local argument from declaration. * wsa_event.h: New file. Move definitions of NUM_SOCKS and struct wsa_event here.
This commit is contained in:
		| @@ -1,3 +1,48 @@ | |||||||
|  | 2008-04-18  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* fhandler.h (-struct wsa_event): Move to wsa_event.h.  Include | ||||||
|  | 	wsa_event.h instead. | ||||||
|  | 	* fhandler_socket.cc (NUM_SOCKS): Move to wsa_event.h. | ||||||
|  | 	(wsa_events): Move from DLL shared area to cygwin_shared shared | ||||||
|  | 	memory.  Accommodate throughout. | ||||||
|  | 	(socket_serial_number): Ditto. | ||||||
|  | 	* fhandler_tape.cc (mt): Ditto. | ||||||
|  | 	(mtinfo_init): Remove. | ||||||
|  | 	(mt): Define as cygwin_shared->mt. | ||||||
|  | 	* flock.cc (FLOCK_PARENT_DIR_ACCESS): Remove. | ||||||
|  | 	(FLOCK_INODE_DIR_ACCESS): Move up in file. | ||||||
|  | 	(FLOCK_MUTANT_ACCESS): Ditto. | ||||||
|  | 	(FLOCK_EVENT_ACCESS): Ditto. | ||||||
|  | 	(get_lock_parent_dir): Remove. | ||||||
|  | 	(inode_t::inode_t): Call get_shared_parent_dir to get parent dir handle. | ||||||
|  | 	Add a "flock-" prefix to file's lock directory name for clarity. | ||||||
|  | 	* mtinfo.h (mtinfo_init): Drop declaration. | ||||||
|  | 	* net.cc (last_used_bindresvport): Move from DLL shared area to | ||||||
|  | 	cygwin_shared shared memory. | ||||||
|  | 	(cygwin_bindresvport_sa): Accommodate above change. | ||||||
|  | 	* sec_helper.cc (_everyone_sd): Move here from flock.cc. | ||||||
|  | 	* security.h (SD_MIN_SIZE): Ditto. | ||||||
|  | 	(everyone_sd): Ditto. | ||||||
|  | 	* shared.cc (cygwin_shared_area): Remove. | ||||||
|  | 	(cygwin_shared_h): New handle. | ||||||
|  | 	(get_shared_parent_dir): New static function. | ||||||
|  | 	(shared_name): Drop session_local argument.  Call get_shared_parent_dir | ||||||
|  | 	here.  Add cygwin-shared subdir to object name. | ||||||
|  | 	(offsets): Reinstantiate SH_CYGWIN_SHARED member. | ||||||
|  | 	(open_shared): Revert change from 2007-03-29 for systems supporting | ||||||
|  | 	SeCreateGlobalPrivilege. | ||||||
|  | 	(shared_info::initialize): Call mtinfo's initialize here. | ||||||
|  | 	(memory_init): Drop call to mtinfo_init. | ||||||
|  | 	* shared_info.h (SHARED_INFO_CB): Accommodate change to shared_info. | ||||||
|  | 	(CURR_SHARED_MAGIC): Ditto. | ||||||
|  | 	(class shared_info): Add members for global socket and tape info | ||||||
|  | 	sharing. | ||||||
|  | 	(enum shared_locations): Reinstantiate SH_CYGWIN_SHARED. | ||||||
|  | 	(get_shared_parent_dir): Declare. | ||||||
|  | 	(shared_name): Drop session_local argument from declaration. | ||||||
|  | 	* wsa_event.h: New file.  Move definitions of NUM_SOCKS and | ||||||
|  | 	struct wsa_event here. | ||||||
|  |  | ||||||
| 2008-04-18  Christopher Faylor  <me+cygwin@cgf.cx> | 2008-04-18  Christopher Faylor  <me+cygwin@cgf.cx> | ||||||
|  |  | ||||||
| 	* autoload.cc (noload): Make sure this and succeeding functions are | 	* autoload.cc (noload): Make sure this and succeeding functions are | ||||||
|   | |||||||
| @@ -394,13 +394,7 @@ class fhandler_mailslot : public fhandler_base | |||||||
|   select_record *select_read (select_record *s); |   select_record *select_read (select_record *s); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct wsa_event | #include "wsa_event.h" | ||||||
| { |  | ||||||
|   LONG serial_number; |  | ||||||
|   long events; |  | ||||||
|   int  connect_errorcode; |  | ||||||
|   pid_t owner; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| class fhandler_socket: public fhandler_base | class fhandler_socket: public fhandler_base | ||||||
| { | { | ||||||
|   | |||||||
| @@ -403,15 +403,9 @@ fhandler_socket::af_local_set_secret (char *buf) | |||||||
| /* Maximum number of concurrently opened sockets from all Cygwin processes | /* Maximum number of concurrently opened sockets from all Cygwin processes | ||||||
|    per session.  Note that shared sockets (through dup/fork/exec) are |    per session.  Note that shared sockets (through dup/fork/exec) are | ||||||
|    counted as one socket. */ |    counted as one socket. */ | ||||||
| #define NUM_SOCKS	(65536 / sizeof (wsa_event)) |  | ||||||
|  |  | ||||||
| #define LOCK_EVENTS	WaitForSingleObject (wsock_mtx, INFINITE) | #define LOCK_EVENTS	WaitForSingleObject (wsock_mtx, INFINITE) | ||||||
| #define UNLOCK_EVENTS	ReleaseMutex (wsock_mtx) | #define UNLOCK_EVENTS	ReleaseMutex (wsock_mtx) | ||||||
|  |  | ||||||
| static wsa_event wsa_events[NUM_SOCKS] __attribute__((section (".cygwin_dll_common"), shared)) = { 0 }; |  | ||||||
|  |  | ||||||
| static LONG socket_serial_number __attribute__((section (".cygwin_dll_common"), shared)) = 0; |  | ||||||
|  |  | ||||||
| static HANDLE wsa_slot_mtx; | static HANDLE wsa_slot_mtx; | ||||||
|  |  | ||||||
| static wsa_event * | static wsa_event * | ||||||
| @@ -422,7 +416,7 @@ search_wsa_event_slot (LONG new_serial_number) | |||||||
|   if (!wsa_slot_mtx) |   if (!wsa_slot_mtx) | ||||||
|     { |     { | ||||||
|       wsa_slot_mtx = CreateMutex (&sec_all, FALSE, |       wsa_slot_mtx = CreateMutex (&sec_all, FALSE, | ||||||
| 				  shared_name (name, "sock", 0, true)); | 				  shared_name (name, "sock", 0)); | ||||||
|       if (!wsa_slot_mtx) |       if (!wsa_slot_mtx) | ||||||
| 	api_fatal ("Couldn't create/open shared socket mutex, %E"); | 	api_fatal ("Couldn't create/open shared socket mutex, %E"); | ||||||
|     } |     } | ||||||
| @@ -436,11 +430,11 @@ search_wsa_event_slot (LONG new_serial_number) | |||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|   unsigned int slot = new_serial_number % NUM_SOCKS; |   unsigned int slot = new_serial_number % NUM_SOCKS; | ||||||
|   while (wsa_events[slot].serial_number) |   while (cygwin_shared->wsa_events[slot].serial_number) | ||||||
|     { |     { | ||||||
|       HANDLE searchmtx = OpenMutex (STANDARD_RIGHTS_READ, FALSE, |       HANDLE searchmtx = OpenMutex (STANDARD_RIGHTS_READ, FALSE, | ||||||
| 	    shared_name (searchname, "sock", wsa_events[slot].serial_number, | 	    shared_name (searchname, "sock", | ||||||
| 			 true)); | 			 cygwin_shared->wsa_events[slot].serial_number)); | ||||||
|       if (!searchmtx) |       if (!searchmtx) | ||||||
| 	break; | 	break; | ||||||
|       /* Mutex still exists, attached socket is active, try next slot. */ |       /* Mutex still exists, attached socket is active, try next slot. */ | ||||||
| @@ -454,10 +448,10 @@ search_wsa_event_slot (LONG new_serial_number) | |||||||
| 	  return NULL; | 	  return NULL; | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|   memset (&wsa_events[slot], 0, sizeof (wsa_event)); |   memset (&cygwin_shared->wsa_events[slot], 0, sizeof (wsa_event)); | ||||||
|   wsa_events[slot].serial_number = new_serial_number; |   cygwin_shared->wsa_events[slot].serial_number = new_serial_number; | ||||||
|   ReleaseMutex (wsa_slot_mtx); |   ReleaseMutex (wsa_slot_mtx); | ||||||
|   return wsa_events + slot; |   return cygwin_shared->wsa_events + slot; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool | bool | ||||||
| @@ -469,12 +463,12 @@ fhandler_socket::init_events () | |||||||
|  |  | ||||||
|   do |   do | ||||||
|     { |     { | ||||||
|       new_serial_number = InterlockedIncrement (&socket_serial_number); |       new_serial_number = | ||||||
|  | 	InterlockedIncrement (&cygwin_shared->socket_serial_number); | ||||||
|       if (!new_serial_number)	/* 0 is reserved for global mutex */ |       if (!new_serial_number)	/* 0 is reserved for global mutex */ | ||||||
| 	InterlockedIncrement (&socket_serial_number); | 	InterlockedIncrement (&cygwin_shared->socket_serial_number); | ||||||
|       wsock_mtx = CreateMutex (&sec_all, FALSE, |       wsock_mtx = CreateMutex (&sec_all, FALSE, | ||||||
| 			       shared_name (name, "sock", new_serial_number, | 			       shared_name (name, "sock", new_serial_number)); | ||||||
| 					    true)); |  | ||||||
|       if (!wsock_mtx) |       if (!wsock_mtx) | ||||||
| 	{ | 	{ | ||||||
| 	  debug_printf ("CreateMutex, %E"); | 	  debug_printf ("CreateMutex, %E"); | ||||||
|   | |||||||
| @@ -22,7 +22,6 @@ details. */ | |||||||
| #include "cygheap.h" | #include "cygheap.h" | ||||||
| #include "shared_info.h" | #include "shared_info.h" | ||||||
| #include "sigproc.h" | #include "sigproc.h" | ||||||
| #include "mtinfo.h" |  | ||||||
|  |  | ||||||
| /* Media changes and bus resets are sometimes reported and the function | /* Media changes and bus resets are sometimes reported and the function | ||||||
|    hasn't been executed.  We repeat all functions which return with one |    hasn't been executed.  We repeat all functions which return with one | ||||||
| @@ -1155,17 +1154,11 @@ mtinfo::initialize () | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static mtinfo mt __attribute__((section (".cygwin_dll_common"), shared)); |  | ||||||
|  |  | ||||||
| void __stdcall |  | ||||||
| mtinfo_init () |  | ||||||
| { |  | ||||||
|   mt.initialize (); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /**********************************************************************/ | /**********************************************************************/ | ||||||
| /* fhandler_dev_tape */ | /* fhandler_dev_tape */ | ||||||
|  |  | ||||||
|  | #define mt	(cygwin_shared->mt) | ||||||
|  |  | ||||||
| #define lock(err_ret_val) if (!_lock ()) return err_ret_val; | #define lock(err_ret_val) if (!_lock ()) return err_ret_val; | ||||||
|  |  | ||||||
| inline bool | inline bool | ||||||
|   | |||||||
| @@ -106,6 +106,7 @@ | |||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include "cygerrno.h" | #include "cygerrno.h" | ||||||
| #include "security.h" | #include "security.h" | ||||||
|  | #include "shared_info.h" | ||||||
| #include "path.h" | #include "path.h" | ||||||
| #include "fhandler.h" | #include "fhandler.h" | ||||||
| #include "dtable.h" | #include "dtable.h" | ||||||
| @@ -133,6 +134,19 @@ static NO_COPY muto lockf_guard; | |||||||
|  |  | ||||||
| #define LOCK_OBJ_NAME_LEN	64 | #define LOCK_OBJ_NAME_LEN	64 | ||||||
|  |  | ||||||
|  | #define FLOCK_INODE_DIR_ACCESS	(DIRECTORY_QUERY \ | ||||||
|  | 				 | DIRECTORY_TRAVERSE \ | ||||||
|  | 				 | DIRECTORY_CREATE_OBJECT \ | ||||||
|  | 				 | READ_CONTROL) | ||||||
|  |  | ||||||
|  | #define FLOCK_MUTANT_ACCESS	(MUTANT_QUERY_STATE \ | ||||||
|  | 				 | SYNCHRONIZE \ | ||||||
|  | 				 | READ_CONTROL) | ||||||
|  |  | ||||||
|  | #define FLOCK_EVENT_ACCESS	(EVENT_QUERY_STATE \ | ||||||
|  | 				 | SYNCHRONIZE \ | ||||||
|  | 				 | READ_CONTROL) | ||||||
|  |  | ||||||
| /* This function takes the own process security descriptor DACL and adds | /* This function takes the own process security descriptor DACL and adds | ||||||
|    SYNCHRONIZE permissions for everyone.  This allows all processes |    SYNCHRONIZE permissions for everyone.  This allows all processes | ||||||
|    to wait for this process to die when blocking in a F_SETLKW on a lock |    to wait for this process to die when blocking in a F_SETLKW on a lock | ||||||
| @@ -190,84 +204,6 @@ allow_others_to_sync () | |||||||
|   done = true; |   done = true; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Helper function to create an event security descriptor which only allows |  | ||||||
|    specific access to everyone.  Only the creating process has all access |  | ||||||
|    rights. */ |  | ||||||
|  |  | ||||||
| #define FLOCK_PARENT_DIR_ACCESS	(DIRECTORY_QUERY \ |  | ||||||
| 				 | DIRECTORY_TRAVERSE \ |  | ||||||
| 				 | DIRECTORY_CREATE_SUBDIRECTORY \ |  | ||||||
| 				 | READ_CONTROL) |  | ||||||
|  |  | ||||||
| #define FLOCK_INODE_DIR_ACCESS	(DIRECTORY_QUERY \ |  | ||||||
| 				 | DIRECTORY_TRAVERSE \ |  | ||||||
| 				 | DIRECTORY_CREATE_OBJECT \ |  | ||||||
| 				 | READ_CONTROL) |  | ||||||
|  |  | ||||||
| #define FLOCK_MUTANT_ACCESS	(MUTANT_QUERY_STATE \ |  | ||||||
| 				 | SYNCHRONIZE \ |  | ||||||
| 				 | READ_CONTROL) |  | ||||||
|  |  | ||||||
| #define FLOCK_EVENT_ACCESS	(EVENT_QUERY_STATE \ |  | ||||||
| 				 | SYNCHRONIZE \ |  | ||||||
| 				 | READ_CONTROL) |  | ||||||
|  |  | ||||||
| #define SD_MIN_SIZE (sizeof (SECURITY_DESCRIPTOR) + MAX_DACL_LEN (1)) |  | ||||||
|  |  | ||||||
| #define everyone_sd(access)	(_everyone_sd (alloca (SD_MIN_SIZE), (access))) |  | ||||||
|  |  | ||||||
| PSECURITY_DESCRIPTOR |  | ||||||
| _everyone_sd (void *buf, ACCESS_MASK access) |  | ||||||
| { |  | ||||||
|   PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) buf; |  | ||||||
|  |  | ||||||
|   if (psd) |  | ||||||
|     { |  | ||||||
|       InitializeSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION); |  | ||||||
|       PACL dacl = (PACL) (psd + 1); |  | ||||||
|       InitializeAcl (dacl, MAX_DACL_LEN (1), ACL_REVISION); |  | ||||||
|       if (!AddAccessAllowedAce (dacl, ACL_REVISION, access,  |  | ||||||
| 				well_known_world_sid)) |  | ||||||
| 	{ |  | ||||||
| 	  debug_printf ("AddAccessAllowedAce: %lu", GetLastError ()); |  | ||||||
| 	  return NULL; |  | ||||||
| 	} |  | ||||||
|       LPVOID ace; |  | ||||||
|       if (!FindFirstFreeAce (dacl, &ace)) |  | ||||||
| 	{ |  | ||||||
| 	  debug_printf ("FindFirstFreeAce: %lu", GetLastError ()); |  | ||||||
| 	  return NULL; |  | ||||||
| 	} |  | ||||||
|       dacl->AclSize = (char *) ace - (char *) dacl; |  | ||||||
|       SetSecurityDescriptorDacl (psd, TRUE, dacl, FALSE); |  | ||||||
|     } |  | ||||||
|   return psd; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* This function returns a handle to the top-level directory in the global |  | ||||||
|    NT namespace used to implement advisory locking. */ |  | ||||||
| static HANDLE |  | ||||||
| get_lock_parent_dir () |  | ||||||
| { |  | ||||||
|   static HANDLE dir; |  | ||||||
|   UNICODE_STRING uname; |  | ||||||
|   OBJECT_ATTRIBUTES attr; |  | ||||||
|   NTSTATUS status; |  | ||||||
|  |  | ||||||
|   INODE_LIST_LOCK(); |  | ||||||
|   if (!dir) |  | ||||||
|     { |  | ||||||
|       RtlInitUnicodeString (&uname, L"\\BaseNamedObjects\\cygwin-fcntl-lk"); |  | ||||||
|       InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF, |  | ||||||
| 				  NULL, everyone_sd (FLOCK_PARENT_DIR_ACCESS)); |  | ||||||
|       status = NtCreateDirectoryObject (&dir, FLOCK_PARENT_DIR_ACCESS, &attr); |  | ||||||
|       if (!NT_SUCCESS (status)) |  | ||||||
| 	api_fatal ("NtCreateDirectoryObject(parent): %p", status); |  | ||||||
|     } |  | ||||||
|   INODE_LIST_UNLOCK (); |  | ||||||
|   return dir; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* Get the handle count of an object. */ | /* Get the handle count of an object. */ | ||||||
| static ULONG | static ULONG | ||||||
| get_obj_handle_count (HANDLE h) | get_obj_handle_count (HANDLE h) | ||||||
| @@ -507,15 +443,15 @@ inode_t::inode_t (__dev32_t dev, __ino64_t ino) | |||||||
| : i_lockf (NULL), i_all_lf (NULL), i_dev (dev), i_ino (ino) | : i_lockf (NULL), i_all_lf (NULL), i_dev (dev), i_ino (ino) | ||||||
| { | { | ||||||
|   HANDLE parent_dir; |   HANDLE parent_dir; | ||||||
|   WCHAR name[32]; |   WCHAR name[48]; | ||||||
|   UNICODE_STRING uname; |   UNICODE_STRING uname; | ||||||
|   OBJECT_ATTRIBUTES attr; |   OBJECT_ATTRIBUTES attr; | ||||||
|   NTSTATUS status; |   NTSTATUS status; | ||||||
|  |  | ||||||
|   parent_dir = get_lock_parent_dir (); |   parent_dir = get_shared_parent_dir (); | ||||||
|   /* Create a subdir which is named after the device and inode_t numbers |   /* Create a subdir which is named after the device and inode_t numbers | ||||||
|      of the given file, in hex notation. */ |      of the given file, in hex notation. */ | ||||||
|   int len = __small_swprintf (name, L"%08x-%016X", dev, ino); |   int len = __small_swprintf (name, L"flock-%08x-%016X", dev, ino); | ||||||
|   RtlInitCountedUnicodeString (&uname, name, len * sizeof (WCHAR)); |   RtlInitCountedUnicodeString (&uname, name, len * sizeof (WCHAR)); | ||||||
|   InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF, |   InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF, | ||||||
| 			      parent_dir, everyone_sd (FLOCK_INODE_DIR_ACCESS)); | 			      parent_dir, everyone_sd (FLOCK_INODE_DIR_ACCESS)); | ||||||
|   | |||||||
| @@ -140,5 +140,3 @@ public: | |||||||
|   void initialize (); |   void initialize (); | ||||||
|   mtinfo_drive *drive (int num) { return &_drive[num]; } |   mtinfo_drive *drive (int num) { return &_drive[num]; } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| extern void __stdcall mtinfo_init (); |  | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ details. */ | |||||||
| #include "cygerrno.h" | #include "cygerrno.h" | ||||||
| #include "security.h" | #include "security.h" | ||||||
| #include "cygwin/version.h" | #include "cygwin/version.h" | ||||||
|  | #include "shared_info.h" | ||||||
| #include "perprocess.h" | #include "perprocess.h" | ||||||
| #include "path.h" | #include "path.h" | ||||||
| #include "fhandler.h" | #include "fhandler.h" | ||||||
| @@ -2140,8 +2141,6 @@ if_freenameindex (struct if_nameindex *ptr) | |||||||
| #define PORT_HIGH	(IPPORT_RESERVED - 1) | #define PORT_HIGH	(IPPORT_RESERVED - 1) | ||||||
| #define NUM_PORTS	(PORT_HIGH - PORT_LOW + 1) | #define NUM_PORTS	(PORT_HIGH - PORT_LOW + 1) | ||||||
|  |  | ||||||
| LONG last_used_bindresvport __attribute__((section (".cygwin_dll_common"), shared)) = IPPORT_RESERVED; |  | ||||||
|  |  | ||||||
| extern "C" int | extern "C" int | ||||||
| cygwin_bindresvport_sa (int fd, struct sockaddr *sa) | cygwin_bindresvport_sa (int fd, struct sockaddr *sa) | ||||||
| { | { | ||||||
| @@ -2199,11 +2198,11 @@ cygwin_bindresvport_sa (int fd, struct sockaddr *sa) | |||||||
|  |  | ||||||
|   for (int i = 0; i < NUM_PORTS; i++) |   for (int i = 0; i < NUM_PORTS; i++) | ||||||
|     { |     { | ||||||
|       while ((myport = InterlockedExchange (&last_used_bindresvport, 0)) == 0) |       while ((myport = InterlockedExchange (&cygwin_shared->last_used_bindresvport, 0)) == 0) | ||||||
| 	low_priority_sleep (0); | 	low_priority_sleep (0); | ||||||
|       if (--myport < PORT_LOW) |       if (--myport < PORT_LOW) | ||||||
| 	myport = PORT_HIGH; | 	myport = PORT_HIGH; | ||||||
|       InterlockedExchange (&last_used_bindresvport, myport); |       InterlockedExchange (&cygwin_shared->last_used_bindresvport, myport); | ||||||
|  |  | ||||||
|       if (sa->sa_family == AF_INET6) |       if (sa->sa_family == AF_INET6) | ||||||
| 	sin6->sin6_port = htons (myport); | 	sin6->sin6_port = htons (myport); | ||||||
|   | |||||||
| @@ -518,3 +518,36 @@ __sec_user (PVOID sa_buf, PSID sid1, PSID sid2, DWORD access2, BOOL inherit) | |||||||
|   psa->bInheritHandle = inherit; |   psa->bInheritHandle = inherit; | ||||||
|   return psa; |   return psa; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* Helper function to create an event security descriptor which only allows | ||||||
|  |    specific access to everyone.  Only the creating process has all access | ||||||
|  |    rights. */ | ||||||
|  |  | ||||||
|  | PSECURITY_DESCRIPTOR | ||||||
|  | _everyone_sd (void *buf, ACCESS_MASK access) | ||||||
|  | { | ||||||
|  |   PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) buf; | ||||||
|  |  | ||||||
|  |   if (psd) | ||||||
|  |     { | ||||||
|  |       InitializeSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION); | ||||||
|  |       PACL dacl = (PACL) (psd + 1); | ||||||
|  |       InitializeAcl (dacl, MAX_DACL_LEN (1), ACL_REVISION); | ||||||
|  |       if (!AddAccessAllowedAce (dacl, ACL_REVISION, access,  | ||||||
|  | 				well_known_world_sid)) | ||||||
|  | 	{ | ||||||
|  | 	  debug_printf ("AddAccessAllowedAce: %lu", GetLastError ()); | ||||||
|  | 	  return NULL; | ||||||
|  | 	} | ||||||
|  |       LPVOID ace; | ||||||
|  |       if (!FindFirstFreeAce (dacl, &ace)) | ||||||
|  | 	{ | ||||||
|  | 	  debug_printf ("FindFirstFreeAce: %lu", GetLastError ()); | ||||||
|  | 	  return NULL; | ||||||
|  | 	} | ||||||
|  |       dacl->AclSize = (char *) ace - (char *) dacl; | ||||||
|  |       SetSecurityDescriptorDacl (psd, TRUE, dacl, FALSE); | ||||||
|  |     } | ||||||
|  |   return psd; | ||||||
|  | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ details. */ | |||||||
| #define MAX_SID_LEN 40 | #define MAX_SID_LEN 40 | ||||||
| #define MAX_DACL_LEN(n) (sizeof (ACL) \ | #define MAX_DACL_LEN(n) (sizeof (ACL) \ | ||||||
| 		   + (n) * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD) + MAX_SID_LEN)) | 		   + (n) * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD) + MAX_SID_LEN)) | ||||||
|  | #define SD_MIN_SIZE (sizeof (SECURITY_DESCRIPTOR) + MAX_DACL_LEN (1)) | ||||||
| #define ACL_DEFAULT_SIZE 3072 | #define ACL_DEFAULT_SIZE 3072 | ||||||
| #define NO_SID ((PSID)NULL) | #define NO_SID ((PSID)NULL) | ||||||
|  |  | ||||||
| @@ -421,6 +422,9 @@ extern SECURITY_ATTRIBUTES sec_none, sec_none_nih, sec_all, sec_all_nih; | |||||||
| extern SECURITY_ATTRIBUTES *__stdcall __sec_user (PVOID sa_buf, PSID sid1, PSID sid2, | extern SECURITY_ATTRIBUTES *__stdcall __sec_user (PVOID sa_buf, PSID sid1, PSID sid2, | ||||||
| 						  DWORD access2, BOOL inherit) | 						  DWORD access2, BOOL inherit) | ||||||
|   __attribute__ ((regparm (3))); |   __attribute__ ((regparm (3))); | ||||||
|  | extern PSECURITY_DESCRIPTOR _everyone_sd (void *buf, ACCESS_MASK access); | ||||||
|  | #define everyone_sd(access)	(_everyone_sd (alloca (SD_MIN_SIZE), (access))) | ||||||
|  |  | ||||||
| extern bool sec_acl (PACL acl, bool original, bool admins, PSID sid1 = NO_SID, | extern bool sec_acl (PACL acl, bool original, bool admins, PSID sid1 = NO_SID, | ||||||
| 		     PSID sid2 = NO_SID, DWORD access2 = 0); | 		     PSID sid2 = NO_SID, DWORD access2 = 0); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,20 +22,52 @@ details. */ | |||||||
| #include "shared_info_magic.h" | #include "shared_info_magic.h" | ||||||
| #include "registry.h" | #include "registry.h" | ||||||
| #include "cygwin_version.h" | #include "cygwin_version.h" | ||||||
| #include "mtinfo.h" | #include "ntdll.h" | ||||||
|  | #include <alloca.h> | ||||||
|  |  | ||||||
| static shared_info cygwin_shared_area __attribute__((section (".cygwin_dll_common"), shared)); |  | ||||||
| shared_info NO_COPY *cygwin_shared; | shared_info NO_COPY *cygwin_shared; | ||||||
| user_info NO_COPY *user_shared; | user_info NO_COPY *user_shared; | ||||||
|  | HANDLE NO_COPY cygwin_shared_h; | ||||||
| HANDLE NO_COPY cygwin_user_h; | HANDLE NO_COPY cygwin_user_h; | ||||||
|  |  | ||||||
|  | /* This function returns a handle to the top-level directory in the global | ||||||
|  |    NT namespace used to implement global objects including shared memory. */ | ||||||
|  |  | ||||||
|  | #define CYG_SHARED_DIR_ACCESS	(DIRECTORY_QUERY \ | ||||||
|  |                                  | DIRECTORY_TRAVERSE \ | ||||||
|  |                                  | DIRECTORY_CREATE_SUBDIRECTORY \ | ||||||
|  |                                  | DIRECTORY_CREATE_OBJECT \ | ||||||
|  |                                  | READ_CONTROL) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | HANDLE | ||||||
|  | get_shared_parent_dir () | ||||||
|  | { | ||||||
|  |   static HANDLE dir; | ||||||
|  |   UNICODE_STRING uname; | ||||||
|  |   OBJECT_ATTRIBUTES attr; | ||||||
|  |   NTSTATUS status; | ||||||
|  |    | ||||||
|  |   if (!dir) | ||||||
|  |     { | ||||||
|  |       RtlInitUnicodeString (&uname, L"\\BaseNamedObjects\\cygwin-shared"); | ||||||
|  |       InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF, | ||||||
|  |                                   NULL, everyone_sd (CYG_SHARED_DIR_ACCESS)); | ||||||
|  |       status = NtCreateDirectoryObject (&dir, CYG_SHARED_DIR_ACCESS, &attr); | ||||||
|  |       if (!NT_SUCCESS (status)) | ||||||
|  |         api_fatal ("NtCreateDirectoryObject(parent): %p", status); | ||||||
|  |     } | ||||||
|  |   return dir; | ||||||
|  | }  | ||||||
|  |  | ||||||
| char * __stdcall | char * __stdcall | ||||||
| shared_name (char *ret_buf, const char *str, int num, bool session_local) | shared_name (char *ret_buf, const char *str, int num) | ||||||
| { | { | ||||||
|   extern bool _cygwin_testing; |   extern bool _cygwin_testing; | ||||||
|  |  | ||||||
|   __small_sprintf (ret_buf, "%s%s.%s.%d", |   get_shared_parent_dir (); | ||||||
| 		   session_local ? "" : cygheap->shared_prefix, |   __small_sprintf (ret_buf, "%scygwin-shared\\%s.%s.%d", | ||||||
|  | 		   cygheap->shared_prefix, | ||||||
| 		   cygwin_version.shared_id, str, num); | 		   cygwin_version.shared_id, str, num); | ||||||
|   if (_cygwin_testing) |   if (_cygwin_testing) | ||||||
|     strcat (ret_buf, cygwin_version.dll_build_date); |     strcat (ret_buf, cygwin_version.dll_build_date); | ||||||
| @@ -47,6 +79,10 @@ shared_name (char *ret_buf, const char *str, int num, bool session_local) | |||||||
|  |  | ||||||
| static ptrdiff_t offsets[] = | static ptrdiff_t offsets[] = | ||||||
| { | { | ||||||
|  |   - pround (sizeof (shared_info)) | ||||||
|  |   - pround (sizeof (user_info)) | ||||||
|  |   - pround (sizeof (console_state)) | ||||||
|  |   - pround (sizeof (_pinfo)), | ||||||
|   - pround (sizeof (user_info)) |   - pround (sizeof (user_info)) | ||||||
|   - pround (sizeof (console_state)) |   - pround (sizeof (console_state)) | ||||||
|   - pround (sizeof (_pinfo)), |   - pround (sizeof (_pinfo)), | ||||||
| @@ -80,44 +116,17 @@ open_shared (const char *name, int n, HANDLE& shared_h, DWORD size, | |||||||
|     m = SH_JUSTOPEN; |     m = SH_JUSTOPEN; | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       /* Beginning with Windows 2003 Server, a process doesn't necessarily |  | ||||||
| 	 have the right to create globally accessible shared memory.  If so, |  | ||||||
| 	 creating the shared memory will fail with ERROR_ACCESS_DENIED if the |  | ||||||
| 	 user doesn't have the SeCreateGlobalPrivilege privilege.  If that |  | ||||||
| 	 happened, we retry to create a shared memory object locally.  This |  | ||||||
| 	 only allows to see the processes in the current user session, but |  | ||||||
| 	 that's better than nothing. */ |  | ||||||
|  |  | ||||||
|       if (name) |       if (name) | ||||||
| 	mapname = shared_name (map_buf, name, n); | 	mapname = shared_name (map_buf, name, n); | ||||||
|       if (m == SH_JUSTOPEN) |       if (m == SH_JUSTOPEN) | ||||||
| 	{ |  | ||||||
| 	shared_h = OpenFileMapping (access, FALSE, mapname); | 	shared_h = OpenFileMapping (access, FALSE, mapname); | ||||||
| 	  if (!shared_h && wincap.has_create_global_privilege () |  | ||||||
| 	      && GetLastError () == ERROR_FILE_NOT_FOUND) |  | ||||||
| 	    shared_h = OpenFileMapping (access, FALSE, mapname + 7); |  | ||||||
| 	} |  | ||||||
|       else |       else | ||||||
| 	{ | 	{ | ||||||
| 	  shared_h = CreateFileMapping (INVALID_HANDLE_VALUE, psa, | 	  shared_h = CreateFileMapping (INVALID_HANDLE_VALUE, psa, | ||||||
| 	  				PAGE_READWRITE, 0, size, mapname); | 	  				PAGE_READWRITE, 0, size, mapname); | ||||||
| 	  switch (GetLastError ()) |  | ||||||
| 	    { |  | ||||||
| 	    case ERROR_ALREADY_EXISTS: |  | ||||||
| 	      m = SH_JUSTOPEN; |  | ||||||
| 	      break; |  | ||||||
| 	    case ERROR_ACCESS_DENIED: |  | ||||||
| 	      if (wincap.has_create_global_privilege ()) |  | ||||||
| 	        { |  | ||||||
| 		  shared_h = CreateFileMapping (INVALID_HANDLE_VALUE, psa, |  | ||||||
| 						PAGE_READWRITE, 0, size, |  | ||||||
| 						mapname + 7); |  | ||||||
| 	  if (GetLastError () == ERROR_ALREADY_EXISTS) | 	  if (GetLastError () == ERROR_ALREADY_EXISTS) | ||||||
| 	    m = SH_JUSTOPEN; | 	    m = SH_JUSTOPEN; | ||||||
| 	} | 	} | ||||||
| 	      break; |  | ||||||
| 	    } |  | ||||||
| 	} |  | ||||||
|       if (shared_h) |       if (shared_h) | ||||||
| 	/* ok! */; | 	/* ok! */; | ||||||
|       else if (m != SH_JUSTOPEN) |       else if (m != SH_JUSTOPEN) | ||||||
| @@ -230,6 +239,8 @@ shared_info::initialize () | |||||||
|       cb = sizeof (*this);	/* Do last, after all shared memory initialization */ |       cb = sizeof (*this);	/* Do last, after all shared memory initialization */ | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |   mt.initialize (); | ||||||
|  |  | ||||||
|   if (cb != SHARED_INFO_CB) |   if (cb != SHARED_INFO_CB) | ||||||
|     system_printf ("size of shared memory region changed from %u to %u", |     system_printf ("size of shared memory region changed from %u to %u", | ||||||
| 		   SHARED_INFO_CB, cb); | 		   SHARED_INFO_CB, cb); | ||||||
| @@ -247,11 +258,17 @@ memory_init () | |||||||
|       cygheap->user.init (); |       cygheap->user.init (); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   cygwin_shared = &cygwin_shared_area; |   /* Initialize general shared memory */ | ||||||
|  |   shared_locations sh_cygwin_shared = SH_CYGWIN_SHARED; | ||||||
|  |   cygwin_shared = (shared_info *) open_shared ("shared", | ||||||
|  | 					       CYGWIN_VERSION_SHARED_DATA, | ||||||
|  | 					       cygwin_shared_h, | ||||||
|  | 					       sizeof (*cygwin_shared), | ||||||
|  | 					       sh_cygwin_shared); | ||||||
|  |  | ||||||
|   cygwin_shared->initialize (); |   cygwin_shared->initialize (); | ||||||
|  |  | ||||||
|   user_shared_initialize (false); |   user_shared_initialize (false); | ||||||
|   mtinfo_init (); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| unsigned | unsigned | ||||||
|   | |||||||
| @@ -10,6 +10,8 @@ details. */ | |||||||
|  |  | ||||||
| #include "tty.h" | #include "tty.h" | ||||||
| #include "security.h" | #include "security.h" | ||||||
|  | #include "wsa_event.h" | ||||||
|  | #include "mtinfo.h" | ||||||
|  |  | ||||||
| /* Mount table entry */ | /* Mount table entry */ | ||||||
|  |  | ||||||
| @@ -121,9 +123,9 @@ public: | |||||||
| 				  cygwin_version.api_minor) | 				  cygwin_version.api_minor) | ||||||
| #define SHARED_VERSION_MAGIC CYGWIN_VERSION_MAGIC (SHARED_MAGIC, SHARED_VERSION) | #define SHARED_VERSION_MAGIC CYGWIN_VERSION_MAGIC (SHARED_MAGIC, SHARED_VERSION) | ||||||
|  |  | ||||||
| #define SHARED_INFO_CB 19992 | #define SHARED_INFO_CB 63912 | ||||||
|  |  | ||||||
| #define CURR_SHARED_MAGIC 0xb7048a88U | #define CURR_SHARED_MAGIC 0x419c874U | ||||||
|  |  | ||||||
| /* NOTE: Do not make gratuitous changes to the names or organization of the | /* NOTE: Do not make gratuitous changes to the names or organization of the | ||||||
|    below class.  The layout is checksummed to determine compatibility between |    below class.  The layout is checksummed to determine compatibility between | ||||||
| @@ -137,8 +139,12 @@ class shared_info | |||||||
|   bool heap_slop_inited; |   bool heap_slop_inited; | ||||||
|   unsigned heap_slop; |   unsigned heap_slop; | ||||||
|   DWORD sys_mount_table_counter; |   DWORD sys_mount_table_counter; | ||||||
|  |  | ||||||
|   tty_list tty; |   tty_list tty; | ||||||
|  |   wsa_event wsa_events[NUM_SOCKS]; | ||||||
|  |   LONG socket_serial_number; | ||||||
|  |   LONG last_used_bindresvport; | ||||||
|  |   mtinfo mt; | ||||||
|  |  | ||||||
|   void initialize (); |   void initialize (); | ||||||
|   unsigned heap_chunk_size (); |   unsigned heap_chunk_size (); | ||||||
|   unsigned heap_slop_size (); |   unsigned heap_slop_size (); | ||||||
| @@ -151,6 +157,7 @@ extern HANDLE cygwin_user_h; | |||||||
|  |  | ||||||
| enum shared_locations | enum shared_locations | ||||||
| { | { | ||||||
|  |   SH_CYGWIN_SHARED, | ||||||
|   SH_USER_SHARED, |   SH_USER_SHARED, | ||||||
|   SH_SHARED_CONSOLE, |   SH_SHARED_CONSOLE, | ||||||
|   SH_MYSELF, |   SH_MYSELF, | ||||||
| @@ -174,7 +181,8 @@ struct console_state | |||||||
| }; | }; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| char *__stdcall shared_name (char *, const char *, int, bool = false); | HANDLE get_shared_parent_dir (); | ||||||
|  | char *__stdcall shared_name (char *, const char *, int); | ||||||
| void *__stdcall open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, | void *__stdcall open_shared (const char *name, int n, HANDLE &shared_h, DWORD size, | ||||||
| 			     shared_locations&, PSECURITY_ATTRIBUTES psa = &sec_all, | 			     shared_locations&, PSECURITY_ATTRIBUTES psa = &sec_all, | ||||||
| 			     DWORD access = FILE_MAP_READ | FILE_MAP_WRITE); | 			     DWORD access = FILE_MAP_READ | FILE_MAP_WRITE); | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								winsup/cygwin/wsa_event.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								winsup/cygwin/wsa_event.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | /* wsa_event.h: type definition of a wsock event storage structure. | ||||||
|  |  | ||||||
|  |    Copyright 2008 Red Hat, Inc. | ||||||
|  |  | ||||||
|  | This file is part of Cygwin. | ||||||
|  |  | ||||||
|  | This software is a copyrighted work licensed under the terms of the | ||||||
|  | Cygwin license.  Please consult the file "CYGWIN_LICENSE" for | ||||||
|  | details. */ | ||||||
|  |  | ||||||
|  | #ifndef _WSA_EVENT_H_ | ||||||
|  | #define _WSA_EVENT_H_ | ||||||
|  |  | ||||||
|  | /* All Cygwin processes together can share 2048 sockets. */ | ||||||
|  | #define NUM_SOCKS       (32768 / sizeof (wsa_event)) | ||||||
|  |    | ||||||
|  | struct wsa_event  | ||||||
|  | { | ||||||
|  |   LONG serial_number; | ||||||
|  |   long events; | ||||||
|  |   int  connect_errorcode; | ||||||
|  |   pid_t owner; | ||||||
|  | };   | ||||||
|  |  | ||||||
|  | #endif /* _WSA_EVENT_H_ */ | ||||||
		Reference in New Issue
	
	Block a user