aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/flatrpc/conn_test.go
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 /pkg/flatrpc/conn_test.go
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 'pkg/flatrpc/conn_test.go')
-rw-r--r--pkg/flatrpc/conn_test.go29
1 files changed, 27 insertions, 2 deletions
diff --git a/pkg/flatrpc/conn_test.go b/pkg/flatrpc/conn_test.go
index 4b108a5a4..87d5e9a8a 100644
--- a/pkg/flatrpc/conn_test.go
+++ b/pkg/flatrpc/conn_test.go
@@ -20,7 +20,11 @@ import (
)
func TestConn(t *testing.T) {
+ connectHello := &ConnectHello{
+ Cookie: 1,
+ }
connectReq := &ConnectRequest{
+ Cookie: 73856093,
Id: 1,
Arch: "arch",
GitRevision: "rev1",
@@ -52,6 +56,9 @@ func TestConn(t *testing.T) {
go func() {
done <- serv.Serve(context.Background(),
func(_ context.Context, c *Conn) error {
+ if err := Send(c, connectHello); err != nil {
+ return err
+ }
connectReqGot, err := Recv[*ConnectRequestRaw](c)
if err != nil {
return err
@@ -79,6 +86,12 @@ func TestConn(t *testing.T) {
c := dial(t, serv.Addr.String())
defer c.Close()
+ connectHelloGot, err := Recv[*ConnectHelloRaw](c)
+ if err != nil {
+ t.Fatal(err)
+ }
+ assert.Equal(t, connectHello, connectHelloGot)
+
if err := Send(c, connectReq); err != nil {
t.Fatal(err)
}
@@ -102,7 +115,11 @@ func TestConn(t *testing.T) {
}
func BenchmarkConn(b *testing.B) {
+ connectHello := &ConnectHello{
+ Cookie: 1,
+ }
connectReq := &ConnectRequest{
+ Cookie: 73856093,
Id: 1,
Arch: "arch",
GitRevision: "rev1",
@@ -125,7 +142,11 @@ func BenchmarkConn(b *testing.B) {
done <- serv.Serve(context.Background(),
func(_ context.Context, c *Conn) error {
for i := 0; i < b.N; i++ {
- _, err := Recv[*ConnectRequestRaw](c)
+ if err := Send(c, connectHello); err != nil {
+ return err
+ }
+
+ _, err = Recv[*ConnectRequestRaw](c)
if err != nil {
return err
}
@@ -143,10 +164,14 @@ func BenchmarkConn(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
+ _, err := Recv[*ConnectHelloRaw](c)
+ if err != nil {
+ b.Fatal(err)
+ }
if err := Send(c, connectReq); err != nil {
b.Fatal(err)
}
- _, err := Recv[*ConnectReplyRaw](c)
+ _, err = Recv[*ConnectReplyRaw](c)
if err != nil {
b.Fatal(err)
}