Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rt.openssl.org #4526] bug: use of ExitProcess on Windows platforms, 1.0.2g #2489

Closed
richsalz opened this issue Feb 2, 2017 · 6 comments
Closed
Milestone

Comments

@richsalz
Copy link
Contributor

richsalz commented Feb 2, 2017

Migrated from rt.openssl.org#4526 (status was 'open')

Requestors:

From tbaen@wynyardgroup.com on 2016-05-02 12:33:22:
Hi,

I'm working in the 1.0.2g version of OpenSSL, in a Windows desktop environment, specifically Win 7, 8.1, and 10 (and their equivalent server and R2 versions).

Problem and Resolution:
The following lines of code make use of the Microsoft API ExitProcess:

Apps\Speed.c line 335:	ExitProcess(ret);
Ms\uplink.c line 22: ExitProcess(1);

These function calls are made after fatal errors are detected and program termination is desired. ExitProcess(), however causes orderly shutdown of a process and all its threads, i.e. it unloads all dlls and runs all destructors. See MSDN for details of exactly what happens (https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx). The MSDN page states that ExitProcess should never be called unless it is known to be safe to call it. These calls should simply be replaced with calls to TerminateProcess(), which is what should be called for disorderly shutdown.

An example of usage:

TerminateProcess(GetCurrentProcess(), exitcode);

Effect of Problem:
Because of a compilation error (wrong c++ runtime), my program executed the uplink.c ExitProcess() call. This caused the single OpenSSL thread to start executing the destructors of all my dlls, and their objects. Unfortunately, about 30 other threads were happily using those objects at that time, eventually causing a 0xC0000005 ACCESS_VIOLATION. Obviously an ACCESS_VIOLATION is the best case scenario, as I'm sure you can imagine at the consequences of undiscovered memory corruption, even in a terminating process.

Regards,

Ty Baen-Price
JADE Development Team Leader
Wynyard Group

DDI +64 3 367 8453

Powerful Software. Connecting the Dots.
wynyardgroup.com

From rsalz@openssl.org on 2016-06-15 17:42:58:

OpenSSL_1_0_2-stable 75f9068 RT4526: Call TerminateProcess, not ExitProcess
master 9c1a9cc RT4526: Call TerminateProcess, not ExitProcess

Author: Rich Salz rsalz@openssl.org
Date: Tue Jun 14 16:19:37 2016 -0400

RT4526: Call TerminateProcess, not ExitProcess

Reviewed-by: Richard Levitte <levitte@openssl.org>

From matt@openssl.org on 2016-06-16 16:44:16:

On Wed Jun 15 17:42:58 2016, rsalz wrote:

OpenSSL_1_0_2-stable 75f9068 RT4526: Call TerminateProcess, not ExitProcess
master 9c1a9cc RT4526: Call TerminateProcess, not ExitProcess

Author: Rich Salz rsalz@openssl.org
Date: Tue Jun 14 16:19:37 2016 -0400

RT4526: Call TerminateProcess, not ExitProcess

Reviewed-by: Richard Levitte levitte@openssl.org

I just reverted this commit. We need to take another look at this, so
reopening this ticket.

Matt

From tbaen@wynyardgroup.com on 2016-06-20 01:53:28:

Hi!

I just looked on GitHub and I see the reason you reverted the change is that TerminateProcess is asynchronous.

That is technically true, but I think it's probably synchronous "enough" for your purposes, since a call to TerminateProcess suspends execution of all threads in the target process. This means it's really only asynchronous if you're calling TerminateProcess one some other process. If you're calling TerminateProcess on your own process, you'll never return from the TerminateProcess call.

Regards,
Ty

