* flock.cc (FLOCK_PARENT_DIR_ACCESS): Define.

(FLOCK_INODE_DIR_ACCESS): Define.
	(FLOCK_MUTANT_ACCESS): Define.
	(FLOCK_EVENT_ACCESS): Define.
	(SD_MIN_SIZE): Define.
	(everyone_sd): Define to simplify calling _everyone_sd.
	(_everyone_sd): Replace everyone_sync_sd.  Take SECURITY_DESCRIPTOR as
	argument and allow to specify access mask.
	(get_lock_parent_dir): Open/Create parent dir with
	FLOCK_PARENT_DIR_ACCESS.  Add text to api_fatal message.
	(inode_t::inode_t): Open/Create dir with FLOCK_INODE_DIR_ACCESS.
	Open/Create mutant with FLOCK_MUTANT_ACCESS.  Add text to api_fatal
	message.
	(lockf_t::create_lock_obj): Create event with FLOCK_EVENT_ACCESS.
	Add text to api_fatal message.
	(lockf_t::open_lock_obj): Open event with FLOCK_EVENT_ACCESS.
	On failure, just return NULL pointer instead of calling api_fatal.
	(lockf_t::get_lock_obj_handle_count): Replace call to small_printf
	with call to debug_printf.
	(lf_setlock): Handle a failure to open the lock event object as
	EDEADLK.  Call system_printf if opening sync objects fail.
	* ntdll.h (DIRECTORY_TRAVERSE): Define.
	(DIRECTORY_CREATE_OBJECT): Define.
	(DIRECTORY_CREATE_SUBDIRECTORY): Define.
	(EVENT_QUERY_STATE): Define.
This commit is contained in:
Corinna Vinschen 2008-03-27 20:03:32 +00:00
parent b5f9c24f7e
commit c46d7be9a6
3 changed files with 97 additions and 31 deletions

View File

@ -1,3 +1,31 @@
2008-03-27 Corinna Vinschen <corinna@vinschen.de>
* flock.cc (FLOCK_PARENT_DIR_ACCESS): Define.
(FLOCK_INODE_DIR_ACCESS): Define.
(FLOCK_MUTANT_ACCESS): Define.
(FLOCK_EVENT_ACCESS): Define.
(SD_MIN_SIZE): Define.
(everyone_sd): Define to simplify calling _everyone_sd.
(_everyone_sd): Replace everyone_sync_sd. Take SECURITY_DESCRIPTOR as
argument and allow to specify access mask.
(get_lock_parent_dir): Open/Create parent dir with
FLOCK_PARENT_DIR_ACCESS. Add text to api_fatal message.
(inode_t::inode_t): Open/Create dir with FLOCK_INODE_DIR_ACCESS.
Open/Create mutant with FLOCK_MUTANT_ACCESS. Add text to api_fatal
message.
(lockf_t::create_lock_obj): Create event with FLOCK_EVENT_ACCESS.
Add text to api_fatal message.
(lockf_t::open_lock_obj): Open event with FLOCK_EVENT_ACCESS.
On failure, just return NULL pointer instead of calling api_fatal.
(lockf_t::get_lock_obj_handle_count): Replace call to small_printf
with call to debug_printf.
(lf_setlock): Handle a failure to open the lock event object as
EDEADLK. Call system_printf if opening sync objects fail.
* ntdll.h (DIRECTORY_TRAVERSE): Define.
(DIRECTORY_CREATE_OBJECT): Define.
(DIRECTORY_CREATE_SUBDIRECTORY): Define.
(EVENT_QUERY_STATE): Define.
2008-03-27 Corinna Vinschen <corinna@vinschen.de>
* syscalls.cc (rename): Fix setting errno in case of trailing "/."

View File

@ -216,23 +216,42 @@ allow_others_to_sync ()
}
/* Helper function to create an event security descriptor which only allows
SYNCHRONIZE access to everyone. Only the creating process has all access
specific access to everyone. Only the creating process has all access
rights. */
static PSECURITY_DESCRIPTOR
everyone_sync_sd ()
{
static PSECURITY_DESCRIPTOR psd;
if (!psd)
#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)
{
const size_t acl_len = sizeof (ACL) +
sizeof (ACCESS_ALLOWED_ACE) + MAX_SID_LEN;
psd = (PSECURITY_DESCRIPTOR)
malloc (sizeof (SECURITY_DESCRIPTOR) + acl_len);
InitializeSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION);
PACL dacl = (PACL) (psd + 1);
InitializeAcl (dacl, acl_len, ACL_REVISION);
if (!AddAccessAllowedAce (dacl, ACL_REVISION, SYNCHRONIZE,
InitializeAcl (dacl, MAX_DACL_LEN (1), ACL_REVISION);
if (!AddAccessAllowedAce (dacl, ACL_REVISION, access,
well_known_world_sid))
{
debug_printf ("AddAccessAllowedAce: %lu", GetLastError ());
@ -265,13 +284,14 @@ get_lock_parent_dir ()
{
RtlInitUnicodeString (&uname, L"\\BaseNamedObjects\\cygwin-fcntl-lk");
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, NULL,
sec_all.lpSecurityDescriptor);
status = NtOpenDirectoryObject (&dir, DIRECTORY_ALL_ACCESS, &attr);
everyone_sd (FLOCK_PARENT_DIR_ACCESS));
status = NtOpenDirectoryObject (&dir, FLOCK_PARENT_DIR_ACCESS, &attr);
if (!NT_SUCCESS (status))
{
status = NtCreateDirectoryObject (&dir, DIRECTORY_ALL_ACCESS, &attr);
status = NtCreateDirectoryObject (&dir, FLOCK_PARENT_DIR_ACCESS,
&attr);
if (!NT_SUCCESS (status))
api_fatal ("NtCreateDirectoryObject: %p", status);
api_fatal ("NtCreateDirectoryObject(parent): %p", status);
}
}
INODE_LIST_UNLOCK ();
@ -446,25 +466,25 @@ inode_t::inode_t (dev_t dev, ino_t ino)
int len = __small_swprintf (name, L"%08x-%016X", dev, ino);
RtlInitCountedUnicodeString (&uname, name, len * sizeof (WCHAR));
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, parent_dir,
sec_all.lpSecurityDescriptor);
status = NtOpenDirectoryObject (&i_dir, DIRECTORY_ALL_ACCESS, &attr);
everyone_sd (FLOCK_INODE_DIR_ACCESS));
status = NtOpenDirectoryObject (&i_dir, FLOCK_INODE_DIR_ACCESS, &attr);
if (!NT_SUCCESS (status))
{
status = NtCreateDirectoryObject (&i_dir, DIRECTORY_ALL_ACCESS, &attr);
status = NtCreateDirectoryObject (&i_dir, FLOCK_INODE_DIR_ACCESS, &attr);
if (!NT_SUCCESS (status))
api_fatal ("NtCreateDirectoryObject: %p", status);
api_fatal ("NtCreateDirectoryObject(inode): %p", status);
}
/* Create a mutex object in the file specific dir, which is used for
access synchronization on the dir and its objects. */
RtlInitUnicodeString (&uname, L"mtx");
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, i_dir,
sec_all.lpSecurityDescriptor);
status = NtOpenMutant (&i_mtx, MUTANT_ALL_ACCESS, &attr);
everyone_sd (FLOCK_MUTANT_ACCESS));
status = NtOpenMutant (&i_mtx, FLOCK_MUTANT_ACCESS, &attr);
if (!NT_SUCCESS (status))
{
status = NtCreateMutant (&i_mtx, MUTANT_ALL_ACCESS, &attr, FALSE);
status = NtCreateMutant (&i_mtx, FLOCK_MUTANT_ACCESS, &attr, FALSE);
if (!NT_SUCCESS (status))
api_fatal ("NtCreateMutant: %p", status);
api_fatal ("NtCreateMutant(inode): %p", status);
}
}
@ -553,11 +573,11 @@ lockf_t::create_lock_obj ()
RtlInitCountedUnicodeString (&uname, name,
LOCK_OBJ_NAME_LEN * sizeof (WCHAR));
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, lf_inode->i_dir,
everyone_sync_sd ());
everyone_sd (FLOCK_EVENT_ACCESS));
status = NtCreateEvent (&lf_obj, EVENT_ALL_ACCESS, &attr,
NotificationEvent, FALSE);
if (!NT_SUCCESS (status))
api_fatal ("NtCreateEvent: %p", status);
api_fatal ("NtCreateEvent(lock): %p", status);
}
/* Open a lock event object for SYNCHRONIZE access (to wait for it). */
@ -577,9 +597,12 @@ lockf_t::open_lock_obj () const
LOCK_OBJ_NAME_LEN * sizeof (WCHAR));
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT, lf_inode->i_dir,
NULL);
status = NtOpenEvent (&obj, SYNCHRONIZE, &attr);
status = NtOpenEvent (&obj, FLOCK_EVENT_ACCESS, &attr);
if (!NT_SUCCESS (status))
api_fatal ("NtOpenEvent: %p", status);
{
SetLastError (RtlNtStatusToDosError (status));
return NULL;
}
return obj;
}
@ -596,7 +619,7 @@ lockf_t::get_lock_obj_handle_count () const
status = NtQueryObject (lf_obj, ObjectBasicInformation,
&obi, sizeof obi, NULL);
if (!NT_SUCCESS (status))
small_printf ("NtQueryObject: %p\n", status);
debug_printf ("NtQueryObject: %p\n", status);
else
hdl_cnt = obi.HandleCount;
}
@ -892,13 +915,23 @@ lf_setlock (lockf_t *lock, inode_t *node, lockf_t **clean)
/* Wait for the blocking object and its holding process. */
HANDLE obj = block->open_lock_obj ();
if (!obj)
{
/* We can't synchronize on the lock event object.
Treat this as a deadlock-like situation for now. */
system_printf ("Can't sync with lock object hold by "
"Win32 pid %lu: %E", block->lf_wid);
NtClose (obj);
return EDEADLK;
}
HANDLE proc = OpenProcess (SYNCHRONIZE, FALSE, block->lf_wid);
if (!proc)
{
/* If we can't synchronize on the process holding the lock,
we will never recognize when the lock has been abandoned.
Treat this as a deadlock-like situation for now. */
debug_printf ("OpenProcess: %E");
system_printf ("Can't sync with process holding a lock "
"(Win32 pid %lu): %E", block->lf_wid);
NtClose (obj);
return EDEADLK;
}

View File

@ -1,6 +1,6 @@
/* ntdll.h. Contains ntdll specific stuff not defined elsewhere.
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc.
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
This file is part of Cygwin.
@ -189,8 +189,13 @@ typedef struct _FILE_ID_BOTH_DIR_INFORMATION
#define LOCK_VM_IN_RAM 2
#define DIRECTORY_QUERY 1
#define DIRECTORY_TRAVERSE 2
#define DIRECTORY_CREATE_OBJECT 4
#define DIRECTORY_CREATE_SUBDIRECTORY 8
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x0f)
#define EVENT_QUERY_STATE 1
typedef ULONG KAFFINITY;
typedef enum _SYSTEM_INFORMATION_CLASS