瀏覽代碼

ipc-util: Fix access rights issue with IPC pipe

This was the reason why game capture could not hook when the hook was
run at administrator level and the game/target was below administrator
level: it was because the plugin created a pipe, and the hook tried to
connect to that pipe, but because the pipe was created as administrator
with default access rights, the pipe did not allow write access for
anything below administrator level, therefor the hook could not connect
to the plugin, and the hook would always fail as a result.

This fixes the issue by creating the pipe with full access rights to
everyone instead of default access rights.
jp9000 10 年之前
父節點
當前提交
8ae0cd2492
共有 1 個文件被更改,包括 35 次插入1 次删除
  1. 35 1
      deps/ipc-util/ipc-util/pipe-windows.c

+ 35 - 1
deps/ipc-util/ipc-util/pipe-windows.c

@@ -24,10 +24,34 @@ static inline bool ipc_pipe_internal_create_events(ipc_pipe_server_t *pipe)
 	return !!pipe->ready_event;
 }
 
+static inline void *create_full_access_security_descriptor()
+{
+	void *sd = malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
+	if (!sd) {
+		return NULL;
+	}
+
+	if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) {
+		goto error;
+	}
+
+	if (!SetSecurityDescriptorDacl(sd, true, NULL, false)) {
+		goto error;
+	}
+
+	return sd;
+
+error:
+	free(sd);
+	return NULL;
+}
+
 static inline bool ipc_pipe_internal_create_pipe(ipc_pipe_server_t *pipe,
 		const char *name)
 {
+	SECURITY_ATTRIBUTES sa;
 	char new_name[512];
+	void *sd;
 	const DWORD access = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED;
 	const DWORD flags = PIPE_TYPE_MESSAGE     |
 	                    PIPE_READMODE_MESSAGE |
@@ -36,8 +60,18 @@ static inline bool ipc_pipe_internal_create_pipe(ipc_pipe_server_t *pipe,
 	strcpy_s(new_name, sizeof(new_name), "\\\\.\\pipe\\");
 	strcat_s(new_name, sizeof(new_name), name);
 
+	sd = create_full_access_security_descriptor();
+	if (!sd) {
+		return false;
+	}
+
+	sa.nLength = sizeof(sa);
+	sa.lpSecurityDescriptor = sd;
+	sa.bInheritHandle = false;
+
 	pipe->handle = CreateNamedPipeA(new_name, access, flags, 1,
-			IPC_PIPE_BUF_SIZE, IPC_PIPE_BUF_SIZE, 0, NULL);
+			IPC_PIPE_BUF_SIZE, IPC_PIPE_BUF_SIZE, 0, &sa);
+	free(sd);
 
 	return pipe->handle != INVALID_HANDLE_VALUE;
 }