-----Original Message-----
From: Matt Caswell via RT [mailto:rt@openssl.org]
Sent: Friday, 17 June 2016 4:44 AM
To: Ty Baen-Price tbaen@wynyardgroup.com
Cc: openssl-dev@openssl.org
Subject: [openssl.org #4526] bug: use of ExitProcess on Windows platforms, 1.0.2g

On Wed Jun 15 17:42:58 2016, rsalz wrote:

OpenSSL_1_0_2-stable 75f9068 RT4526: Call TerminateProcess, not
ExitProcess master 9c1a9cc RT4526: Call TerminateProcess, not
ExitProcess

Author: Rich Salz rsalz@openssl.org
Date: Tue Jun 14 16:19:37 2016 -0400

RT4526: Call TerminateProcess, not ExitProcess

Reviewed-by: Richard Levitte levitte@openssl.org

I just reverted this commit. We need to take another look at this, so reopening this ticket.

Matt

--
Ticket here: http://rt.openssl.org/Ticket/Display.html?id=4526
Please log in as guest with password guest if prompted

[re-edited for better readability /@levitte]

@mattcaswell mattcaswell added this to the 1.1.1 milestone Jan 19, 2018
@richsalz
Copy link
Contributor Author

This is not behavior introduced in 1.1.1, so removing that milestone.

@richsalz richsalz removed this from the 1.1.1 milestone Jun 27, 2018
@mattcaswell mattcaswell added this to the Assessed milestone Jul 2, 2018
@levitte
Copy link
Member

levitte commented Feb 13, 2019

This needs a revisit in newer branches

@levitte
Copy link
Member

levitte commented Feb 21, 2019

@mattcaswell, can you remember why you reverted the change to use TerminateProcess()?

@mattcaswell
Copy link
Member

I don't recall the details of this but commit f219a1b has this description:

"TerminateProcess is asynchronous, so the code as written in the above commit is not correct. It is also probably not needed in the speed case. Reverting in order to figure out the correct solution."

The original gitlab merge request (this was pre github), additionally claims that the original code did not even compile at the time that we reverted it.

@levitte
Copy link
Member

levitte commented Feb 21, 2019

Yeah, so re asynchronous, I'll quote the response from the description above:

Hi!

I just looked on GitHub and I see the reason you reverted the change is that TerminateProcess is asynchronous.

That is technically true, but I think it's probably synchronous "enough" for your purposes, since a call to TerminateProcess suspends execution of all threads in the target process. This means it's really only asynchronous if you're calling TerminateProcess one some other process. If you're calling TerminateProcess on your own process, you'll never return from the TerminateProcess call.

Regards,
Ty

As for not compiling (assume you meant the code with TerminateProcess), that should be looked into, of courses.

I'm thinking of reapplying the original patch and then bash it mercilessly until it compiles properly... and concerns about such action?

@mattcaswell
Copy link
Member

Nope.

levitte added a commit to levitte/openssl that referenced this issue Feb 22, 2019
Ty Baen-Price explains:

> Problem and Resolution:
> The following lines of code make use of the Microsoft API ExitProcess:
>
> ```
> Apps\Speed.c line 335:	ExitProcess(ret);
> Ms\uplink.c line 22: ExitProcess(1);
> ```
>
> These function calls are made after fatal errors are detected and
> program termination is desired. ExitProcess(), however causes
> _orderly_ shutdown of a process and all its threads, i.e. it unloads
> all dlls and runs all destructors. See MSDN for details of exactly
> what happens
> (https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx).
> The MSDN page states that ExitProcess should never be called unless
> it is _known to be safe_ to call it. These calls should simply be
> replaced with calls to TerminateProcess(), which is what should be
> called for _disorderly_ shutdown.
>
> An example of usage:
>
> ```
> TerminateProcess(GetCurrentProcess(), exitcode);
> ```
>
> Effect of Problem:
> Because of a compilation error (wrong c++ runtime), my program
> executed the uplink.c ExitProcess() call. This caused the single
> OpenSSL thread to start executing the destructors of all my dlls,
> and their objects. Unfortunately, about 30 other threads were
> happily using those objects at that time, eventually causing a
> 0xC0000005 ACCESS_VIOLATION. Obviously an ACCESS_VIOLATION is the
> best case scenario, as I'm sure you can imagine at the consequences
> of undiscovered memory corruption, even in a terminating process.

And on the subject of `TerminateProcess()` being asynchronous:

> That is technically true, but I think it's probably synchronous
> "enough" for your purposes, since a call to TerminateProcess
> suspends execution of all threads in the target process. This means
> it's really only asynchronous if you're calling TerminateProcess one
> some _other_ process. If you're calling TerminateProcess on your own
> process, you'll never return from the TerminateProcess call.

Fixes openssl#2489
Was originally RT-4526
levitte added a commit that referenced this issue Feb 22, 2019
Ty Baen-Price explains:

> Problem and Resolution:
> The following lines of code make use of the Microsoft API ExitProcess:
>
> ```
> Apps\Speed.c line 335:	ExitProcess(ret);
> Ms\uplink.c line 22: ExitProcess(1);
> ```
>
> These function calls are made after fatal errors are detected and
> program termination is desired. ExitProcess(), however causes
> _orderly_ shutdown of a process and all its threads, i.e. it unloads
> all dlls and runs all destructors. See MSDN for details of exactly
> what happens
> (https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx).
> The MSDN page states that ExitProcess should never be called unless
> it is _known to be safe_ to call it. These calls should simply be
> replaced with calls to TerminateProcess(), which is what should be
> called for _disorderly_ shutdown.
>
> An example of usage:
>
> ```
> TerminateProcess(GetCurrentProcess(), exitcode);
> ```
>
> Effect of Problem:
> Because of a compilation error (wrong c++ runtime), my program
> executed the uplink.c ExitProcess() call. This caused the single
> OpenSSL thread to start executing the destructors of all my dlls,
> and their objects. Unfortunately, about 30 other threads were
> happily using those objects at that time, eventually causing a
> 0xC0000005 ACCESS_VIOLATION. Obviously an ACCESS_VIOLATION is the
> best case scenario, as I'm sure you can imagine at the consequences
> of undiscovered memory corruption, even in a terminating process.

And on the subject of `TerminateProcess()` being asynchronous:

> That is technically true, but I think it's probably synchronous
> "enough" for your purposes, since a call to TerminateProcess
> suspends execution of all threads in the target process. This means
> it's really only asynchronous if you're calling TerminateProcess one
> some _other_ process. If you're calling TerminateProcess on your own
> process, you'll never return from the TerminateProcess call.

Fixes #2489
Was originally RT-4526

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from #8301)

(cherry picked from commit 9257959)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants