[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#818007: wheezy-pu: package aptdaemon/0.45-2+deb7u1.debdiff



Package: release.debian.org
Severity: normal
Tags: wheezy
User: release.debian.org@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 <agx@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?= <agx@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

Reply to: