[英].Net core child processes do not inherit (socket) handles from parent process (Windows)
We implemented a Windows assembly in C#. This program is listening on a socket for incoming connections and starting child processes (unmanaged c code) which should then be using this socket.我们在 C# 中实现了一个 Windows 程序集。该程序正在侦听传入连接的套接字并启动子进程(非托管 c 代码),然后应该使用该套接字。 The child processes are started by a command line which includes the socket's handle as an argument.
子进程由包含套接字句柄作为参数的命令行启动。 The entire mechanism works fine with.Net 4.8 Framework, but is failing with.Net 6. This is an excerpt of the code we are using:
整个机制在 .Net 4.8 Framework 上运行良好,但在 .Net 6 上运行失败。这是我们正在使用的代码的摘录:
GetUserNameAndDomain(user, out var userName, out var domain);
var process = new Process{StartInfo = new ProcessStartInfo(command, arguments){UseShellExecute = false}};
WrapperImpersonationContext wrapperImpersonationContext = new WrapperImpersonationContext(domain, userName, password.ToUnsecureString(), false, false);
using (wrapperImpersonationContext) {
Action impersonationAction = () =>
{
process.Start();
};
wrapperImpersonationContext.Enter(impersonationAction);
}
where the impersonation stuff is mainly doing something like模仿的东西主要是在做类似的事情
public WrapperImpersonationContext(string domain, string username, string password, bool automaticallyEnter = true, bool logonAsService = false) {
mDomain = domain;
mUsername = username;
mPassword = password;
mLogonType = logonAsService ? LOGON32_LOGON_SERVICE : LOGON32_LOGON_INTERACTIVE;
if (automaticallyEnter)
Enter();
}
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public void Enter(Action impersonationAction = null) {
//if (IsInContext)
// return;
mToken = new IntPtr(0);
try {
LogFactory.WriteVerbose("Logon to user '{0}' in domain '{1}'", mUsername, mDomain);
mToken = IntPtr.Zero;
bool logonSuccessfull = LogonUser(mUsername, mDomain, mPassword, mLogonType, LOGON32_PROVIDER_DEFAULT, ref mToken);
if (logonSuccessfull == false) {
int error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}
WindowsIdentity identity = new WindowsIdentity(mToken);
WindowsIdentity.RunImpersonated(new Microsoft.Win32.SafeHandles.SafeAccessTokenHandle(mToken), impersonationAction);
LogFactory.WriteVerbose("Impersonation was successfully");
} catch (Exception exception) {
LogFactory.WriteWarning(exception);
throw;
}
}
We used Sysinternals Process Explorer to look at the parent and child processes' handles.我们使用 Sysinternals Process Explorer 查看父进程和子进程的句柄。 Using.Net 4.8 we clearly saw that the socket handle passed on in the command line is available in the child processes' handle list.
使用.Net 4.8,我们清楚地看到在命令行中传递的套接字句柄在子进程的句柄列表中可用。 Using.Net 6 the passed on handle however is not.
然而,使用.Net 6 传递的句柄不是。 With.Net 6 less handles seem to be inherited compared to.Net 4.8.
与.Net 6相比,似乎继承了.Net 4.8更少的句柄。
How comes that.Net 6 is behaving differently in this area?为什么 .Net 6 在这方面表现不同? All researches/reading that we did indicated that the 'handle inheritance' should still be the same in.Net 6.
我们所做的所有研究/阅读都表明“句柄继承”在 .Net 6 中应该仍然相同。
We used GetHandleInformation() to find out that the socket we want to access in the child process was not marked as 'inheritable' in .NET 6 (whereas it is when using.Net 4.8).我们使用 GetHandleInformation() 发现我们想要在子进程中访问的套接字在 .NET 6 中未标记为“可继承”(而在使用 .Net 4.8 时是这样)。 Now we use SetHandleInformation() to set the flag to 1 and voila - we can pass on the handle now.
现在我们使用 SetHandleInformation() 将标志设置为 1 瞧——我们现在可以传递句柄了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.