* cygheap.cc (cygheap_init): Fix formatting. Remove comment. Set

shared_prefix depending only on terminal service capability.
	* dcrt0.cc (dll_crt0_1): Don't call set_cygwin_privileges here.
	* fhandler_fifo.cc (fhandler_fifo::open): Create the mutex as global
	object.
	* posix_ipc.cc (ipc_mutex_init): Use cygheap->shared_prefix.
	(ipc_cond_init): Ditto.
	* sec_helper.cc (privilege_name): Make static.  Use LookupPrivilegeName
	directly to be independent of the state of cygheap.
	(set_privilege): Take a LUID as parameter instead of an index value.
	Only print debug output in case of failure.
	(set_cygwin_privileges): Add comment.  Use LookupPrivilegeValue to
	get privilege LUIDs.
	(init_global_security): Call set_cygwin_privileges here.
	* security.h (privilege_name): Drop declaration.
	(set_privilege): Declare according to above change.
	(set_process_privilege): Call privilege_luid to get LUID.
	(_push_thread_privilege): Ditto.
	* shared.cc (open_shared): Add comment.  On systems supporting the
	SeCreateGlobalPrivilege, try to create/open global shared memory first.
	Fall back to local shared memory if that fails.
	* thread.cc (semaphore::semaphore): Use cygheap->shared_prefix.
	* wincap.h (wincapc::has_create_global_privilege): New element.
	* wincap.cc: Implement above element throughout.
This commit is contained in:
Corinna Vinschen 2007-03-29 16:37:36 +00:00
parent 519aec5d59
commit e6fbf13e48
11 changed files with 111 additions and 58 deletions

View File

@ -1,3 +1,30 @@
2007-03-29 Corinna Vinschen <corinna@vinschen.de>
* cygheap.cc (cygheap_init): Fix formatting. Remove comment. Set
shared_prefix depending only on terminal service capability.
* dcrt0.cc (dll_crt0_1): Don't call set_cygwin_privileges here.
* fhandler_fifo.cc (fhandler_fifo::open): Create the mutex as global
object.
* posix_ipc.cc (ipc_mutex_init): Use cygheap->shared_prefix.
(ipc_cond_init): Ditto.
* sec_helper.cc (privilege_name): Make static. Use LookupPrivilegeName
directly to be independent of the state of cygheap.
(set_privilege): Take a LUID as parameter instead of an index value.
Only print debug output in case of failure.
(set_cygwin_privileges): Add comment. Use LookupPrivilegeValue to
get privilege LUIDs.
(init_global_security): Call set_cygwin_privileges here.
* security.h (privilege_name): Drop declaration.
(set_privilege): Declare according to above change.
(set_process_privilege): Call privilege_luid to get LUID.
(_push_thread_privilege): Ditto.
* shared.cc (open_shared): Add comment. On systems supporting the
SeCreateGlobalPrivilege, try to create/open global shared memory first.
Fall back to local shared memory if that fails.
* thread.cc (semaphore::semaphore): Use cygheap->shared_prefix.
* wincap.h (wincapc::has_create_global_privilege): New element.
* wincap.cc: Implement above element throughout.
2007-03-28 Christopher Faylor <me@cgf.cx>
* spawn.cc (spawn_guts): Start pure-windows processes in a suspended

View File

@ -153,7 +153,8 @@ cygheap_init ()
cygheap_protect.init ("cygheap_protect");
if (!cygheap)
{
cygheap = (init_cygheap *) memset (_cygheap_start, 0, _cygheap_mid - _cygheap_start);
cygheap = (init_cygheap *) memset (_cygheap_start, 0,
_cygheap_mid - _cygheap_start);
cygheap_max = cygheap;
_csbrk (sizeof (*cygheap));
}
@ -162,35 +163,9 @@ cygheap_init ()
if (!cygheap->sigs)
sigalloc ();
/* TODO: This is plain wrong. There's a difference between global shared
memory and every other global object. It's still allowed to
create any global object from a process not having the
SE_CREATE_GLOBAL_NAME privilege. It's only disallowed to create
global shared memory objects when not running in session 0 or
when not having the privilege.
The end result should look like this:
- All objects shared between multiple processes except shared
memory should always be created as global objects.
- Shared memory only needed locally should stick to being session
local.
- Every process should always try to create resp. open shared
memory as global.
- Only if that fails it should try to create the shared memory
as local shared memory, or ...
- ... the MS suggested workaround is to create a file backed shared
memory if a process has not the privilege to create global shared
memory.
However, this has to be planned carefully, especially given that
every single process creates its own (resp. the child's) shared
memory area with the process specific information. */
if (!cygheap->shared_prefix)
cygheap->shared_prefix = cstrdup (
wincap.has_terminal_services ()
&& (set_privilege (hProcToken, SE_CREATE_GLOBAL_PRIV, true) >= 0
|| GetLastError () == ERROR_NO_SUCH_PRIVILEGE)
? "Global\\" : "");
wincap.has_terminal_services () ? "Global\\" : "");
}
/* Copyright (C) 1997, 2000 DJ Delorie */

View File

@ -839,9 +839,6 @@ dll_crt0_1 (void *)
#endif
pinfo_init (envp, envc);
/* Can be set only after environment has been initialized. */
set_cygwin_privileges (hProcToken);
if (!old_title && GetConsoleTitle (title_buf, TITLESIZE))
old_title = title_buf;

View File

@ -155,7 +155,8 @@ fhandler_fifo::open (int flags, mode_t)
/* Generate a semi-unique name to associate with this fifo but try to ensure
that it is no larger than CYG_MAX_PATH */
for (p = mutex, p1 = strchr (get_name (), '\0');
strcpy (mutex, cygheap->shared_prefix);
for (p = mutex + strlen (mutex), p1 = strchr (get_name (), '\0');
--p1 >= get_name () && p < emutex ; p++)
*p = (*p1 == '/') ? '_' : *p1;
strncpy (p, FIFO_PREFIX, emutex - p);

View File

@ -13,6 +13,9 @@ details. */
#include "path.h"
#include "cygerrno.h"
#include "cygtls.h"
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
#include "security.h"
#include "sigproc.h"
#include <sys/stat.h>
@ -89,8 +92,7 @@ static int
ipc_mutex_init (HANDLE *pmtx, const char *name)
{
char buf[CYG_MAX_PATH];
__small_sprintf (buf, "%scyg_pmtx/%s",
wincap.has_terminal_services () ? "Global\\" : "", name);
__small_sprintf (buf, "%scyg_pmtx/%s", cygheap->shared_prefix, name);
*pmtx = CreateMutex (&sec_all, FALSE, buf);
if (!*pmtx)
debug_printf ("failed: %E\n");
@ -132,8 +134,7 @@ static int
ipc_cond_init (HANDLE *pevt, const char *name)
{
char buf[CYG_MAX_PATH];
__small_sprintf (buf, "%scyg_pevt/%s",
wincap.has_terminal_services () ? "Global\\" : "", name);
__small_sprintf (buf, "%scyg_pevt/%s", cygheap->shared_prefix, name);
*pevt = CreateEvent (&sec_all, TRUE, FALSE, buf);
if (!*pevt)
debug_printf ("failed: %E\n");

View File

@ -427,23 +427,22 @@ privilege_luid_by_name (const char *pname)
return NULL;
}
const char *
privilege_name (cygpriv_idx idx)
static const char *
privilege_name (const LUID *priv_luid, char *buf, DWORD *size)
{
if (idx < 0 || idx >= SE_NUM_PRIVS)
if (!priv_luid || !LookupPrivilegeName (NULL, (LUID *) priv_luid, buf, size))
return "<unknown privilege>";
return cygpriv[idx];
return buf;
}
int
set_privilege (HANDLE token, cygpriv_idx privilege, bool enable)
set_privilege (HANDLE token, const LUID *priv_luid, bool enable)
{
int ret = -1;
const LUID *priv_luid;
TOKEN_PRIVILEGES new_priv, orig_priv;
DWORD size;
if (!(priv_luid = privilege_luid (privilege)))
if (!priv_luid)
{
__seterrno ();
goto out;
@ -474,16 +473,29 @@ set_privilege (HANDLE token, cygpriv_idx privilege, bool enable)
ret = (orig_priv.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED) ? 1 : 0;
out:
syscall_printf ("%d = set_privilege ((token %x) %s, %d)",
ret, token, privilege_name (privilege), enable);
if (ret < 0)
{
DWORD siz = 256;
char buf[siz];
debug_printf ("%d = set_privilege ((token %x) %s, %d)",
ret, token, privilege_name (priv_luid, buf, &siz), enable);
}
return ret;
}
/* This is called very early in process initialization. The code must
not depend on anything. */
void
set_cygwin_privileges (HANDLE token)
{
set_privilege (token, SE_RESTORE_PRIV, true);
set_privilege (token, SE_BACKUP_PRIV, true);
LUID priv_luid;
if (LookupPrivilegeValue (NULL, SE_RESTORE_NAME, &priv_luid))
set_privilege (token, &priv_luid, true);
if (LookupPrivilegeValue (NULL, SE_BACKUP_NAME, &priv_luid))
set_privilege (token, &priv_luid, true);
if (LookupPrivilegeValue (NULL, SE_CREATE_GLOBAL_NAME, &priv_luid))
set_privilege (token, &priv_luid, true);
}
/* Function to return a common SECURITY_DESCRIPTOR that
@ -518,6 +530,8 @@ init_global_security ()
sec_none.lpSecurityDescriptor = sec_none_nih.lpSecurityDescriptor = NULL;
sec_all.lpSecurityDescriptor = sec_all_nih.lpSecurityDescriptor =
get_null_sd ();
set_cygwin_privileges (hProcToken);
}
bool

View File

@ -321,7 +321,6 @@ enum cygpriv_idx {
const LUID *privilege_luid (enum cygpriv_idx idx);
const LUID *privilege_luid_by_name (const char *pname);
const char *privilege_name (enum cygpriv_idx idx);
inline BOOL
legal_sid_type (SID_NAME_USE type)
@ -381,10 +380,10 @@ bool get_logon_server (const char * domain, char * server, WCHAR *wserver,
bool rediscovery);
/* sec_helper.cc: Security helper functions. */
int set_privilege (HANDLE token, enum cygpriv_idx privilege, bool enable);
int set_privilege (HANDLE token, const LUID *priv_luid, bool enable);
void set_cygwin_privileges (HANDLE token);
#define set_process_privilege(p,v) set_privilege (hProcToken, (p), (v))
#define set_process_privilege(p,v) set_privilege (hProcToken, privilege_luid (p), (v))
#define _push_thread_privilege(_priv, _val, _check) { \
HANDLE _dup_token = NULL; \
@ -397,7 +396,7 @@ void set_cygwin_privileges (HANDLE token);
else if (!ImpersonateLoggedOnUser (_dup_token)) \
debug_printf ("ImpersonateLoggedOnUser: %E"); \
else \
set_privilege (_dup_token, (_priv), (_val));
set_privilege (_dup_token, privilege_luid (_priv), (_val));
#define push_thread_privilege(_priv, _val) _push_thread_privilege(_priv,_val,1)
#define push_self_privilege(_priv, _val) _push_thread_privilege(_priv,_val,0)

View File

@ -84,16 +84,43 @@ open_shared (const char *name, int n, HANDLE& shared_h, DWORD size,
m = SH_JUSTOPEN;
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)
mapname = shared_name (map_buf, name, n);
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
{
shared_h = CreateFileMapping (INVALID_HANDLE_VALUE, psa, PAGE_READWRITE,
0, size, mapname);
if (GetLastError () == ERROR_ALREADY_EXISTS)
m = SH_JUSTOPEN;
shared_h = CreateFileMapping (INVALID_HANDLE_VALUE, psa,
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)
m = SH_JUSTOPEN;
}
break;
}
}
if (shared_h)
/* ok! */;

View File

@ -29,6 +29,7 @@ details. */
#include "winsup.h"
#include <limits.h>
#include "path.h"
#include "cygerrno.h"
#include <assert.h>
#include <stdlib.h>
@ -37,6 +38,9 @@ details. */
#include "perprocess.h"
#include "security.h"
#include "cygtls.h"
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
#include <semaphore.h>
#include <stdio.h>
#include <sys/timeb.h>
@ -2968,8 +2972,7 @@ semaphore::semaphore (unsigned long long shash, LUID sluid, int sfd,
{
char name[CYG_MAX_PATH];
__small_sprintf (name, "%scyg_psem/cyg%016X%08x%08x",
wincap.has_terminal_services () ? "Global\\" : "",
__small_sprintf (name, "%scyg_psem/cyg%016X%08x%08x", cygheap->shared_prefix,
hash, luid.HighPart, luid.LowPart);
this->win32_obj_id = ::CreateSemaphore (&sec_all, value, LONG_MAX, name);
if (!this->win32_obj_id)

View File

@ -21,6 +21,7 @@ static NO_COPY wincaps wincap_unknown = {
has_physical_mem_access:true,
has_process_io_counters:false,
has_terminal_services:false,
has_create_global_privilege:false,
has_ioctl_storage_get_media_types_ex:false,
has_extended_priority_class:false,
has_guid_volumes:false,
@ -47,6 +48,7 @@ static NO_COPY wincaps wincap_nt4 = {
has_physical_mem_access:true,
has_process_io_counters:false,
has_terminal_services:false,
has_create_global_privilege:false,
has_ioctl_storage_get_media_types_ex:false,
has_extended_priority_class:false,
has_guid_volumes:false,
@ -73,6 +75,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
has_physical_mem_access:true,
has_process_io_counters:false,
has_terminal_services:false,
has_create_global_privilege:false,
has_ioctl_storage_get_media_types_ex:false,
has_extended_priority_class:false,
has_guid_volumes:false,
@ -99,6 +102,7 @@ static NO_COPY wincaps wincap_2000 = {
has_physical_mem_access:true,
has_process_io_counters:true,
has_terminal_services:true,
has_create_global_privilege:false,
has_ioctl_storage_get_media_types_ex:false,
has_extended_priority_class:true,
has_guid_volumes:true,
@ -125,6 +129,7 @@ static NO_COPY wincaps wincap_xp = {
has_physical_mem_access:true,
has_process_io_counters:true,
has_terminal_services:true,
has_create_global_privilege:false,
has_ioctl_storage_get_media_types_ex:true,
has_extended_priority_class:true,
has_guid_volumes:true,
@ -151,6 +156,7 @@ static NO_COPY wincaps wincap_2003 = {
has_physical_mem_access:false,
has_process_io_counters:true,
has_terminal_services:true,
has_create_global_privilege:true,
has_ioctl_storage_get_media_types_ex:true,
has_extended_priority_class:true,
has_guid_volumes:true,
@ -177,6 +183,7 @@ static NO_COPY wincaps wincap_vista = {
has_physical_mem_access:false,
has_process_io_counters:true,
has_terminal_services:true,
has_create_global_privilege:true,
has_ioctl_storage_get_media_types_ex:true,
has_extended_priority_class:true,
has_guid_volumes:true,

View File

@ -21,6 +21,7 @@ struct wincaps
unsigned has_physical_mem_access : 1;
unsigned has_process_io_counters : 1;
unsigned has_terminal_services : 1;
unsigned has_create_global_privilege : 1;
unsigned has_ioctl_storage_get_media_types_ex : 1;
unsigned has_extended_priority_class : 1;
unsigned has_guid_volumes : 1;
@ -63,6 +64,7 @@ public:
bool IMPLEMENT (has_physical_mem_access)
bool IMPLEMENT (has_process_io_counters)
bool IMPLEMENT (has_terminal_services)
bool IMPLEMENT (has_create_global_privilege)
bool IMPLEMENT (has_ioctl_storage_get_media_types_ex)
bool IMPLEMENT (has_extended_priority_class)
bool IMPLEMENT (has_guid_volumes)