From ee42c46bd317b9e46c800b3fda3fa5648e3e1e6e Mon Sep 17 00:00:00 2001 From: Simon Frei Date: Sat, 11 Aug 2018 09:10:29 +0200 Subject: [PATCH 1/2] lib/model: Catch racy nil deref in ClusterConfig (#5106) --- lib/model/model.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/model/model.go b/lib/model/model.go index e0b06ef18..9fe78274b 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -953,12 +953,17 @@ func (m *Model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon if cfg.Paused { continue } + fs, ok := m.folderFiles[folder.ID] + if !ok { + // Shouldn't happen because !cfg.Paused, but might happen + // if the folder is about to be unpaused, but not yet. + continue + } if !folder.DisableTempIndexes { tempIndexFolders = append(tempIndexFolders, folder.ID) } - fs := m.folderFiles[folder.ID] myIndexID := fs.IndexID(protocol.LocalDeviceID) mySequence := fs.Sequence(protocol.LocalDeviceID) var startSequence int64 From 7c0798b6224e6407e3b0872b204b6fc224d70325 Mon Sep 17 00:00:00 2001 From: Simon Frei Date: Wed, 15 Aug 2018 16:33:03 +0200 Subject: [PATCH 2/2] lib/model: Always release the lock (#5126) --- lib/model/model.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/model/model.go b/lib/model/model.go index 9fe78274b..a8d9dae7e 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -1307,8 +1307,6 @@ func (m *Model) Request(deviceID protocol.DeviceID, folder, name string, offset return protocol.ErrInvalid } - m.fmut.RLock() - if cfg, ok := m.cfg.Folder(folder); !ok || !cfg.SharedWith(deviceID) { l.Warnf("Request from %s for file %s in unshared folder %q", deviceID, name, folder) return protocol.ErrNoSuchFile @@ -1317,10 +1315,16 @@ func (m *Model) Request(deviceID protocol.DeviceID, folder, name string, offset return protocol.ErrInvalid } - folderCfg := m.folderCfgs[folder] + m.fmut.RLock() + folderCfg, ok := m.folderCfgs[folder] folderIgnores := m.folderIgnores[folder] - m.fmut.RUnlock() + if !ok { + // The folder might be already unpaused in the config, but not yet + // in the model. + l.Debugf("Request from %s for file %s in unstarted folder %q", deviceID, name, folder) + return protocol.ErrInvalid + } // Make sure the path is valid and in canonical form var err error