diff options
author | David Kalnischkies <david@kalnischkies.de> | 2014-10-07 21:17:04 +0200 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2014-10-07 21:17:04 +0200 |
commit | 8f45798d532223adc378a4ad9ecfc64b3be26e4f (patch) | |
tree | de964d38c9c216670993f188ed592b8cc900ae58 | |
parent | f8aba23f2e8a4c52869cd3869a716df28267597a (diff) |
set PR_SET_NO_NEW_PRIVS also if run as non-root
Changing user and co works only as root, but can do some things for
methods run as normal user as well to protect them from being able to
call setuid binaries like sudo to elevate their privileges.
Also uses a cheap trick now to build with old unsupporting kernels.
-rw-r--r-- | apt-pkg/contrib/fileutl.cc | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 86eec7c36..844a6bd3c 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -2165,27 +2165,32 @@ bool Popen(const char* Args[], FileFd &Fd, pid_t &Child, FileFd::OpenMode Mode)/ /*}}}*/ bool DropPrivileges() /*{{{*/ { + if(_config->FindB("Debug::NoDropPrivs", false) == true) + 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!" +#endif + // see prctl(2), needs linux3.5 at runtime - magic constant to avoid it at buildtime + int ret = prctl(38, 1, 0, 0, 0); + // ignore EINVAL - kernel is too old to understand the option + if(ret < 0 && errno != EINVAL) + _error->Warning("PR_SET_NO_NEW_PRIVS failed with %i", ret); +#endif + // uid will be 0 in the end, but gid might be different anyway - uid_t old_uid = getuid(); - gid_t old_gid = getgid(); + uid_t const old_uid = getuid(); + gid_t const old_gid = getgid(); if (old_uid != 0) return true; - if(_config->FindB("Debug::NoDropPrivs", false) == true) - return true; const std::string toUser = _config->Find("APT::Sandbox::User", "_apt"); struct passwd *pw = getpwnam(toUser.c_str()); if (pw == NULL) return _error->Error("No user %s, can not drop rights", toUser.c_str()); -#if __gnu_linux__ - // see prctl(2), needs linux3.5 - int ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); - // ignore EINVAL - kernel is too old to understand the option - if(ret < 0 && errno != EINVAL) - _error->Warning("PR_SET_NO_NEW_PRIVS failed with %i", ret); -#endif // Do not change the order here, it might break things if (setgroups(1, &pw->pw_gid)) return _error->Errno("setgroups", "Failed to setgroups"); |