Extensions/libraries/plugins might enable FPU/SSE2 exceptions, causing floating-point operations to crash (533035, r=robarnold,bsmedberg).

This commit is contained in:
Andreas Gal 2009-12-17 13:56:12 -08:00
parent 8b449748c7
commit f02162a25b
4 changed files with 208 additions and 13 deletions

View File

@ -67,6 +67,7 @@ CPPSRCS = \
nsXREDirProvider.cpp \
nsNativeAppSupportBase.cpp \
nsAppData.cpp \
nsSigHandlers.cpp \
$(NULL)
ifdef MOZ_SPLASHSCREEN
@ -120,10 +121,6 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
CMMSRCS += MacApplicationDelegate.mm
endif
ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
CPPSRCS += nsSigHandlers.cpp
endif
SHARED_LIBRARY_LIBS += ../profile/src/$(LIB_PREFIX)profile_s.$(LIB_SUFFIX)
ifdef MOZ_ENABLE_XREMOTE

View File

@ -239,9 +239,7 @@ protected:
};
#endif
#if defined(XP_UNIX) || defined(XP_BEOS)
extern void InstallUnixSignalHandlers(const char *ProgramName);
#endif
extern void InstallSignalHandlers(const char *ProgramName);
#define FILE_COMPATIBILITY_INFO NS_LITERAL_CSTRING("compatibility.ini")
@ -2678,9 +2676,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
#endif
#endif
#if defined(XP_UNIX) || defined(XP_BEOS)
InstallUnixSignalHandlers(argv[0]);
#endif
InstallSignalHandlers(argv[0]);
#ifdef MOZ_ACCESSIBILITY_ATK
// Reset GTK_MODULES, strip atk-bridge if exists

View File

@ -42,6 +42,10 @@
* platforms that do not support it.
*/
#include "nsSigHandlers.h"
#ifdef XP_UNIX
#include <signal.h>
#include <stdio.h>
#include <string.h>
@ -55,6 +59,7 @@
#include <sys/resource.h>
#include <unistd.h>
#include <stdlib.h> // atoi
#include <ucontext.h>
#endif
#if defined(SOLARIS)
@ -204,7 +209,53 @@ my_glib_log_func(const gchar *log_domain, GLogLevelFlags log_level,
#endif
void InstallUnixSignalHandlers(const char *ProgramName)
static void fpehandler(int signum, siginfo_t *si, void *context)
{
#ifdef XP_MACOSX
ucontext_t *uc = (ucontext_t *)context;
#if defined(__i386__) || defined(__amd64__)
_STRUCT_FP_CONTROL *ctrl = &uc->uc_mcontext->__fs.__fpu_fcw;
ctrl->__invalid = ctrl->__denorm = ctrl->__zdiv = ctrl->__ovrfl = ctrl->__undfl = ctrl->__precis = 1;
_STRUCT_FP_STATUS *status = &uc->uc_mcontext->__fs.__fpu_fsw;
status->__invalid = status->__denorm = status->__zdiv = status->__ovrfl = status->__undfl =
status->__precis = status->__stkflt = status->__errsumm = 0;
__uint32_t *mxcsr = &uc->uc_mcontext->__fs.__fpu_mxcsr;
*mxcsr |= SSE_EXCEPTION_MASK; /* disable all SSE exceptions */
*mxcsr &= ~SSE_STATUS_FLAGS; /* clear all pending SSE exceptions */
#endif
#endif
#ifdef LINUX
ucontext_t *uc = (ucontext_t *)context;
#if defined(__i386__)
/*
* It seems that we have no access to mxcsr on Linux. libc
* seems to be translating cw/sw to mxcsr.
*/
unsigned long int *cw = &uc->uc_mcontext.fpregs->cw;
*cw |= FPU_EXCEPTION_MASK;
unsigned long int *sw = &uc->uc_mcontext.fpregs->sw;
*sw &= ~FPU_STATUS_FLAGS;
#endif
#if defined(__amd64__)
uint16_t *cw = &uc->uc_mcontext.fpregs->cwd;
*cwd |= FPU_EXCEPTION_MASK;
uint16_t *sw = &uc->uc_mcontext.fpregs->swd;
*swd &= ~FPU_STATUS_FLAGS;
__uint32_t *mxcsr = &uc->uc_mcontext->fpregs->mxcsr;
*mxcsr |= SSE_EXCEPTION_MASK; /* disable all SSE exceptions */
*mxcsr &= ~SSE_STATUS_FLAGS; /* clear all pending SSE exceptions */
#endif
#endif
}
void InstallSignalHandlers(const char *ProgramName)
{
PL_strncpy(_progname,ProgramName, (sizeof(_progname)-1) );
@ -226,15 +277,19 @@ void InstallUnixSignalHandlers(const char *ProgramName)
signal(SIGSEGV, abnormal_exit_handler);
signal(SIGILL, abnormal_exit_handler);
signal(SIGABRT, abnormal_exit_handler);
signal(SIGFPE, abnormal_exit_handler);
#elif defined(CRAWL_STACK_ON_SIGSEGV)
signal(SIGSEGV, ah_crap_handler);
signal(SIGILL, ah_crap_handler);
signal(SIGABRT, ah_crap_handler);
signal(SIGFPE, ah_crap_handler);
#endif // CRAWL_STACK_ON_SIGSEGV
/* Install a handler for floating point exceptions and disable them if they occur. */
struct sigaction sa, osa;
sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
sa.sa_sigaction = fpehandler;
sigaction(SIGFPE, &sa, &osa);
#if defined(DEBUG) && defined(LINUX)
const char *memLimit = PR_GetEnv("MOZ_MEM_LIMIT");
if (memLimit && *memLimit)
@ -289,3 +344,78 @@ void InstallUnixSignalHandlers(const char *ProgramName)
}
#endif
}
#elif XP_WIN
#include <windows.h>
#ifdef _M_IX86
/*
* WinNT.h prior to SDK7 does not expose the structure of the ExtendedRegisters for ia86.
* We known that MxCsr is at offset 0x18 and is a DWORD.
*/
#define MXCSR(ctx) (*(DWORD *)(((BYTE *)(ctx)->ExtendedRegisters) + 0x18))
#endif
#ifdef _M_X64
#define MXCSR(ctx) (ctx)->MxCsr
#endif
#if defined(_M_IA32) || define(_M_X64)
#define X87CW(ctx) (ctx)->FloatSave.ControlWord
#define X87SW(ctx) (ctx)->FloatSave.StatusWord
/*
* SSE traps raise these exception codes, which are defined in internal NT headers
* but not winbase.h
*/
#define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4
#define STATUS_FLOAT_MULTIPLE_TRAPS 0xC00002B5
LONG __stdcall FpeHandler(PEXCEPTION_POINTERS pe)
{
PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord;
CONTEXT *c = (CONTEXT*)pe->ContextRecord;
switch (e->ExceptionCode) {
case STATUS_FLOAT_DENORMAL_OPERAND:
case STATUS_FLOAT_DIVIDE_BY_ZERO:
case STATUS_FLOAT_INEXACT_RESULT:
case STATUS_FLOAT_INVALID_OPERATION:
case STATUS_FLOAT_OVERFLOW:
case STATUS_FLOAT_STACK_CHECK:
case STATUS_FLOAT_UNDERFLOW:
case STATUS_FLOAT_MULTIPLE_FAULTS:
case STATUS_FLOAT_MULTIPLE_TRAPS:
X87CW(c) |= FPU_EXCEPTION_MASK; /* disable all FPU exceptions */
X86SW(c) &= ~FPU_STATUS_FLAGS; /* clear all pending FPU exceptions */
#ifdef _M_IA32
if (c->ContextFlags & CONTEXT_EXTENDED_REGISTERS) {
#endif
MXCSR(c) |= SSE_EXCEPTION_MASK; /* disable all SSE exceptions */
MXCSR(c) &= ~SSE_STATUS_FLAGS; /* clear all pending SSE exceptions */
#ifdef _M_IA32
}
#endif
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
void InstallSignalHandlers(const char *ProgramName)
{
SetUnhandledExceptionFilter(FpeHandler);
}
#else
void InstallSignalHandlers(const char *ProgramName)
{
}
#endif
#else
#error No signal handling implementation for this platform.
#endif

View File

@ -0,0 +1,72 @@
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corp
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Andreas Gal <gal@uci.edu>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#if defined(_M_IA32) || defined(_M_X86) || defined(__i386__) || defined(__amd64__)
/*
* x87 FPU Control Word:
*
* 0 -> IM Invalid Operation
* 1 -> DM Denormalized Operand
* 2 -> ZM Zero Divide
* 3 -> OM Overflow
* 4 -> UM Underflow
* 5 -> PM Precision
*/
#define FPU_EXCEPTION_MASK 0x3f
/*
* x86 FPU Status Word:
*
* 0..5 -> Exception flags (see x86 FPU Control Word)
* 6 -> SF Stack Fault
* 7 -> ES Error Summary Status
*/
#define FPU_STATUS_FLAGS 0xff
/*
* MXCSR Control and Status Register:
*
* 0..5 -> Exception flags (see x86 FPU Control Word)
* 6 -> DAZ Denormals Are Zero
* 7..12 -> Exception mask (see x86 FPU Control Word)
*/
#define SSE_STATUS_FLAGS FPU_EXCEPTION_MASK
#define SSE_EXCEPTION_MASK (FPU_EXCEPTION_MASK << 7)
#endif