Add ossig.h. Move SignalHandler to ossig.h
This avoids a circular dependency between misc.h and trap.h. It also allows us to logically segregate and group code to replace C++ handlers, like set_terminatepull/286/head
parent
91ca6c117d
commit
3815b908ab
86
misc.h
86
misc.h
|
|
@ -114,13 +114,13 @@ NAMESPACE_BEGIN(CryptoPP)
|
||||||
// Forward declaration for IntToString specialization
|
// Forward declaration for IntToString specialization
|
||||||
class Integer;
|
class Integer;
|
||||||
|
|
||||||
// ************** compile-time CRYPTOPP_ASSERTion ***************
|
// ************** compile-time assertion ***************
|
||||||
|
|
||||||
#if CRYPTOPP_DOXYGEN_PROCESSING
|
#if CRYPTOPP_DOXYGEN_PROCESSING
|
||||||
//! \brief Compile time CRYPTOPP_ASSERTion
|
//! \brief Compile time CRYPTOPP_ASSERTion
|
||||||
//! \param expr the expression to evaluate
|
//! \param expr the expression to evaluate
|
||||||
//! \details Asserts the expression expr though a dummy struct.
|
//! \details Asserts the expression expr though a dummy struct.
|
||||||
#define CRYPTOPP_COMPILE_ASSERT(expr) ...
|
#define CRYPTOPP_COMPILE_ASSERT(expr) { ... }
|
||||||
#else // CRYPTOPP_DOXYGEN_PROCESSING
|
#else // CRYPTOPP_DOXYGEN_PROCESSING
|
||||||
template <bool b>
|
template <bool b>
|
||||||
struct CompileAssert
|
struct CompileAssert
|
||||||
|
|
@ -331,88 +331,6 @@ const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CRYPTOPP_BSD_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
|
|
||||||
//! \brief Signal handler function pointer
|
|
||||||
//! \sa SignalHandler
|
|
||||||
extern "C" {
|
|
||||||
typedef void (*SignalHandlerFn) (int);
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Signal handler for Linux and Unix compatibles
|
|
||||||
//! \tparam S Signal number
|
|
||||||
//! \tparam O Flag indicating exsting handler should be overwriiten
|
|
||||||
//! \details SignalHandler() can be used to install a signal handler with the signature
|
|
||||||
//! <tt>void handler_fn(int)</tt>. If <tt>SignalHandlerFn</tt> is not <tt>NULL</tt>, then
|
|
||||||
//! the sigaction is set to the function and the sigaction flags is set to the flags.
|
|
||||||
//! If <tt>SignalHandlerFn</tt> is <tt>NULL</tt>, then a default handler is installed
|
|
||||||
//! using sigaction flags set to 0. The default handler only returns from the call.
|
|
||||||
//! \details Upon destruction the previous signal handler is restored.
|
|
||||||
//! \warning Do not use SignalHandler in a code block that uses <tt>setjmp</tt> or <tt>longjmp</tt>
|
|
||||||
//! because the destructor may not run.
|
|
||||||
//! \since Crypto++ 5.6.5
|
|
||||||
//! \sa SignalHandlerFn, \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT", DebugTrapHandler
|
|
||||||
template <int S, bool O=false>
|
|
||||||
struct SignalHandler : private NotCopyable
|
|
||||||
{
|
|
||||||
//! \brief Construct a signal handler
|
|
||||||
//! \param pfn Pointer to a signal handler function
|
|
||||||
//! \param flags Flags to use with the signal handler
|
|
||||||
//! \details SignalHandler() installs a signal handler with the signature
|
|
||||||
//! <tt>void handler_fn(int)</tt>. If <tt>SignalHandlerFn</tt> is not <tt>NULL</tt>, then
|
|
||||||
//! the sigaction is set to the function and the sigaction flags is set to the flags.
|
|
||||||
//! If <tt>SignalHandlerFn</tt> is <tt>NULL</tt>, then a default handler is installed
|
|
||||||
//! using sigaction flags set to 0. The default handler only returns from the call.
|
|
||||||
//! \details Upon destruction the previous signal handler is restored.
|
|
||||||
//! \warning Do not use SignalHandler in a code block that uses <tt>setjmp</tt> or <tt>longjmp</tt>
|
|
||||||
//! because the destructor may not run.
|
|
||||||
//! \since Crypto++ 5.6.5
|
|
||||||
SignalHandler(SignalHandlerFn pfn = 0, int flags = 0) : m_installed(false)
|
|
||||||
{
|
|
||||||
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/sigaction.html
|
|
||||||
struct sigaction new_handler;
|
|
||||||
// memset(&new_handler, 0x00, sizeof(new_handler));
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
ret = sigaction (S, 0, &m_old);
|
|
||||||
if (ret != 0) break; // Failed
|
|
||||||
|
|
||||||
// Don't step on another's handler if Overwrite=false
|
|
||||||
if (m_old.sa_handler != 0 && !O) break;
|
|
||||||
|
|
||||||
// Set up the structure to specify the action.
|
|
||||||
new_handler.sa_handler = (pfn ? pfn : &SignalHandler::NullHandler);
|
|
||||||
new_handler.sa_flags = (pfn ? flags : 0);
|
|
||||||
|
|
||||||
ret = sigemptyset (&new_handler.sa_mask);
|
|
||||||
if (ret != 0) break; // Failed
|
|
||||||
|
|
||||||
// Install it
|
|
||||||
ret = sigaction (S, &new_handler, 0);
|
|
||||||
if (ret != 0) break; // Failed
|
|
||||||
|
|
||||||
m_installed = true;
|
|
||||||
|
|
||||||
} while(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
~SignalHandler()
|
|
||||||
{
|
|
||||||
if (m_installed)
|
|
||||||
sigaction (S, &m_old, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
struct sigaction m_old;
|
|
||||||
bool m_installed;
|
|
||||||
|
|
||||||
static void NullHandler(int /*unused*/) { }
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************** misc functions ***************
|
// ************** misc functions ***************
|
||||||
|
|
||||||
#if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) || defined(CRYPTOPP_WANT_SECURE_LIB)
|
#if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) || defined(CRYPTOPP_WANT_SECURE_LIB)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
// ossig.h - written and placed in the public domain by Jeffrey Walton
|
||||||
|
// Copyright assigned to Crypto++ project.
|
||||||
|
|
||||||
|
//! \file ossig.h
|
||||||
|
//! \brief Utility class for trapping OS signals.
|
||||||
|
//! \since Crypto++ 5.6.5
|
||||||
|
|
||||||
|
#ifndef CRYPTOPP_OS_SIGNAL_H
|
||||||
|
#define CRYPTOPP_OS_SIGNAL_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined(CRYPTOPP_BSD_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE)
|
||||||
|
# include <signal.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NAMESPACE_BEGIN(CryptoPP)
|
||||||
|
|
||||||
|
// ************** Unix and Linux compatibles ***************
|
||||||
|
|
||||||
|
#if defined(CRYPTOPP_BSD_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
|
||||||
|
//! \brief Signal handler function pointer
|
||||||
|
//! \sa SignalHandler
|
||||||
|
extern "C" {
|
||||||
|
typedef void (*SignalHandlerFn) (int);
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Signal handler for Linux and Unix compatibles
|
||||||
|
//! \tparam S Signal number
|
||||||
|
//! \tparam O Flag indicating exsting handler should be overwriiten
|
||||||
|
//! \details SignalHandler() can be used to install a signal handler with the signature
|
||||||
|
//! <tt>void handler_fn(int)</tt>. If <tt>SignalHandlerFn</tt> is not <tt>NULL</tt>, then
|
||||||
|
//! the sigaction is set to the function and the sigaction flags is set to the flags.
|
||||||
|
//! If <tt>SignalHandlerFn</tt> is <tt>NULL</tt>, then a default handler is installed
|
||||||
|
//! using sigaction flags set to 0. The default handler only returns from the call.
|
||||||
|
//! \details Upon destruction the previous signal handler is restored if the former signal handler
|
||||||
|
//! was replaced.
|
||||||
|
//! \warning Do not use SignalHandler in a code block that uses <tt>setjmp</tt> or <tt>longjmp</tt>
|
||||||
|
//! because the destructor may not run.
|
||||||
|
//! \since Crypto++ 5.6.5
|
||||||
|
//! \sa SignalHandlerFn, \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT", DebugTrapHandler
|
||||||
|
template <int S, bool O=false>
|
||||||
|
struct SignalHandler
|
||||||
|
{
|
||||||
|
//! \brief Construct a signal handler
|
||||||
|
//! \param pfn Pointer to a signal handler function
|
||||||
|
//! \param flags Flags to use with the signal handler
|
||||||
|
//! \details SignalHandler() installs a signal handler with the signature
|
||||||
|
//! <tt>void handler_fn(int)</tt>. If <tt>SignalHandlerFn</tt> is not <tt>NULL</tt>, then
|
||||||
|
//! the sigaction is set to the function and the sigaction flags is set to the flags.
|
||||||
|
//! If <tt>SignalHandlerFn</tt> is <tt>NULL</tt>, then a default handler is installed
|
||||||
|
//! using sigaction flags set to 0. The default handler only returns from the call.
|
||||||
|
//! \details Upon destruction the previous signal handler is restored if the former signal handler
|
||||||
|
//! was overwritten.
|
||||||
|
//! \warning Do not use SignalHandler in a code block that uses <tt>setjmp</tt> or <tt>longjmp</tt>
|
||||||
|
//! because the destructor may not run. <tt>setjmp</tt> is why cpu.cpp does not use SignalHandler
|
||||||
|
//! during CPU feature testing.
|
||||||
|
//! \since Crypto++ 5.6.5
|
||||||
|
SignalHandler(SignalHandlerFn pfn = 0, int flags = 0) : m_installed(false)
|
||||||
|
{
|
||||||
|
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/sigaction.html
|
||||||
|
struct sigaction new_handler;
|
||||||
|
// memset(&new_handler, 0x00, sizeof(new_handler));
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = sigaction (S, 0, &m_old);
|
||||||
|
if (ret != 0) break; // Failed
|
||||||
|
|
||||||
|
// Don't step on another's handler if Overwrite=false
|
||||||
|
if (m_old.sa_handler != 0 && !O) break;
|
||||||
|
|
||||||
|
// Set up the structure to specify the action.
|
||||||
|
new_handler.sa_handler = (pfn ? pfn : &SignalHandler::NullHandler);
|
||||||
|
new_handler.sa_flags = (pfn ? flags : 0);
|
||||||
|
|
||||||
|
ret = sigemptyset (&new_handler.sa_mask);
|
||||||
|
if (ret != 0) break; // Failed
|
||||||
|
|
||||||
|
// Install it
|
||||||
|
ret = sigaction (S, &new_handler, 0);
|
||||||
|
if (ret != 0) break; // Failed
|
||||||
|
|
||||||
|
m_installed = true;
|
||||||
|
|
||||||
|
} while(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
~SignalHandler()
|
||||||
|
{
|
||||||
|
if (m_installed)
|
||||||
|
sigaction (S, &m_old, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct sigaction m_old;
|
||||||
|
bool m_installed;
|
||||||
|
|
||||||
|
static void NullHandler(int /*unused*/) { /* continue*/ }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Not copyable
|
||||||
|
SignalHandler(const SignalHandler &);
|
||||||
|
void operator=(const SignalHandler &);
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // CRYPTOPP_OS_SIGNAL_H
|
||||||
2
test.cpp
2
test.cpp
|
|
@ -21,6 +21,7 @@
|
||||||
#include "whrlpool.h"
|
#include "whrlpool.h"
|
||||||
#include "tiger.h"
|
#include "tiger.h"
|
||||||
#include "smartptr.h"
|
#include "smartptr.h"
|
||||||
|
#include "ossig.h"
|
||||||
#include "trap.h"
|
#include "trap.h"
|
||||||
|
|
||||||
#include "validate.h"
|
#include "validate.h"
|
||||||
|
|
@ -132,6 +133,7 @@ RandomNumberGenerator & GlobalRNG()
|
||||||
// See misc.h and trap.h for comments and usage
|
// See misc.h and trap.h for comments and usage
|
||||||
#if CRYPTOPP_DEBUG && (defined(CRYPTOPP_BSD_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE))
|
#if CRYPTOPP_DEBUG && (defined(CRYPTOPP_BSD_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE))
|
||||||
static const SignalHandler<SIGTRAP, false> s_dummyHandler;
|
static const SignalHandler<SIGTRAP, false> s_dummyHandler;
|
||||||
|
// static const DebugTrapHandle s_dummyHandler;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int CRYPTOPP_API main(int argc, char *argv[])
|
int CRYPTOPP_API main(int argc, char *argv[])
|
||||||
|
|
|
||||||
47
trap.h
47
trap.h
|
|
@ -17,6 +17,7 @@
|
||||||
#define CRYPTOPP_TRAP_H
|
#define CRYPTOPP_TRAP_H
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "ossig.h"
|
||||||
|
|
||||||
#if CRYPTOPP_DEBUG
|
#if CRYPTOPP_DEBUG
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
|
|
@ -24,8 +25,6 @@
|
||||||
# if defined(CRYPTOPP_WIN32_AVAILABLE)
|
# if defined(CRYPTOPP_WIN32_AVAILABLE)
|
||||||
# define WIN32_LEAN_AND_MEAN
|
# define WIN32_LEAN_AND_MEAN
|
||||||
# include <Windows.h>
|
# include <Windows.h>
|
||||||
# elif defined(CRYPTOPP_BSD_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE)
|
|
||||||
# include <signal.h>
|
|
||||||
# endif
|
# endif
|
||||||
#endif // CRYPTOPP_DEBUG
|
#endif // CRYPTOPP_DEBUG
|
||||||
|
|
||||||
|
|
@ -131,46 +130,14 @@ NAMESPACE_BEGIN(CryptoPP)
|
||||||
//! \since Crypto++ 5.6.5
|
//! \since Crypto++ 5.6.5
|
||||||
//! \sa \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT", SignalHandler, <A HREF="http://github.com/weidai11/cryptopp/issues/277">Issue 277</A>,
|
//! \sa \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT", SignalHandler, <A HREF="http://github.com/weidai11/cryptopp/issues/277">Issue 277</A>,
|
||||||
//! <A HREF="http://seclists.org/oss-sec/2016/q3/520">CVE-2016-7420</A>
|
//! <A HREF="http://seclists.org/oss-sec/2016/q3/520">CVE-2016-7420</A>
|
||||||
struct DebugTrapHandler
|
|
||||||
{
|
|
||||||
DebugTrapHandler()
|
|
||||||
{
|
|
||||||
// http://pubs.opengroup.org/onlinepubs/007908799/xsh/sigaction.html
|
|
||||||
struct sigaction old_handler, new_handler;
|
|
||||||
memset(&old_handler, 0x00, sizeof(old_handler));
|
|
||||||
memset(&new_handler, 0x00, sizeof(new_handler));
|
|
||||||
|
|
||||||
do
|
#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
|
||||||
{
|
class DebugTrapHandler : public SignalHandler<SIGILL, false> { };
|
||||||
int ret = 0;
|
#else
|
||||||
|
typedef SignalHandler<SIGILL, false> DebugTrapHandler;
|
||||||
|
#endif
|
||||||
|
|
||||||
ret = sigaction (SIGTRAP, 0, &old_handler);
|
#endif // Linux, Unix and Documentation
|
||||||
if (ret != 0) break; // Failed
|
|
||||||
|
|
||||||
// Don't step on another's handler
|
|
||||||
if (old_handler.sa_handler != 0) break;
|
|
||||||
|
|
||||||
// Set up the structure to specify the NULL action.
|
|
||||||
new_handler.sa_handler = &DebugTrapHandler::NullHandler;
|
|
||||||
new_handler.sa_flags = 0;
|
|
||||||
|
|
||||||
ret = sigemptyset (&new_handler.sa_mask);
|
|
||||||
if (ret != 0) break; // Failed
|
|
||||||
|
|
||||||
// Install it
|
|
||||||
ret = sigaction (SIGTRAP, &new_handler, 0);
|
|
||||||
if (ret != 0) break; // Failed
|
|
||||||
|
|
||||||
} while(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void NullHandler(int /*unused*/) { }
|
|
||||||
|
|
||||||
private:
|
|
||||||
DebugTrapHandler(const DebugTrapHandler &);
|
|
||||||
void operator=(const DebugTrapHandler &);
|
|
||||||
};
|
|
||||||
#endif // DebugTrapHandler
|
|
||||||
|
|
||||||
NAMESPACE_END
|
NAMESPACE_END
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue