From c8670efc153bc80c314076c0f716f68a92bc86e6 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Wed, 12 Sep 2018 14:08:36 -0400 Subject: [PATCH] Fix a lock inversion In CreateContainer(), don't use ROLayerStores() to get a list of the read-only layer stores after we've acquired the lock on the writeable layer store. ROLayerStores() acquires the graph lock, which we should never try to acquire while we're holding the layer store lock. Signed-off-by: Nalin Dahyabhai --- store.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/store.go b/store.go index 33b91a3538..e0deb2c30c 100644 --- a/store.go +++ b/store.go @@ -1091,11 +1091,6 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat if err != nil { return nil, err } - rlstore.Lock() - defer rlstore.Unlock() - if modified, err := rlstore.Modified(); modified || err != nil { - rlstore.Load() - } if id == "" { id = stringid.GenerateRandomID() } @@ -1108,6 +1103,10 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat idMappingsOptions := options.IDMappingOptions if image != "" { var imageHomeStore ROImageStore + lstores, err := s.ROLayerStores() + if err != nil { + return nil, err + } istore, err := s.ImageStore() if err != nil { return nil, err @@ -1116,6 +1115,11 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat if err != nil { return nil, err } + rlstore.Lock() + defer rlstore.Unlock() + if modified, err := rlstore.Modified(); modified || err != nil { + rlstore.Load() + } var cimage *Image for _, store := range append([]ROImageStore{istore}, istores...) { store.Lock() @@ -1134,10 +1138,6 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat } imageID = cimage.ID - lstores, err := s.ROLayerStores() - if err != nil { - return nil, err - } ilayer, err := s.imageTopLayerForMapping(cimage, imageHomeStore, imageHomeStore == istore, rlstore, lstores, idMappingsOptions) if err != nil { return nil, err @@ -1150,6 +1150,11 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat gidMap = ilayer.GIDMap } } else { + rlstore.Lock() + defer rlstore.Unlock() + if modified, err := rlstore.Modified(); modified || err != nil { + rlstore.Load() + } if !options.HostUIDMapping && len(options.UIDMap) == 0 { uidMap = s.uidMap }