diff -Nru walinuxagent-2.2.32/debian/changelog walinuxagent-2.2.32/debian/changelog --- walinuxagent-2.2.32/debian/changelog 2018-10-29 08:13:23.000000000 +0000 +++ walinuxagent-2.2.32/debian/changelog 2019-03-11 12:39:32.000000000 +0000 @@ -1,3 +1,10 @@ +walinuxagent (2.2.32-0ubuntu1~18.04.2) bionic-security; urgency=medium + + * debian/patches/CVE-2019-0804.patch: + - Cherry-pick fixes from upstream for handling swap file. + + -- Ɓukasz 'sil2100' Zemczak Mon, 11 Mar 2019 13:39:32 +0100 + walinuxagent (2.2.32-0ubuntu1~18.04.1) bionic; urgency=medium * Backport of the disco version. diff -Nru walinuxagent-2.2.32/debian/patches/CVE-2019-0804.patch walinuxagent-2.2.32/debian/patches/CVE-2019-0804.patch --- walinuxagent-2.2.32/debian/patches/CVE-2019-0804.patch 1970-01-01 00:00:00.000000000 +0000 +++ walinuxagent-2.2.32/debian/patches/CVE-2019-0804.patch 2019-03-11 12:39:32.000000000 +0000 @@ -0,0 +1,135 @@ +Description: Add fixes for handling swap file + This is a cherry-pick of 4 fixes from upstream. +Author: mbearup + +--- +diff --git a/azurelinuxagent/daemon/resourcedisk/default.py b/azurelinuxagent/daemon/resourcedisk/default.py +index 0f0925d..43761ab 100644 +--- a/azurelinuxagent/daemon/resourcedisk/default.py ++++ b/azurelinuxagent/daemon/resourcedisk/default.py +@@ -16,6 +16,7 @@ + # + + import os ++import stat + import re + import sys + import threading +@@ -245,16 +246,27 @@ def get_mount_string(mount_options, partition, mount_point): + else: + return 'mount {0} {1}'.format(partition, mount_point) + ++ @staticmethod ++ def check_existing_swap_file(swapfile, swaplist, size): ++ if swapfile in swaplist and os.path.isfile(swapfile) and os.path.getsize(swapfile) == size: ++ logger.info("Swap already enabled") ++ # restrict access to owner (remove all access from group, others) ++ swapfile_mode = os.stat(swapfile).st_mode ++ if swapfile_mode & (stat.S_IRWXG | stat.S_IRWXO): ++ swapfile_mode = swapfile_mode & ~(stat.S_IRWXG | stat.S_IRWXO) ++ logger.info("Changing mode of {0} to {1:o}".format(swapfile, swapfile_mode)) ++ os.chmod(swapfile, swapfile_mode) ++ return True ++ ++ return False ++ + def create_swap_space(self, mount_point, size_mb): + size_kb = size_mb * 1024 + size = size_kb * 1024 + swapfile = os.path.join(mount_point, 'swapfile') + swaplist = shellutil.run_get_output("swapon -s")[1] + +- if swapfile in swaplist \ +- and os.path.isfile(swapfile) \ +- and os.path.getsize(swapfile) == size: +- logger.info("Swap already enabled") ++ if self.check_existing_swap_file(swapfile, swaplist, size): + return + + if os.path.isfile(swapfile) and os.path.getsize(swapfile) != size: +@@ -305,13 +317,18 @@ def mkfile(self, filename, nbytes): + # Probable errors: + # - OSError: Seen on Cygwin, libc notimpl? + # - AttributeError: What if someone runs this under... ++ fd = None ++ + try: +- with open(filename, 'w') as f: +- os.posix_fallocate(f.fileno(), 0, nbytes) +- return 0 ++ fd = os.open(filename, os.O_CREAT | os.O_WRONLY | os.O_EXCL, stat.S_IRUSR | stat.S_IWUSR) ++ os.posix_fallocate(fd, 0, nbytes) ++ return 0 + except: + # Not confident with this thing, just keep trying... + pass ++ finally: ++ if fd is not None: ++ os.close(fd) + + # fallocate command + ret = shellutil.run( +diff --git a/tests/distro/test_resourceDisk.py b/tests/distro/test_resourceDisk.py +index d2ce6e1..753dc84 100644 +--- a/tests/distro/test_resourceDisk.py ++++ b/tests/distro/test_resourceDisk.py +@@ -19,6 +19,7 @@ + # http://msdn.microsoft.com/en-us/library/cc227259%28PROT.13%29.aspx + + import sys ++import stat + from azurelinuxagent.common.utils import shellutil + from azurelinuxagent.daemon.resourcedisk import get_resourcedisk_handler + from tests.tools import * +@@ -38,6 +39,10 @@ def test_mkfile(self): + # assert + assert os.path.exists(test_file) + ++ # only the owner should have access ++ mode = os.stat(test_file).st_mode & (stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) ++ assert mode == stat.S_IRUSR | stat.S_IWUSR ++ + # cleanup + os.remove(test_file) + +@@ -83,7 +88,6 @@ def test_mkfile_xfs_fs(self): + assert run_patch.call_count == 1 + assert "dd if" in run_patch.call_args_list[0][0][0] + +- + def test_change_partition_type(self): + resource_handler = get_resourcedisk_handler() + # test when sfdisk --part-type does not exist +@@ -105,6 +109,32 @@ def test_change_partition_type(self): + assert run_patch.call_count == 1 + assert "sfdisk --part-type" in run_patch.call_args_list[0][0][0] + ++ def test_check_existing_swap_file(self): ++ test_file = os.path.join(self.tmp_dir, 'test_swap_file') ++ file_size = 1024 * 128 ++ if os.path.exists(test_file): ++ os.remove(test_file) ++ ++ with open(test_file, "wb") as file: ++ file.write(bytes(file_size)) ++ ++ os.chmod(test_file, stat.S_ISUID | stat.S_ISGID | stat.S_IRUSR | stat.S_IWUSR | stat.S_IRWXG | stat.S_IRWXO) # 0o6677 ++ ++ def swap_on(_): # mimic the output of "swapon -s" ++ return [ ++ "Filename Type Size Used Priority", ++ "{0} partition 16498684 0 -2".format(test_file) ++ ] ++ ++ with patch.object(shellutil, "run_get_output", side_effect=swap_on): ++ get_resourcedisk_handler().check_existing_swap_file(test_file, test_file, file_size) ++ ++ # it should remove access from group, others ++ mode = os.stat(test_file).st_mode & (stat.S_ISUID | stat.S_ISGID | stat.S_IRWXU | stat.S_IWUSR | stat.S_IRWXG | stat.S_IRWXO) # 0o6777 ++ assert mode == stat.S_ISUID | stat.S_ISGID | stat.S_IRUSR | stat.S_IWUSR # 0o6600 ++ ++ os.remove(test_file) ++ + + if __name__ == '__main__': + unittest.main() diff -Nru walinuxagent-2.2.32/debian/patches/series walinuxagent-2.2.32/debian/patches/series --- walinuxagent-2.2.32/debian/patches/series 2018-10-29 08:13:23.000000000 +0000 +++ walinuxagent-2.2.32/debian/patches/series 2019-03-11 12:39:32.000000000 +0000 @@ -1,2 +1,3 @@ disable_import_test.patch disable_udev_overrides.patch +CVE-2019-0804.patch