X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/9983999d294887046abf386adc31190700d89b61..e8afd16892e87a6e2f17c1019ee455f5583387c2:/apt-pkg/contrib/fileutl.cc diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index f6351b7b5..8ec868ec0 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -800,8 +800,9 @@ pid_t ExecFork(std::set KeepFDs) signal(SIGCONT,SIG_DFL); signal(SIGTSTP,SIG_DFL); + long ScOpenMax = sysconf(_SC_OPEN_MAX); // Close all of our FDs - just in case - for (int K = 3; K != sysconf(_SC_OPEN_MAX); K++) + for (int K = 3; K != ScOpenMax; K++) { if(KeepFDs.find(K) == KeepFDs.end()) fcntl(K,F_SETFD,FD_CLOEXEC); @@ -874,6 +875,25 @@ bool StartsWithGPGClearTextSignature(string const &FileName) return true; } /*}}}*/ +// ChangeOwnerAndPermissionOfFile - set file attributes to requested values /*{{{*/ +bool ChangeOwnerAndPermissionOfFile(char const * const requester, char const * const file, char const * const user, char const * const group, mode_t const mode) +{ + if (strcmp(file, "/dev/null") == 0) + return true; + bool Res = true; + if (getuid() == 0 && strlen(user) != 0 && strlen(group) != 0) // if we aren't root, we can't chown, so don't try it + { + // ensure the file is owned by root and has good permissions + struct passwd const * const pw = getpwnam(user); + struct group const * const gr = getgrnam(group); + if (pw != NULL && gr != NULL && chown(file, pw->pw_uid, gr->gr_gid) != 0) + Res &= _error->WarningE(requester, "chown to %s:%s of file %s failed", user, group, file); + } + if (chmod(file, mode) != 0) + Res &= _error->WarningE(requester, "chmod 0%o of file %s failed", mode, file); + return Res; +} + /*}}}*/ class FileFdPrivate { /*{{{*/ public: @@ -2066,9 +2086,11 @@ std::string GetTempDir() /*{{{*/ tmpdir = P_tmpdir; #endif - // check that tmpdir is set and exists struct stat st; - if (!tmpdir || strlen(tmpdir) == 0 || stat(tmpdir, &st) != 0) + if (!tmpdir || strlen(tmpdir) == 0 || // tmpdir is set + stat(tmpdir, &st) != 0 || (st.st_mode & S_IFDIR) == 0 || // exists and is directory + access(tmpdir, R_OK | W_OK | X_OK) != 0 // current user has rwx access to directory + ) tmpdir = "/tmp"; return string(tmpdir); @@ -2168,12 +2190,6 @@ bool DropPrivileges() /*{{{*/ if(_config->FindB("Debug::NoDropPrivs", false) == true) return true; - // empty setting disables DropPrivilidges - this also ensures - // backward compatibility, see bug #764506 - const std::string toUser = _config->Find("APT::Sandbox::User"); - if (toUser.empty()) - return true; - #if __gnu_linux__ #if defined(PR_SET_NO_NEW_PRIVS) && ( PR_SET_NO_NEW_PRIVS != 38 ) #error "PR_SET_NO_NEW_PRIVS is defined, but with a different value than expected!" @@ -2185,6 +2201,12 @@ bool DropPrivileges() /*{{{*/ _error->Warning("PR_SET_NO_NEW_PRIVS failed with %i", ret); #endif + // empty setting disables privilege dropping - this also ensures + // backward compatibility, see bug #764506 + const std::string toUser = _config->Find("APT::Sandbox::User"); + if (toUser.empty()) + return true; + // uid will be 0 in the end, but gid might be different anyway uid_t const old_uid = getuid(); gid_t const old_gid = getgid();