Fix various OS-related comments
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
bb0fc7a2c0
commit
00e9bf2bb3
|
@ -207,17 +207,16 @@ enum fcwd_version_t {
|
|||
FCWD_W8
|
||||
};
|
||||
|
||||
/* This class is used to store the CWD starting with Windows Vista.
|
||||
The CWD storage in the RTL_USER_PROCESS_PARAMETERS block is only
|
||||
an afterthought now. The actual CWD storage is a FAST_CWD structure
|
||||
which is allocated on the process heap. The new method only requires
|
||||
minimal locking and it's much more multi-thread friendly. Presumably
|
||||
it minimizes contention when accessing the CWD.
|
||||
/* This class is used to store the CWD. The CWD storage in the
|
||||
RTL_USER_PROCESS_PARAMETERS block is only an afterthought now. The actual
|
||||
CWD storage is a FAST_CWD structure which is allocated on the process heap.
|
||||
The new method only requires minimal locking and it's much more multi-thread
|
||||
friendly. Presumably it minimizes contention when accessing the CWD.
|
||||
The class fcwd_access_t is supposed to encapsulate the gory implementation
|
||||
details depending on OS version from the calling functions.
|
||||
The layout of all structures has been tested on 32 and 64 bit. */
|
||||
class fcwd_access_t {
|
||||
/* This is the layout used in Windows 8. */
|
||||
/* This is the layout used in Windows 8 and later. */
|
||||
struct FAST_CWD_8 {
|
||||
LONG ReferenceCount; /* Only release when this is 0. */
|
||||
HANDLE DirectoryHandle;
|
||||
|
|
|
@ -523,13 +523,12 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries)
|
|||
We DONT_RESOLVE_DLL_REFERENCES at first in case the DLL lands in
|
||||
the wrong spot;
|
||||
|
||||
NOTE: This step skips DLLs which loaded at their preferred
|
||||
address in the parent because they should behave (we already
|
||||
verified that their preferred address in the child is
|
||||
available). However, this may fail on a Vista/Win7 machine with
|
||||
ASLR active, because the ASLR base address will usually not equal
|
||||
the preferred base recorded in the dll. In this case, we should
|
||||
make the LoadLibraryExW call unconditional.
|
||||
NOTE: This step skips DLLs which loaded at their preferred address in
|
||||
the parent because they should behave (we already verified that their
|
||||
preferred address in the child is available). However, this may fail
|
||||
with ASLR active, because the ASLR base address will usually not equal
|
||||
the preferred base recorded in the dll. In this case, we should make
|
||||
the LoadLibraryExW call unconditional.
|
||||
*/
|
||||
for ( ; d; d = dlls.inext ())
|
||||
if (d->handle != d->preferred_base)
|
||||
|
|
|
@ -304,8 +304,8 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
|
|||
dev.parse (name);
|
||||
else if (strcmp (name, ":sock:") == 0
|
||||
/* NtQueryObject returns an error when called on an LSP socket
|
||||
handle. While fdsock now tries to fetch the underlying
|
||||
base socket, this only works on Vista and later. */
|
||||
handle. fdsock tries to fetch the underlying base socket,
|
||||
but this might fail. */
|
||||
|| (strcmp (name, unknown_file) == 0
|
||||
&& !::getsockopt ((SOCKET) handle, SOL_SOCKET, SO_RCVBUF,
|
||||
(char *) &rcv, &len)))
|
||||
|
|
|
@ -1888,12 +1888,11 @@ fhandler_disk_file::opendir (int fd)
|
|||
|
||||
NFS clients hide dangling symlinks from directory queries,
|
||||
unless you use the FileNamesInformation info class.
|
||||
On newer NFS clients (>=Vista) FileIdBothDirectoryInformation
|
||||
works fine, but only if the NFS share is mounted to a drive
|
||||
letter. TODO: We don't test that here for now, but it might
|
||||
be worth to test if there's a speed gain in using
|
||||
FileIdBothDirectoryInformation, because it doesn't require to
|
||||
open the file to read the inode number. */
|
||||
FileIdBothDirectoryInformation works fine, but only if the NFS
|
||||
share is mounted to a drive letter. TODO: We don't test that
|
||||
here for now, but it might be worth to test if there's a speed
|
||||
gain in using FileIdBothDirectoryInformation, because it doesn't
|
||||
require to open the file to read the inode number. */
|
||||
if (pc.hasgood_inode ())
|
||||
{
|
||||
dir->__flags |= dirent_set_d_ino;
|
||||
|
|
|
@ -38,11 +38,11 @@ eval_start_address ()
|
|||
So we let the heap start at 0x6:00000000L. */
|
||||
uintptr_t start_address = 0x600000000L;
|
||||
#else
|
||||
/* Starting with Vista, Windows performs heap ASLR. This spoils the entire
|
||||
region below 0x20000000 for us, because that region is used by Windows
|
||||
to randomize heap and stack addresses. Therefore we put our heap into a
|
||||
safe region starting at 0x20000000. This should work right from the start
|
||||
in 99% of the cases. */
|
||||
/* Windows performs heap ASLR. This spoils the entire region below
|
||||
0x20000000 for us, because that region is used by Windows to randomize
|
||||
heap and stack addresses. Therefore we put our heap into a safe region
|
||||
starting at 0x20000000. This should work right from the start in 99%
|
||||
of the cases. */
|
||||
uintptr_t start_address = 0x20000000L;
|
||||
if ((uintptr_t) NtCurrentTeb () >= 0xbf000000L)
|
||||
{
|
||||
|
|
|
@ -385,7 +385,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|||
and stuff like that. */
|
||||
&& !is_mvfs (RtlEqualUnicodePathPrefix (&fsname, &ro_u_mvfs, FALSE))
|
||||
/* NWFS == Novell Netware FS. Broken info class, see below. */
|
||||
/* NcFsd == Novell Netware FS via own driver since Windows Vista. */
|
||||
/* NcFsd == Novell Netware FS via own driver. */
|
||||
&& !is_nwfs (RtlEqualUnicodeString (&fsname, &ro_u_nwfs, FALSE))
|
||||
&& !is_ncfsd (RtlEqualUnicodeString (&fsname, &ro_u_ncfsd, FALSE))
|
||||
/* UNIXFS == TotalNet Advanced Server (TAS). Doesn't support
|
||||
|
|
|
@ -608,7 +608,7 @@ fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
|
|||
handle inheritance. An explanation for this weird behaviour would
|
||||
be nice, though.
|
||||
|
||||
NOTE 2. Testing on x86_64 (XP, Vista, 2008 R2, W8) indicates that
|
||||
NOTE 2. Testing on x86_64 (Vista, 2008 R2, W8) indicates that
|
||||
this is no problem on 64 bit. So we set the default buffer size to
|
||||
the default values in current 3.x Linux versions.
|
||||
|
||||
|
@ -1821,8 +1821,8 @@ get_adapters_addresses (PIP_ADAPTER_ADDRESSES *pa_ret, ULONG family)
|
|||
DWORD ret;
|
||||
gaa_wa param = { family, pa_ret };
|
||||
|
||||
if ((uintptr_t) ¶m >= (uintptr_t) 0x80000000L
|
||||
&& wincap.has_gaa_largeaddress_bug ())
|
||||
if (wincap.has_gaa_largeaddress_bug ()
|
||||
&& (uintptr_t) ¶m >= (uintptr_t) 0x80000000L)
|
||||
{
|
||||
/* In Windows Vista and Windows 7 under WOW64, GetAdaptersAddresses fails
|
||||
if it's running in a thread with a stack located in the large address
|
||||
|
@ -3371,8 +3371,8 @@ cygwin_getaddrinfo (const char *hostname, const char *servname,
|
|||
| AI_NUMERICSERV | AI_ADDRCONFIG | AI_V4MAPPED
|
||||
| AI_IDN_MASK)))
|
||||
return EAI_BADFLAGS;
|
||||
/* AI_NUMERICSERV is not supported prior to Windows Vista. We just check
|
||||
the servname parameter by ourselves here. */
|
||||
/* AI_NUMERICSERV is not supported "by Microsoft providers". We just
|
||||
check the servname parameter by ourselves here. */
|
||||
if (hints && (hints->ai_flags & AI_NUMERICSERV))
|
||||
{
|
||||
char *p;
|
||||
|
|
|
@ -2889,9 +2889,7 @@ restart:
|
|||
|
||||
/* Reparse points are potentially symlinks. This check must be
|
||||
performed before checking the SYSTEM attribute for sysfile
|
||||
symlinks, since reparse points can have this flag set, too.
|
||||
For instance, Vista starts to create a couple of reparse points
|
||||
with SYSTEM and HIDDEN flags set. */
|
||||
symlinks, since reparse points can have this flag set, too. */
|
||||
if ((fileattr & FILE_ATTRIBUTE_REPARSE_POINT))
|
||||
{
|
||||
res = check_reparse_point (h, fs.is_remote_drive ());
|
||||
|
@ -3974,13 +3972,9 @@ fcwd_access_t::SetVersionFromPointer (PBYTE buf_p, bool is_buffer)
|
|||
}
|
||||
|
||||
/* This function scans the code in ntdll.dll to find the address of the
|
||||
global variable used to access the CWD starting with Vista. While the
|
||||
pointer is global, it's not exported from the DLL, unfortunately.
|
||||
Therefore we have to use some knowledge to figure out the address.
|
||||
|
||||
This code has been tested on Vista 32/64 bit, Server 2008 32/64 bit,
|
||||
Windows 7 32/64 bit, Server 2008 R2 (which is only 64 bit anyway),
|
||||
Windows 8 32/64 bit, Windows 8.1 32/64 bit, and Server 2012 R2. */
|
||||
global variable used to access the CWD. While the pointer is global,
|
||||
it's not exported from the DLL, unfortunately. Therefore we have to
|
||||
use some knowledge to figure out the address. */
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
|
@ -4240,9 +4234,8 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count)
|
|||
fast_cwd_ptr = find_fast_cwd ();
|
||||
if (fast_cwd_ptr)
|
||||
{
|
||||
/* Default method starting with Vista. If we got a valid value for
|
||||
fast_cwd_ptr, we can simply replace the RtlSetCurrentDirectory_U
|
||||
function entirely, just as on pre-Vista. */
|
||||
/* If we got a valid value for fast_cwd_ptr, we can simply replace
|
||||
the RtlSetCurrentDirectory_U function entirely. */
|
||||
PVOID heap = peb.ProcessHeap;
|
||||
/* First allocate a new fcwd_access_t structure on the heap.
|
||||
The new fcwd_access_t structure is 4 byte bigger than the old one,
|
||||
|
@ -4274,14 +4267,13 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* This is more a hack, and it's only used on Vista and later if we
|
||||
failed to find the fast_cwd_ptr value. What we do here is to call
|
||||
RtlSetCurrentDirectory_U and let it set up a new FAST_CWD
|
||||
structure. Afterwards, compute the address of that structure
|
||||
utilizing the fact that the buffer address in the user process
|
||||
parameter block is actually pointing to the buffer in that
|
||||
FAST_CWD structure. Then replace the directory handle in that
|
||||
structure with our own handle and close the original one.
|
||||
/* This is more a hack, and it's only used if we failed to find the
|
||||
fast_cwd_ptr value. We call RtlSetCurrentDirectory_U and let it
|
||||
set up a new FAST_CWD structure. Afterwards, compute the address
|
||||
of that structure utilizing the fact that the buffer address in
|
||||
the user process parameter block is actually pointing to the buffer
|
||||
in that FAST_CWD structure. Then replace the directory handle in
|
||||
that structure with our own handle and close the original one.
|
||||
|
||||
Note that the call to RtlSetCurrentDirectory_U also closes our
|
||||
old dir handle, so there won't be any handle left open.
|
||||
|
@ -4374,13 +4366,6 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
|
|||
- SetCurrentDirectory can naturally not work on virtual Cygwin paths
|
||||
like /proc or /cygdrive.
|
||||
|
||||
Unfortunately, even though we have access to the Win32 process parameter
|
||||
block, we can't just replace the directory handle. Starting with Vista,
|
||||
the handle is used elsewhere, and just replacing the handle in the process
|
||||
parameter block shows quite surprising results.
|
||||
FIXME: If we ever find a *safe* way to replace the directory handle in
|
||||
the process parameter block, we're back in business.
|
||||
|
||||
Nevertheless, doing entirely without SetCurrentDirectory is not really
|
||||
feasible, because it breaks too many mixed applications using the Win32
|
||||
API.
|
||||
|
@ -4401,11 +4386,11 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
|
|||
}
|
||||
|
||||
/* Memorize old DismountCount before opening the dir. This value is
|
||||
stored in the FAST_CWD structure on Vista and later. It would be
|
||||
simpler to fetch the old DismountCount in override_win32_cwd, but
|
||||
Windows also fetches it before opening the directory handle. It's
|
||||
not quite clear if that's really required, but since we don't know
|
||||
the side effects of this action, we better follow Windows' lead. */
|
||||
stored in the FAST_CWD structure. It would be simpler to fetch the
|
||||
old DismountCount in override_win32_cwd, but Windows also fetches
|
||||
it before opening the directory handle. It's not quite clear if
|
||||
that's really required, but since we don't know the side effects of
|
||||
this action, we better follow Windows' lead. */
|
||||
ULONG old_dismount_count = SharedUserData.DismountCount;
|
||||
/* Open a directory handle with FILE_OPEN_FOR_BACKUP_INTENT and with all
|
||||
sharing flags set. The handle is right now used in exceptions.cc only,
|
||||
|
|
|
@ -36,12 +36,11 @@ issetugid (void)
|
|||
return cygheap->user.issetuid () ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Starting with Windows Vista, the token returned by system functions
|
||||
is a restricted token. The full admin token is linked to it and can
|
||||
be fetched with NtQueryInformationToken. This function returns the original
|
||||
token on pre-Vista, and the elevated token on Vista++ if it's available,
|
||||
the original token otherwise. The token handle is also made inheritable
|
||||
since that's necessary anyway. */
|
||||
/* The token returned by system functions is a restricted token. The full
|
||||
admin token is linked to it and can be fetched with NtQueryInformationToken.
|
||||
This function returns the elevated token if available, the original token
|
||||
otherwise. The token handle is also made inheritable since that's necessary
|
||||
anyway. */
|
||||
static HANDLE
|
||||
get_full_privileged_inheritable_token (HANDLE token)
|
||||
{
|
||||
|
@ -219,7 +218,7 @@ get_user_profile_directory (PCWSTR sidstr, PWCHAR path, SIZE_T path_len)
|
|||
}
|
||||
|
||||
/* Load user profile if it's not already loaded. If the user profile doesn't
|
||||
exist on the machine, and if we're running Vista or later, try to create it.
|
||||
exist on the machine try to create it.
|
||||
|
||||
Return a handle to the loaded user registry hive only if it got actually
|
||||
loaded here, not if it already existed. There's no reliable way to know
|
||||
|
@ -821,8 +820,8 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
|
|||
|
||||
/* Check that all groups in the setgroups () list are in the token.
|
||||
A token created through ADVAPI should be allowed to contain more
|
||||
groups than requested through setgroups(), especially since Vista
|
||||
and the addition of integrity groups. */
|
||||
groups than requested through setgroups(), especially since the
|
||||
addition of integrity groups. */
|
||||
memset (saw, 0, sizeof(saw));
|
||||
for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
|
||||
{
|
||||
|
|
|
@ -628,11 +628,6 @@ _recycler_sd (void *buf, bool users, bool dir)
|
|||
return NULL;
|
||||
RtlCreateSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION);
|
||||
PACL dacl = (PACL) (psd + 1);
|
||||
/* Pre-Vista, the per-user recycler dir has a rather too complicated
|
||||
ACL by default, which has distinct ACEs for inheritable and non-inheritable
|
||||
permissions. However, this ACL is practically equivalent to the ACL
|
||||
created since Vista. Therefore we simplify our job here and create the
|
||||
pre-Vista permissions the same way as on Vista and later. */
|
||||
RtlCreateAcl (dacl, MAX_DACL_LEN (3), ACL_REVISION);
|
||||
RtlAddAccessAllowedAceEx (dacl, ACL_REVISION,
|
||||
dir ? SUB_CONTAINERS_AND_OBJECTS_INHERIT
|
||||
|
|
|
@ -89,7 +89,6 @@ void uinfo_init ();
|
|||
#define SE_MANAGE_VOLUME_PRIVILEGE 28U
|
||||
#define SE_IMPERSONATE_PRIVILEGE 29U
|
||||
#define SE_CREATE_GLOBAL_PRIVILEGE 30U
|
||||
/* Starting with Vista */
|
||||
#define SE_TRUSTED_CREDMAN_ACCESS_PRIVILEGE 31U
|
||||
#define SE_RELABEL_PRIVILEGE 32U
|
||||
#define SE_INCREASE_WORKING_SET_PRIVILEGE 33U
|
||||
|
|
|
@ -268,11 +268,11 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags)
|
|||
them into the recycler. */
|
||||
if (pfni->FileNameLength == 2) /* root dir. */
|
||||
goto out;
|
||||
/* The recycler name on Vista and later is $Recycler.Bin by default. If the
|
||||
recycler dir disappeared for some reason, the shell32.dll recreates the
|
||||
directory in all upper case. So, we never know beforehand if the dir
|
||||
is written in mixed case or in all upper case. That's a problem when
|
||||
using casesensitivity. If the file handle given to FileRenameInformation
|
||||
/* The recycler name is $Recycler.Bin by default. If the recycler dir
|
||||
disappeared for some reason, the shell32.dll recreates the directory in
|
||||
all upper case. So, we never know beforehand if the dir is written in
|
||||
mixed case or in all upper case. That's a problem when using
|
||||
casesensitivity. If the file handle given to FileRenameInformation
|
||||
has been opened casesensitive, the call also handles the path to the
|
||||
target dir casesensitive. Rather then trying to find the right name
|
||||
of the recycler, we just reopen the file to move with OBJ_CASE_INSENSITIVE,
|
||||
|
@ -958,10 +958,10 @@ try_again:
|
|||
"Subsequently, the only legal operation by such a caller is
|
||||
to close the open file handle."
|
||||
|
||||
FIXME? On Vista and later, we could use FILE_HARD_LINK_INFORMATION
|
||||
to find all hardlinks and use one of them to restore the R/O bit,
|
||||
after the NtClose, but before we stop the transaction. This
|
||||
avoids the aforementioned problem entirely . */
|
||||
FIXME? We could use FILE_HARD_LINK_INFORMATION to find all
|
||||
hardlinks and use one of them to restore the R/O bit, after the
|
||||
NtClose, but before we stop the transaction. This avoids the
|
||||
aforementioned problem entirely . */
|
||||
else if (pc.is_lnk_symlink () && num_links > 1)
|
||||
NtSetAttributesFile (fh, pc.file_attributes ());
|
||||
}
|
||||
|
@ -3219,9 +3219,9 @@ seteuid32 (uid_t uid)
|
|||
CW_TOKEN_RESTRICTED);
|
||||
setuid (getuid ());
|
||||
|
||||
Note that using the current uid is a requirement! Starting with Windows
|
||||
Vista, we have restricted tokens galore (UAC), so this is really just
|
||||
a special case to restict your own processes to lesser rights. */
|
||||
Note that using the current uid is a requirement! We have restricted
|
||||
tokens galore (UAC), so this is really just a special case to restrict
|
||||
your own processes to lesser rights. */
|
||||
bool request_restricted_uid_switch = (uid == myself->uid
|
||||
&& cygheap->user.ext_token_is_restricted);
|
||||
if (uid == myself->uid && !cygheap->user.groups.ischanged
|
||||
|
|
Loading…
Reference in New Issue