Blob Blame History Raw
From a6fec757c8a17f3a5b92fb766b0f2eeb3b1a208a Mon Sep 17 00:00:00 2001
From: Giuseppe Scrivano <gscrivan@redhat.com>
Date: Thu, 19 Dec 2019 19:06:00 +0100
Subject: [PATCH] store: keep graph lock during Mount

This solves a race condition where a mountpoint is created without the
home mount being present.

The cause is that another process could be calling the graph driver
cleanup as part of store.Shutdown() causing the unmount of the
driver home directory.

The unmount could happen between the time the rlstore is retrieved and
the actual mount, causing the driver mount to be done without a home
mount below it.

A third process then would re-create again the home mount, shadowing
the previous mount.

Closes: https://bugzilla.redhat.com/show_bug.cgi?id=1757845

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
---
 store.go | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/store.go b/store.go
index 65808b8a0..272153e51 100644
--- a/vendor/github.com/containers/storage/store.go
+++ b/vendor/github.com/containers/storage/store.go
@@ -2479,6 +2479,10 @@ func (s *store) Mount(id, mountLabel string) (string, error) {
 	if err != nil {
 		return "", err
 	}
+
+	s.graphLock.Lock()
+	defer s.graphLock.Unlock()
+
 	rlstore.Lock()
 	defer rlstore.Unlock()
 	if modified, err := rlstore.Modified(); modified || err != nil {
@@ -2486,6 +2490,18 @@ func (s *store) Mount(id, mountLabel string) (string, error) {
 			return "", err
 		}
 	}
+
+	/* We need to make sure the home mount is present when the Mount is done.  */
+	if s.graphLock.TouchedSince(s.lastLoaded) {
+		s.graphDriver = nil
+		s.layerStore = nil
+		s.graphDriver, err = s.getGraphDriver()
+		if err != nil {
+			return "", err
+		}
+		s.lastLoaded = time.Now()
+	}
+
 	if rlstore.Exists(id) {
 		options := drivers.MountOpts{
 			MountLabel: mountLabel,