Bug 1746231: Convert the script callback to take a JSContext instead of a system bool r=freddyb,iain

Differential Revision: https://phabricator.services.mozilla.com/D133930
This commit is contained in:
Tom Ritter 2021-12-21 20:40:33 +00:00
parent 3d7f8fe67c
commit 4c04a4a674
5 changed files with 34 additions and 25 deletions

View File

@ -31,7 +31,8 @@
#include "js/ContextOptions.h"
#include "js/PropertyAndElement.h" // JS_GetElement
#include "js/RegExp.h"
#include "js/RegExpFlags.h" // JS::RegExpFlags
#include "js/RegExpFlags.h" // JS::RegExpFlags
#include "js/friend/ErrorMessages.h" // JSMSG_UNSAFE_FILENAME
#include "mozilla/ExtensionPolicyService.h"
#include "mozilla/Logging.h"
#include "mozilla/Preferences.h"
@ -1209,8 +1210,8 @@ void nsContentSecurityUtils::AssertAboutPageHasCSP(Document* aDocument) {
#endif
/* static */
bool nsContentSecurityUtils::ValidateScriptFilename(const char* aFilename,
bool aIsSystemRealm) {
bool nsContentSecurityUtils::ValidateScriptFilename(JSContext* cx,
const char* aFilename) {
// If the pref is permissive, allow everything
if (StaticPrefs::security_allow_parent_unrestricted_js_loads()) {
return true;
@ -1340,8 +1341,7 @@ bool nsContentSecurityUtils::ValidateScriptFilename(const char* aFilename,
// Log to MOZ_LOG
MOZ_LOG(sCSMLog, LogLevel::Error,
("ValidateScriptFilename System:%i %s\n", (aIsSystemRealm ? 1 : 0),
aFilename));
("ValidateScriptFilename Failed: %s\n", aFilename));
// Send Telemetry
FilenameTypeAndDetails fileNameTypeAndDetails =
@ -1380,11 +1380,23 @@ bool nsContentSecurityUtils::ValidateScriptFilename(const char* aFilename,
#elif defined(FUZZING)
auto crashString = nsContentSecurityUtils::SmartFormatCrashString(
aFilename,
NS_ConvertUTF16toUTF8(fileNameTypeAndDetails.second.value()).get(),
fileNameTypeAndDetails.second.isSome()
? NS_ConvertUTF16toUTF8(fileNameTypeAndDetails.second.value()).get()
: "(None)",
"Blocking a script load %s from file %s");
MOZ_CRASH_UNSAFE_PRINTF("%s", crashString.get());
#endif
// If we got here we are going to return false, so set the error context
const char* utf8Filename;
if (mozilla::IsUtf8(mozilla::MakeStringSpan(aFilename))) {
utf8Filename = aFilename;
} else {
utf8Filename = "(invalid UTF-8 filename)";
}
JS_ReportErrorNumberUTF8(cx, js::GetErrorMessage, nullptr,
JSMSG_UNSAFE_FILENAME, utf8Filename);
// Presently we are not enforcing any restrictions for the script filename,
// we're only reporting Telemetry. In the future we will assert in debug
// builds and return false to prevent execution in non-debug builds.

View File

@ -81,8 +81,7 @@ class nsContentSecurityUtils {
static void AssertAboutPageHasCSP(mozilla::dom::Document* aDocument);
#endif
static bool ValidateScriptFilename(const char* aFilename,
bool aIsSystemRealm);
static bool ValidateScriptFilename(JSContext* cx, const char* aFilename);
// Helper Function to Post a message to the corresponding JS-Console
static void LogMessageToConsole(nsIHttpChannel* aChannel, const char* aMsg);
};

View File

@ -85,8 +85,8 @@ JS_PUBLIC_API void AssertObjectBelongsToCurrentThread(JSObject* obj);
* See also CompileOptions::setSkipFilenameValidation to opt-out of the callback
* for specific parse jobs.
*/
using FilenameValidationCallback = bool (*)(const char* filename,
bool isSystemRealm);
using FilenameValidationCallback = bool (*)(JSContext* cx,
const char* filename);
JS_PUBLIC_API void SetFilenameValidationCallback(FilenameValidationCallback cb);
} /* namespace JS */

View File

@ -2852,13 +2852,23 @@ static bool SetTestFilenameValidationCallback(JSContext* cx, unsigned argc,
// Accept all filenames that start with "safe". In system code also accept
// filenames starting with "system".
auto testCb = [](const char* filename, bool isSystemRealm) -> bool {
auto testCb = [](JSContext* cx, const char* filename) -> bool {
if (strstr(filename, "safe") == filename) {
return true;
}
if (isSystemRealm && strstr(filename, "system") == filename) {
if (cx->realm()->isSystem() && strstr(filename, "system") == filename) {
return true;
}
const char* utf8Filename;
if (mozilla::IsUtf8(mozilla::MakeStringSpan(filename))) {
utf8Filename = filename;
} else {
utf8Filename = "(invalid UTF-8 filename)";
}
JS_ReportErrorNumberUTF8(cx, js::GetErrorMessage, nullptr,
JSMSG_UNSAFE_FILENAME, utf8Filename);
return false;
};
JS::SetFilenameValidationCallback(testCb);

View File

@ -763,19 +763,7 @@ ScriptSourceObject* ScriptSourceObject::create(JSContext* cx,
return true;
}
if (gFilenameValidationCallback(filename, cx->realm()->isSystem())) {
return true;
}
const char* utf8Filename;
if (mozilla::IsUtf8(mozilla::MakeStringSpan(filename))) {
utf8Filename = filename;
} else {
utf8Filename = "(invalid UTF-8 filename)";
}
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_UNSAFE_FILENAME,
utf8Filename);
return false;
return gFilenameValidationCallback(cx, filename);
}
/* static */