Browse Source

Limit maximum length of kernelopts property

Theoretically libvirt/libxl should reject too long values anyway, but
lets provide early feedback and reject value that would cause VM start
fail later.

Reported by @DemiMarie
Marek Marczykowski-Górecki 3 years ago
parent
commit
a0f82a2a93
2 changed files with 19 additions and 4 deletions
  1. 2 4
      qubes/tests/vm/qubesvm.py
  2. 17 0
      qubes/vm/qubesvm.py

+ 2 - 4
qubes/tests/vm/qubesvm.py

@@ -540,10 +540,8 @@ class TC_90_QubesVM(QubesVMTestsMixin, qubes.tests.QubesTestCase):
         del vm.kernelopts
         self.assertPropertyDefaultValue(vm, 'kernelopts',
             qubes.config.defaults['kernelopts'])
-        self.assertPropertyValue(vm, 'kernelopts', '',
-            '', '')
-        # TODO?
-        # self.assertPropertyInvalidValue(vm, 'kernelopts', None),
+        self.assertPropertyValue(vm, 'kernelopts', '', '', '')
+        self.assertPropertyInvalidValue(vm, 'kernelopts', 'A' * 1024),
 
     @unittest.skip('test not implemented')
     def test_261_kernelopts_pcidevs(self):

+ 17 - 0
qubes/vm/qubesvm.py

@@ -71,6 +71,22 @@ def _setter_kernel(self, prop, value):
     return value
 
 
+def _setter_kernelopts(self, prop, value):
+    """Helper for setting the domain kernelopts and running sanity checks on it.
+    """
+    if not value:
+        return ''
+    value = str(value)
+    # At least some parts of the Xen boot ABI limits the cmdline to 1024 chars.
+    # Limit it here to 512 chars, to leave some space for kernelopts_common
+    # and still be safe also against off-by-one errors.
+    if len(value) > 512:
+        raise qubes.exc.QubesPropertyValueError(
+            self, prop, value,
+            'Kernelopts value too long (512 chars max)')
+    return value
+
+
 def _setter_positive_int(self, prop, value):
     """ Helper for setting a positive int. Checks that the int is > 0 """
     # pylint: disable=unused-argument
@@ -635,6 +651,7 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
     kernelopts = qubes.property(
         'kernelopts', type=str, load_stage=4,
         default=_default_kernelopts,
+        setter=_setter_kernelopts,
         doc='Kernel command line passed to domain. TemplateBasedVMs use its '
             'template\'s value by default.')