aboutsummaryrefslogtreecommitdiffstats
path: root/executor/executor_runner.h
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2025-02-20 12:25:04 +0100
committerAlexander Potapenko <glider@google.com>2025-02-20 16:45:37 +0000
commit0808a665bc75ab0845906bfeca0d12fb520ae6eb (patch)
tree04e77371226d0433dd8a865b01bc1eeedebd3348 /executor/executor_runner.h
parent506687987fc2f8f40b2918782fc2943285fdc602 (diff)
pkg/rpcserver: pkg/flatrpc: executor: add handshake stage 0
As we figured out in #5805, syz-manager treats random incoming RPC connections as trusted, and will crash if a non-executor client sends an invalid packet to it. To address this issue, we introduce another stage of handshake, which includes a cookie exchange: - upon connection from an executor, the manager sends a ConnectHello RPC message to it, which contains a random 64-bit cookie; - the executor calculates a hash of that cookie and includes it into its ConnectRequest together with the other information; - before checking the validity of ConnectRequest, the manager ensures client sanity (passed ID didn't change, hashed cookie has the expected value) We deliberately pick a random cookie instead of a magic number: if the fuzzer somehow learns to send packets to the manager, we don't want it to crash multiple managers on the same machine.
Diffstat (limited to 'executor/executor_runner.h')
-rw-r--r--executor/executor_runner.h16
1 files changed, 16 insertions, 0 deletions
diff --git a/executor/executor_runner.h b/executor/executor_runner.h
index a3b668893..88fc785db 100644
--- a/executor/executor_runner.h
+++ b/executor/executor_runner.h
@@ -629,9 +629,24 @@ private:
failmsg("bad restarting", "restarting=%d", restarting_);
}
+ // Implementation must match that in pkg/rpcserver/rpcserver.go.
+ uint64 HashAuthCookie(uint64 cookie)
+ {
+ const uint64_t prime1 = 73856093;
+ const uint64_t prime2 = 83492791;
+
+ return (cookie * prime1) ^ prime2;
+ }
+
int Handshake()
{
+ // Handshake stage 0: get a cookie from the manager.
+ rpc::ConnectHelloRawT conn_hello;
+ conn_.Recv(conn_hello);
+
+ // Handshake stage 1: share basic information about the client.
rpc::ConnectRequestRawT conn_req;
+ conn_req.cookie = HashAuthCookie(conn_hello.cookie);
conn_req.id = vm_index_;
conn_req.arch = GOARCH;
conn_req.git_revision = GIT_REVISION;
@@ -656,6 +671,7 @@ private:
if (conn_reply.cover)
max_signal_.emplace();
+ // Handshake stage 2: share information requested by the manager.
rpc::InfoRequestRawT info_req;
info_req.files = ReadFiles(conn_reply.files);