Repository: syncthing/syncthing (language: go)

Issue:
Nil deref in index handler
Panic were reported in android a few times and then here an actual/ful panic trace was referenced:
https://forum.syncthing.net/t/syncthing-1-26-crashing-on-android-in-syncthing-fork/21115/2

> 
> 11-19 11:32:51.661 11506 21478 W SyncthingNativeCode: panic: runtime error: invalid memory address or nil pointer dereference
> 11-19 11:32:51.661 11506 21478 W SyncthingNativeCode: [signal SIGSEGV: segmentation violation code=0x1 addr=0x60 pc=0x637d5ee060]
> 11-19 11:32:51.661 11506 21478 W SyncthingNativeCode:
> 11-19 11:32:51.661 11506 21478 W SyncthingNativeCode: goroutine 325 [running]:
> 11-19 11:32:51.663 21476     0 E Go      : github.com/syncthing/syncthing/lib/model.(*indexHandlerRegistry).startLocked(_, {{0x4000363e44, 0xc}, {0x4000363e70, 0xc}, 0x0, {0x400011af78, 0x18}, 0x1, {0x40000c2b40, ...}, ...}, ...)
> 11-19 11:32:51.663 21476     0 E Go      :      github.com/syncthing/syncthing/lib/model/indexhandler.go:419 +0x100
> 11-19 11:32:51.663 21476     0 E Go      : github.com/syncthing/syncthing/lib/model.(*indexHandlerRegistry).AddIndexInfo(0x400040e370, {0x40001307b0, 0xc}, 0x4000000640)
> 11-19 11:32:51.663 21476     0 E Go      :      github.com/syncthing/syncthing/lib/model/indexhandler.go:439 +0x430
> 11-19 11:32:51.663 21476     0 E Go      : github.com/syncthing/syncthing/lib/model.(*model).ccHandleFolders(_, {_, _, _}, {{0xdb, 0xa, 0xa4, 0x47, 0xc6, 0x6f, ...}, ...}, ...)
> 11-19 11:32:51.663 21476     0 E Go      :      github.com/syncthing/syncthing/lib/model/model.go:1496 +0x5a8
> 11-19 11:32:51.663 21476     0 E Go      : github.com/syncthing/syncthing/lib/model.(*model).ClusterConfig(0x40001c6180, {0x637d8d4148, 0x4000eec350}, {{0x400154ca00?, 0x40000e8088?, 0x40000e8088?}, 0x68?})
> 11-19 11:32:51.663 21476     0 E Go      :      github.com/syncthing/syncthing/lib/model/model.go:1296 +0x784
> 11-19 11:32:51.663 21476     0 E Go      : github.com/syncthing/syncthing/lib/protocol.(*connectionWrappingModel).ClusterConfig(0x4000bc5d68?, {{0x400154ca00?, 0x10?, 0x637d710540?}, 0x1?})
> 11-19 11:32:51.663 21476     0 E Go      :      github.com/syncthing/syncthing/lib/protocol/protocol.go:1143 +0x50
> 11-19 11:32:51.663 21476     0 E Go      : github.com/syncthing/syncthing/lib/protocol.encryptedModel.ClusterConfig(...)
> 11-19 11:32:51.663 21476     0 E Go      :      github.com/syncthing/syncthing/lib/protocol/encryption.go:155
> 11-19 11:32:51.663 21476     0 E Go      : github.com/syncthing/syncthing/lib/protocol.(*rawConnection).dispatcherLoop(0x4000116a20)
> 11-19 11:32:51.663 21476     0 E Go      :      github.com/syncthing/syncthing/lib/protocol/protocol.go:496 +0x308
> 11-19 11:32:51.663 21476     0 E Go      : github.com/syncthing/syncthing/lib/protocol.(*rawConnection).Start.func2()
> 11-19 11:32:51.663 21476     0 E Go      :      github.com/syncthing/syncthing/lib/protocol/protocol.go:307 +0x24
> 11-19 11:32:51.663 21476     0 E Go      : created by github.com/syncthing/syncthing/lib/protocol.(*rawConnection).Start
> 11-19 11:32:51.663 21476     0 E Go      :      github.com/syncthing/syncthing/lib/protocol/protocol.go:306 +0x144
> 11-19 11:32:51.663 21476     0 E Go      :

There's recently changed/added code that sets up index handlers and access fmut protected fields without holding the lock: https://github.com/syncthing/syncthing/blob/main/lib/model/model.go#L1370  
I don't see how exactly this can lead to the panic, but presumably some race around pausing a folder.

I am sending a PR shortly.


Discussion / hints:

Fix patch:
diff --git a/lib/model/model.go b/lib/model/model.go
index c8007f61dcd..64475468d82 100644
--- a/lib/model/model.go
+++ b/lib/model/model.go
@@ -1346,6 +1346,9 @@ func (m *model) ensureIndexHandler(conn protocol.Connection) *indexHandlerRegist
 	deviceID := conn.DeviceID()
 	connID := conn.ConnectionID()
 
+	// We must acquire fmut first when acquiring both locks.
+	m.fmut.RLock()
+	defer m.fmut.RUnlock()
 	m.pmut.Lock()
 	defer m.pmut.Unlock()
 


Test patch: