diff options
author | scottc <scottc> | 2002-06-15 23:39:46 +0000 |
---|---|---|
committer | scottc <scottc> | 2002-06-15 23:39:46 +0000 |
commit | 0987b427ccf762ff19dc4b1382d845dfbb9e627b (patch) | |
tree | 3128c53a6d68bd9e05a534278ed92181dc064568 /winsup | |
parent | 1c4132e7b723a16c7893b2132557f1f95d8a57e5 (diff) | |
download | gdb-0987b427ccf762ff19dc4b1382d845dfbb9e627b.tar.gz |
* cygserver.cc (check_and_dup_handle): Only use security code if
running on NT, i.e. if wincap.has_security().
(client_request_attach_tty::serve): Add check for has_security().
* cygserver_process.cc (process_cache::process): Use DWORD winpid
throughout to avoid win32 vs. cygwin pid confusion.
(process::process): Ditto.
* cygserver_shm.cc (client_request_shm::serve): Only use security
code if running on NT, i.e. if wincap.has_security().
* cygserver_shm.h (client_request_shm::parameters.in): Replace the
ambiguous pid field with cygpid and winpid fields.
(client_request_shm::client_request_shm): Reduce to only two
client-side constructors: one for SHM_CREATE, another for all the
other requests.
* shm.cc (client_request_shm::client_request_shm):
Ditto. Initialize cygpid and winpid fields here. On NT initialize
sd_buf here using set_security_attribute() to make use of the euid
and egid.
(shmat): Use new client_request_shm constructor.
(shmdt): Ditto.
(shmctl): Ditto.
(shmget): Ditto. Remove security code, now performed in the
relevant client_request_shm constructor.
* include/cygwin/cygserver_process.h: (class cleanup_routine):
Change winpid type to DWORD.
(class process): Ditto.
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 32 | ||||
-rwxr-xr-x | winsup/cygwin/cygserver.cc | 87 | ||||
-rwxr-xr-x | winsup/cygwin/cygserver_process.cc | 20 | ||||
-rwxr-xr-x | winsup/cygwin/cygserver_shm.cc | 71 | ||||
-rw-r--r-- | winsup/cygwin/cygserver_shm.h | 7 | ||||
-rwxr-xr-x | winsup/cygwin/include/cygwin/cygserver_process.h | 8 | ||||
-rw-r--r-- | winsup/cygwin/shm.cc | 92 |
7 files changed, 182 insertions, 135 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 0251f731e8e..ea53c4cadd0 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,31 @@ +2002-06-16 Conrad Scott <conrad.scott@dsl.pipex.com> + + * cygserver.cc (check_and_dup_handle): Only use security code if + running on NT, i.e. if wincap.has_security(). + (client_request_attach_tty::serve): Add check for has_security(). + * cygserver_process.cc (process_cache::process): Use DWORD winpid + throughout to avoid win32 vs. cygwin pid confusion. + (process::process): Ditto. + * cygserver_shm.cc (client_request_shm::serve): Only use security + code if running on NT, i.e. if wincap.has_security(). + * cygserver_shm.h (client_request_shm::parameters.in): Replace the + ambiguous pid field with cygpid and winpid fields. + (client_request_shm::client_request_shm): Reduce to only two + client-side constructors: one for SHM_CREATE, another for all the + other requests. + * shm.cc (client_request_shm::client_request_shm): + Ditto. Initialize cygpid and winpid fields here. On NT initialize + sd_buf here using set_security_attribute() to make use of the euid + and egid. + (shmat): Use new client_request_shm constructor. + (shmdt): Ditto. + (shmctl): Ditto. + (shmget): Ditto. Remove security code, now performed in the + relevant client_request_shm constructor. + * include/cygwin/cygserver_process.h: (class cleanup_routine): + Change winpid type to DWORD. + (class process): Ditto. + 2002-06-15 Conrad Scott <conrad.scott@dsl.pipex.com> * woutsup.h: New file. @@ -447,7 +475,7 @@ mount entry is not found. (mount_info::set_flags_from_win32_path): Ditto. -2002-06-04 Christopher Faylor <cgf@redhat.com> +2002-06-04 Christopher Faylor <ccygserver_shm.ccgf@redhat.com> * dtable.cc (handle_to_fn): Correct placement and length of name buffer. (Suggested by Pavel Tsekov) @@ -583,7 +611,7 @@ 2002-06-02 Christopher Faylor <cgf@redhat.com> - * fhandler_disk_file.cc (fhandler_disk_file::fstat_by_name): Check + * fhandler_disk_file.cc (fhacygserver_shm.ccndler_disk_file::fstat_by_name): Check specifically for non-existent file, first. (fhandler_disk_file::fstat): Perform fd open on files with funny characters. diff --git a/winsup/cygwin/cygserver.cc b/winsup/cygwin/cygserver.cc index e76d24589dd..a1fa756e9be 100755 --- a/winsup/cygwin/cygserver.cc +++ b/winsup/cygwin/cygserver.cc @@ -166,49 +166,57 @@ check_and_dup_handle (HANDLE from_process, HANDLE to_process, { HANDLE local_handle = NULL; int ret_val = EACCES; - char sd_buf [1024]; - PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR) &sd_buf; - DWORD bytes_needed; - PRIVILEGE_SET ps; - DWORD ps_len = sizeof (ps); - BOOL status; if (from_process != GetCurrentProcess ()) { + if (!DuplicateHandle (from_process, from_handle, + GetCurrentProcess (), &local_handle, + 0, bInheritHandle, + DUPLICATE_SAME_ACCESS)) + { + system_printf ("error getting handle(%u) to server (%lu)", + (unsigned int)from_handle, GetLastError ()); + goto out; + } + } else + local_handle = from_handle; - if (!DuplicateHandle (from_process, from_handle, - GetCurrentProcess (), &local_handle, - 0, bInheritHandle, - DUPLICATE_SAME_ACCESS)) - { - system_printf ("error getting handle(%u) to server (%lu)", - (unsigned int)from_handle, GetLastError ()); - goto out; - } -} else - local_handle = from_handle; - - if (!GetKernelObjectSecurity (local_handle, - OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - sd, sizeof (sd_buf), &bytes_needed)) + if (!wincap.has_security ()) + assert (!from_process_token); + else { - system_printf ("error getting handle SD (%lu)", GetLastError ()); - goto out; - } + char sd_buf [1024]; + PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR) &sd_buf; + DWORD bytes_needed; + PRIVILEGE_SET ps; + DWORD ps_len = sizeof (ps); + BOOL status; + + if (!GetKernelObjectSecurity (local_handle, + (OWNER_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION + | DACL_SECURITY_INFORMATION), + sd, sizeof (sd_buf), &bytes_needed)) + { + system_printf ("error getting handle SD (%lu)", GetLastError ()); + goto out; + } - MapGenericMask (&access, &access_mapping); + MapGenericMask (&access, &access_mapping); - if (!AccessCheck (sd, from_process_token, access, &access_mapping, - &ps, &ps_len, &access, &status)) - { - system_printf ("error checking access rights (%lu)", GetLastError ()); - goto out; - } + if (!AccessCheck (sd, from_process_token, access, &access_mapping, + &ps, &ps_len, &access, &status)) + { + system_printf ("error checking access rights (%lu)", + GetLastError ()); + goto out; + } - if (!status) - { - system_printf ("access to object denied"); - goto out; + if (!status) + { + system_printf ("access to object denied"); + goto out; + } } if (!DuplicateHandle (from_process, from_handle, @@ -222,7 +230,7 @@ check_and_dup_handle (HANDLE from_process, HANDLE to_process, ret_val = 0; -out: + out: if (local_handle && from_process != GetCurrentProcess ()) CloseHandle (local_handle); @@ -246,6 +254,13 @@ client_request_attach_tty::serve(transport_layer_base *conn, class process_cache HANDLE token_handle = NULL; DWORD rc; + if (!wincap.has_security ()) + { + debug_printf ("this should not be called in a system without security"); + header.error_code = EINVAL; + return; + } + if (header.cb != sizeof (req)) { header.error_code = EINVAL; diff --git a/winsup/cygwin/cygserver_process.cc b/winsup/cygwin/cygserver_process.cc index 6eef702b67d..94529b85112 100755 --- a/winsup/cygwin/cygserver_process.cc +++ b/winsup/cygwin/cygserver_process.cc @@ -47,25 +47,25 @@ process_cache::~process_cache () } class process * -process_cache::process (long pid) +process_cache::process (DWORD winpid) { class process *entry = head; /* TODO: make this more granular, so a search doesn't involve the write lock */ EnterCriticalSection (&cache_write_access); if (!entry) { - entry = new class process (pid); + entry = new class process (winpid); entry->next = (class process *) InterlockedExchangePointer (&head, entry); PulseEvent (cache_add_trigger); } else { - while (entry->winpid != pid && entry->next) + while (entry->winpid != winpid && entry->next) entry = entry->next; - if (entry->winpid != pid) + if (entry->winpid != winpid) { - class process *new_entry = new class process (pid); + class process *new_entry = new class process (winpid); new_entry->next = (class process *) InterlockedExchangePointer (&entry->next, new_entry); @@ -187,18 +187,18 @@ do_process_init (void) /* we don't have a cache shutdown capability today */ } -process::process (long pid): -winpid (pid), next (NULL), cleaning_up (0), head (NULL), _exit_status (STILL_ACTIVE) +process::process (DWORD winpid): +winpid (winpid), next (NULL), cleaning_up (0), head (NULL), _exit_status (STILL_ACTIVE) { pthread_once (&process_init, do_process_init); EnterCriticalSection (&process_access); - thehandle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid); + thehandle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, winpid); if (!thehandle) { - system_printf ("unable to obtain handle for new cache process %ld", pid); + system_printf ("unable to obtain handle for new cache process %lu", winpid); thehandle = INVALID_HANDLE_VALUE; } - debug_printf ("Got handle %p for new cache process %ld", thehandle, pid); + debug_printf ("Got handle %p for new cache process %lu", thehandle, winpid); InitializeCriticalSection (&access); LeaveCriticalSection (&process_access); } diff --git a/winsup/cygwin/cygserver_shm.cc b/winsup/cygwin/cygserver_shm.cc index 7f0496e0b51..6e4b71655b3 100755 --- a/winsup/cygwin/cygserver_shm.cc +++ b/winsup/cygwin/cygserver_shm.cc @@ -1,14 +1,14 @@ /* cygserver_shm.cc: Single unix specification IPC interface for Cygwin -Copyright 2001, 2002 Red Hat, Inc. + Copyright 2001, 2002 Red Hat, Inc. -Originally written by Robert Collins <robert.collins@hotmail.com> + Originally written by Robert Collins <robert.collins@hotmail.com> -This file is part of Cygwin. + 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. */ + This software is a copyrighted work licensed under the terms of the + Cygwin license. Please consult the file "CYGWIN_LICENSE" for + details. */ #include "woutsup.h" @@ -54,7 +54,7 @@ getsystemallocgranularity () client_request_shm::client_request_shm ():client_request (CYGSERVER_REQUEST_SHM_GET, - sizeof (parameters)) + sizeof (parameters)) { buffer = (char *) ¶meters; } @@ -185,18 +185,11 @@ delete_shmnode (shmnode **nodeptr) void client_request_shm::serve (transport_layer_base * conn, process_cache * cache) { -// DWORD sd_size = 4096; -// char sd_buf[4096]; - PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) parameters.in.sd_buf; -// /* create a sd for our open requests based on shmflag & 0x01ff */ -// psd = alloc_sd (getuid (), getgid (), cygheap->user.logsrv (), -// parameters.in.shmflg & 0x01ff, psd, &sd_size); - HANDLE from_process_handle = NULL; HANDLE token_handle = NULL; DWORD rc; - from_process_handle = cache->process (parameters.in.pid)->handle (); + from_process_handle = cache->process (parameters.in.winpid)->handle (); /* possible TODO: reduce the access on the handle before we use it */ /* Note that unless we do this, we don't need to call CloseHandle - it's kept open * by the process cache until the process terminates. @@ -209,31 +202,23 @@ client_request_shm::serve (transport_layer_base * conn, process_cache * cache) return; } - conn->impersonate_client (); - - rc = OpenThreadToken (GetCurrentThread (), - TOKEN_QUERY, TRUE, &token_handle); - - conn->revert_to_self (); - - if (!rc) + if (wincap.has_security ()) { - debug_printf ("error opening thread token (%lu)", GetLastError ()); - header.error_code = EACCES; - CloseHandle (from_process_handle); - return; - } + conn->impersonate_client (); + rc = OpenThreadToken (GetCurrentThread (), + TOKEN_QUERY, TRUE, &token_handle); - /* we trust the clients request - we will be doing it as them, and - * the worst they can do is open their own permissions - */ - + conn->revert_to_self (); - SECURITY_ATTRIBUTES sa; - sa.nLength = sizeof (sa); - sa.lpSecurityDescriptor = psd; - sa.bInheritHandle = TRUE; /* the memory structures inherit ok */ + if (!rc) + { + debug_printf ("error opening thread token (%lu)", GetLastError ()); + header.error_code = EACCES; + CloseHandle (from_process_handle); + return; + } + } char *shmname = NULL, *shmaname = NULL; char stringbuf[29], stringbuf1[29]; @@ -473,6 +458,16 @@ client_request_shm::serve (transport_layer_base * conn, process_cache * cache) /* couldn't find a currently open shm area. */ /* create one */ + + /* we trust the clients request - we will be doing it as them, and + * the worst they can do is open their own permissions + */ + + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof (sa); + sa.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR) parameters.in.sd_buf; + sa.bInheritHandle = TRUE; /* the memory structures inherit ok */ + /* do this as the client */ conn->impersonate_client (); /* This may need sh_none... it's only a control structure */ @@ -482,8 +477,8 @@ client_request_shm::serve (transport_layer_base * conn, process_cache * cache) 0x00000000, getsystemallocgranularity (), shmname // object name - ); - int lasterr = GetLastError (); + ); + DWORD lasterr = GetLastError (); conn->revert_to_self (); if (filemap == NULL) diff --git a/winsup/cygwin/cygserver_shm.h b/winsup/cygwin/cygserver_shm.h index f1dcaa53f48..6d8e21c9552 100644 --- a/winsup/cygwin/cygserver_shm.h +++ b/winsup/cygwin/cygserver_shm.h @@ -26,12 +26,11 @@ class client_request_shm : public client_request #ifndef __INSIDE_CYGWIN__ virtual void serve (transport_layer_base *conn, process_cache *cache); #endif - client_request_shm (key_t, size_t, int, char psdbuf[4096], pid_t); + client_request_shm (key_t ntype, size_t nsize, int shmflg); client_request_shm (); - client_request_shm (int, int, pid_t); - client_request_shm (int, int); + client_request_shm (int ntype, int nshmid); union { - struct {int type; pid_t pid; int shm_id; key_t key; size_t size; int shmflg; char sd_buf[4096];} in; + struct {int type; pid_t cygpid; DWORD winpid; int shm_id; key_t key; size_t size; int shmflg; char sd_buf[4096];} in; struct {int shm_id; HANDLE filemap; HANDLE attachmap; key_t key;} out; } parameters; }; diff --git a/winsup/cygwin/include/cygwin/cygserver_process.h b/winsup/cygwin/include/cygwin/cygserver_process.h index c8ff40b091e..098600b775d 100755 --- a/winsup/cygwin/include/cygwin/cygserver_process.h +++ b/winsup/cygwin/include/cygwin/cygserver_process.h @@ -38,15 +38,15 @@ public: cleanup_routine () : next (NULL) {}; class cleanup_routine * next; /* MUST BE SYNCHRONOUS */ - virtual void cleanup (long winpid); + virtual void cleanup (DWORD winpid); }; class process { public: HANDLE handle (); - long winpid; - process (long); + DWORD winpid; + process (DWORD winpid); ~process (); DWORD exit_code (); class process * next; @@ -67,7 +67,7 @@ class process_cache:public threaded_queue public: process_cache (unsigned int initial_workers); virtual ~ process_cache (); - class process *process (long); + class process *process (DWORD winpid); /* remove a process from the cache */ int handle_snapshot (HANDLE *, class process **, ssize_t, int); void remove_process (class process *); diff --git a/winsup/cygwin/shm.cc b/winsup/cygwin/shm.cc index b14eb4d35fa..581cc6585f6 100644 --- a/winsup/cygwin/shm.cc +++ b/winsup/cygwin/shm.cc @@ -12,6 +12,7 @@ details. */ #include "winsup.h" #include <sys/stat.h> +#include <assert.h> #include <errno.h> #include "cygerrno.h" #include <unistd.h> @@ -44,37 +45,61 @@ getsystemallocgranularity () return buffer_offset; } -client_request_shm::client_request_shm (int ntype, int nshm_id): -client_request (CYGSERVER_REQUEST_SHM_GET, sizeof (parameters)) +/* + * Used for: SHM_ATTACH, SHM_DETACH, SHM_REATTACH, and SHM_DEL. + */ +client_request_shm::client_request_shm (int ntype, int nshmid) + : client_request (CYGSERVER_REQUEST_SHM_GET, sizeof (parameters)) { - buffer = (char *) ¶meters; - parameters.in.shm_id = nshm_id; - parameters.in.type = SHM_REATTACH; - parameters.in.pid = GetCurrentProcessId (); -} + assert (ntype == SHM_REATTACH \ + || ntype == SHM_ATTACH \ + || ntype == SHM_DETACH \ + || ntype == SHM_DEL); -client_request_shm::client_request_shm (int ntype, int nshm_id, pid_t npid): -client_request (CYGSERVER_REQUEST_SHM_GET, sizeof (parameters)) -{ buffer = (char *) ¶meters; - parameters.in.shm_id = nshm_id; + parameters.in.type = ntype; - parameters.in.pid = npid; + parameters.in.cygpid = getpid (); + parameters.in.winpid = GetCurrentProcessId (); + parameters.in.shm_id = nshmid; + + assert (parameters.in.cygpid > 0); + assert (parameters.in.winpid != 0); + + debug_printf ("created: ntype = %d, shmid = %d", ntype, nshmid); } -client_request_shm::client_request_shm (key_t nkey, size_t nsize, - int nshmflg, - char psdbuf[4096], - pid_t npid): -client_request (CYGSERVER_REQUEST_SHM_GET, sizeof (parameters)) +/* + * Used for: SHM_CREATE. + */ +client_request_shm::client_request_shm (key_t nkey, size_t nsize, int nshmflg) + : client_request (CYGSERVER_REQUEST_SHM_GET, sizeof (parameters)) { + assert (nkey != (key_t) -1); + assert (nsize >= 0); + buffer = (char *) ¶meters; + + parameters.in.type = SHM_CREATE; + parameters.in.cygpid = getpid (); + parameters.in.winpid = GetCurrentProcessId (); parameters.in.key = nkey; parameters.in.size = nsize; parameters.in.shmflg = nshmflg; - parameters.in.type = SHM_CREATE; - parameters.in.pid = npid; - memcpy (parameters.in.sd_buf, psdbuf, 4096); + + assert (parameters.in.cygpid > 0); + assert (parameters.in.winpid != 0); + + if (wincap.has_security ()) + { + SECURITY_ATTRIBUTES sa = sec_none; + set_security_attribute (nshmflg & 0777, &sa, + parameters.in.sd_buf, + sizeof (parameters.in.sd_buf)); + } + + debug_printf ("created: key = 0x%0llx, size = %ld, shmflg = %o", + nkey, nsize, nshmflg); } static shmnode *shm_head = NULL; @@ -223,8 +248,7 @@ shmat (int shmid, const void *shmaddr, int shmflg) /* couldn't find a currently open shm control area for the key - probably because * shmget hasn't been called. * Allocate a new control block - this has to be handled by the daemon */ - client_request_shm *req = - new client_request_shm (SHM_REATTACH, shmid, GetCurrentProcessId ()); + client_request_shm *req = new client_request_shm (SHM_REATTACH, shmid); int rc; if ((rc = cygserver_request (req))) @@ -276,8 +300,7 @@ shmat (int shmid, const void *shmaddr, int shmflg) return (void *) -1; } /* tell the daemon we have attached */ - client_request_shm *req = - new client_request_shm (SHM_ATTACH, shmid); + client_request_shm *req = new client_request_shm (SHM_ATTACH, shmid); int rc; if ((rc = cygserver_request (req))) { @@ -326,7 +349,7 @@ shmdt (const void *shmaddr) UnmapViewOfFile (attachnode->data); /* tell the daemon we have attached */ client_request_shm *req = - new client_request_shm (SHM_DETACH, tempnode->shm_id); + new client_request_shm (SHM_DETACH, tempnode->shm_id); int rc; if ((rc = cygserver_request (req))) { @@ -349,8 +372,7 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf) /* couldn't find a currently open shm control area for the key - probably because * shmget hasn't been called. * Allocate a new control block - this has to be handled by the daemon */ - client_request_shm *req = - new client_request_shm (SHM_REATTACH, shmid, GetCurrentProcessId ()); + client_request_shm *req = new client_request_shm (SHM_REATTACH, shmid); int rc; if ((rc = cygserver_request (req))) @@ -409,8 +431,7 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf) * daemon has an attach. The daemon gets asked to detach immediately. */ //waiting for the daemon to handle terminating process's - client_request_shm *req = - new client_request_shm (SHM_DEL, shmid, GetCurrentProcessId ()); + client_request_shm *req = new client_request_shm (SHM_DEL, shmid); int rc; if ((rc = cygserver_request (req))) { @@ -455,15 +476,6 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf) extern "C" int shmget (key_t key, size_t size, int shmflg) { - DWORD sd_size = 4096; - char sd_buf[4096]; - PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf; - /* create a sd for our open requests based on shmflag & 0x01ff */ - InitializeSecurityDescriptor (psd, - SECURITY_DESCRIPTOR_REVISION); - psd = alloc_sd (getuid32 (), getgid32 (), - shmflg & 0x01ff, psd, &sd_size); - if (key == (key_t) - 1) { set_errno (ENOENT); @@ -503,9 +515,7 @@ shmget (key_t key, size_t size, int shmflg) } /* couldn't find a currently open shm control area for the key. * Allocate a new control block - this has to be handled by the daemon */ - client_request_shm *req = - new client_request_shm (key, size, shmflg, sd_buf, - GetCurrentProcessId ()); + client_request_shm *req = new client_request_shm (key, size, shmflg); int rc; if ((rc = cygserver_request (req))) |