From: Daniel Lenski <dlenski@gmail.com> Date: Mon, 3 Jan 2022 16:26:52 +0000 (-0500) Subject: dumb_socketpair(): Try a whole series of plausible temporary/writable directories... X-Git-Tag: v8.20~30^2~1 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=a39a0ea3a6ba4ea09f1c16df3590675b2b841a3c;p=users%2Fdwmw2%2Fopenconnect.git dumb_socketpair(): Try a whole series of plausible temporary/writable directories for AF_UNIX sockets This is probably trying too hard. Discussed in https://gitlab.com/openconnect/openconnect/-/merge_requests/320#note_800005154 Signed-off-by: Daniel Lenski <dlenski@gmail.com> --- diff --git a/compat.c b/compat.c index 841d092a..e7b56343 100644 --- a/compat.c +++ b/compat.c @@ -428,26 +428,52 @@ int dumb_socketpair(OPENCONNECT_CMD_SOCKET socks[2], int make_overlapped) * https://github.com/microsoft/WSL/issues/4240#issuecomment-549663217 * * So we must use a named path, and that comes with all the attendant - * problems of permissions and collisions. Generating a path in the - * temporary directory, combining current high-res time and PID, seems - * like a less-bad option. + * problems of permissions and collisions. Trying various temporary + * directories and putting high-res time and PID in the filename, that + * seems like a less-bad option. */ LARGE_INTEGER ticks; - DWORD n = GetTempPath(UNIX_PATH_MAX, a.unaddr.sun_path); - /* If temp dir is too long, give up and just use current directory. */ - if (n >= UNIX_PATH_MAX - 8) - n = 0; - /* GetTempFileName could be used here. - * (https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamea) - * However it only adds 16 bits of time-based random bits, - * fails if there isn't room for a 14-character filename, and - * seems to offers no other apparent advantages. So we will - * use high-res timer ticks and PID for filename. - */ - QueryPerformanceCounter(&ticks); - snprintf(a.unaddr.sun_path + n, UNIX_PATH_MAX - n, - "%"PRIx64"-%"PRId32".$$$", ticks.QuadPart, GetCurrentProcessId()); - a.unaddr.sun_family = AF_UNIX; + DWORD n; + int bind_try = 0; + + for (;;) { + switch (bind_try++) { + case 0: + /* "The returned string ends with a backslash" */ + n = GetTempPath(UNIX_PATH_MAX, a.unaddr.sun_path); + break; + case 1: + /* Heckuva job with API consistency, Microsoft! + * unless the Windows directory is the root directory." + */ + n = GetWindowsDirectory(a.unaddr.sun_path, UNIX_PATH_MAX); + n += snprintf(a.unaddr.sun_path + n, UNIX_PATH_MAX - n, "\\Temp\\"); + break; + case 2: + n = snprintf(a.unaddr.sun_path, UNIX_PATH_MAX, "C:\\Temp\\"); + break; + case 3: + n = 0; /* Current directory */ + break; + case 4: + goto fallback; + } + + /* GetTempFileName could be used here. + * (https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamea) + * However it only adds 16 bits of time-based random bits, + * fails if there isn't room for a 14-character filename, and + * seems to offers no other apparent advantages. So we will + * use high-res timer ticks and PID for filename. + */ + QueryPerformanceCounter(&ticks); + snprintf(a.unaddr.sun_path + n, UNIX_PATH_MAX - n, + "%"PRIx64"-%"PRId32".$$$", ticks.QuadPart, GetCurrentProcessId()); + a.unaddr.sun_family = AF_UNIX; + + if (bind(listener, &a.addr, addrlen) != SOCKET_ERROR) + break; + } } else { a.inaddr.sin_family = AF_INET; a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); @@ -456,12 +482,10 @@ int dumb_socketpair(OPENCONNECT_CMD_SOCKET socks[2], int make_overlapped) if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, (socklen_t) sizeof(reuse)) == -1) goto fallback;; - } - if (bind(listener, &a.addr, addrlen) == SOCKET_ERROR) - goto fallback; + if (bind(listener, &a.addr, addrlen) == SOCKET_ERROR) + goto fallback; - if (domain == AF_INET) { memset(&a, 0, sizeof(a)); if (getsockname(listener, &a.addr, &addrlen) == SOCKET_ERROR) goto fallback;