Browse Source

Limit memory & CPU when running qemu-img info

It was found that a modified or corrupted image file can cause a DoS
on the host when getting image info with qemu-img.

This uses the newer 'prlimit' parameter for oslo.concurrency execute
to set an address space limit of 1GB and CPU time limit of 2 seconds
when running the qemu-img info command.

Change-Id: If5b7129b266ef065642bc7898ce9dcf93722a053
Closes-bug: #1449062
(cherry picked from commit 78f17f0ad7)
Sean McGinnis 2 years ago
parent
commit
8547444775

+ 5
- 1
cinder/image/image_utils.py View File

@@ -54,6 +54,9 @@ image_helper_opts = [cfg.StrOpt('image_conversion_dir',
54 54
 CONF = cfg.CONF
55 55
 CONF.register_opts(image_helper_opts)
56 56
 
57
+QEMU_IMG_LIMITS = processutils.ProcessLimits(
58
+    cpu_time=2,
59
+    address_space=1 * units.Gi)
57 60
 
58 61
 # NOTE(abhishekk): qemu-img convert command supports raw, qcow2, qed,
59 62
 # vdi, vmdk, vhd and vhdx disk-formats but glance doesn't support qed
@@ -71,7 +74,8 @@ def qemu_img_info(path, run_as_root=True):
71 74
     cmd = ('env', 'LC_ALL=C', 'qemu-img', 'info', path)
72 75
     if os.name == 'nt':
73 76
         cmd = cmd[2:]
74
-    out, _err = utils.execute(*cmd, run_as_root=run_as_root)
77
+    out, _err = utils.execute(*cmd, run_as_root=run_as_root,
78
+                              prlimit=QEMU_IMG_LIMITS)
75 79
     return imageutils.QemuImgInfo(out)
76 80
 
77 81
 

+ 6
- 3
cinder/tests/unit/test_image_utils.py View File

@@ -39,7 +39,8 @@ class TestQemuImgInfo(test.TestCase):
39 39
 
40 40
         output = image_utils.qemu_img_info(test_path)
41 41
         mock_exec.assert_called_once_with('env', 'LC_ALL=C', 'qemu-img',
42
-                                          'info', test_path, run_as_root=True)
42
+                                          'info', test_path, run_as_root=True,
43
+                                          prlimit=image_utils.QEMU_IMG_LIMITS)
43 44
         self.assertEqual(mock_info.return_value, output)
44 45
 
45 46
     @mock.patch('oslo_utils.imageutils.QemuImgInfo')
@@ -52,7 +53,8 @@ class TestQemuImgInfo(test.TestCase):
52 53
 
53 54
         output = image_utils.qemu_img_info(test_path, run_as_root=False)
54 55
         mock_exec.assert_called_once_with('env', 'LC_ALL=C', 'qemu-img',
55
-                                          'info', test_path, run_as_root=False)
56
+                                          'info', test_path, run_as_root=False,
57
+                                          prlimit=image_utils.QEMU_IMG_LIMITS)
56 58
         self.assertEqual(mock_info.return_value, output)
57 59
 
58 60
     @mock.patch('cinder.image.image_utils.os')
@@ -67,7 +69,8 @@ class TestQemuImgInfo(test.TestCase):
67 69
 
68 70
         output = image_utils.qemu_img_info(test_path)
69 71
         mock_exec.assert_called_once_with('qemu-img', 'info', test_path,
70
-                                          run_as_root=True)
72
+                                          run_as_root=True,
73
+                                          prlimit=image_utils.QEMU_IMG_LIMITS)
71 74
         self.assertEqual(mock_info.return_value, output)
72 75
 
73 76
     @mock.patch('cinder.utils.execute')

+ 7
- 0
releasenotes/notes/apply-limits-to-qemu-img-29f722a1bf4b91f8.yaml View File

@@ -0,0 +1,7 @@
1
+---
2
+security:
3
+  - The qemu-img tool now has resource limits applied
4
+    which prevent it from using more than 1GB of address
5
+    space or more than 2 seconds of CPU time. This provides
6
+    protection against denial of service attacks from
7
+    maliciously crafted or corrupted disk images.

Loading…
Cancel
Save