Skip to content
Permalink
Browse files
Change Integrity audit logging to use OS_LOG_TYPE_ERROR.
https://bugs.webkit.org/show_bug.cgi?id=241742

Reviewed by Yusuke Suzuki.

On OS(DARWIN), Integrity audit code now uses an OSLogPrintStream to achieve this
logging with type OS_LOG_TYPE_ERROR.  On other ports, we just route the logging
to WTF::dataFile() instead.

Also removed __VA_ARGS__ support when !VA_OPT_SUPPORTED.  This never worked in the first
place.  Ports without VA_OPT_SUPPORTED will have to live with degraded logging.

Added WTFReportBacktraceWithPrefixAndPrintStream and WTFPrintBacktraceWithPrefixAndPrintStream
to support this new Integrity audit logging.  Removed the old WTFPrintBacktraceWithPrefix
because it was never used by external clients.  It was only used by as an internal support
function by other stack dumper functions.

* Source/JavaScriptCore/tools/Integrity.cpp:
(JSC::Integrity::logFile):
(JSC::Integrity::logF):
(JSC::Integrity::logLnF):
(JSC::Integrity::verifyCell):
* Source/JavaScriptCore/tools/Integrity.h:
* Source/WTF/wtf/Assertions.cpp:
* Source/WTF/wtf/Assertions.h:

Canonical link: https://commits.webkit.org/251666@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295661 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Mark Lam committed Jun 19, 2022
1 parent 1726a5e commit 23272376caff6f758cfb154dc6721b545e313d71
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 21 deletions.
@@ -34,6 +34,8 @@
#include "JSGlobalObject.h"
#include "Options.h"
#include "VMInspectorInlines.h"
#include <wtf/DataLog.h>
#include <wtf/OSLogPrintStream.h>

