From b8181f76f8acf431336c0f213eb932eaca1dcf90 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Sun, 26 May 2024 17:48:14 -0700 Subject: windows: ipc listen use after free --- src/platform/windows/win_debug.c | 4 ++-- src/platform/windows/win_ipclisten.c | 36 ++++++++++++++++-------------------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/platform/windows/win_debug.c b/src/platform/windows/win_debug.c index 3b3c4ab7..b9e2fbe0 100644 --- a/src/platform/windows/win_debug.c +++ b/src/platform/windows/win_debug.c @@ -1,5 +1,5 @@ // -// Copyright 2020 Staysail Systems, Inc. +// Copyright 2024 Staysail Systems, Inc. // Copyright 2018 Capitar IT Group BV // // This software is supplied under the terms of the MIT License, a @@ -111,7 +111,7 @@ static struct { { ERROR_DUP_NAME, NNG_EADDRINUSE }, { ERROR_BROKEN_PIPE, NNG_ECLOSED }, { ERROR_BAD_PIPE, NNG_ECLOSED }, - { ERROR_NO_DATA, NNG_ECLOSED }, + { ERROR_NO_DATA, NNG_ECONNRESET }, { ERROR_PIPE_NOT_CONNECTED, NNG_ECLOSED }, { ERROR_OPERATION_ABORTED, NNG_ECLOSED }, { ERROR_SHARING_VIOLATION, NNG_EBUSY }, diff --git a/src/platform/windows/win_ipclisten.c b/src/platform/windows/win_ipclisten.c index 89fe7268..84efe401 100644 --- a/src/platform/windows/win_ipclisten.c +++ b/src/platform/windows/win_ipclisten.c @@ -42,6 +42,9 @@ ipc_accept_done(ipc_listener *l, int rv) nni_cv_wake(&l->cv); if (l->closed) { + rv = NNG_ECLOSED; + } + if (rv != 0) { // Closed, so bail. DisconnectNamedPipe(l->f); nni_aio_finish_error(aio, NNG_ECLOSED); @@ -83,32 +86,25 @@ ipc_accept_start(ipc_listener *l) { nni_aio *aio; - if (l->closed) { - while ((aio = nni_list_first(&l->aios)) != NULL) { - nni_list_remove(&l->aios, aio); - nni_aio_finish_error(aio, NNG_ECLOSED); - } - nni_cv_wake(&l->cv); - } - while ((aio = nni_list_first(&l->aios)) != NULL) { int rv; - if ((ConnectNamedPipe(l->f, &l->io.olpd)) || - ((rv = GetLastError()) == ERROR_IO_PENDING)) { - // Success, or pending, handled via completion pkt. + if (l->closed) { + nni_aio_list_remove(aio); + nni_aio_finish_error(aio, NNG_ECLOSED); + } else if (ConnectNamedPipe(l->f, &l->io.olpd)) { + rv = 0; + } else if ((rv = GetLastError()) == ERROR_IO_PENDING) { + // asynchronous completion pending return; + } else if (rv == ERROR_PIPE_CONNECTED) { + rv = 0; } - if (rv == ERROR_PIPE_CONNECTED) { - // Kind of like success, but as this is technically - // an "error", we have to complete it ourself. - // Fake a completion. - ipc_accept_done(l, 0); - } else { - // Fast-fail (synchronous). - nni_aio_finish_error(aio, nni_win_error(rv)); - } + // synchronous completion + ipc_accept_done(l, rv); } + + nni_cv_wake(&l->cv); } static void -- cgit v1.2.3-70-g09d2