Package: release.debian.org Severity: normal Tags: wheezy User: release.debian....@packages.debian.org Usertags: pu
Hi, I'd like to update apt-daemon in wheezy to fix CVE-2015-1323 which is already fixed in squeeze-lts. The debdiff is attached. -- System Information: Debian Release: stretch/sid APT prefers testing APT policy: (990, 'testing'), (500, 'stable-updates'), (500, 'unstable'), (500, 'stable'), (1, 'experimental') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 4.1.0-2-amd64 (SMP w/4 CPU cores) Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system)
diff --git a/debian/changelog b/debian/changelog index eb3eb13..80547b9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +aptdaemon (0.45-2+deb7u1) oldstable-proposed-updates; urgency=medium + + * Non maintainer upload + * Add CVE-2015-1323.patch to address CVE-2015-1323 - taken from + 0.43+bzr805-0ubuntu10 (Closes: #789162) + + -- Guido Günther <a...@sigxcpu.org> Mon, 29 Feb 2016 08:33:47 +0100 + aptdaemon (0.45-2) unstable; urgency=medium * Check downloaded key id; merged from Ubuntu (CVE-2012-0962) diff --git a/debian/patches/CVE-2015-1323.patch b/debian/patches/CVE-2015-1323.patch new file mode 100644 index 0000000..09bcfb6 --- /dev/null +++ b/debian/patches/CVE-2015-1323.patch @@ -0,0 +1,373 @@ +From: =?utf-8?q?Guido_G=C3=BCnther?= <a...@sigxcpu.org> +Date: Sun, 28 Feb 2016 19:55:02 +0100 +Subject: CVE-2015-1323 + +--- + aptdaemon/core.py | 10 ++++++---- + aptdaemon/pkcompat.py | 11 +++++++---- + aptdaemon/policykit1.py | 9 ++++++--- + aptdaemon/worker.py | 43 ++++++++++++++++++++++++++++++++++++++----- + tests/test_dbus_type.py | 6 ++++-- + tests/test_unicodedecoding.py | 3 ++- + tests/test_worker.py | 31 ++++++++++++++++--------------- + 7 files changed, 79 insertions(+), 34 deletions(-) + +diff --git a/aptdaemon/core.py b/aptdaemon/core.py +index b69923d..6d841e3 100644 +--- a/aptdaemon/core.py ++++ b/aptdaemon/core.py +@@ -330,7 +330,7 @@ class Transaction(DBusObject): + "DebconfSocket", "MetaData", "Locale", + "RemoveObsoleteDepends") + +- def __init__(self, tid, role, queue, pid, uid, cmdline, sender, ++ def __init__(self, tid, role, queue, pid, uid, gid, cmdline, sender, + connect=True, bus=None, packages=None, kwargs=None): + """Initialize a new Transaction instance. + +@@ -365,6 +365,7 @@ class Transaction(DBusObject): + kwargs = {} + self.queue = queue + self.uid = uid ++ self.gid = gid + self.locale = dbus.String("") + self.allow_unauthenticated = dbus.Boolean(False) + self.remove_obsoleted_depends = dbus.Boolean(False) +@@ -1469,11 +1470,12 @@ class AptDaemon(DBusObject): + @inline_callbacks + def _create_trans(self, role, sender, packages=None, kwargs=None): + """Helper method which returns the tid of a new transaction.""" +- pid, uid, cmdline = \ ++ pid, uid, gid, cmdline = \ + yield policykit1.get_proc_info_from_dbus_name(sender, self.bus) + tid = uuid.uuid4().get_hex() +- trans = Transaction(tid, role, self.queue, pid, uid, cmdline, sender, +- packages=packages, kwargs=kwargs, bus=self.bus) ++ trans = Transaction( ++ tid, role, self.queue, pid, uid, gid, cmdline, sender, ++ packages=packages, kwargs=kwargs, bus=self.bus) + self.queue.limbo[trans.tid] = trans + return_value(trans.tid) + +diff --git a/aptdaemon/pkcompat.py b/aptdaemon/pkcompat.py +index 0806201..845c72e 100644 +--- a/aptdaemon/pkcompat.py ++++ b/aptdaemon/pkcompat.py +@@ -408,9 +408,10 @@ class PackageKit(aptdaemon.core.DBusObject): + + @inline_callbacks + def _get_tid(self, sender): +- pid, uid, cmdline = \ ++ pid, uid, gid, cmdline = \ + yield policykit1.get_proc_info_from_dbus_name(sender, self.bus) +- pktrans = PackageKitTransaction(pid, uid, cmdline, self.queue, sender) ++ pktrans = PackageKitTransaction( ++ pid, uid, gid, cmdline, self.queue, sender) + return_value(pktrans.tid) + + # pylint: disable-msg=C0103,C0322 +@@ -531,7 +532,8 @@ class MergedTransaction(aptdaemon.core.Transaction): + def __init__(self, pktrans, role, queue, connect=True, + bus=None, packages=None, kwargs=None): + aptdaemon.core.Transaction.__init__(self, pktrans.tid[1:], role, queue, +- pktrans.pid, pktrans.uid, ++ pktrans.pid, ++ pktrans.uid, pktrans.gid, + pktrans.cmdline, pktrans.sender, + connect, bus, packages, kwargs) + self.pktrans = pktrans +@@ -617,7 +619,7 @@ class PackageKitTransaction(aptdaemon.core.DBusObject): + + """Provides a PackageKit transaction object.""" + +- def __init__(self, pid, uid, cmdline, queue, sender, ++ def __init__(self, pid, uid, gid, cmdline, queue, sender, + connect=True, bus=None): + pklog.info("Initializing PackageKit transaction") + bus_name = None +@@ -643,6 +645,7 @@ class PackageKitTransaction(aptdaemon.core.DBusObject): + self._status = pk_enums.STATUS_SETUP + self._last_package = "" + self.uid = uid ++ self.gid = gid + self.pid = pid + self.cmdline = cmdline + self.role = pk_enums.ROLE_UNKNOWN +diff --git a/aptdaemon/policykit1.py b/aptdaemon/policykit1.py +index 3ecef85..ed45a41 100644 +--- a/aptdaemon/policykit1.py ++++ b/aptdaemon/policykit1.py +@@ -151,11 +151,14 @@ def get_proc_info_from_dbus_name(dbus_name, bus=None): + bus = dbus.SystemBus() + pid = yield get_pid_from_dbus_name(dbus_name, bus) + with open("/proc/%s/status" % pid) as proc: +- values = [v for v in proc.readlines() if v.startswith("Uid:")] ++ lines = proc.readlines() ++ uid_values = [v for v in lines if v.startswith("Uid:")] ++ gid_values = [v for v in lines if v.startswith("Gid:")] + with open("/proc/%s/cmdline" % pid) as cmdline_file: + cmdline = cmdline_file.read() +- uid = int(values[0].split()[1]) +- return_value((pid, uid, cmdline)) ++ uid = int(uid_values[0].split()[1]) ++ gid = int(gid_values[0].split()[1]) ++ return_value((pid, uid, gid, cmdline)) + + + # vim:ts=4:sw=4:et +diff --git a/aptdaemon/worker.py b/aptdaemon/worker.py +index c0f88f2..d41fc17 100644 +--- a/aptdaemon/worker.py ++++ b/aptdaemon/worker.py +@@ -63,6 +63,25 @@ log = logging.getLogger("AptDaemon.Worker") + _ = lambda s: s + + ++@contextlib.contextmanager ++def set_euid_egid(uid, gid): ++ # no need to drop privs ++ if os.getuid() != 0 and os.getgid() != 0: ++ yield ++ return ++ # temporary drop privs ++ os.setegid(gid) ++ old_groups = os.getgroups() ++ os.setgroups([gid]) ++ os.seteuid(uid) ++ try: ++ yield ++ finally: ++ os.seteuid(os.getuid()) ++ os.setegid(os.getgid()) ++ os.setgroups(old_groups) ++ ++ + class AptWorker(GObject.GObject): + + """Worker which processes transactions from the queue.""" +@@ -588,7 +607,7 @@ password %s\n\n""" % (netloc_public + res.path, res.username, res.password)) + log.info("Installing local package file: %s", path) + # Check if the dpkg can be installed at all + trans.status = STATUS_RESOLVING_DEP +- deb = self._check_deb_file(path, force, trans.uid) ++ deb = self._check_deb_file(path, force, trans.uid, trans.gid) + # Check for required changes and apply them before + (install, remove, unauth) = deb.required_changes + self._call_plugins("modify_cache_after") +@@ -1173,7 +1192,7 @@ password %s\n\n""" % (netloc_public + res.path, res.username, res.password)) + + return depends, required_download, required_space, unauthenticated + +- def _check_deb_file(self, path, force, uid): ++ def _check_deb_file(self, path, force, uid, gid): + """Perform some basic checks for the Debian package. + + :param trans: The transaction instance. +@@ -1182,8 +1201,15 @@ password %s\n\n""" % (netloc_public + res.path, res.username, res.password)) + """ + #FIXME: Unblock lintian call + path = path.encode("UTF-8") +- if not os.path.isfile(path): +- raise TransactionFailed(ERROR_UNREADABLE_PACKAGE_FILE, path) ++ # This code runs as root for simulate and simulate requires no ++ # authentication - so we need to ensure we do not leak information ++ # about files here (LP: #1449587, CVE-2015-1323) ++ # ++ # Note that the actual lintian run is also droping privs (real, ++ # not just seteuid) ++ with set_euid_egid(uid, gid): ++ if not os.path.isfile(path): ++ raise TransactionFailed(ERROR_UNREADABLE_PACKAGE_FILE, path) + if not force and os.path.isfile("/usr/bin/lintian"): + tags_dir = os.path.join(apt_pkg.config.find_dir("Dir"), + "usr", "share", "aptdaemon") +@@ -1210,10 +1236,17 @@ password %s\n\n""" % (netloc_public + res.path, res.username, res.password)) + fatal_args = ["/usr/bin/lintian", "--tags-from-file", + tags_fatal_file, "--no-override", path] + for lintian_args in (nonfatal_args, fatal_args): ++ def _perm_drop_privs(): ++ try: ++ os.setgroups([gid]) ++ except OSError: ++ pass ++ os.setgid(gid) ++ os.setuid(uid) + proc = subprocess.Popen(lintian_args, + stderr=subprocess.STDOUT, + stdout=subprocess.PIPE, close_fds=True, +- preexec_fn=lambda: os.setuid(uid)) ++ preexec_fn=_perm_drop_privs) + while proc.poll() is None: + self._iterate_mainloop() + time.sleep(0.05) +diff --git a/tests/test_dbus_type.py b/tests/test_dbus_type.py +index 17f1349..25038c6 100644 +--- a/tests/test_dbus_type.py ++++ b/tests/test_dbus_type.py +@@ -137,7 +137,8 @@ class DBusTypeTest(test.AptDaemonTestCase): + def test_transaction_properties(self): + """Test object properties.""" + trans = core.Transaction(None, enums.ROLE_REMOVE_PACKAGES, None, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), ++ sys.argv[0], + "org.debian.apt.test", bus=self.dbus) + proxy = self.dbus.get_object(core.APTDAEMON_DBUS_INTERFACE, + trans.tid) +@@ -152,7 +153,8 @@ class DBusTypeTest(test.AptDaemonTestCase): + def test_transaction_signals(self): + """Test signal emittion.""" + trans = core.Transaction(None, enums.ROLE_COMMIT_PACKAGES, None, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), ++ sys.argv[0], + "org.debian.apt.test", bus=self.dbus, + packages=[["silly-base"],[],[],[],[],[]]) + proxy = self.dbus.get_object("org.debian.apt", trans.tid) +diff --git a/tests/test_unicodedecoding.py b/tests/test_unicodedecoding.py +index a1735cb..c64107b 100644 +--- a/tests/test_unicodedecoding.py ++++ b/tests/test_unicodedecoding.py +@@ -49,7 +49,8 @@ class TestUnicodeDecoding(AptDaemonTestCase): + self.start_dbus_daemon() + self.dbus = dbus.bus.BusConnection(self.dbus_address) + self.trans = Transaction(None, "role-test", None, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), ++ sys.argv[0], + "org.debian.apt.test", bus=self.dbus) + + def test(self): +diff --git a/tests/test_worker.py b/tests/test_worker.py +index 46b2df8..2ac1f59 100644 +--- a/tests/test_worker.py ++++ b/tests/test_worker.py +@@ -78,7 +78,8 @@ class WorkerTestCase(aptdaemon.test.AptDaemonTestCase): + self.chroot.add_repository("/does/not/exist", copy_list=False) + # Only update the repository from the working snippet + trans = Transaction(None, enums.ROLE_UPDATE_CACHE, +- self.queue, os.getpid(), os.getuid(), sys.argv[0], ++ self.queue, os.getpid(), os.getuid(), ++ os.getgid(), sys.argv[0], + "org.debian.apt.test", bus=self.dbus, + kwargs={"sources_list": "test.list"}) + self.worker.simulate(trans) +@@ -100,8 +101,8 @@ class WorkerTestCase(aptdaemon.test.AptDaemonTestCase): + "silly-base_0.1-0_all.deb")) + # Install the package + trans = Transaction(None, enums.ROLE_UPGRADE_SYSTEM, +- self.queue, os.getpid(), +- os.getuid(), sys.argv[0], ++ self.queue, os.getpid(), os.getgid(), ++ os.getuid(), os.getgid(), sys.argv[0], + "org.debian.apt.test", bus=self.dbus, + kwargs={"safe_mode": False}) + self.worker.simulate(trans) +@@ -131,7 +132,7 @@ class WorkerTestCase(aptdaemon.test.AptDaemonTestCase): + self.chroot.add_test_repository(copy_sig=False) + # Install the package + trans = Transaction(None, enums.ROLE_INSTALL_PACKAGES, self.queue, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), sys.argv[0], + "org.debian.apt.test", bus=self.dbus, + packages=[["silly-base"],[],[],[],[], []]) + self.worker.simulate(trans) +@@ -145,7 +146,7 @@ class WorkerTestCase(aptdaemon.test.AptDaemonTestCase): + + # Allow installation of unauthenticated packages + trans = Transaction(None, enums.ROLE_INSTALL_PACKAGES, self.queue, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), sys.argv[0], + "org.debian.apt.test", bus=self.dbus, + packages=[["silly-base"],[],[],[],[], []]) + trans.allow_unauthenticated = True +@@ -165,7 +166,7 @@ class WorkerTestCase(aptdaemon.test.AptDaemonTestCase): + self.chroot.add_test_repository() + # Install the package + trans = Transaction(None, enums.ROLE_INSTALL_PACKAGES, self.queue, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), sys.argv[0], + "org.debian.apt.test", bus=self.dbus, + packages=[["silly-depend-base"],[],[],[],[], []]) + self.worker.simulate(trans) +@@ -193,7 +194,7 @@ class WorkerTestCase(aptdaemon.test.AptDaemonTestCase): + Architecture: all + Auto-Installed: 1""") + trans = Transaction(None, enums.ROLE_REMOVE_PACKAGES, self.queue, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), sys.argv[0], + "org.debian.apt.test", bus=self.dbus, + packages=[[],[],["silly-depend-base"],[],[],[]]) + trans.remove_obsoleted_depends = True +@@ -217,7 +218,7 @@ Auto-Installed: 1""") + "silly-depend-base_0.1-0_all.deb"]: + self.chroot.install_debfile(os.path.join(REPO_PATH, pkg)) + trans = Transaction(None, enums.ROLE_REMOVE_PACKAGES, self.queue, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), sys.argv[0], + "org.debian.apt.test", bus=self.dbus, + packages=[[],[],["silly-base"],[],[],[]]) + self.worker.simulate(trans) +@@ -238,7 +239,7 @@ Auto-Installed: 1""") + pass + # Don't allow to remove essential packages + trans = Transaction(None, enums.ROLE_REMOVE_PACKAGES, self.queue, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), sys.argv[0], + "org.debian.apt.test", bus=self.dbus, + packages=[[],[],["silly-essential"],[],[],[]]) + self.worker.run(trans) +@@ -255,7 +256,7 @@ Auto-Installed: 1""") + pkg = os.path.join(REPO_PATH, "silly-base_0.1-0update1_all.deb") + self.chroot.install_debfile(pkg) + trans = Transaction(None, enums.ROLE_COMMIT_PACKAGES, self.queue, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), sys.argv[0], + "org.debian.apt.test", bus=self.dbus, + packages=[[],[],[],[],[],["silly-base=0.1-0"]]) + self.worker.run(trans) +@@ -272,7 +273,7 @@ Auto-Installed: 1""") + for pkg in ["silly-base_0.1-0_all.deb", "silly-config_0.1-0_all.deb"]: + self.chroot.install_debfile(os.path.join(REPO_PATH, pkg)) + trans = Transaction(None, enums.ROLE_REMOVE_PACKAGES, self.queue, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), sys.argv[0], + "org.debian.apt.test", bus=self.dbus, + packages=[[],[],[],["silly-config"],[],[]]) + self.worker.run(trans) +@@ -297,7 +298,7 @@ Auto-Installed: 1""") + pkg = os.path.join( + REPO_PATH, "silly-depend-base-lintian-broken_0.1-0_all.deb") + trans = Transaction(None, enums.ROLE_INSTALL_FILE, self.queue, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), sys.argv[0], + "org.debian.apt.test", bus=self.dbus, + kwargs={"path": os.path.join(REPO_PATH, pkg), + "force": False}) +@@ -328,7 +329,7 @@ Auto-Installed: 1""") + """ + pkg = os.path.join(REPO_PATH, "silly-base_0.1-0_all.deb") + trans = Transaction(None, enums.ROLE_INSTALL_FILE, self.queue, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), sys.argv[0], + "org.debian.apt.test", bus=self.dbus, + kwargs={"path": os.path.join(REPO_PATH, pkg), + "force": True}) +@@ -349,7 +350,7 @@ Auto-Installed: 1""") + for pkg in ["silly-base_0.1-0_all.deb", "silly-broken_0.1-0_all.deb"]: + self.chroot.install_debfile(os.path.join(REPO_PATH, pkg), True) + trans = Transaction(None, enums.ROLE_FIX_BROKEN_DEPENDS, self.queue, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), sys.argv[0], + "org.debian.apt.test", bus=self.dbus) + self.worker.simulate(trans) + self.loop.run() +@@ -390,7 +391,7 @@ Auto-Installed: 1""") + return license_key, license_path + self.chroot.add_test_repository() + trans = Transaction(None, enums.ROLE_ADD_LICENSE_KEY, self.queue, +- os.getpid(), os.getuid(), sys.argv[0], ++ os.getpid(), os.getuid(), os.getgid(), sys.argv[0], + "org.debian.apt.test", + kwargs={"pkg_name": "silly-license", + "json_token": "lalelu", diff --git a/debian/patches/series b/debian/patches/series index b359dca..a081711 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1 +1,2 @@ aptd-import-from-keyserver.patch +CVE-2015-1323.patch