]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/contrib/fileutl.cc
Drop Privileges to "Debian-apt" in most acquire methods
[apt.git] / apt-pkg / contrib / fileutl.cc
index 6b8f04dea1519f5206f6385f551dc92cf0764d81..de67a94b9cce9db491310268315968371a216af6 100644 (file)
@@ -48,6 +48,7 @@
 #include <errno.h>
 #include <glob.h>
 #include <pwd.h>
+#include <grp.h>
 
 #include <set>
 #include <algorithm>
 #include <endian.h>
 #include <stdint.h>
 
+#if __gnu_linux__
+#include <sys/prctl.h>
+#endif
+
 #include <apti18n.h>
                                                                        /*}}}*/
 
@@ -2173,14 +2178,41 @@ bool DropPrivs()
    if (getuid() != 0)
       return true;
 
-   const std::string nobody = _config->Find("APT::User::Nobody", "nobody");
+   if(_config->FindB("Debug::NoDropPrivs", false) == true)
+      return true;
+
+   const std::string nobody = _config->Find("APT::User::Nobody", "Debian-apt");
    struct passwd *pw = getpwnam(nobody.c_str());
    if (pw == NULL)
       return _error->Warning("No user %s, can not drop rights", nobody.c_str());
+
+#if __gnu_linux__
+   // see prctl(2), needs linux3.5
+   int ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0,0, 0);
+   if(ret < 0)
+      _error->Warning("PR_SET_NO_NEW_PRIVS failed with %i", ret);
+#endif
+
+   if (setgroups(1, &pw->pw_gid) != 1)
+      return _error->Errno("setgroups", "Failed to setgroups");
+
+   if (setegid(pw->pw_gid) != 0)
+      return _error->Errno("setgid", "Failed to setgid");
    if (setgid(pw->pw_gid) != 0)
       return _error->Errno("setgid", "Failed to setgid");
+   
    if (setuid(pw->pw_uid) != 0)
       return _error->Errno("setuid", "Failed to setuid");
+   // the seteuid() is probably uneeded (at least thats what the linux
+   // man-page says about setuid(2)) but we cargo culted it anyway
+   if (setuid(pw->pw_uid) != 0)
+      return _error->Errno("setuid", "Failed to setuid");
+
+   // be defensive
+   if(setgid(0) != -1 || setegid(0) != -1)
+      return _error->Error("Could restore gid to root, privilege dropping does not work");
+   if(setuid(0) != -1 || seteuid(0) != -1)
+      return _error->Error("Could restore uid to root, privilege dropping does not work");
 
    return true;
 }