namespace JSC {
namespace Integrity {
@@ -42,6 +44,40 @@ namespace IntegrityInternal {
static constexpr bool verbose = false;
}

PrintStream& logFile()
{
#if OS(DARWIN)
static PrintStream* s_file;
static std::once_flag once;
std::call_once(once, [] {
// We want to use OS_LOG_TYPE_ERROR because we want to guarantee that the log makes it into
// the file system, and is not potentially stuck in some memory buffer. Integrity audit logs
// are used for debugging error states. So, this is an appropriate use of OS_LOG_TYPE_ERROR.
s_file = OSLogPrintStream::open("com.apple.JavaScriptCore", "Integrity", OS_LOG_TYPE_ERROR).release();
});
return *s_file;
#else
return WTF::dataFile();
#endif
}

void logF(const char* format, ...)
{
va_list argList;
va_start(argList, format);
logFile().vprintf(format, argList);
va_end(argList);
}

void logLnF(const char* format, ...)
{
va_list argList;
va_start(argList, format);
logFile().vprintf(format, argList);
va_end(argList);
logFile().println();
}

Random::Random(VM& vm)
{
reloadAndCheckShouldAuditSlow(vm);
@@ -140,19 +176,19 @@ bool Analyzer::analyzeVM(VM& vm, Analyzer::Action action)

#define AUDIT_VERIFY(cond, format, ...) do { \
IA_ASSERT_WITH_ACTION(cond, { \
WTFLogAlways(" cell %p", cell); \
Integrity::logLnF(" cell %p", cell); \
if (action == Action::LogAndCrash) \
RELEASE_ASSERT((cond), ##__VA_ARGS__); \
RELEASE_ASSERT((cond)); \
else \
return false; \
}, format, ##__VA_ARGS__); \
}); \
} while (false)

#else // not (COMPILER(MSVC) || !VA_OPT_SUPPORTED)

#define AUDIT_VERIFY(cond, format, ...) do { \
IA_ASSERT_WITH_ACTION(cond, { \
WTFLogAlways(" cell %p", cell); \
Integrity::logLnF(" cell %p", cell); \
if (action == Action::LogAndCrash) \
RELEASE_ASSERT((cond) __VA_OPT__(,) __VA_ARGS__); \
else \
@@ -290,14 +326,14 @@ JSCell* doAudit(VM& vm, JSCell* cell)
bool verifyCell(JSCell* cell)
{
bool valid = Analyzer::analyzeCell(cell, Analyzer::Action::LogOnly);
WTFLogAlways("Cell %p is %s", cell, valid ? "VALID" : "INVALID");
Integrity::logLnF("Cell %p is %s", cell, valid ? "VALID" : "INVALID");
return valid;
}

bool verifyCell(VM& vm, JSCell* cell)
{
bool valid = Analyzer::analyzeCell(vm, cell, Analyzer::Action::LogOnly);
WTFLogAlways("Cell %p is %s", cell, valid ? "VALID" : "INVALID");
Integrity::logLnF("Cell %p is %s", cell, valid ? "VALID" : "INVALID");
return valid;
}

@@ -48,6 +48,10 @@ typedef struct OpaqueJSPropertyNameAccumulator* JSPropertyNameAccumulatorRef;
typedef const struct OpaqueJSValue* JSValueRef;
typedef struct OpaqueJSValue* JSObjectRef;

namespace WTF {
class PrintStream;
}

namespace JSC {

class JSCell;
@@ -177,34 +181,33 @@ template<typename T> ALWAYS_INLINE T audit(T value) { return value; }
#if COMPILER(MSVC) || !VA_OPT_SUPPORTED

#define IA_LOG(assertion, format, ...) do { \
WTFLogAlways("Integrity ERROR: %s @ %s:%d\n", #assertion, __FILE__, __LINE__); \
WTFLogAlways(" " format, ##__VA_ARGS__); \
Integrity::logLnF("ERROR: %s @ %s:%d", #assertion, __FILE__, __LINE__); \
} while (false)

#define IA_ASSERT_WITH_ACTION(assertion, action, ...) do { \
if (UNLIKELY(!(assertion))) { \
IA_LOG(assertion, __VA_ARGS__); \
WTFReportBacktraceWithPrefix(" "); \
WTFReportBacktraceWithPrefixAndPrintStream(Integrity::logFile(), " "); \
action; \
} \
} while (false)

#define IA_ASSERT(assertion, ...) \
IA_ASSERT_WITH_ACTION(assertion, { \
RELEASE_ASSERT((assertion), ##__VA_ARGS__); \
}, ## __VA_ARGS__)
RELEASE_ASSERT((assertion)); \
})

#else // not (COMPILER(MSVC) || !VA_OPT_SUPPORTED)

#define IA_LOG(assertion, format, ...) do { \
WTFLogAlways("Integrity ERROR: %s @ %s:%d\n", #assertion, __FILE__, __LINE__); \
WTFLogAlways(" " format __VA_OPT__(,) __VA_ARGS__); \
Integrity::logLnF("ERROR: %s @ %s:%d", #assertion, __FILE__, __LINE__); \
Integrity::logLnF(" " format __VA_OPT__(,) __VA_ARGS__); \
} while (false)

#define IA_ASSERT_WITH_ACTION(assertion, action, ...) do { \
if (UNLIKELY(!(assertion))) { \
IA_LOG(assertion, __VA_ARGS__); \
WTFReportBacktraceWithPrefix(" "); \
WTFReportBacktraceWithPrefixAndPrintStream(Integrity::logFile(), " "); \
action; \
} \
} while (false)
@@ -216,6 +219,10 @@ template<typename T> ALWAYS_INLINE T audit(T value) { return value; }

#endif // COMPILER(MSVC) || !VA_OPT_SUPPORTED

JS_EXPORT_PRIVATE WTF::PrintStream& logFile();
JS_EXPORT_PRIVATE void logF(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
JS_EXPORT_PRIVATE void logLnF(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);

} // namespace Integrity

} // namespace JSC
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2021 Apple Inc. All rights reserved.
* Copyright (C) 2003-2022 Apple Inc. All rights reserved.
* Copyright (C) 2007-2009 Torch Mobile, Inc.
* Copyright (C) 2011 University of Szeged. All rights reserved.
*
@@ -279,14 +279,20 @@ class CrashLogPrintStream final : public PrintStream {
};

void WTFReportBacktraceWithPrefix(const char* prefix)
{
CrashLogPrintStream out;
WTFReportBacktraceWithPrefixAndPrintStream(out, prefix);
}

void WTFReportBacktraceWithPrefixAndPrintStream(PrintStream& out, const char* prefix)
{
static constexpr int framesToShow = 31;
static constexpr int framesToSkip = 2;
void* samples[framesToShow + framesToSkip];
int frames = framesToShow + framesToSkip;

WTFGetBacktrace(samples, &frames);
WTFPrintBacktraceWithPrefix(samples + framesToSkip, frames - framesToSkip, prefix);
WTFPrintBacktraceWithPrefixAndPrintStream(out, samples + framesToSkip, frames - framesToSkip, prefix);
}

void WTFReportBacktrace()
@@ -300,16 +306,16 @@ void WTFReportBacktrace()
WTFPrintBacktrace(samples + framesToSkip, frames - framesToSkip);
}

void WTFPrintBacktraceWithPrefix(void** stack, int size, const char* prefix)
void WTFPrintBacktraceWithPrefixAndPrintStream(PrintStream& out, void** stack, int size, const char* prefix)
{
CrashLogPrintStream out;
StackTrace stackTrace(stack, size, prefix);
out.print(stackTrace);
}

void WTFPrintBacktrace(void** stack, int size)
{
WTFPrintBacktraceWithPrefix(stack, size, "");
CrashLogPrintStream out;
WTFPrintBacktraceWithPrefixAndPrintStream(out, stack, size, "");
}

#if !defined(NDEBUG) || !(OS(DARWIN) || PLATFORM(PLAYSTATION))
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2019 Apple Inc. All rights reserved.
* Copyright (C) 2003-2022 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -154,6 +154,9 @@ extern "C" {
enum class WTFLogChannelState : uint8_t { Off, On, OnWithAccumulation };
#undef Always
enum class WTFLogLevel : uint8_t { Always, Error, Warning, Info, Debug };
namespace WTF {
class PrintStream;
}
#else
typedef uint8_t WTFLogChannelState;
typedef uint8_t WTFLogLevel;
@@ -228,7 +231,10 @@ WTF_EXPORT_PRIVATE bool WTFWillLogWithLevel(WTFLogChannel*, WTFLogLevel);
WTF_EXPORT_PRIVATE void WTFGetBacktrace(void** stack, int* size);
WTF_EXPORT_PRIVATE void WTFReportBacktraceWithPrefix(const char*);
WTF_EXPORT_PRIVATE void WTFReportBacktrace(void);
WTF_EXPORT_PRIVATE void WTFPrintBacktraceWithPrefix(void** stack, int size, const char* prefix);
#ifdef __cplusplus
WTF_EXPORT_PRIVATE void WTFReportBacktraceWithPrefixAndPrintStream(WTF::PrintStream&, const char*);
void WTFPrintBacktraceWithPrefixAndPrintStream(WTF::PrintStream&, void** stack, int size, const char* prefix);
#endif
WTF_EXPORT_PRIVATE void WTFPrintBacktrace(void** stack, int size);
#if !RELEASE_LOG_DISABLED
WTF_EXPORT_PRIVATE void WTFReleaseLogStackTrace(WTFLogChannel*);

0 comments on commit 2327237

Please sign in to comment.