From 0e4bd4b41899715f0090c7a12de875d5a614360a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Feb 2022 18:43:16 +0100 Subject: [PATCH] Sign symbols so that we can trust opening buffers for them from guests Co-Authored-By: Nathan Sobo Co-Authored-By: Max Brunsfeld --- Cargo.lock | 84 ++++++++++++++++++++++++++++------- crates/project/Cargo.toml | 3 +- crates/project/src/project.rs | 32 ++++++++++++- crates/rpc/proto/zed.proto | 1 + 4 files changed, 101 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 696a9ba509afeaf57db6c06b1f507571384efd67..93674db8b94f27ef6877768f20334fb1cabcbce8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -409,7 +409,7 @@ dependencies = [ "rand 0.7.3", "serde", "serde_json", - "sha2", + "sha2 0.9.5", ] [[package]] @@ -686,6 +686,15 @@ dependencies = [ "generic-array 0.14.4", ] +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array 0.14.4", +] + [[package]] name = "block-padding" version = "0.1.5" @@ -1124,7 +1133,7 @@ dependencies = [ "hmac 0.10.1", "percent-encoding", "rand 0.8.3", - "sha2", + "sha2 0.9.5", "time 0.2.25", "version_check", ] @@ -1187,6 +1196,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + [[package]] name = "cpuid-bool" version = "0.2.0" @@ -1280,6 +1298,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-common" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +dependencies = [ + "generic-array 0.14.4", + "typenum", +] + [[package]] name = "crypto-mac" version = "0.8.0" @@ -1447,6 +1475,16 @@ dependencies = [ "generic-array 0.14.4", ] +[[package]] +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer 0.10.2", + "crypto-common", +] + [[package]] name = "dirs" version = "3.0.1" @@ -2604,7 +2642,7 @@ dependencies = [ "cfg-if 1.0.0", "ecdsa", "elliptic-curve", - "sha2", + "sha2 0.9.5", ] [[package]] @@ -2691,9 +2729,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.98" +version = "0.2.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" +checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" [[package]] name = "libloading" @@ -3065,7 +3103,7 @@ dependencies = [ "serde", "serde_json", "serde_path_to_error", - "sha2", + "sha2 0.9.5", "thiserror", "url", ] @@ -3183,7 +3221,7 @@ checksum = "d053368e1bae4c8a672953397bd1bd7183dde1c72b0b7612a15719173148d186" dependencies = [ "ecdsa", "elliptic-curve", - "sha2", + "sha2 0.9.5", ] [[package]] @@ -3537,6 +3575,7 @@ dependencies = [ "rpc", "serde", "serde_json", + "sha2 0.10.2", "smol", "sum_tree", "tempdir", @@ -3972,7 +4011,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad22c7226e4829104deab21df575e995bfbc4adfad13a595e387477f238c1aec" dependencies = [ "globset", - "sha2", + "sha2 0.9.5", "walkdir", ] @@ -4111,7 +4150,7 @@ dependencies = [ "password-hash", "pbkdf2", "salsa20", - "sha2", + "sha2 0.9.5", ] [[package]] @@ -4281,7 +4320,7 @@ checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", - "cpufeatures", + "cpufeatures 0.1.4", "digest 0.9.0", "opaque-debug 0.3.0", ] @@ -4300,11 +4339,22 @@ checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", - "cpufeatures", + "cpufeatures 0.1.4", "digest 0.9.0", "opaque-debug 0.3.0", ] +[[package]] +name = "sha2" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures 0.2.1", + "digest 0.10.3", +] + [[package]] name = "shell-words" version = "1.0.0" @@ -4573,7 +4623,7 @@ dependencies = [ "serde", "serde_json", "sha-1 0.9.6", - "sha2", + "sha2 0.9.5", "smallvec", "sqlformat", "sqlx-rt 0.2.0", @@ -4622,7 +4672,7 @@ dependencies = [ "serde", "serde_json", "sha-1 0.9.6", - "sha2", + "sha2 0.9.5", "smallvec", "sqlformat", "sqlx-rt 0.5.5", @@ -4651,7 +4701,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "sha2", + "sha2 0.9.5", "sqlx-core 0.4.2", "sqlx-rt 0.2.0", "syn", @@ -4671,7 +4721,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "sha2", + "sha2 0.9.5", "sqlx-core 0.5.5", "sqlx-rt 0.5.5", "syn", @@ -5293,9 +5343,9 @@ checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d" [[package]] name = "typenum" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "ucd-trie" diff --git a/crates/project/Cargo.toml b/crates/project/Cargo.toml index 1130282e0e9257195995818229922894c3da1455..f72ba133c32df4135cbd4e0f68c6eac9e300252d 100644 --- a/crates/project/Cargo.toml +++ b/crates/project/Cargo.toml @@ -35,8 +35,10 @@ libc = "0.2" log = "0.4" parking_lot = "0.11.1" postage = { version = "0.4.1", features = ["futures-traits"] } +rand = "0.8.3" serde = { version = "1", features = ["derive"] } serde_json = { version = "1.0.64", features = ["preserve_order"] } +sha2 = "0.10" smol = "1.2.5" toml = "0.5" @@ -48,6 +50,5 @@ language = { path = "../language", features = ["test-support"] } lsp = { path = "../lsp", features = ["test-support"] } util = { path = "../util", features = ["test-support"] } rpc = { path = "../rpc", features = ["test-support"] } -rand = "0.8.3" tempdir = { version = "0.3.7" } unindent = "0.1.7" diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 8a76645aeedac204cea9dfb37bd0482f165a95eb..3bd0ca4c2628eb87e2e3e37e6ba50e4af2e550bf 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -21,9 +21,12 @@ use language::{ use lsp::{DiagnosticSeverity, LanguageServer}; use lsp_command::*; use postage::{broadcast, prelude::Stream, sink::Sink, watch}; +use rand::prelude::*; +use sha2::{Digest, Sha256}; use smol::block_on; use std::{ convert::TryInto, + hash::Hash, mem, ops::Range, path::{Component, Path, PathBuf}, @@ -56,6 +59,7 @@ pub struct Project { postage::watch::Receiver, Arc>>>, >, shared_buffers: HashMap>>, + nonce: u128, } enum OpenBuffer { @@ -129,6 +133,7 @@ pub struct Symbol { pub name: String, pub kind: lsp::SymbolKind, pub range: Range, + pub signature: [u8; 32], } #[derive(Default)] @@ -276,6 +281,7 @@ impl Project { language_servers_with_diagnostics_running: 0, language_servers: Default::default(), started_language_servers: Default::default(), + nonce: StdRng::from_entropy().gen(), } }) } @@ -328,6 +334,7 @@ impl Project { language_servers_with_diagnostics_running: 0, language_servers: Default::default(), started_language_servers: Default::default(), + nonce: StdRng::from_entropy().gen(), }; for worktree in worktrees { this.add_worktree(&worktree, cx); @@ -1289,6 +1296,7 @@ impl Project { .unwrap_or_else(|| { CodeLabel::plain(lsp_symbol.name.clone(), None) }); + let signature = this.symbol_signature(worktree_id, &path); Some(Symbol { source_worktree_id, @@ -1299,6 +1307,7 @@ impl Project { label, path, range: range_from_lsp(lsp_symbol.location.range), + signature, }) }, )); @@ -2725,7 +2734,15 @@ impl Project { .payload .symbol .ok_or_else(|| anyhow!("invalid symbol"))?; - let symbol = this.read_with(&cx, |this, _| this.deserialize_symbol(symbol))?; + let symbol = this.read_with(&cx, |this, _| { + let symbol = this.deserialize_symbol(symbol)?; + let signature = this.symbol_signature(symbol.worktree_id, &symbol.path); + if signature == symbol.signature { + Ok(symbol) + } else { + Err(anyhow!("invalid symbol signature")) + } + })?; let buffer = this .update(&mut cx, |this, cx| this.open_buffer_for_symbol(&symbol, cx)) .await?; @@ -2737,6 +2754,14 @@ impl Project { }) } + fn symbol_signature(&self, worktree_id: WorktreeId, path: &Path) -> [u8; 32] { + let mut hasher = Sha256::new(); + hasher.update(worktree_id.to_proto().to_be_bytes()); + hasher.update(path.to_string_lossy().as_bytes()); + hasher.update(self.nonce.to_be_bytes()); + hasher.finalize().as_slice().try_into().unwrap() + } + async fn handle_open_buffer( this: ModelHandle, envelope: TypedEnvelope, @@ -2920,6 +2945,10 @@ impl Project { path: PathBuf::from(serialized_symbol.path), range: PointUtf16::new(start.row, start.column)..PointUtf16::new(end.row, end.column), kind, + signature: serialized_symbol + .signature + .try_into() + .map_err(|_| anyhow!("invalid signature"))?, }) } @@ -3220,6 +3249,7 @@ fn serialize_symbol(symbol: &Symbol) -> proto::Symbol { row: symbol.range.end.row, column: symbol.range.end.column, }), + signature: symbol.signature.to_vec(), } } diff --git a/crates/rpc/proto/zed.proto b/crates/rpc/proto/zed.proto index 91bf28ffe01cfd784b051310360d482125036543..664d103a158ee741acf4eb43db067d6b8c186a09 100644 --- a/crates/rpc/proto/zed.proto +++ b/crates/rpc/proto/zed.proto @@ -193,6 +193,7 @@ message Symbol { string path = 6; Point start = 7; Point end = 8; + bytes signature = 9; } message OpenBufferForSymbol {