Skip to content

Commit 19f9a2b

Browse files
zakharvoitmibrunin
authored andcommitted
[Backport] Security bug 1221068
Cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/3103206: [M90-LTS] NativeIO: Fix potential NativeIOHost lifetime issue. See https://crbug.com/1221068#c16 for a description. (cherry picked from commit 1737623a5311badc6396e65503f802d6267b10be) Bug: 1221068 Change-Id: I93b62f39190519da1101f6a45009baf998516491 Commit-Queue: Victor Costan <[email protected]> Cr-Original-Commit-Position: refs/heads/master@{#908087} Reviewed-by: Artem Sumaneev <[email protected]> Owners-Override: Artem Sumaneev <[email protected]> Commit-Queue: Zakhar Voit <[email protected]> Cr-Commit-Position: refs/branch-heads/4430@{#1572} Cr-Branched-From: e5ce7dc4f7518237b3d9bb93cccca35d25216cbe-refs/heads/master@{#857950} Reviewed-by: Allan Sandfeld Jensen <[email protected]>
1 parent 8570531 commit 19f9a2b

File tree

4 files changed

+27
-27
lines changed

4 files changed

+27
-27
lines changed

chromium/content/browser/native_io/native_io_host.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,11 @@ void NativeIOHost::DidDeleteAllData(base::File::Error error) {
599599
std::move(delete_all_data_callbacks_);
600600
delete_all_data_callbacks_.clear();
601601
for (DeleteAllDataCallback& callback : callbacks) {
602-
std::move(callback).Run(error, this);
602+
std::move(callback).Run(error);
603603
}
604+
605+
// May delete `this`.
606+
manager_->DidDeleteHostData(this, base::PassKey<NativeIOHost>());
604607
}
605608

606609
} // namespace content

chromium/content/browser/native_io/native_io_host.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ class NativeIOFileHost;
3838
// sequences, if desired.
3939
class NativeIOHost : public blink::mojom::NativeIOHost {
4040
public:
41-
using DeleteAllDataCallback =
42-
base::OnceCallback<void(base::File::Error result, NativeIOHost* host)>;
41+
using DeleteAllDataCallback = base::OnceCallback<void(base::File::Error)>;
4342

4443
// `allow_set_length_ipc` gates NativeIOFileHost::SetLength(), which works
4544
// around a sandboxing limitation on macOS < 10.15. This is plumbed as a flag

chromium/content/browser/native_io/native_io_manager.cc

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,15 @@ void NativeIOManager::OnHostReceiverDisconnect(NativeIOHost* host) {
165165
MaybeDeleteHost(host);
166166
}
167167

168+
void NativeIOManager::DidDeleteHostData(NativeIOHost* host,
169+
base::PassKey<NativeIOHost>) {
170+
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
171+
DCHECK(host != nullptr);
172+
DCHECK(!host->delete_all_data_in_progress());
173+
174+
MaybeDeleteHost(host);
175+
}
176+
168177
void NativeIOManager::MaybeDeleteHost(NativeIOHost* host) {
169178
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
170179
DCHECK(host != nullptr);
@@ -177,18 +186,6 @@ void NativeIOManager::MaybeDeleteHost(NativeIOHost* host) {
177186
hosts_.erase(host->origin());
178187
}
179188

180-
void NativeIOManager::OnDeleteOriginDataCompleted(
181-
storage::QuotaClient::DeleteOriginDataCallback callback,
182-
base::File::Error result,
183-
NativeIOHost* host) {
184-
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
185-
MaybeDeleteHost(host);
186-
blink::mojom::QuotaStatusCode quota_result =
187-
result == base::File::FILE_OK ? blink::mojom::QuotaStatusCode::kOk
188-
: blink::mojom::QuotaStatusCode::kUnknown;
189-
std::move(callback).Run(quota_result);
190-
}
191-
192189
void NativeIOManager::DeleteOriginData(
193190
const url::Origin& origin,
194191
storage::QuotaClient::DeleteOriginDataCallback callback) {
@@ -224,12 +221,16 @@ void NativeIOManager::DeleteOriginData(
224221
DCHECK(insert_succeeded);
225222
}
226223

227-
// base::Unretained is safe here because this NativeIOManager owns the
228-
// NativeIOHost. So, the unretained NativeIOManager is guaranteed to outlive
229-
// the NativeIOHost and the closure that it uses.
230-
it->second->DeleteAllData(
231-
base::BindOnce(&NativeIOManager::OnDeleteOriginDataCompleted,
232-
base::Unretained(this), std::move(callback)));
224+
// DeleteAllData() will call DidDeleteHostData() asynchronously, which may
225+
// delete this entry from `hosts_`.
226+
it->second->DeleteAllData(base::BindOnce(
227+
[](storage::mojom::QuotaClient::DeleteOriginDataCallback callback,
228+
base::File::Error error) {
229+
std::move(callback).Run((error == base::File::FILE_OK)
230+
? blink::mojom::QuotaStatusCode::kOk
231+
: blink::mojom::QuotaStatusCode::kUnknown);
232+
},
233+
std::move(callback)));
233234
}
234235

235236
void NativeIOManager::GetOriginsForType(

chromium/content/browser/native_io/native_io_manager.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,10 @@ class CONTENT_EXPORT NativeIOManager {
117117
// NativeIOHost.
118118
void OnHostReceiverDisconnect(NativeIOHost* host);
119119

120-
// Callback function when DeleteOriginData has completed.
120+
// Called when a NativeIOHost finishes processing a data deletion request.
121121
//
122-
// `host` must be owned by this manager.
123-
void OnDeleteOriginDataCompleted(
124-
storage::QuotaClient::DeleteOriginDataCallback callback,
125-
base::File::Error result,
126-
NativeIOHost* host);
122+
// `host` must be owned by this manager. `host` may be deleted.
123+
void DidDeleteHostData(NativeIOHost* host, base::PassKey<NativeIOHost>);
127124

128125
storage::QuotaManagerProxy* quota_manager_proxy() const {
129126
return quota_manager_proxy_.get();

0 commit comments

Comments
 (0)