From 550ab420d398f303ff8cbc51e1f4dab79f8cbdf2 Mon Sep 17 00:00:00 2001
From: Julian Andres Klode <jak@debian.org>
Date: Wed, 24 Sep 2014 20:57:30 +0200
Subject: [PATCH] DropPrivs: Also check for saved set-user-ID and set-group-ID

---
 apt-pkg/contrib/fileutl.cc | 20 ++++++++++++++++++++
 buildlib/config.h.in       |  4 ++++
 configure.ac               |  6 ++++++
 3 files changed, 30 insertions(+)

diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index 98544b60c..05c2f2e00 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -2237,6 +2237,26 @@ bool DropPrivs()
    if (geteuid() != pw->pw_uid)
       return _error->Error("Could not switch effective user");
 
+#ifdef HAVE_GETRESUID
+   uid_t ruid = 0;
+   uid_t euid = 0;
+   uid_t suid = 0;
+   if (getresuid(&ruid, &euid, &suid))
+      return _error->Errno("getresuid", "Could not get saved set-user-ID");
+   if (suid != pw->pw_uid)
+      return _error->Error("Could not switch saved set-user-ID");
+#endif
+
+#ifdef HAVE_GETRESGID
+   gid_t rgid = 0;
+   gid_t egid = 0;
+   gid_t sgid = 0;
+   if (getresgid(&rgid, &egid, &sgid))
+      return _error->Errno("getresuid", "Could not get saved set-group-ID");
+   if (sgid != pw->pw_gid)
+      return _error->Error("Could not switch saved set-group-ID");
+#endif
+
    /* TODO: Check saved uid/saved gid as well */
    return true;
 }
diff --git a/buildlib/config.h.in b/buildlib/config.h.in
index 6b72fb393..c0fd2e8c6 100644
--- a/buildlib/config.h.in
+++ b/buildlib/config.h.in
@@ -28,6 +28,10 @@
 /* If there is no socklen_t, define this for the netdb shim */
 #undef NEED_SOCKLEN_T_DEFINE
 
+/* We need the getresuid() function */
+#undef HAVE_GETRESUID
+#undef HAVE_GETRESGID
+
 /* Define to the size of the filesize containing structures */
 #undef _FILE_OFFSET_BITS
 
diff --git a/configure.ac b/configure.ac
index 89950fccd..5d0e0a9db 100644
--- a/configure.ac
+++ b/configure.ac
@@ -172,6 +172,12 @@ AC_EGREP_HEADER(h_errno, netdb.h, [AC_MSG_RESULT(normal)],
        [AC_MSG_ERROR("not found.")])
    ])
 
+
+dnl check for setuid checking function
+AC_CHECK_FUNCS(getresuid getresgid)
+AC_SUBST(HAVE_GETRESUID)
+AC_SUBST(HAVE_GETRESGID)
+
 dnl Check for doxygen
 AC_PATH_PROG(DOXYGEN, doxygen)
 
-- 
2.47.2