Make using natives for fuzzing more permissive
This makes creating whitelisted runtime functions more permissive on fuzzers (when --allow-natives-for-fuzzing is passed). - Runtime functions with too few arguments are replaced with undefined. - Superfluous arguments are ignored. This reduces syntax-error rate on fuzzers. Also prevents dcheck errors when fuzzing debug builds and fuzzers use too many arguments for runtime functions. Bug: chromium:1044942 Change-Id: I23b45398421c50bc82d1e8bfdf019f565253db96 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2039352 Commit-Queue: Michael Achenbach <machenbach@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#66202}
This commit is contained in:
parent
f925176e19
commit
cf05e4ca79
@ -356,17 +356,16 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name,
|
||||
const Runtime::Function* function =
|
||||
Runtime::FunctionForName(name->raw_data(), name->length());
|
||||
|
||||
// Be more premissive when fuzzing. Intrinsics are not supported.
|
||||
if (FLAG_allow_natives_for_fuzzing) {
|
||||
return NewV8RuntimeFunctionForFuzzing(function, args, pos);
|
||||
}
|
||||
|
||||
if (function != nullptr) {
|
||||
// Check for possible name clash.
|
||||
DCHECK_EQ(Context::kNotFound,
|
||||
Context::IntrinsicIndexForName(name->raw_data(), name->length()));
|
||||
|
||||
// When fuzzing, only allow whitelisted runtime functions.
|
||||
if (FLAG_allow_natives_for_fuzzing &&
|
||||
!Runtime::IsWhitelistedForFuzzing(function->function_id)) {
|
||||
return factory()->NewUndefinedLiteral(kNoSourcePosition);
|
||||
}
|
||||
|
||||
// Check that the expected number of arguments are being passed.
|
||||
if (function->nargs != -1 && function->nargs != args.length()) {
|
||||
ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
|
||||
@ -376,11 +375,6 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name,
|
||||
return factory()->NewCallRuntime(function, args, pos);
|
||||
}
|
||||
|
||||
// Intrinsics are not supported for fuzzing.
|
||||
if (FLAG_allow_natives_for_fuzzing) {
|
||||
return factory()->NewUndefinedLiteral(kNoSourcePosition);
|
||||
}
|
||||
|
||||
int context_index =
|
||||
Context::IntrinsicIndexForName(name->raw_data(), name->length());
|
||||
|
||||
@ -393,6 +387,34 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name,
|
||||
return factory()->NewCallRuntime(context_index, args, pos);
|
||||
}
|
||||
|
||||
// More permissive runtime-function creation on fuzzers.
|
||||
Expression* Parser::NewV8RuntimeFunctionForFuzzing(
|
||||
const Runtime::Function* function, const ScopedPtrList<Expression>& args,
|
||||
int pos) {
|
||||
CHECK(FLAG_allow_natives_for_fuzzing);
|
||||
|
||||
// Intrinsics are not supported for fuzzing. Only allow whitelisted runtime
|
||||
// functions. Also prevent later errors due to too few arguments and just
|
||||
// ignore this call.
|
||||
if (function == nullptr ||
|
||||
!Runtime::IsWhitelistedForFuzzing(function->function_id) ||
|
||||
function->nargs > args.length()) {
|
||||
return factory()->NewUndefinedLiteral(kNoSourcePosition);
|
||||
}
|
||||
|
||||
// Flexible number of arguments permitted.
|
||||
if (function->nargs == -1) {
|
||||
return factory()->NewCallRuntime(function, args, pos);
|
||||
}
|
||||
|
||||
// Otherwise ignore superfluous arguments.
|
||||
ScopedPtrList<Expression> permissive_args(pointer_buffer());
|
||||
for (int i = 0; i < function->nargs; i++) {
|
||||
permissive_args.Add(args.at(i));
|
||||
}
|
||||
return factory()->NewCallRuntime(function, permissive_args, pos);
|
||||
}
|
||||
|
||||
Parser::Parser(ParseInfo* info)
|
||||
: ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
|
||||
info->extension(), info->GetOrCreateAstValueFactory(),
|
||||
|
@ -833,6 +833,10 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
|
||||
Expression* NewV8Intrinsic(const AstRawString* name,
|
||||
const ScopedPtrList<Expression>& args, int pos);
|
||||
|
||||
Expression* NewV8RuntimeFunctionForFuzzing(
|
||||
const Runtime::Function* function, const ScopedPtrList<Expression>& args,
|
||||
int pos);
|
||||
|
||||
V8_INLINE Statement* NewThrowStatement(Expression* exception, int pos) {
|
||||
return factory()->NewExpressionStatement(
|
||||
factory()->NewThrow(exception, pos), pos);
|
||||
|
@ -10,10 +10,17 @@
|
||||
assertEquals(undefined, %GetOptimizationStatus(function (){}));
|
||||
|
||||
// Blacklisted intrinsics can have wrong arguments.
|
||||
%GetOptimizationStatus(1, 2, 3, 4);
|
||||
assertEquals(undefined, %GetOptimizationStatus(1, 2, 3, 4));
|
||||
|
||||
// We don't care if an intrinsic actually exists.
|
||||
assertEquals(undefined, %FooBar());
|
||||
|
||||
// Check whitelisted intrinsic.
|
||||
assertNotEquals(undefined, %IsBeingInterpreted());
|
||||
|
||||
// Whitelisted runtime functions with too few args are ignored.
|
||||
assertEquals(undefined, %DeoptimizeFunction());
|
||||
|
||||
// Superfluous arguments are ignored.
|
||||
%DeoptimizeFunction(function() {}, undefined);
|
||||
assertNotEquals(undefined, %IsBeingInterpreted(1, 2, 3));
|
||||
|
Loading…
Reference in New Issue
Block a user