PowerShell / PowerShell/Win32-OpenSSH

Git server doesn't work with Win32-OpenSSH. Enclosed, please find three defects which I isolated and worked around..

Open
#752 52 comments 6 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

0 - Backlog Issue-Bug
Dominant language
No language data
Stars
8.3k
Forks
819
PR merge metrics
No merged PRs in 30d

Description

I pulled version: 0.0.14.0 on May 19. I just fetched version: 0.0.15.0 (June 4) today to compare. I don't believe the below issues have been corrected.

Git using Win32-OpenSSH ssh server runs as a nopty service. There are two defects in the nopty code:

  1. shell-host.c passes through to cmd.exe, single quotes as literals. The literal single quotes become part of the file path name, resulting in an incorrect file path.
  2. The service loop in shell-host.c, which passes its stdin to the child stdin is coded with incorrect file handles. Part of the input is currently passed back to sshd.

A temporary workaround for issue 1 is to replace all single quotes with double quotes just before the call to invoke cmd /c:

@@ -1136,7 +1136,21 @@ start_withno_pty(wchar_t *command)
	if (command) {
		GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L" /c"));
		GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L" "));

	+	int i = 0;
	+	while (command[i] != L'\0')
	+	{
	+		if (command[i] == L'\'' )
	+			command[i] = L'\"';
	+		i++;
	+	}
		GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, command));

A fix for issue 2 is to use the child process file handle instead of the sshd file handle:

@@ -1184,7 +1198,7 @@ start_withno_pty(wchar_t *command)
			/* for backspace, we need to send space and another backspace for visual erase */
			if (buf[i] == '\b') {
				if (in_cmd_len > 0) {
-					GOTO_CLEANUP_ON_FALSE(WriteFile(pipe_out, "\b \b", 3, &wr, NULL));
+					GOTO_CLEANUP_ON_FALSE(WriteFile(child_pipe_write, "\b \b", 3, &wr, NULL));
					in_cmd_len--;
				}
				i++;
@@ -1194,10 +1208,10 @@ start_withno_pty(wchar_t *command)
			/* For CR and LF */
			if ((buf[i] == '\r') || (buf[i] == '\n')) {
				/* TODO - do a much accurate mapping */
-				GOTO_CLEANUP_ON_FALSE(WriteFile(pipe_out, buf + i, 1, &wr, NULL));
+				GOTO_CLEANUP_ON_FALSE(WriteFile(child_pipe_write, buf + i, 1, &wr, NULL));
				if ((buf[i] == '\r') && ((i == rd - 1) || (buf[i + 1] != '\n'))) {
					buf[i] = '\n';
-					GOTO_CLEANUP_ON_FALSE(WriteFile(pipe_out, buf + i, 1, &wr, NULL));
+					GOTO_CLEANUP_ON_FALSE(WriteFile(child_pipe_write, buf + i, 1, &wr, NULL));
				}
				in_cmd[in_cmd_len] = buf[i];
				in_cmd_len++;
@@ -1207,7 +1221,7 @@ start_withno_pty(wchar_t *command)
				continue;
			}
 
-			GOTO_CLEANUP_ON_FALSE(WriteFile(pipe_out, buf + i, 1, &wr, NULL));
+			GOTO_CLEANUP_ON_FALSE(WriteFile(child_pipe_write, buf + i, 1, &wr, NULL));
			in_cmd[in_cmd_len] = buf[i];
			in_cmd_len++;
			if (in_cmd_len == MAX_CMD_LEN - 1) {

Finally, there is defect and debug issue in signal_sigchld.c. The zombied children count can become too large, which causes a seg fault. When debugging sshd.exe /ddd, debug3() is writing during signal processing which corrupts the stack. Debug3() should not write while running on an exception frame. A check for incorrect zombie count should be added:

@@ -104,14 +104,20 @@ sw_child_to_zombie(DWORD index)
	DWORD last_non_zombie, zombie_pid;
	HANDLE zombie_handle;
 
-	debug3("zombie'ing child at index %d, %d zombies of %d", index,
-		children.num_zombies, children.num_children);
+	//debug3("zombie'ing child at index %d, %d zombies of %d", index,
+		//children.num_zombies, children.num_children);
 
	if (index >= children.num_children) {
		errno = EINVAL;
		return -1;
	}
-
+	//debug3(" %x zombies,  %x children",children.num_zombies, children.num_children);
+	if((children.num_children - children.num_zombies) == 0)
+	{
+		//debug2("children == zombies, can't make more zombies");
+		errno = EINVAL;
+		return -1;
+	}
	last_non_zombie = children.num_children - children.num_zombies - 1;
	if (last_non_zombie != index) {
		/* swap */

I'm running on Windows 10 and Windows 7 systems.

Extreme care must be taken with search paths when debugging a git server using ssh protocol on Windows, especially if cygwin and mingw, etc., are also installed on the system This is true for the client and server side. Multiple executables for ssh, sshd, and git commands can cause problems if close attention is not paid to search paths.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in shell-host.c at start_withno_pty and in signal_sigchld.c at sw_child_to_zombie. Reproduce the nopty service behavior with Win32-OpenSSH on Windows, focusing on command quoting, child pipe handles, zombie accounting, and signal-time logging. Done means all three reported defects are corrected without regressions.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
networking, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.