runProgram: support gid, uid, chdir
This commit is contained in:
		
							parent
							
								
									dde8eeb39a
								
							
						
					
					
						commit
						b4a05edbfe
					
				
					 3 changed files with 30 additions and 22 deletions
				
			
		|  | @ -465,26 +465,22 @@ void handleDiffHook(bool allowVfork, uid_t uid, uid_t gid, Path tryA, Path tryB, | |||
| { | ||||
|     auto diffHook = settings.diffHook; | ||||
|     if (diffHook != "" && settings.runDiffHook) { | ||||
|         auto wrapper = [&]() { | ||||
|             if (chdir("/") == -1) | ||||
|                 throw SysError("chdir / failed"); | ||||
|             if (setgid(gid) == -1) | ||||
|                 throw SysError("setgid failed"); | ||||
|             if (setgroups(0, 0) == -1) | ||||
|                 throw SysError("setgroups failed"); | ||||
|             if (setuid(uid) == -1) | ||||
|                 throw SysError("setuid failed"); | ||||
| 
 | ||||
|         try { | ||||
|                 auto diff = runProgram(diffHook, true, {tryA, tryB, drvPath, tmpDir}); | ||||
|                 if (diff != "") | ||||
|                     printError(chomp(diff)); | ||||
|             RunOptions diffHookOptions(diffHook,{tryA, tryB, drvPath, tmpDir}); | ||||
|             diffHookOptions.searchPath = true; | ||||
|             diffHookOptions.uid = uid; | ||||
|             diffHookOptions.gid = gid; | ||||
|             diffHookOptions.chdir = "/"; | ||||
| 
 | ||||
|             auto diffRes = runProgram(diffHookOptions); | ||||
|             if (!statusOk(diffRes.first)) | ||||
|                 throw ExecError(diffRes.first, fmt("diff-hook program '%1%' %2%", diffHook, statusToString(diffRes.first))); | ||||
| 
 | ||||
|             if (diffRes.second != "") | ||||
|                 printError(chomp(diffRes.second)); | ||||
|         } catch (Error & error) { | ||||
|             printError("diff hook execution failed: %s", error.what()); | ||||
|         } | ||||
|         }; | ||||
| 
 | ||||
|         doFork(allowVfork, wrapper); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ | |||
| #include <future> | ||||
| 
 | ||||
| #include <fcntl.h> | ||||
| #include <grp.h> | ||||
| #include <limits.h> | ||||
| #include <pwd.h> | ||||
| #include <sys/ioctl.h> | ||||
|  | @ -914,8 +915,8 @@ void killUser(uid_t uid) | |||
| 
 | ||||
| /* Wrapper around vfork to prevent the child process from clobbering
 | ||||
|    the caller's stack frame in the parent. */ | ||||
| pid_t doFork(bool allowVfork, std::function<void()> fun) __attribute__((noinline)); | ||||
| pid_t doFork(bool allowVfork, std::function<void()> fun) | ||||
| static pid_t doFork(bool allowVfork, std::function<void()> fun) __attribute__((noinline)); | ||||
| static pid_t doFork(bool allowVfork, std::function<void()> fun) | ||||
| { | ||||
| #ifdef __linux__ | ||||
|     pid_t pid = allowVfork ? vfork() : fork(); | ||||
|  | @ -1025,6 +1026,16 @@ void runProgram2(const RunOptions & options) | |||
|         if (source && dup2(in.readSide.get(), STDIN_FILENO) == -1) | ||||
|             throw SysError("dupping stdin"); | ||||
| 
 | ||||
|         //if (options.chdir && chdir((*options.chdir).c_str()) == -1)
 | ||||
|         //    throw SysError("chdir failed");
 | ||||
|         if (options.gid && setgid(*options.gid) == -1) | ||||
|             throw SysError("setgid failed"); | ||||
|         /* Drop all other groups if we're setgid. */ | ||||
|         if (options.gid && setgroups(0, 0) == -1) | ||||
|             throw SysError("setgroups failed"); | ||||
|         if (options.uid && setuid(*options.uid) == -1) | ||||
|             throw SysError("setuid failed"); | ||||
| 
 | ||||
|         Strings args_(options.args); | ||||
|         args_.push_front(options.program); | ||||
| 
 | ||||
|  |  | |||
|  | @ -265,10 +265,11 @@ string runProgram(Path program, bool searchPath = false, | |||
|     const Strings & args = Strings(), | ||||
|     const std::optional<std::string> & input = {}); | ||||
| 
 | ||||
| pid_t doFork(bool allowVfork, std::function<void()> fun); | ||||
| 
 | ||||
| struct RunOptions | ||||
| { | ||||
|     std::optional<uid_t> uid; | ||||
|     std::optional<uid_t> gid; | ||||
|     std::optional<Path> chdir; | ||||
|     Path program; | ||||
|     bool searchPath = true; | ||||
|     Strings args; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue