Set up a minimal /dev in chroots
Not bind-mounting the /dev from the host also solves the problem with /dev/shm being a symlink to something not in the chroot.
This commit is contained in:
		
							parent
							
								
									c9f6232304
								
							
						
					
					
						commit
						3fd01b171a
					
				
					 8 changed files with 40 additions and 17 deletions
				
			
		| 
						 | 
				
			
			@ -2013,6 +2013,26 @@ void DerivationGoal::initChild()
 | 
			
		|||
                    throw SysError(format("unable to make filesystem `%1%' private") % fs);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Set up a nearly empty /dev, unless the user asked to
 | 
			
		||||
               bind-mount the host /dev. */
 | 
			
		||||
            if (dirsInChroot.find("/dev") == dirsInChroot.end()) {
 | 
			
		||||
                createDirs(chrootRootDir + "/dev/shm");
 | 
			
		||||
                Strings ss;
 | 
			
		||||
                ss.push_back("/dev/full");
 | 
			
		||||
                ss.push_back("/dev/kvm");
 | 
			
		||||
                ss.push_back("/dev/null");
 | 
			
		||||
                ss.push_back("/dev/ptmx");
 | 
			
		||||
                ss.push_back("/dev/random");
 | 
			
		||||
                ss.push_back("/dev/tty");
 | 
			
		||||
                ss.push_back("/dev/urandom");
 | 
			
		||||
                ss.push_back("/dev/zero");
 | 
			
		||||
                foreach (Strings::iterator, i, ss) dirsInChroot[*i] = *i;
 | 
			
		||||
                createSymlink("/proc/self/fd", chrootRootDir + "/dev/fd");
 | 
			
		||||
                createSymlink("/proc/self/fd/0", chrootRootDir + "/dev/stdin");
 | 
			
		||||
                createSymlink("/proc/self/fd/1", chrootRootDir + "/dev/stdout");
 | 
			
		||||
                createSymlink("/proc/self/fd/2", chrootRootDir + "/dev/stderr");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Bind-mount all the directories from the "host"
 | 
			
		||||
               filesystem that we want in the chroot
 | 
			
		||||
               environment. */
 | 
			
		||||
| 
						 | 
				
			
			@ -2042,9 +2062,8 @@ void DerivationGoal::initChild()
 | 
			
		|||
 | 
			
		||||
            /* Mount a new tmpfs on /dev/shm to ensure that whatever
 | 
			
		||||
               the builder puts in /dev/shm is cleaned up automatically. */
 | 
			
		||||
            if (pathExists("/dev/shm"))
 | 
			
		||||
                if (mount("none", (chrootRootDir + "/dev/shm").c_str(), "tmpfs", 0, 0) == -1)
 | 
			
		||||
                    throw SysError("mounting /dev/shm");
 | 
			
		||||
            if (pathExists("/dev/shm") && mount("none", (chrootRootDir + "/dev/shm").c_str(), "tmpfs", 0, 0) == -1)
 | 
			
		||||
                throw SysError("mounting /dev/shm");
 | 
			
		||||
 | 
			
		||||
            /* Do the chroot().  Below we do a chdir() to the
 | 
			
		||||
               temporary build directory to make sure the current
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ int LocalStore::openGCLock(LockType lockType)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void createSymlink(const Path & link, const Path & target)
 | 
			
		||||
static void makeSymlink(const Path & link, const Path & target)
 | 
			
		||||
{
 | 
			
		||||
    /* Create directories up to `gcRoot'. */
 | 
			
		||||
    createDirs(dirOf(link));
 | 
			
		||||
| 
						 | 
				
			
			@ -61,9 +61,7 @@ void createSymlink(const Path & link, const Path & target)
 | 
			
		|||
    /* Create the new symlink. */
 | 
			
		||||
    Path tempLink = (format("%1%.tmp-%2%-%3%")
 | 
			
		||||
        % link % getpid() % rand()).str();
 | 
			
		||||
    if (symlink(target.c_str(), tempLink.c_str()) == -1)
 | 
			
		||||
        throw SysError(format("symlinking `%1%' to `%2%'")
 | 
			
		||||
            % tempLink % target);
 | 
			
		||||
    createSymlink(target, tempLink);
 | 
			
		||||
 | 
			
		||||
    /* Atomically replace the old one. */
 | 
			
		||||
    if (rename(tempLink.c_str(), link.c_str()) == -1)
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +81,7 @@ void LocalStore::addIndirectRoot(const Path & path)
 | 
			
		|||
    string hash = printHash32(hashString(htSHA1, path));
 | 
			
		||||
    Path realRoot = canonPath((format("%1%/%2%/auto/%3%")
 | 
			
		||||
        % settings.nixStateDir % gcRootsDir % hash).str());
 | 
			
		||||
    createSymlink(realRoot, path);
 | 
			
		||||
    makeSymlink(realRoot, path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +102,7 @@ Path addPermRoot(StoreAPI & store, const Path & _storePath,
 | 
			
		|||
           point to the Nix store. */
 | 
			
		||||
        if (pathExists(gcRoot) && (!isLink(gcRoot) || !isInStore(readLink(gcRoot))))
 | 
			
		||||
            throw Error(format("cannot create symlink `%1%'; already exists") % gcRoot);
 | 
			
		||||
        createSymlink(gcRoot, storePath);
 | 
			
		||||
        makeSymlink(gcRoot, storePath);
 | 
			
		||||
        store.addIndirectRoot(gcRoot);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -119,7 +117,7 @@ Path addPermRoot(StoreAPI & store, const Path & _storePath,
 | 
			
		|||
                    % gcRoot % rootsDir);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        createSymlink(gcRoot, storePath);
 | 
			
		||||
        makeSymlink(gcRoot, storePath);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Check that the root can be found by the garbage collector.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,7 +42,6 @@ Settings::Settings()
 | 
			
		|||
    useSubstitutes = true;
 | 
			
		||||
    useChroot = false;
 | 
			
		||||
    useSshSubstituter = false;
 | 
			
		||||
    dirsInChroot.insert("/dev");
 | 
			
		||||
    dirsInChroot.insert("/dev/pts");
 | 
			
		||||
    impersonateLinux26 = false;
 | 
			
		||||
    keepLog = true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -243,8 +243,7 @@ LocalStore::LocalStore(bool reserveSpace)
 | 
			
		|||
    Path gcRootsDir = settings.nixStateDir + "/gcroots";
 | 
			
		||||
    if (!pathExists(gcRootsDir)) {
 | 
			
		||||
        createDirs(gcRootsDir);
 | 
			
		||||
        if (symlink(profilesDir.c_str(), (gcRootsDir + "/profiles").c_str()) == -1)
 | 
			
		||||
            throw SysError(format("creating symlink to `%1%'") % profilesDir);
 | 
			
		||||
        createSymlink(profilesDir, gcRootsDir + "/profiles");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    checkStoreNotSymlink();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -319,8 +319,7 @@ struct RestoreSink : ParseSink
 | 
			
		|||
    void createSymlink(const Path & path, const string & target)
 | 
			
		||||
    {
 | 
			
		||||
        Path p = dstPath + path;
 | 
			
		||||
        if (symlink(target.c_str(), p.c_str()) == -1)
 | 
			
		||||
            throw SysError(format("creating symlink `%1%'") % p);
 | 
			
		||||
        nix::createSymlink(target, p);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -386,6 +386,13 @@ Paths createDirs(const Path & path)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void createSymlink(const Path & target, const Path & link)
 | 
			
		||||
{
 | 
			
		||||
    if (symlink(target.c_str(), link.c_str()))
 | 
			
		||||
        throw SysError(format("creating symlink from `%1%' to `%2%'") % link % target);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LogType logType = ltPretty;
 | 
			
		||||
Verbosity verbosity = lvlInfo;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -93,6 +93,9 @@ Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
 | 
			
		|||
   list of created directories, in order of creation. */
 | 
			
		||||
Paths createDirs(const Path & path);
 | 
			
		||||
 | 
			
		||||
/* Create a symlink. */
 | 
			
		||||
void createSymlink(const Path & target, const Path & link);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<class T, class A>
 | 
			
		||||
T singleton(const A & a)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,8 +118,7 @@ void switchLink(Path link, Path target)
 | 
			
		|||
    if (dirOf(target) == dirOf(link)) target = baseNameOf(target);
 | 
			
		||||
 | 
			
		||||
    Path tmp = canonPath(dirOf(link) + "/.new_" + baseNameOf(link));
 | 
			
		||||
    if (symlink(target.c_str(), tmp.c_str()) != 0)
 | 
			
		||||
        throw SysError(format("creating symlink `%1%'") % tmp);
 | 
			
		||||
    createSymlink(target, tmp);
 | 
			
		||||
    /* The rename() system call is supposed to be essentially atomic
 | 
			
		||||
       on Unix.  That is, if we have links `current -> X' and
 | 
			
		||||
       `new_current -> Y', and we rename new_current to current, a
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue