Compare commits
10 Commits
e79304d7b4
...
6604db8b80
Author | SHA1 | Date |
---|---|---|
|
6604db8b80 | |
|
1c4a00962f | |
|
293785382c | |
|
0480315010 | |
|
538b29a8da | |
|
80ff7bc26c | |
|
e9dd5d8f25 | |
|
a903878948 | |
|
9fc746d17d | |
|
28489b0702 |
|
@ -1,4 +1,4 @@
|
|||
# Build libraries optimizing for space, not speed.
|
||||
# Turn off warnings about symbols named the same as registers
|
||||
CFLAGS_FOR_TARGET = -g -Os -Wa,-C
|
||||
CXXFLAGS_FOR_TARGET = -g -Os -Wa,-C
|
||||
CFLAGS_FOR_TARGET += -g -Os -Wa,-C
|
||||
CXXFLAGS_FOR_TARGET += -g -Os -Wa,-C
|
||||
|
|
|
@ -1486,12 +1486,12 @@ format_proc_cpuinfo (void *, char *&destbuf)
|
|||
|
||||
/* ftcprint (features1, 6, "split_lock_detect");*//* MSR_TEST_CTRL split lock */
|
||||
|
||||
/* cpuid 0x00000007 ecx & Windows [20]20H1/[20]2004+ */
|
||||
if (maxf >= 0x00000007 && wincap.osname () >= "10.0"
|
||||
&& wincap.build_number () >= 19041)
|
||||
/* Windows [20]20H1/[20]2004/19041 user shadow stack */
|
||||
if (maxf >= 0x00000007 && wincap.has_user_shstk ())
|
||||
{
|
||||
/* cpuid 0x00000007 ecx CET shadow stack */
|
||||
cpuid (&unused, &unused, &features1, &unused, 0x00000007, 0);
|
||||
ftcprint (features1, 7, "user_shstk"); /* "user shadow stack" */
|
||||
ftcprint (features1, 7, "user_shstk"); /* user shadow stack */
|
||||
}
|
||||
|
||||
/* cpuid 0x00000007:1 eax */
|
||||
|
|
|
@ -1297,17 +1297,7 @@ fhandler_pty_slave::mask_switch_to_nat_pipe (bool mask, bool xfer)
|
|||
else if (InterlockedDecrement (&num_reader) == 0)
|
||||
CloseHandle (slave_reading);
|
||||
|
||||
/* This is needed when cygwin-app is started from non-cygwin app if
|
||||
pseudo console is disabled. */
|
||||
bool need_xfer = get_ttyp ()->nat_fg (get_ttyp ()->getpgid ())
|
||||
&& get_ttyp ()->switch_to_nat_pipe && !get_ttyp ()->pcon_activated;
|
||||
|
||||
/* In GDB, transfer input based on setpgid() does not work because
|
||||
GDB may not set terminal process group properly. Therefore,
|
||||
transfer input here if isHybrid is set. */
|
||||
bool need_gdb_xfer =
|
||||
isHybrid && GetStdHandle (STD_INPUT_HANDLE) == get_handle ();
|
||||
if (!!masked != mask && xfer && (need_gdb_xfer || need_xfer))
|
||||
if (!!masked != mask && xfer && get_ttyp ()->switch_to_nat_pipe)
|
||||
{
|
||||
if (mask && get_ttyp ()->pty_input_state_eq (tty::to_nat))
|
||||
{
|
||||
|
@ -2238,11 +2228,7 @@ fhandler_pty_master::write (const void *ptr, size_t len)
|
|||
if (!get_ttyp ()->pcon_start)
|
||||
{ /* Pseudo console initialization has been done in above code. */
|
||||
pinfo pp (get_ttyp ()->pcon_start_pid);
|
||||
bool pcon_fg = (pp && get_ttyp ()->getpgid () == pp->pgid);
|
||||
/* GDB may set WINPID rather than cygwin PID to process group
|
||||
when the debugged process is a non-cygwin process.*/
|
||||
pcon_fg |= !pinfo (get_ttyp ()->getpgid ());
|
||||
if (get_ttyp ()->switch_to_nat_pipe && pcon_fg
|
||||
if (get_ttyp ()->switch_to_nat_pipe
|
||||
&& get_ttyp ()->pty_input_state_eq (tty::to_cyg))
|
||||
{
|
||||
/* This accept_input() call is needed in order to transfer input
|
||||
|
@ -4089,7 +4075,14 @@ fhandler_pty_slave::cleanup_for_non_cygwin_app (handle_set_t *p, tty *ttyp,
|
|||
DWORD force_switch_to)
|
||||
{
|
||||
ttyp->wait_fwd ();
|
||||
if (ttyp->getpgid () == myself->pgid && stdin_is_ptys
|
||||
DWORD current_pid = myself->exec_dwProcessId ?: myself->dwProcessId;
|
||||
DWORD switch_to = force_switch_to;
|
||||
WaitForSingleObject (p->pipe_sw_mutex, INFINITE);
|
||||
if (!switch_to)
|
||||
switch_to = get_console_process_id (current_pid, false, true, true);
|
||||
if (!switch_to)
|
||||
switch_to = get_console_process_id (current_pid, false, true, false);
|
||||
if ((!switch_to && (ttyp->pcon_activated || stdin_is_ptys))
|
||||
&& ttyp->pty_input_state_eq (tty::to_nat))
|
||||
{
|
||||
WaitForSingleObject (p->input_mutex, mutex_timeout);
|
||||
|
@ -4099,7 +4092,6 @@ fhandler_pty_slave::cleanup_for_non_cygwin_app (handle_set_t *p, tty *ttyp,
|
|||
release_attach_mutex ();
|
||||
ReleaseMutex (p->input_mutex);
|
||||
}
|
||||
WaitForSingleObject (p->pipe_sw_mutex, INFINITE);
|
||||
if (ttyp->pcon_activated)
|
||||
close_pseudoconsole (ttyp, force_switch_to);
|
||||
else
|
||||
|
|
|
@ -56,4 +56,11 @@ details. */
|
|||
#define __PATH_MAX 4096
|
||||
#define __PIPE_BUF 4096
|
||||
|
||||
/* XATTR_NAME_MAX is the maximum XATTR name length excluding the null
|
||||
* terminator. Since only XATTRs in the `user' namespace are allowed and the
|
||||
* `user.' prefix is not stored, the maximum is increased by 5. */
|
||||
#define XATTR_NAME_MAX 260
|
||||
#define XATTR_SIZE_MAX 65536
|
||||
#define XATTR_LIST_MAX 65536
|
||||
|
||||
#endif /* _CYGWIN_LIMITS_H__ */
|
||||
|
|
|
@ -32,6 +32,7 @@ struct wincaps
|
|||
unsigned has_linux_tcp_keepalive_sockopts : 1;
|
||||
unsigned has_tcp_maxrtms : 1;
|
||||
unsigned has_con_broken_tabs : 1;
|
||||
unsigned has_user_shstk : 1;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -84,6 +85,7 @@ public:
|
|||
bool IMPLEMENT (has_linux_tcp_keepalive_sockopts)
|
||||
bool IMPLEMENT (has_tcp_maxrtms)
|
||||
bool IMPLEMENT (has_con_broken_tabs)
|
||||
bool IMPLEMENT (has_user_shstk)
|
||||
|
||||
void disable_case_sensitive_dirs ()
|
||||
{
|
||||
|
|
|
@ -17,9 +17,11 @@ details. */
|
|||
#include "tls_pbuf.h"
|
||||
#include <stdlib.h>
|
||||
#include <attr/xattr.h>
|
||||
#include <cygwin/limits.h>
|
||||
|
||||
#define MAX_EA_NAME_LEN 256
|
||||
#define MAX_EA_VALUE_LEN 65536
|
||||
/* On storage the `user.` prefix is not included but the terminating null byte
|
||||
is needed.*/
|
||||
#define _XATTR_NAME_MAX_ONDISK_ (XATTR_NAME_MAX - strlen("user.") + 1)
|
||||
|
||||
/* At least one maximum sized entry fits.
|
||||
CV 2014-04-04: NtQueryEaFile function chokes on buffers bigger than 64K
|
||||
|
@ -27,13 +29,13 @@ details. */
|
|||
on a remote share, at least on Windows 7 and later.
|
||||
In theory the buffer should have a size of
|
||||
|
||||
sizeof (FILE_FULL_EA_INFORMATION) + MAX_EA_NAME_LEN
|
||||
+ MAX_EA_VALUE_LEN
|
||||
sizeof (FILE_FULL_EA_INFORMATION) + _XATTR_NAME_MAX_ONDISK_
|
||||
+ XATTR_SIZE_MAX
|
||||
|
||||
(65804 bytes), but we're opting for simplicity here, and
|
||||
a 64K buffer has the advantage that we can use a tmp_pathbuf
|
||||
buffer, rather than having to alloca 64K from stack. */
|
||||
#define EA_BUFSIZ MAX_EA_VALUE_LEN
|
||||
#define EA_BUFSIZ XATTR_SIZE_MAX
|
||||
|
||||
#define NEXT_FEA(p) ((PFILE_FULL_EA_INFORMATION) (p->NextEntryOffset \
|
||||
? (char *) p + p->NextEntryOffset : NULL))
|
||||
|
@ -55,7 +57,7 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||
returns the last EA entry of the file infinitely. Even utilizing the
|
||||
optional EaIndex only helps marginally. If you use that, the last
|
||||
EA in the file is returned twice. */
|
||||
char lastname[MAX_EA_NAME_LEN];
|
||||
char lastname[_XATTR_NAME_MAX_ONDISK_];
|
||||
|
||||
__try
|
||||
{
|
||||
|
@ -95,7 +97,7 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||
__leave;
|
||||
}
|
||||
|
||||
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
||||
if ((nlen = strlen (name)) >= _XATTR_NAME_MAX_ONDISK_)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
|
@ -197,7 +199,7 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||
/* For compatibility with Linux, we always prepend "user." to
|
||||
the attribute name, so effectively we only support user
|
||||
attributes from a application point of view. */
|
||||
char tmpbuf[MAX_EA_NAME_LEN * 2];
|
||||
char tmpbuf[_XATTR_NAME_MAX_ONDISK_ * 2];
|
||||
char *tp = stpcpy (tmpbuf, "user.");
|
||||
stpcpy (tp, fea->EaName);
|
||||
/* NTFS stores all EA names in uppercase unfortunately. To
|
||||
|
@ -297,7 +299,7 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||
/* Skip "user." prefix. */
|
||||
name += 5;
|
||||
|
||||
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
||||
if ((nlen = strlen (name)) >= _XATTR_NAME_MAX_ONDISK_)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
|
|
|
@ -929,7 +929,13 @@ fetch_home_env (void)
|
|||
/* If `HOME` is set, prefer it */
|
||||
const char *home = getenv ("HOME");
|
||||
if (home)
|
||||
return strdup (home);
|
||||
{
|
||||
/* In the very early code path of `user_info::initialize ()`, the value
|
||||
of the environment variable `HOME` is still in its Windows form. */
|
||||
if (isdrive (home) || home[0] == '\\')
|
||||
return (char *) cygwin_create_path (CCP_WIN_A_TO_POSIX, home);
|
||||
return strdup (home);
|
||||
}
|
||||
|
||||
/* If `HOME` is unset, fall back to `HOMEDRIVE``HOMEPATH`
|
||||
(without a directory separator, as `HOMEPATH` starts with one). */
|
||||
|
@ -1485,9 +1491,9 @@ get_logon_sid ()
|
|||
}
|
||||
}
|
||||
|
||||
/* Fetch special AzureAD group, which is part of the token group list but
|
||||
*not* recognized by LookupAccountSid (ERROR_NONE_MAPPED). */
|
||||
static cygsid azure_grp_sid ("");
|
||||
/* Fetch special AzureAD and IIS APPPOOL groups, which are part of the token
|
||||
group list but *not* recognized by LookupAccountSid (ERROR_NONE_MAPPED). */
|
||||
static cygsid azure_grp_sid (""), iis_apppool_grp_sid ("");
|
||||
|
||||
static void
|
||||
get_azure_grp_sid ()
|
||||
|
@ -1515,6 +1521,36 @@ get_azure_grp_sid ()
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_iis_apppool_grp_sid ()
|
||||
{
|
||||
if (PSID (iis_apppool_grp_sid) == NO_SID)
|
||||
{
|
||||
NTSTATUS status;
|
||||
ULONG size;
|
||||
tmp_pathbuf tp;
|
||||
PTOKEN_GROUPS groups = (PTOKEN_GROUPS) tp.w_get ();
|
||||
|
||||
status = NtQueryInformationToken (hProcToken, TokenGroups, groups,
|
||||
2 * NT_MAX_PATH, &size);
|
||||
if (!NT_SUCCESS (status))
|
||||
debug_printf ("NtQueryInformationToken (TokenGroups) %y", status);
|
||||
else
|
||||
{
|
||||
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
|
||||
{
|
||||
PSID sid = groups->Groups[pg].Sid;
|
||||
if (sid_id_auth (sid) == 5 &&
|
||||
sid_sub_auth (sid, 0) == SECURITY_APPPOOL_ID_BASE_RID)
|
||||
{
|
||||
iis_apppool_grp_sid = sid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
pwdgrp::add_account_post_fetch (char *line, bool lock)
|
||||
{
|
||||
|
@ -1796,6 +1832,16 @@ pwdgrp::construct_sid_from_name (cygsid &sid, wchar_t *name, wchar_t *sep)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
if (sep && wcscmp (name, L"IIS APPPOOL\\Group") == 0)
|
||||
{
|
||||
get_iis_apppool_grp_sid ();
|
||||
if (PSID (logon_sid) != NO_SID)
|
||||
{
|
||||
sid = iis_apppool_grp_sid;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (!sep && wcscmp (name, L"CurrentSession") == 0)
|
||||
{
|
||||
get_logon_sid ();
|
||||
|
@ -2018,8 +2064,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
|
|||
/* Last but not least, some validity checks on the name style. */
|
||||
if (!fq_name)
|
||||
{
|
||||
/* AzureAD user must be prepended by "domain" name. */
|
||||
if (sid_id_auth (sid) == 12)
|
||||
/* AzureAD and IIS APPPOOL users must be prepended by "domain"
|
||||
name. */
|
||||
if (sid_id_auth (sid) == 12 ||
|
||||
(sid_id_auth (sid) == 5 &&
|
||||
sid_sub_auth (sid, 0) == SECURITY_APPPOOL_ID_BASE_RID))
|
||||
return NULL;
|
||||
/* name_only account is either builtin or primary domain, or
|
||||
account domain on non-domain machines. */
|
||||
|
@ -2045,8 +2094,10 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* AzureAD accounts should be fully qualifed either. */
|
||||
if (sid_id_auth (sid) == 12)
|
||||
/* AzureAD and IIS APPPOOL accounts should be fully qualifed either. */
|
||||
if (sid_id_auth (sid) == 12 ||
|
||||
(sid_id_auth (sid) == 5 &&
|
||||
sid_sub_auth (sid, 0) == SECURITY_APPPOOL_ID_BASE_RID))
|
||||
break;
|
||||
/* Otherwise, no fully_qualified for builtin accounts, except for
|
||||
NT SERVICE, for which we require the prefix. Note that there's
|
||||
|
@ -2125,6 +2176,19 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
|
|||
sid = csid = azure_grp_sid;
|
||||
break;
|
||||
}
|
||||
else if (arg.id == 0x1002)
|
||||
{
|
||||
/* IIS APPPOOL S-1-5-82-* user */
|
||||
csid = cygheap->user.saved_sid ();
|
||||
}
|
||||
else if (arg.id == 0x1003)
|
||||
{
|
||||
/* Special IIS APPPOOL group SID */
|
||||
get_iis_apppool_grp_sid ();
|
||||
/* LookupAccountSidW will fail. */
|
||||
sid = csid = iis_apppool_grp_sid;
|
||||
break;
|
||||
}
|
||||
else if (arg.id == 0xfffe)
|
||||
{
|
||||
/* Special case "nobody" for reproducible construction of a
|
||||
|
@ -2253,7 +2317,9 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
|
|||
|
||||
Those we let pass, but no others. */
|
||||
bool its_ok = false;
|
||||
if (sid_id_auth (sid) == 12)
|
||||
if (sid_id_auth (sid) == 12 ||
|
||||
(sid_id_auth (sid) == 5 &&
|
||||
sid_sub_auth (sid, 0) == SECURITY_APPPOOL_ID_BASE_RID))
|
||||
its_ok = true;
|
||||
else /* Microsoft Account */
|
||||
{
|
||||
|
@ -2342,7 +2408,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
|
|||
posix_offset = fetch_posix_offset (td, &loc_ldap);
|
||||
}
|
||||
}
|
||||
/* AzureAD S-1-12-1-W-X-Y-Z user */
|
||||
/* AzureAD S-1-12-1-W-X-Y-Z and IIS APPOOL S-1-5-82-* user */
|
||||
else if (sid_id_auth (sid) == 12)
|
||||
{
|
||||
uid = gid = 0x1000;
|
||||
|
@ -2355,6 +2421,21 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
|
|||
name, fully_qualified_name);
|
||||
break;
|
||||
}
|
||||
/* IIS APPOOL S-1-5-82-* user */
|
||||
else if (sid_id_auth (sid) == 5 &&
|
||||
sid_sub_auth (sid, 0) == SECURITY_APPPOOL_ID_BASE_RID)
|
||||
{
|
||||
uid = 0x1002;
|
||||
gid = 0x1003;
|
||||
fully_qualified_name = true;
|
||||
home = cygheap->pg.get_home ((PUSER_INFO_3) NULL, sid, dom, name,
|
||||
fully_qualified_name);
|
||||
shell = cygheap->pg.get_shell ((PUSER_INFO_3) NULL, sid, dom,
|
||||
name, fully_qualified_name);
|
||||
gecos = cygheap->pg.get_gecos ((PUSER_INFO_3) NULL, sid, dom,
|
||||
name, fully_qualified_name);
|
||||
break;
|
||||
}
|
||||
/* If the domain returned by LookupAccountSid is not our machine
|
||||
name, and if our machine is no domain member, we lose. We have
|
||||
nobody to ask for the POSIX offset. */
|
||||
|
@ -2614,6 +2695,20 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
|
|||
fully_qualified_name = true;
|
||||
acc_type = SidTypeUnknown;
|
||||
}
|
||||
else if (sid_id_auth (sid) == 5 &&
|
||||
sid_sub_auth (sid, 0) == SECURITY_APPPOOL_ID_BASE_RID)
|
||||
{
|
||||
/* Special IIS APPPOOL group SID which can't be resolved by
|
||||
LookupAccountSid (ERROR_NONE_MAPPED). This is only allowed
|
||||
as group entry, not as passwd entry. */
|
||||
if (is_passwd ())
|
||||
return NULL;
|
||||
uid = gid = 0x1003;
|
||||
wcpcpy (dom, L"IIS APPPOOL");
|
||||
wcpcpy (name = namebuf, L"Group");
|
||||
fully_qualified_name = true;
|
||||
acc_type = SidTypeUnknown;
|
||||
}
|
||||
else if (sid_id_auth (sid) == 5 /* SECURITY_NT_AUTHORITY */
|
||||
&& sid_sub_auth (sid, 0) == SECURITY_LOGON_IDS_RID)
|
||||
{
|
||||
|
|
|
@ -31,6 +31,7 @@ static const wincaps wincap_8_1 = {
|
|||
has_linux_tcp_keepalive_sockopts:false,
|
||||
has_tcp_maxrtms:false,
|
||||
has_con_broken_tabs:false,
|
||||
has_user_shstk:false,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -52,6 +53,7 @@ static const wincaps wincap_10_1507 = {
|
|||
has_linux_tcp_keepalive_sockopts:false,
|
||||
has_tcp_maxrtms:false,
|
||||
has_con_broken_tabs:false,
|
||||
has_user_shstk:false,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -73,6 +75,7 @@ static const wincaps wincap_10_1607 = {
|
|||
has_linux_tcp_keepalive_sockopts:false,
|
||||
has_tcp_maxrtms:true,
|
||||
has_con_broken_tabs:false,
|
||||
has_user_shstk:false,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -94,6 +97,7 @@ static const wincaps wincap_10_1703 = {
|
|||
has_linux_tcp_keepalive_sockopts:false,
|
||||
has_tcp_maxrtms:true,
|
||||
has_con_broken_tabs:true,
|
||||
has_user_shstk:false,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -115,6 +119,7 @@ static const wincaps wincap_10_1709 = {
|
|||
has_linux_tcp_keepalive_sockopts:true,
|
||||
has_tcp_maxrtms:true,
|
||||
has_con_broken_tabs:true,
|
||||
has_user_shstk:false,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -136,6 +141,7 @@ static const wincaps wincap_10_1803 = {
|
|||
has_linux_tcp_keepalive_sockopts:true,
|
||||
has_tcp_maxrtms:true,
|
||||
has_con_broken_tabs:true,
|
||||
has_user_shstk:false,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -157,6 +163,7 @@ static const wincaps wincap_10_1809 = {
|
|||
has_linux_tcp_keepalive_sockopts:true,
|
||||
has_tcp_maxrtms:true,
|
||||
has_con_broken_tabs:true,
|
||||
has_user_shstk:false,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -178,6 +185,7 @@ static const wincaps wincap_10_1903 = {
|
|||
has_linux_tcp_keepalive_sockopts:true,
|
||||
has_tcp_maxrtms:true,
|
||||
has_con_broken_tabs:true,
|
||||
has_user_shstk:false,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -199,6 +207,7 @@ static const wincaps wincap_10_2004 = {
|
|||
has_linux_tcp_keepalive_sockopts:true,
|
||||
has_tcp_maxrtms:true,
|
||||
has_con_broken_tabs:true,
|
||||
has_user_shstk:true,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -220,6 +229,7 @@ static const wincaps wincap_11 = {
|
|||
has_linux_tcp_keepalive_sockopts:true,
|
||||
has_tcp_maxrtms:true,
|
||||
has_con_broken_tabs:false,
|
||||
has_user_shstk:true,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue