summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc
blob: b6d50a9e7a01e45d4cd155c021d4dfcd8b0ea6b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"

#include "testing/libfuzzer/libfuzzer_exports.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"

namespace blink {

// Intentionally leaked during fuzzing.
// See testing/libfuzzer/efficient_fuzzing.md.
DummyPageHolder* g_page_holder = nullptr;

int LLVMFuzzerInitialize(int* argc, char*** argv) {
  static BlinkFuzzerTestSupport test_support = BlinkFuzzerTestSupport();
  // Scope cannot be created before BlinkFuzzerTestSupport because it requires
  // that Oilpan be initialized to access blink::ThreadState::Current.
  LEAK_SANITIZER_DISABLED_SCOPE;
  g_page_holder = std::make_unique<DummyPageHolder>().release();

  // Set loader sandbox flags and install a new document so the document
  // has all possible sandbox flags set on the document already when the
  // CSP is bound.
  scoped_refptr<SharedBuffer> empty_document_data = SharedBuffer::Create();
  g_page_holder->GetFrame().Loader().ForceSandboxFlags(
      mojom::blink::WebSandboxFlags::kAll);
  g_page_holder->GetFrame().ForceSynchronousDocumentInstall(
      "text/html", empty_document_data);
  return 0;
}

int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  String header = String::FromUTF8(data, size);
  unsigned hash = header.IsNull() ? 0 : header.Impl()->GetHash();

  // Use the 'hash' value to pick header_type and header_source input.
  // 1st bit: header type.
  // 2nd bit: header source: HTTP (or other)
  // 3rd bit: header source: Meta or OriginPolicy (if not HTTP)
  network::mojom::ContentSecurityPolicyType header_type =
      hash & 0x01 ? network::mojom::ContentSecurityPolicyType::kEnforce
                  : network::mojom::ContentSecurityPolicyType::kReport;
  network::mojom::ContentSecurityPolicySource header_source =
      network::mojom::ContentSecurityPolicySource::kHTTP;
  if (hash & 0x02) {
    header_source =
        (hash & 0x04)
            ? network::mojom::ContentSecurityPolicySource::kMeta
            : network::mojom::ContentSecurityPolicySource::kOriginPolicy;
  }

  // Construct and initialize a policy from the string.
  auto* csp = MakeGarbageCollected<ContentSecurityPolicy>();
  csp->DidReceiveHeader(header, header_type, header_source);
  g_page_holder->GetDocument().InitContentSecurityPolicy(csp);

  // Force a garbage collection.
  // Specify namespace explicitly. Otherwise it conflicts on Mac OS X with:
  // CoreServices.framework/Frameworks/CarbonCore.framework/Headers/Threads.h.
  ThreadState::Current()->CollectAllGarbageForTesting(
      BlinkGC::kNoHeapPointersOnStack);

  return 0;
}

}  // namespace blink

extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
  return blink::LLVMFuzzerInitialize(argc, argv);
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  return blink::LLVMFuzzerTestOneInput(data, size);
}