In the chroot, make all mounted filesystems private
This is required on systemd, which mounts filesystems as "shared" subtrees. Changes to shared trees in a private mount namespace are propagated to the outside world, which is bad.
This commit is contained in:
		
							parent
							
								
									f0eab0636b
								
							
						
					
					
						commit
						56e30e161c
					
				
					 3 changed files with 21 additions and 3 deletions
				
			
		|  | @ -1853,6 +1853,24 @@ void DerivationGoal::initChild() | ||||||
|             char domainname[] = "(none)"; // kernel default
 |             char domainname[] = "(none)"; // kernel default
 | ||||||
|             setdomainname(domainname, sizeof(domainname)); |             setdomainname(domainname, sizeof(domainname)); | ||||||
| 
 | 
 | ||||||
|  |             /* Make all filesystems private.  This is necessary
 | ||||||
|  |                because subtrees may have been mounted as "shared" | ||||||
|  |                (MS_SHARED).  (Systemd does this, for instance.)  Even | ||||||
|  |                though we have a private mount namespace, mounting | ||||||
|  |                filesystems on top of a shared subtree still propagates | ||||||
|  |                outside of the namespace.  Making a subtree private is | ||||||
|  |                local to the namespace, though, so setting MS_PRIVATE | ||||||
|  |                does not affect the outside world. */ | ||||||
|  |             Strings mounts = tokenizeString(readFile("/proc/self/mountinfo", true), "\n"); | ||||||
|  |             foreach (Strings::iterator, i, mounts) { | ||||||
|  |                 Strings fields = tokenizeString(*i, " "); | ||||||
|  |                 assert(fields.size() >= 5); | ||||||
|  |                 Strings::iterator j = fields.begin(); | ||||||
|  |                 std::advance(j, 4); | ||||||
|  |                 if (mount(0, j->c_str(), 0, MS_PRIVATE, 0) == -1) | ||||||
|  |                     throw SysError(format("unable to make filesystem `%1%' private") % *j); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             /* Bind-mount all the directories from the "host"
 |             /* Bind-mount all the directories from the "host"
 | ||||||
|                filesystem that we want in the chroot |                filesystem that we want in the chroot | ||||||
|                environment. */ |                environment. */ | ||||||
|  |  | ||||||
|  | @ -224,12 +224,12 @@ string readFile(int fd) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| string readFile(const Path & path) | string readFile(const Path & path, bool drain) | ||||||
| { | { | ||||||
|     AutoCloseFD fd = open(path.c_str(), O_RDONLY); |     AutoCloseFD fd = open(path.c_str(), O_RDONLY); | ||||||
|     if (fd == -1) |     if (fd == -1) | ||||||
|         throw SysError(format("opening file `%1%'") % path); |         throw SysError(format("opening file `%1%'") % path); | ||||||
|     return readFile(fd); |     return drain ? drainFD(fd) : readFile(fd); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -63,7 +63,7 @@ Strings readDirectory(const Path & path); | ||||||
| 
 | 
 | ||||||
| /* Read the contents of a file into a string. */ | /* Read the contents of a file into a string. */ | ||||||
| string readFile(int fd); | string readFile(int fd); | ||||||
| string readFile(const Path & path); | string readFile(const Path & path, bool drain = false); | ||||||
| 
 | 
 | ||||||
| /* Write a string to a file. */ | /* Write a string to a file. */ | ||||||
| void writeFile(const Path & path, const string & s); | void writeFile(const Path & path, const string & s); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue