Skip to content

Commit 9cd76a8

Browse files
trop[bot]nornagon
andauthored
fix: prevent UAF crash in setCertificateVerifyProc (#33253)
* fix: prevent UAF crash in setCertificateVerifyProc * fix patch * fix tests Co-authored-by: Jeremy Rose <[email protected]>
1 parent a9b1779 commit 9cd76a8

File tree

2 files changed

+48
-36
lines changed

2 files changed

+48
-36
lines changed

patches/chromium/expose_setuseragent_on_networkcontext.patch

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ index 14c71cc69388da46f62d9835e2a06fef0870da02..9481ea08401ae29ae9c1d960491b05b3
3333

3434
} // namespace net
3535
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
36-
index ca62a13420aa9c114c00054bbe1215f96285a4e9..01be46b1eaed2aadfd24eac9d102da99521b175c 100644
36+
index 20373c0e86852446569c401c4a993512cb388fc7..9b6dbdad1a17148303ddecaada17a57d4ea22bb2 100644
3737
--- a/services/network/network_context.cc
3838
+++ b/services/network/network_context.cc
39-
@@ -1331,6 +1331,13 @@ void NetworkContext::SetNetworkConditions(
39+
@@ -1343,6 +1343,13 @@ void NetworkContext::SetNetworkConditions(
4040
std::move(network_conditions));
4141
}
4242

patches/chromium/network_service_allow_remote_certificate_verification_logic.patch

+46-34
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This adds a callback from the network service that's used to implement
77
session.setCertificateVerifyCallback.
88

99
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
10-
index 8ff62f92ed6efdbfc18db53db3c5bb59c1acfe34..ca62a13420aa9c114c00054bbe1215f96285a4e9 100644
10+
index 8ff62f92ed6efdbfc18db53db3c5bb59c1acfe34..20373c0e86852446569c401c4a993512cb388fc7 100644
1111
--- a/services/network/network_context.cc
1212
+++ b/services/network/network_context.cc
1313
@@ -126,6 +126,11 @@
@@ -22,12 +22,38 @@ index 8ff62f92ed6efdbfc18db53db3c5bb59c1acfe34..ca62a13420aa9c114c00054bbe1215f9
2222
#if BUILDFLAG(IS_CT_SUPPORTED)
2323
#include "components/certificate_transparency/chrome_ct_policy_enforcer.h"
2424
#include "components/certificate_transparency/chrome_require_ct_delegate.h"
25-
@@ -433,6 +438,79 @@ bool GetFullDataFilePath(
25+
@@ -433,6 +438,91 @@ bool GetFullDataFilePath(
2626

2727
} // namespace
2828

2929
+class RemoteCertVerifier : public net::CertVerifier {
3030
+ public:
31+
+ class Request : public net::CertVerifier::Request {
32+
+ public:
33+
+ Request() {}
34+
+ ~Request() override = default;
35+
+ void OnRemoteResponse(
36+
+ const RequestParams& params,
37+
+ net::CertVerifyResult* verify_result,
38+
+ int error_from_upstream,
39+
+ net::CompletionOnceCallback callback,
40+
+ int error_from_client,
41+
+ const net::CertVerifyResult& verify_result_from_client) {
42+
+ if (error_from_client == net::ERR_ABORTED) {
43+
+ // use the default
44+
+ std::move(callback).Run(error_from_upstream);
45+
+ } else {
46+
+ // use the override
47+
+ verify_result->Reset();
48+
+ verify_result->verified_cert = verify_result_from_client.verified_cert;
49+
+ std::move(callback).Run(error_from_client);
50+
+ }
51+
+ }
52+
+ base::WeakPtr<Request> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
53+
+ private:
54+
+ base::WeakPtrFactory<Request> weak_factory_{this};
55+
+ };
56+
+
3157
+ RemoteCertVerifier(std::unique_ptr<net::CertVerifier> upstream): upstream_(std::move(upstream)) {
3258
+ }
3359
+ ~RemoteCertVerifier() override = default;
@@ -44,56 +70,42 @@ index 8ff62f92ed6efdbfc18db53db3c5bb59c1acfe34..ca62a13420aa9c114c00054bbe1215f9
4470
+ int Verify(const RequestParams& params,
4571
+ net::CertVerifyResult* verify_result,
4672
+ net::CompletionOnceCallback callback,
47-
+ std::unique_ptr<Request>* out_req,
73+
+ std::unique_ptr<CertVerifier::Request>* out_req,
4874
+ const net::NetLogWithSource& net_log) override {
4975
+ out_req->reset();
5076
+
5177
+ net::CompletionOnceCallback callback2 = base::BindOnce(
5278
+ &RemoteCertVerifier::OnRequestFinished, base::Unretained(this),
53-
+ params, std::move(callback), verify_result);
54-
+ int result = upstream_->Verify(params, verify_result,
55-
+ std::move(callback2), out_req, net_log);
56-
+ if (result != net::ERR_IO_PENDING) {
57-
+ // Synchronous completion
58-
+ }
59-
+
60-
+ return result;
79+
+ params, std::move(callback), verify_result, out_req);
80+
+ return upstream_->Verify(params, verify_result, std::move(callback2), out_req, net_log);
6181
+ }
6282
+
6383
+
6484
+ void SetConfig(const Config& config) override {
6585
+ upstream_->SetConfig(config);
6686
+ }
6787
+
68-
+ void OnRequestFinished(const RequestParams& params, net::CompletionOnceCallback callback, net::CertVerifyResult* verify_result, int error) {
88+
+ void OnRequestFinished(const RequestParams& params,
89+
+ net::CompletionOnceCallback callback,
90+
+ net::CertVerifyResult* verify_result,
91+
+ std::unique_ptr<CertVerifier::Request>* out_req,
92+
+ int error) {
6993
+ if (client_.is_bound()) {
94+
+ // We take a weak pointer to the request because deletion of the request
95+
+ // is what signals cancellation. Thus if the request is cancelled, the
96+
+ // callback won't be called, thus avoiding UAF, because |verify_result|
97+
+ // is freed when the request is cancelled.
98+
+ *out_req = std::make_unique<Request>();
99+
+ base::WeakPtr<Request> weak_req = static_cast<Request*>(out_req->get())->GetWeakPtr();
70100
+ client_->Verify(error, *verify_result, params.certificate(),
71101
+ params.hostname(), params.flags(), params.ocsp_response(),
72-
+ base::BindOnce(&RemoteCertVerifier::OnRemoteResponse,
73-
+ base::Unretained(this), params, verify_result, error,
74-
+ std::move(callback)));
102+
+ base::BindOnce(&Request::OnRemoteResponse,
103+
+ weak_req, params, verify_result, error, std::move(callback)));
75104
+ } else {
76105
+ std::move(callback).Run(error);
77106
+ }
78107
+ }
79108
+
80-
+ void OnRemoteResponse(
81-
+ const RequestParams& params,
82-
+ net::CertVerifyResult* verify_result,
83-
+ int error,
84-
+ net::CompletionOnceCallback callback,
85-
+ int error2,
86-
+ const net::CertVerifyResult& verify_result2) {
87-
+ if (error2 == net::ERR_ABORTED) {
88-
+ // use the default
89-
+ std::move(callback).Run(error);
90-
+ } else {
91-
+ // use the override
92-
+ verify_result->Reset();
93-
+ verify_result->verified_cert = verify_result2.verified_cert;
94-
+ std::move(callback).Run(error2);
95-
+ }
96-
+ }
97109
+ private:
98110
+ std::unique_ptr<net::CertVerifier> upstream_;
99111
+ mojo::Remote<mojom::CertVerifierClient> client_;
@@ -102,7 +114,7 @@ index 8ff62f92ed6efdbfc18db53db3c5bb59c1acfe34..ca62a13420aa9c114c00054bbe1215f9
102114
constexpr uint32_t NetworkContext::kMaxOutstandingRequestsPerProcess;
103115

104116
NetworkContext::PendingCertVerify::PendingCertVerify() = default;
105-
@@ -671,6 +749,13 @@ void NetworkContext::SetClient(
117+
@@ -671,6 +761,13 @@ void NetworkContext::SetClient(
106118
client_.Bind(std::move(client));
107119
}
108120

@@ -116,7 +128,7 @@ index 8ff62f92ed6efdbfc18db53db3c5bb59c1acfe34..ca62a13420aa9c114c00054bbe1215f9
116128
void NetworkContext::CreateURLLoaderFactory(
117129
mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
118130
mojom::URLLoaderFactoryParamsPtr params) {
119-
@@ -2226,6 +2311,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
131+
@@ -2226,6 +2323,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
120132
std::move(cert_verifier));
121133
cert_verifier = base::WrapUnique(cert_verifier_with_trust_anchors_);
122134
#endif // BUILDFLAG(IS_CHROMEOS)

0 commit comments

Comments
 (0)