def test_limit_rss(): # This should fail to allocate about 100 MiB. script = "s = 100 * 1024**2 * 'x'" cmd = ["python", "-c", script] cmd = cmdutils.prlimit(cmd, address_space=100 * 1024**2) rc, out, err = commands.execCmd(cmd, raw=True) assert rc == 1 assert b"MemoryError" in err
def test_limit_rss(): # This should fail to allocate about 100 MiB. script = "s = 100 * 1024**2 * 'x'" cmd = ["python", "-c", script] cmd = cmdutils.prlimit(cmd, address_space=100 * MiB) with pytest.raises(cmdutils.Error) as e: commands.run(cmd) assert e.value.rc == 1 assert b"MemoryError" in e.value.err
def info(image, format=None, unsafe=False, trusted_image=True, backing_chain=False): cmd = [_qemuimg.cmd, "info", "--output", "json"] if format: cmd.extend(("-f", format)) if unsafe: cmd.append('-U') if backing_chain: cmd.append('--backing-chain') cmd.append(image) if not trusted_image: # NOQA (long urls) # # Turns out qemu image parser is not hardened against malicious input # and can be abused to allocate an arbitrary amount of memory and/or # dump a lot of information when used with "--output=json". # # These values were recommended by Daniel P. Berrange in: # http://lists.nongnu.org/archive/html/qemu-block/2018-07/msg00488.html # # Richard W.M. Jones adds more info here: # http://lists.nongnu.org/archive/html/qemu-block/2018-07/msg00547.html # # The 30 seconds cpu_time value came from this bug: # https://bugs.launchpad.net/nova/+bug/1705340 # Showing qemu-img info take more then 8 seconds with 120G snapshot. # # TODO: It does not make sense that qemu-img will need 30 seconds of # cpu time for reading valid image qcow2 header, or checking the size # of a raw image. Investigate why we need these values. cmd = cmdutils.prlimit(cmd, cpu_time=30, address_space=GiB) out = _run_cmd(cmd) try: info = _parse_qemuimg_json(out, list if backing_chain else dict) except ValueError as e: raise InvalidOutput( cmd, out, "Failed to process qemu-img output: %s" % e) chain = info if backing_chain else [info] for node in chain: for key in ("virtual-size", "format"): if key not in node: raise InvalidOutput(cmd, out, "Missing field: %r" % key) return info
def test_limit_cpu(): # This takes 6 seconds on i7-5600U CPU @ 2.60GHz. We assume that it will # never take less then 1 second. Increase n if this starts to fail # randomly. script = """ n = 2**27 while n: n -= 1 """ cmd = ["python", "-c", script] cmd = cmdutils.prlimit(cmd, cpu_time=1) rc, out, err = commands.execCmd(cmd, raw=True) assert rc == -9
def test_limit_cpu(): # This takes 6 seconds on i7-5600U CPU @ 2.60GHz. We assume that it will # never take less then 1 second. Increase n if this starts to fail # randomly. script = """ n = 2**27 while n: n -= 1 """ cmd = ["python", "-c", script] cmd = cmdutils.prlimit(cmd, cpu_time=1) with pytest.raises(cmdutils.Error) as e: commands.run(cmd) assert e.value.rc == -9
def info(image, format=None, unsafe=False, trusted_image=True): cmd = [_qemuimg.cmd, "info", "--output", "json"] if format: cmd.extend(("-f", format)) if unsafe: cmd.append('-U') cmd.append(image) if not trusted_image: # NOQA (long urls) # # Turns out qemu image parser is not hardened against malicious input # and can be abused to allocate an arbitrary amount of memory and/or # dump a lot of information when used with "--output=json". # # These values were recommended by Daniel P. Berrange in: # http://lists.nongnu.org/archive/html/qemu-block/2018-07/msg00488.html # # Richard W.M. Jones adds more info here: # http://lists.nongnu.org/archive/html/qemu-block/2018-07/msg00547.html # # The 30 seconds cpu_time value came from this bug: # https://bugs.launchpad.net/nova/+bug/1705340 # Showing qemu-img info take more then 8 seconds with 120G snapshot. # # TODO: It does not make sense that qemu-img will need 30 seconds of # cpu time for reading valid image qcow2 header, or checking the size # of a raw image. Investigate why we need these values. cmd = cmdutils.prlimit(cmd, cpu_time=30, address_space=GiB) out = _run_cmd(cmd) try: qemu_info = _parse_qemuimg_json(out) except ValueError: raise InvalidOutput(cmd, out, "Failed to process qemu-img output") try: info = { 'format': qemu_info['format'], 'virtualsize': qemu_info['virtual-size'], } except KeyError as key: raise InvalidOutput(cmd, out, "Missing field: %r" % key) # In qemu-img info, actual-size means: # File storage: the number of allocated blocks multiplied by # the block size 512. # Block storage: always 0 # This behavior isn't documented - # https://bugzilla.redhat.com/1578259 if 'actual-size' in qemu_info: info['actualsize'] = qemu_info['actual-size'] if 'cluster-size' in qemu_info: info['clustersize'] = qemu_info['cluster-size'] if 'backing-filename' in qemu_info: info['backingfile'] = qemu_info['backing-filename'] if qemu_info['format'] == FORMAT.QCOW2: specific_data = qemu_info['format-specific']['data'] try: info['compat'] = specific_data['compat'] except KeyError: raise InvalidOutput(cmd, out, "'compat' expected but not found") if 'bitmaps' in specific_data: info['bitmaps'] = specific_data['bitmaps'] return info
def test_true(): # true should succeed with these limits. cmd = cmdutils.prlimit(["true"], address_space=100 * 1024**2, cpu_time=1) rc, out, err = commands.execCmd(cmd, raw=True) assert rc == 0
def test_true(): # true should succeed with these limits. cmd = cmdutils.prlimit(["true"], address_space=100 * MiB, cpu_time=1) assert commands.run(cmd) == b''
def info(image, format=None, unsafe=False, trusted_image=True): cmd = [_qemuimg.cmd, "info", "--output", "json"] if format: cmd.extend(("-f", format)) if unsafe: cmd.append('-U') cmd.append(image) if not trusted_image: # NOQA (long urls) # # Turns out qemu image parser is not hardened against malicious input # and can be abused to allocate an arbitrary amount of memory and/or # dump a lot of information when used with "--output=json". # # These values were recommended by Daniel P. Berrange in: # http://lists.nongnu.org/archive/html/qemu-block/2018-07/msg00488.html # # Richard W.M. Jones adds more info here: # http://lists.nongnu.org/archive/html/qemu-block/2018-07/msg00547.html # # The 30 seconds cpu_time value came from this bug: # https://bugs.launchpad.net/nova/+bug/1705340 # Showing qemu-img info take more then 8 seconds with 120G snapshot. # # TODO: It does not make sense that qemu-img will need 30 seconds of # cpu time for reading valid image qcow2 header, or checking the size # of a raw image. Investigate why we need these values. cmd = cmdutils.prlimit(cmd, cpu_time=30, address_space=1024**3) out = _run_cmd(cmd) try: qemu_info = _parse_qemuimg_json(out) except ValueError: raise InvalidOutput(cmd, out, "Failed to process qemu-img output") try: info = { 'format': qemu_info['format'], 'virtualsize': qemu_info['virtual-size'], } except KeyError as key: raise InvalidOutput(cmd, out, "Missing field: %r" % key) # In qemu-img info, actual-size means: # File storage: the number of allocated blocks multiplied by # the block size 512. # Block storage: always 0 # This behavior isn't documented - # https://bugzilla.redhat.com/1578259 if 'actual-size' in qemu_info: info['actualsize'] = qemu_info['actual-size'] if 'cluster-size' in qemu_info: info['clustersize'] = qemu_info['cluster-size'] if 'backing-filename' in qemu_info: info['backingfile'] = qemu_info['backing-filename'] if qemu_info['format'] == FORMAT.QCOW2: try: info['compat'] = qemu_info['format-specific']['data']['compat'] except KeyError: raise InvalidOutput(cmd, out, "'compat' expected but not found") return info