def test_context(self):
     """
     Test the context related method.
     """
     output = "output system_u:object_r:svirt_t:s0-s1:c250,c280 test"
     result = utils_selinux.get_context_from_str(string=output)
     self.assertEqual(result, "system_u:object_r:svirt_t:s0-s1:c250,c280")
     result = utils_selinux.get_context_of_file(filename=__file__)
     utils_selinux.set_context_of_file(filename=__file__, context=result)
     utils_selinux.get_context_of_process(pid=1)
 def test_context(self):
     """
     Test the context related method.
     """
     output = "output system_u:object_r:svirt_t:s0-s1:c250,c280 test"
     result = utils_selinux.get_context_from_str(context=output)
     self.assertEqual(result, "system_u:object_r:svirt_t:s0-s1:c250,c280")
     result = utils_selinux.get_context_of_file(filename=__file__)
     utils_selinux.set_context_of_file(filename=__file__, context=result)
     utils_selinux.get_context_of_process(pid=1)
def run(test, params, env):
    """
    Test svirt in adding disk to VM.

    (1).Init variables for test.
    (2).Config qemu conf if need
    (3).Label the VM and disk with proper label.
    (4).Start VM and check the context.
    (5).Destroy VM and check the context.
    """
    # Get general variables.
    status_error = ('yes' == params.get("status_error", 'no'))
    host_sestatus = params.get("svirt_start_destroy_host_selinux", "enforcing")
    # Get variables about seclabel for VM.
    sec_type = params.get("svirt_start_destroy_vm_sec_type", "dynamic")
    sec_model = params.get("svirt_start_destroy_vm_sec_model", "selinux")
    sec_label = params.get("svirt_start_destroy_vm_sec_label", None)
    sec_baselabel = params.get("svirt_start_destroy_vm_sec_baselabel", None)
    security_driver = params.get("security_driver", None)
    security_default_confined = params.get("security_default_confined", None)
    security_require_confined = params.get("security_require_confined", None)
    no_sec_model = 'yes' == params.get("no_sec_model", 'no')
    sec_relabel = params.get("svirt_start_destroy_vm_sec_relabel", "yes")
    sec_dict = {'type': sec_type, 'relabel': sec_relabel}
    sec_dict_list = []

    def _set_sec_model(model):
        """
        Set sec_dict_list base on given sec model type
        """
        sec_dict_copy = sec_dict.copy()
        sec_dict_copy['model'] = model
        if sec_type != "none":
            if sec_type == "dynamic" and sec_baselabel:
                sec_dict_copy['baselabel'] = sec_baselabel
            else:
                sec_dict_copy['label'] = sec_label
        sec_dict_list.append(sec_dict_copy)

    if not no_sec_model:
        if "," in sec_model:
            sec_models = sec_model.split(",")
            for model in sec_models:
                _set_sec_model(model)
        else:
            _set_sec_model(sec_model)
    else:
        sec_dict_list.append(sec_dict)

    logging.debug("sec_dict_list is: %s" % sec_dict_list)
    poweroff_with_destroy = ("destroy" == params.get(
                             "svirt_start_destroy_vm_poweroff", "destroy"))
    # Get variables about VM and get a VM object and VMXML instance.
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
    backup_xml = vmxml.copy()

    # Get varialbles about image.
    img_label = params.get('svirt_start_destroy_disk_label')
    # Backup disk Labels.
    disks = vm.get_disk_devices()
    backup_labels_of_disks = {}
    backup_ownership_of_disks = {}
    for disk in disks.values():
        disk_path = disk['source']
        backup_labels_of_disks[disk_path] = utils_selinux.get_context_of_file(
            filename=disk_path)
        f = os.open(disk_path, 0)
        stat_re = os.fstat(f)
        backup_ownership_of_disks[disk_path] = "%s:%s" % (stat_re.st_uid,
                                                          stat_re.st_gid)
    # Backup selinux of host.
    backup_sestatus = utils_selinux.get_status()

    qemu_conf = utils_config.LibvirtQemuConfig()
    libvirtd = utils_libvirtd.Libvirtd()

    def _resolve_label(label_string):
        labels = label_string.split(":")
        label_type = labels[2]
        if len(labels) == 4:
            label_range = labels[3]
        elif len(labels) > 4:
            label_range = "%s:%s" % (labels[3], labels[4])
        else:
            label_range = None
        return (label_type, label_range)

    def _check_label_equal(label1, label2):
        label1s = label1.split(":")
        label2s = label2.split(":")
        for i in range(len(label1s)):
            if label1s[i] != label2s[i]:
                return False
        return True

    try:
        # Set disk label
        (img_label_type, img_label_range) = _resolve_label(img_label)
        for disk in disks.values():
            disk_path = disk['source']
            dir_path = "%s(/.*)?" % os.path.dirname(disk_path)
            # Using semanage set context persistently
            utils_selinux.set_defcon(context_type=img_label_type,
                                     pathregex=dir_path,
                                     context_range=img_label_range)
            o_r = utils_selinux.verify_defcon(pathname=disk_path,
                                              readonly=False,
                                              forcedesc=True)
            orig_label_type = backup_labels_of_disks[disk_path].split(":")[2]
            if o_r and (orig_label_type != img_label_type):
                raise error.TestFail("change disk label(%s) failed" % img_label_type)
            os.chown(disk_path, 107, 107)

        # Set selinux of host.
        utils_selinux.set_status(host_sestatus)

        # Set qemu conf
        if security_driver:
            qemu_conf.set_string('security_driver', security_driver)
        if security_default_confined:
            qemu_conf.security_default_confined = security_default_confined
        if security_require_confined:
            qemu_conf.security_require_confined = security_require_confined
        if (security_driver or security_default_confined or
                security_require_confined):
            logging.debug("the qemu.conf content is: %s" % qemu_conf)
            libvirtd.restart()

        # Set the context of the VM.
        vmxml.set_seclabel(sec_dict_list)
        vmxml.sync()
        logging.debug("the domain xml is: %s" % vmxml.xmltreefile)

        # restart libvirtd
        libvirtd.restart()

        # Start VM to check the VM is able to access the image or not.
        try:
            vm.start()
            # Start VM successfully.
            # VM with seclabel can access the image with the context.
            if status_error:
                raise error.TestFail("Test succeeded in negative case.")
            # Check the label of VM and image when VM is running.
            vm_context = utils_selinux.get_context_of_process(vm.get_pid())
            if (sec_type == "static") and (not vm_context == sec_label):
                raise error.TestFail("Label of VM is not expected after "
                                     "starting.\n"
                                     "Detail: vm_context=%s, sec_label=%s"
                                     % (vm_context, sec_label))
            disk_context = utils_selinux.get_context_of_file(
                filename=disks.values()[0]['source'])
            if (sec_relabel == "no") and (not disk_context == img_label):
                raise error.TestFail("Label of disk is not expected after VM "
                                     "starting.\n"
                                     "Detail: disk_context=%s, img_label=%s."
                                     % (disk_context, img_label))
            if sec_relabel == "yes" and not no_sec_model:
                vmxml = VMXML.new_from_dumpxml(vm_name)
                imagelabel = vmxml.get_seclabel()[0]['imagelabel']
                # the disk context is 'system_u:object_r:svirt_image_t:s0',
                # when VM started, the MLS/MCS Range will be added automatically.
                # imagelabel turns to be 'system_u:object_r:svirt_image_t:s0:cxx,cxxx'
                # but we shouldn't check the MCS range.
                if not _check_label_equal(disk_context, imagelabel):
                    raise error.TestFail("Label of disk is not relabeled by "
                                         "VM\nDetal: disk_context="
                                         "%s, imagelabel=%s"
                                         % (disk_context, imagelabel))
            # Check the label of disk after VM being destroyed.
            if poweroff_with_destroy:
                vm.destroy(gracefully=False)
            else:
                vm.wait_for_login()
                vm.shutdown()
            img_label_after = utils_selinux.get_context_of_file(
                filename=disks.values()[0]['source'])
            if (not img_label_after == img_label):
                # Bug 547546 - RFE: the security drivers must remember original
                # permissions/labels and restore them after
                # https://bugzilla.redhat.com/show_bug.cgi?id=547546

                err_msg = "Label of disk is not restored in VM shuting down.\n"
                err_msg += "Detail: img_label_after=%s, " % img_label_after
                err_msg += "img_label_before=%s.\n" % img_label
                err_msg += "More info in https://bugzilla.redhat.com/show_bug"
                err_msg += ".cgi?id=547546"
                raise error.TestFail(err_msg)
        except virt_vm.VMStartError, e:
            # Starting VM failed.
            # VM with seclabel can not access the image with the context.
            if not status_error:
                raise error.TestFail("Test failed in positive case."
                                     "error: %s" % e)
    finally:
        # clean up
        for path, label in backup_labels_of_disks.items():
            # Using semanage set context persistently
            dir_path = "%s(/.*)?" % os.path.dirname(path)
            (img_label_type, img_label_range) = _resolve_label(label)
            utils_selinux.set_defcon(context_type=img_label_type,
                                     pathregex=dir_path,
                                     context_range=img_label_range)
            utils_selinux.verify_defcon(pathname=path,
                                        readonly=False,
                                        forcedesc=True)
        for path, label in backup_ownership_of_disks.items():
            label_list = label.split(":")
            os.chown(path, int(label_list[0]), int(label_list[1]))
        backup_xml.sync()
        utils_selinux.set_status(backup_sestatus)
        if (security_driver or security_default_confined or
                security_require_confined):
            qemu_conf.restore()
            libvirtd.restart()
Exemple #4
0
def run(test, params, env):
    """
    Test svirt in adding disk to VM.

    (1).Init variables for test.
    (2).Config qemu conf if need
    (3).Label the VM and disk with proper label.
    (4).Start VM and check the context.
    (5).Destroy VM and check the context.
    """
    # Get general variables.
    status_error = ('yes' == params.get("status_error", 'no'))
    host_sestatus = params.get("svirt_start_destroy_host_selinux", "enforcing")
    # Get variables about seclabel for VM.
    sec_type = params.get("svirt_start_destroy_vm_sec_type", "dynamic")
    sec_model = params.get("svirt_start_destroy_vm_sec_model", "selinux")
    sec_label = params.get("svirt_start_destroy_vm_sec_label", None)
    sec_baselabel = params.get("svirt_start_destroy_vm_sec_baselabel", None)
    security_driver = params.get("security_driver", None)
    security_default_confined = params.get("security_default_confined", None)
    security_require_confined = params.get("security_require_confined", None)
    no_sec_model = 'yes' == params.get("no_sec_model", 'no')
    sec_relabel = params.get("svirt_start_destroy_vm_sec_relabel", "yes")
    sec_dict = {'type': sec_type, 'relabel': sec_relabel}
    sec_dict_list = []

    def _set_sec_model(model):
        """
        Set sec_dict_list base on given sec model type
        """
        sec_dict_copy = sec_dict.copy()
        sec_dict_copy['model'] = model
        if sec_type != "none":
            if sec_type == "dynamic" and sec_baselabel:
                sec_dict_copy['baselabel'] = sec_baselabel
            else:
                sec_dict_copy['label'] = sec_label
        sec_dict_list.append(sec_dict_copy)

    if not no_sec_model:
        if "," in sec_model:
            sec_models = sec_model.split(",")
            for model in sec_models:
                _set_sec_model(model)
        else:
            _set_sec_model(sec_model)
    else:
        sec_dict_list.append(sec_dict)

    logging.debug("sec_dict_list is: %s" % sec_dict_list)
    poweroff_with_destroy = ("destroy" == params.get(
        "svirt_start_destroy_vm_poweroff", "destroy"))
    # Get variables about VM and get a VM object and VMXML instance.
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
    backup_xml = vmxml.copy()

    # Get varialbles about image.
    img_label = params.get('svirt_start_destroy_disk_label')
    # Backup disk Labels.
    disks = vm.get_disk_devices()
    backup_labels_of_disks = {}
    backup_ownership_of_disks = {}
    for disk in disks.values():
        disk_path = disk['source']
        backup_labels_of_disks[disk_path] = utils_selinux.get_context_of_file(
            filename=disk_path)
        f = os.open(disk_path, 0)
        stat_re = os.fstat(f)
        backup_ownership_of_disks[disk_path] = "%s:%s" % (stat_re.st_uid,
                                                          stat_re.st_gid)
    # Backup selinux of host.
    backup_sestatus = utils_selinux.get_status()

    qemu_conf = utils_config.LibvirtQemuConfig()
    libvirtd = utils_libvirtd.Libvirtd()

    def _resolve_label(label_string):
        labels = label_string.split(":")
        label_type = labels[2]
        if len(labels) == 4:
            label_range = labels[3]
        elif len(labels) > 4:
            label_range = "%s:%s" % (labels[3], labels[4])
        else:
            label_range = None
        return (label_type, label_range)

    def _check_label_equal(label1, label2):
        label1s = label1.split(":")
        label2s = label2.split(":")
        for i in range(len(label1s)):
            if label1s[i] != label2s[i]:
                return False
        return True

    try:
        # Set disk label
        (img_label_type, img_label_range) = _resolve_label(img_label)
        for disk in disks.values():
            disk_path = disk['source']
            dir_path = "%s(/.*)?" % os.path.dirname(disk_path)
            # Using semanage set context persistently
            utils_selinux.set_defcon(context_type=img_label_type,
                                     pathregex=dir_path,
                                     context_range=img_label_range)
            o_r = utils_selinux.verify_defcon(pathname=disk_path,
                                              readonly=False,
                                              forcedesc=True)
            orig_label_type = backup_labels_of_disks[disk_path].split(":")[2]
            if o_r and (orig_label_type != img_label_type):
                raise error.TestFail("change disk label(%s) failed" %
                                     img_label_type)
            os.chown(disk_path, 107, 107)

        # Set selinux of host.
        utils_selinux.set_status(host_sestatus)

        # Set qemu conf
        if security_driver:
            qemu_conf.set_string('security_driver', security_driver)
        if security_default_confined:
            qemu_conf.security_default_confined = security_default_confined
        if security_require_confined:
            qemu_conf.security_require_confined = security_require_confined
        if (security_driver or security_default_confined
                or security_require_confined):
            logging.debug("the qemu.conf content is: %s" % qemu_conf)
            libvirtd.restart()

        # Set the context of the VM.
        vmxml.set_seclabel(sec_dict_list)
        vmxml.sync()
        logging.debug("the domain xml is: %s" % vmxml.xmltreefile)

        # restart libvirtd
        libvirtd.restart()

        # Start VM to check the VM is able to access the image or not.
        try:
            vm.start()
            # Start VM successfully.
            # VM with seclabel can access the image with the context.
            if status_error:
                raise error.TestFail("Test succeeded in negative case.")
            # Check the label of VM and image when VM is running.
            vm_context = utils_selinux.get_context_of_process(vm.get_pid())
            if (sec_type == "static") and (not vm_context == sec_label):
                raise error.TestFail("Label of VM is not expected after "
                                     "starting.\n"
                                     "Detail: vm_context=%s, sec_label=%s" %
                                     (vm_context, sec_label))
            disk_context = utils_selinux.get_context_of_file(
                filename=disks.values()[0]['source'])
            if (sec_relabel == "no") and (not disk_context == img_label):
                raise error.TestFail("Label of disk is not expected after VM "
                                     "starting.\n"
                                     "Detail: disk_context=%s, img_label=%s." %
                                     (disk_context, img_label))
            if sec_relabel == "yes" and not no_sec_model:
                vmxml = VMXML.new_from_dumpxml(vm_name)
                imagelabel = vmxml.get_seclabel()[0]['imagelabel']
                # the disk context is 'system_u:object_r:svirt_image_t:s0',
                # when VM started, the MLS/MCS Range will be added automatically.
                # imagelabel turns to be 'system_u:object_r:svirt_image_t:s0:cxx,cxxx'
                # but we shouldn't check the MCS range.
                if not _check_label_equal(disk_context, imagelabel):
                    raise error.TestFail("Label of disk is not relabeled by "
                                         "VM\nDetal: disk_context="
                                         "%s, imagelabel=%s" %
                                         (disk_context, imagelabel))
            # Check the label of disk after VM being destroyed.
            if poweroff_with_destroy:
                vm.destroy(gracefully=False)
            else:
                vm.wait_for_login()
                vm.shutdown()
            img_label_after = utils_selinux.get_context_of_file(
                filename=disks.values()[0]['source'])
            if (not img_label_after == img_label):
                # Bug 547546 - RFE: the security drivers must remember original
                # permissions/labels and restore them after
                # https://bugzilla.redhat.com/show_bug.cgi?id=547546

                err_msg = "Label of disk is not restored in VM shuting down.\n"
                err_msg += "Detail: img_label_after=%s, " % img_label_after
                err_msg += "img_label_before=%s.\n" % img_label
                err_msg += "More info in https://bugzilla.redhat.com/show_bug"
                err_msg += ".cgi?id=547546"
                raise error.TestFail(err_msg)
        except virt_vm.VMStartError, e:
            # Starting VM failed.
            # VM with seclabel can not access the image with the context.
            if not status_error:
                raise error.TestFail("Test failed in positive case."
                                     "error: %s" % e)
    finally:
        # clean up
        for path, label in backup_labels_of_disks.items():
            # Using semanage set context persistently
            dir_path = "%s(/.*)?" % os.path.dirname(path)
            (img_label_type, img_label_range) = _resolve_label(label)
            utils_selinux.set_defcon(context_type=img_label_type,
                                     pathregex=dir_path,
                                     context_range=img_label_range)
            utils_selinux.verify_defcon(pathname=path,
                                        readonly=False,
                                        forcedesc=True)
        for path, label in backup_ownership_of_disks.items():
            label_list = label.split(":")
            os.chown(path, int(label_list[0]), int(label_list[1]))
        backup_xml.sync()
        utils_selinux.set_status(backup_sestatus)
        if (security_driver or security_default_confined
                or security_require_confined):
            qemu_conf.restore()
            libvirtd.restart()
Exemple #5
0
def run(test, params, env):
    """
    This case check error messages in libvirtd logging.

    Implemetent test cases:
    with_iptables:  Simply start libvirtd when using iptables service
                          as firewall.
    with_firewalld: Simply start libvirtd when using firewalld service
                          as firewall.
    """
    def _error_handler(errors, line):
        """
        A callback function called when new error lines appares in libvirtd
        log, then this line is appended to list 'errors'

        :param errors: A list to contain all error lines.
        :param line: Newly found error line in libvirtd log.
        """
        errors.append(line)

    test_type = params.get('test_type')

    old_iptables = None
    old_firewalld = None
    iptables = None
    try:
        # Setup firewall services according to test type.
        if test_type == 'with_firewalld':
            old_iptables, old_firewalld = _set_iptables_firewalld(False, True)
        elif test_type == 'with_iptables':
            old_iptables, old_firewalld = _set_iptables_firewalld(True, False)
        elif test_type == 'stop_iptables':
            # Use _set_iptables_firewalld(False, False) on rhel6 will got skip
            # as firewalld not on rhel6, but the new case which came from bug
            # 716612 is mainly a rhel6 problem and should be tested, so skip
            # using the  _set_iptables_firewalld function and direct stop
            # iptables.
            try:
                utils_misc.find_command('iptables')
                iptables = service.Factory.create_service('iptables')
            except ValueError:
                msg = "Can't find service iptables."
                raise error.TestNAError(msg)

            utils.run('iptables-save > /tmp/iptables.save')
            if not iptables.stop():
                msg = "Can't stop service iptables"
                raise error.TestError(msg)

        try:
            errors = []
            # Run libvirt session and collect errors in log.
            libvirtd_session = LibvirtdSession(
                error_func=_error_handler,
                error_params=(errors,),
            )

            libvirt_pid = libvirtd_session.get_pid()
            libvirt_context = utils_selinux.get_context_of_process(libvirt_pid)
            logging.debug("The libvirtd pid context is: %s" % libvirt_context)

            # Check errors.
            if errors:
                logging.debug("Found errors in libvirt log:")
                for line in errors:
                    logging.debug(line)
                if test_type == 'stop_iptables':
                    for line in errors:
                        # libvirtd process started without virt_t will failed
                        # to set iptable rules which is expected here
                        if ("/sbin/iptables" and
                                "unexpected exit status 1" not in line):
                            raise error.TestFail("Found errors other than"
                                                 " iptables failure in"
                                                 " libvirt log.")
                else:
                    raise error.TestFail("Found errors in libvirt log.")
        finally:
            libvirtd_session.close()
    finally:
        # Recover services status.
        if test_type in ('with_firewalld', 'with_iptables'):
            _set_iptables_firewalld(old_iptables, old_firewalld)
        elif test_type == "stop_iptables" and iptables:
            iptables.start()
            utils.run('iptables-restore < /tmp/iptables.save')
        if os.path.exists("/tmp/iptables.save"):
            os.remove("/tmp/iptables.save")
def run(test, params, env):
    """
    Test svirt in adding disk to VM.

    (1).Init variables for test.
    (2).Label the VM and disk with proper label.
    (3).Start VM and check the context.
    (4).Destroy VM and check the context.
    """
    # Get general variables.
    status_error = ('yes' == params.get("status_error", 'no'))
    host_sestatus = params.get("svirt_start_destroy_host_selinux", "enforcing")
    # Get variables about seclabel for VM.
    sec_type = params.get("svirt_start_destroy_vm_sec_type", "dynamic")
    sec_model = params.get("svirt_start_destroy_vm_sec_model", "selinux")
    sec_label = params.get("svirt_start_destroy_vm_sec_label", None)
    sec_relabel = params.get("svirt_start_destroy_vm_sec_relabel", "yes")
    sec_dict = {
        'type': sec_type,
        'model': sec_model,
        'label': sec_label,
        'relabel': sec_relabel
    }
    # Get variables about VM and get a VM object and VMXML instance.
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
    backup_xml = vmxml.copy()

    # Get varialbles about image.
    img_label = params.get('svirt_start_destroy_disk_label')
    # Label the disks of VM with img_label.
    disks = vm.get_disk_devices()
    backup_labels_of_disks = {}
    for disk in disks.values():
        disk_path = disk['source']
        backup_labels_of_disks[disk_path] = utils_selinux.get_context_of_file(
            filename=disk_path)
        utils_selinux.set_context_of_file(filename=disk_path,
                                          context=img_label)
    # Set selinux of host.
    backup_sestatus = utils_selinux.get_status()
    utils_selinux.set_status(host_sestatus)
    # Set the context of the VM.
    vmxml.set_seclabel(sec_dict)
    vmxml.sync()

    try:
        # Start VM to check the VM is able to access the image or not.
        try:
            vm.start()
            # Start VM successfully.
            # VM with seclabel can access the image with the context.
            if status_error:
                raise error.TestFail("Test successed in negative case.")
            # Check the label of VM and image when VM is running.
            vm_context = utils_selinux.get_context_of_process(vm.get_pid())
            if (sec_type == "static") and (not vm_context == sec_label):
                raise error.TestFail(
                    "Label of VM is not expected after starting.\n"
                    "Detail: vm_context=%s, sec_label=%s" %
                    (vm_context, sec_label))
            disk_context = utils_selinux.get_context_of_file(
                filename=disks.values()[0]['source'])
            if (sec_relabel == "no") and (not disk_context == img_label):
                raise error.TestFail("Label of disk is not expected after VM "
                                     "starting.\n"
                                     "Detail: disk_context=%s, img_label=%s." %
                                     (disk_context, img_label))
            if sec_relabel == "yes":
                vmxml = VMXML.new_from_dumpxml(vm_name)
                imagelabel = vmxml.get_seclabel()['imagelabel']
                if not disk_context == imagelabel:
                    raise error.TestFail(
                        "Label of disk is not relabeled by VM\n"
                        "Detal: disk_context=%s, imagelabel=%s" %
                        (disk_context, imagelabel))
            # Check the label of disk after VM being destroyed.
            vm.destroy()
            img_label_after = utils_selinux.get_context_of_file(
                filename=disks.values()[0]['source'])
            if (not img_label_after == img_label):
                raise error.TestFail(
                    "Bug: Label of disk is not restored in VM "
                    "shuting down.\n"
                    "Detail: img_label_after=%s, "
                    "img_label_before=%s.\n" % (img_label_after, img_label))
        except virt_vm.VMStartError, e:
            # Starting VM failed.
            # VM with seclabel can not access the image with the context.
            if not status_error:
                raise error.TestFail("Test failed in positive case."
                                     "error: %s" % e)
    finally:
        # clean up
        for path, label in backup_labels_of_disks.items():
            utils_selinux.set_context_of_file(filename=path, context=label)
        backup_xml.sync()
        utils_selinux.set_status(backup_sestatus)
Exemple #7
0
def run(test, params, env):
    """
    This case check error messages in libvirtd logging.

    Implemetent test cases:
    with_iptables:  Simply start libvirtd when using iptables service
                          as firewall.
    with_firewalld: Simply start libvirtd when using firewalld service
                          as firewall.
    """
    def _error_handler(errors, line):
        """
        A callback function called when new error lines appares in libvirtd
        log, then this line is appended to list 'errors'

        :param errors: A list to contain all error lines.
        :param line: Newly found error line in libvirtd log.
        """
        errors.append(line)

    test_type = params.get('test_type')

    old_iptables = None
    old_firewalld = None
    iptables = None
    try:
        # Setup firewall services according to test type.
        if test_type == 'with_firewalld':
            old_iptables, old_firewalld = _set_iptables_firewalld(False, True)
        elif test_type == 'with_iptables':
            old_iptables, old_firewalld = _set_iptables_firewalld(True, False)
        elif test_type == 'stop_iptables':
            # Use _set_iptables_firewalld(False, False) on rhel6 will got skip
            # as firewalld not on rhel6, but the new case which came from bug
            # 716612 is mainly a rhel6 problem and should be tested, so skip
            # using the  _set_iptables_firewalld function and direct stop
            # iptables.
            try:
                utils_misc.find_command('iptables')
                iptables = service.Factory.create_service('iptables')
            except ValueError:
                msg = "Can't find service iptables."
                raise error.TestNAError(msg)

            utils.run('iptables-save > /tmp/iptables.save')
            if not iptables.stop():
                msg = "Can't stop service iptables"
                raise error.TestError(msg)

        try:
            errors = []
            # Run libvirt session and collect errors in log.
            libvirtd_session = LibvirtdSession(
                error_func=_error_handler,
                error_params=(errors, ),
            )

            libvirt_pid = libvirtd_session.get_pid()
            libvirt_context = utils_selinux.get_context_of_process(libvirt_pid)
            logging.debug("The libvirtd pid context is: %s" % libvirt_context)

            # Check errors.
            if errors:
                logging.debug("Found errors in libvirt log:")
                for line in errors:
                    logging.debug(line)
                if test_type == 'stop_iptables':
                    for line in errors:
                        # libvirtd process started without virt_t will failed
                        # to set iptable rules which is expected here
                        if ("/sbin/iptables"
                                and "unexpected exit status 1" not in line):
                            raise error.TestFail("Found errors other than"
                                                 " iptables failure in"
                                                 " libvirt log.")
                else:
                    raise error.TestFail("Found errors in libvirt log.")
        finally:
            libvirtd_session.close()
    finally:
        # Recover services status.
        if test_type in ('with_firewalld', 'with_iptables'):
            _set_iptables_firewalld(old_iptables, old_firewalld)
        elif test_type == "stop_iptables" and iptables:
            iptables.start()
            utils.run('iptables-restore < /tmp/iptables.save')
        if os.path.exists("/tmp/iptables.save"):
            os.remove("/tmp/iptables.save")
def run_svirt_start_destroy(test, params, env):
    """
    Test svirt in adding disk to VM.

    (1).Init variables for test.
    (2).Label the VM and disk with proper label.
    (3).Start VM and check the context.
    (4).Destroy VM and check the context.
    """
    # Get general variables.
    status_error = ('yes' == params.get("status_error", 'no'))
    host_sestatus = params.get("svirt_start_destroy_host_selinux", "enforcing")
    # Get variables about seclabel for VM.
    sec_type = params.get("svirt_start_destroy_vm_sec_type", "dynamic")
    sec_model = params.get("svirt_start_destroy_vm_sec_model", "selinux")
    sec_label = params.get("svirt_start_destroy_vm_sec_label", None)
    sec_relabel = params.get("svirt_start_destroy_vm_sec_relabel", "yes")
    sec_dict = {'type': sec_type, 'model': sec_model, 'label': sec_label,
                'relabel': sec_relabel}
    # Get variables about VM and get a VM object and VMXML instance.
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
    backup_xml = vmxml.copy()

    # Get varialbles about image.
    img_label = params.get('svirt_start_destroy_disk_label')
    # Label the disks of VM with img_label.
    disks = vm.get_disk_devices()
    backup_labels_of_disks = {}
    for disk in disks.values():
        disk_path = disk['source']
        backup_labels_of_disks[disk_path] = utils_selinux.get_context_of_file(
            filename=disk_path)
        utils_selinux.set_context_of_file(filename=disk_path,
                                          context=img_label)
    # Set selinux of host.
    backup_sestatus = utils_selinux.get_status()
    utils_selinux.set_status(host_sestatus)
    # Set the context of the VM.
    vmxml.set_seclabel(sec_dict)
    vmxml.sync()

    try:
        # Start VM to check the VM is able to access the image or not.
        try:
            vm.start()
            # Start VM successfully.
            # VM with seclabel can access the image with the context.
            if status_error:
                raise error.TestFail("Test successed in negative case.")
            # Check the label of VM and image when VM is running.
            vm_context = utils_selinux.get_context_of_process(vm.get_pid())
            if (sec_type == "static") and (not vm_context == sec_label):
                raise error.TestFail("Label of VM is not expected after starting.\n"
                                     "Detail: vm_context=%s, sec_label=%s"
                                     % (vm_context, sec_label))
            disk_context = utils_selinux.get_context_of_file(
                filename=disks.values()[0]['source'])
            if (sec_relabel == "no") and (not disk_context == img_label):
                raise error.TestFail("Label of disk is not expected after VM "
                                     "starting.\n"
                                     "Detail: disk_context=%s, img_label=%s."
                                     % (disk_context, img_label))
            if sec_relabel == "yes":
                vmxml = VMXML.new_from_dumpxml(vm_name)
                imagelabel = vmxml.get_seclabel()['imagelabel']
                if not disk_context == imagelabel:
                    raise error.TestFail("Label of disk is not relabeled by VM\n"
                                         "Detal: disk_context=%s, imagelabel=%s"
                                         % (disk_context, imagelabel))
            # Check the label of disk after VM being destroyed.
            vm.destroy()
            img_label_after = utils_selinux.get_context_of_file(
                filename=disks.values()[0]['source'])
            if (not img_label_after == img_label):
                raise error.TestFail("Bug: Label of disk is not restored in VM "
                                     "shuting down.\n"
                                     "Detail: img_label_after=%s, "
                                     "img_label_before=%s.\n"
                                     % (img_label_after, img_label))
        except virt_vm.VMStartError, e:
            # Starting VM failed.
            # VM with seclabel can not access the image with the context.
            if not status_error:
                raise error.TestFail("Test failed in positive case."
                                     "error: %s" % e)
    finally:
        # clean up
        for path, label in backup_labels_of_disks.items():
            utils_selinux.set_context_of_file(filename=path, context=label)
        backup_xml.sync()
        utils_selinux.set_status(backup_sestatus)
def run(test, params, env):
    """
    Test svirt in adding disk to VM.

    (1).Init variables for test.
    (2).Config qemu conf if need
    (3).Label the VM and disk with proper label.
    (4).Start VM and check the context.
    (5).Destroy VM and check the context.
    """
    # Get general variables.
    status_error = ('yes' == params.get("status_error", 'no'))
    host_sestatus = params.get("svirt_start_destroy_host_selinux", "enforcing")
    # Get variables about seclabel for VM.
    sec_type = params.get("svirt_start_destroy_vm_sec_type", "dynamic")
    sec_model = params.get("svirt_start_destroy_vm_sec_model", "selinux")
    sec_label = params.get("svirt_start_destroy_vm_sec_label", None)
    security_driver = params.get("security_driver", None)
    security_default_confined = params.get("security_default_confined", None)
    security_require_confined = params.get("security_require_confined", None)
    no_sec_model = 'yes' == params.get("no_sec_model", 'no')
    sec_relabel = params.get("svirt_start_destroy_vm_sec_relabel", "yes")
    sec_dict = {'type': sec_type, 'relabel': sec_relabel}
    sec_dict_list = []
    if not no_sec_model:
        if "," in sec_model:
            sec_models = sec_model.split(",")
            for model in sec_models:
                sec_dict['model'] = model
                if sec_type != "none":
                    sec_dict['label'] = sec_label
                sec_dict_copy = sec_dict.copy()
                sec_dict_list.append(sec_dict_copy)
        else:
            sec_dict['model'] = sec_model
            if sec_type != "none":
                sec_dict['label'] = sec_label
            sec_dict_list.append(sec_dict)
    else:
        sec_dict_list.append(sec_dict)

    logging.debug("sec_dict_list is: %s" % sec_dict_list)
    poweroff_with_destroy = ("destroy" == params.get(
                             "svirt_start_destroy_vm_poweroff", "destroy"))
    # Get variables about VM and get a VM object and VMXML instance.
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
    backup_xml = vmxml.copy()

    # Get varialbles about image.
    img_label = params.get('svirt_start_destroy_disk_label')
    # Backup disk Labels.
    disks = vm.get_disk_devices()
    backup_labels_of_disks = {}
    backup_ownership_of_disks = {}
    for disk in disks.values():
        disk_path = disk['source']
        backup_labels_of_disks[disk_path] = utils_selinux.get_context_of_file(
            filename=disk_path)
        f = os.open(disk_path, 0)
        stat_re = os.fstat(f)
        backup_ownership_of_disks[disk_path] = "%s:%s" % (stat_re.st_uid,
                                                          stat_re.st_gid)
    # Backup selinux of host.
    backup_sestatus = utils_selinux.get_status()

    qemu_conf = utils_config.LibvirtQemuConfig()
    libvirtd = utils_libvirtd.Libvirtd()
    try:
        # Set disk label
        for disk in disks.values():
            disk_path = disk['source']
            utils_selinux.set_context_of_file(filename=disk_path,
                                              context=img_label)
            os.chown(disk_path, 107, 107)

        # Set selinux of host.
        utils_selinux.set_status(host_sestatus)

        # Set qemu conf
        if security_driver:
            qemu_conf.set_string('security_driver', security_driver)
        if security_default_confined:
            qemu_conf.security_default_confined = security_default_confined
        if security_require_confined:
            qemu_conf.security_require_confined = security_require_confined
        if (security_driver or security_default_confined or
                security_require_confined):
            logging.debug("the qemu.conf content is: %s" % qemu_conf)
            libvirtd.restart()

        # Set the context of the VM.
        vmxml.set_seclabel(sec_dict_list)
        vmxml.sync()
        logging.debug("the domain xml is: %s" % vmxml.xmltreefile)

        # Start VM to check the VM is able to access the image or not.
        try:
            vm.start()
            # Start VM successfully.
            # VM with seclabel can access the image with the context.
            if status_error:
                raise error.TestFail("Test succeeded in negative case.")
            # Check the label of VM and image when VM is running.
            vm_context = utils_selinux.get_context_of_process(vm.get_pid())
            if (sec_type == "static") and (not vm_context == sec_label):
                raise error.TestFail("Label of VM is not expected after "
                                     "starting.\n"
                                     "Detail: vm_context=%s, sec_label=%s"
                                     % (vm_context, sec_label))
            disk_context = utils_selinux.get_context_of_file(
                filename=disks.values()[0]['source'])
            if (sec_relabel == "no") and (not disk_context == img_label):
                raise error.TestFail("Label of disk is not expected after VM "
                                     "starting.\n"
                                     "Detail: disk_context=%s, img_label=%s."
                                     % (disk_context, img_label))
            if sec_relabel == "yes" and not no_sec_model:
                vmxml = VMXML.new_from_dumpxml(vm_name)
                imagelabel = vmxml.get_seclabel()[0]['imagelabel']
                if not disk_context == imagelabel:
                    raise error.TestFail("Label of disk is not relabeled by "
                                         "VM\nDetal: disk_context="
                                         "%s, imagelabel=%s"
                                         % (disk_context, imagelabel))
            # Check the label of disk after VM being destroyed.
            if poweroff_with_destroy:
                vm.destroy(gracefully=False)
            else:
                vm.wait_for_login()
                vm.shutdown()
            img_label_after = utils_selinux.get_context_of_file(
                filename=disks.values()[0]['source'])
            if (not img_label_after == img_label):
                # Bug 547546 - RFE: the security drivers must remember original
                # permissions/labels and restore them after
                # https://bugzilla.redhat.com/show_bug.cgi?id=547546
                err_msg = "Label of disk is not restored in VM shuting down.\n"
                err_msg += "Detail: img_label_after=%s, " % img_label_after
                err_msg += "img_label_before=%s.\n" % img_label
                err_msg += "More info in https://bugzilla.redhat.com/show_bug"
                err_msg += ".cgi?id=547546"
                raise error.TestFail(err_msg)
        except virt_vm.VMStartError, e:
            # Starting VM failed.
            # VM with seclabel can not access the image with the context.
            if not status_error:
                raise error.TestFail("Test failed in positive case."
                                     "error: %s" % e)
    finally:
        # clean up
        for path, label in backup_labels_of_disks.items():
            utils_selinux.set_context_of_file(filename=path, context=label)
        for path, label in backup_ownership_of_disks.items():
            label_list = label.split(":")
            os.chown(path, int(label_list[0]), int(label_list[1]))
        backup_xml.sync()
        utils_selinux.set_status(backup_sestatus)
        if (security_driver or security_default_confined or
                security_require_confined):
            qemu_conf.restore()
            libvirtd.restart()
def run(test, params, env):
    """
    Test svirt in adding disk to VM.

    (1).Init variables for test.
    (2).Config qemu conf if need
    (3).Label the VM and disk with proper label.
    (4).Start VM and check the context.
    (5).Destroy VM and check the context.
    """
    # Get general variables.
    status_error = ('yes' == params.get("status_error", 'no'))
    host_sestatus = params.get("svirt_start_destroy_host_selinux", "enforcing")
    # Get variables about seclabel for VM.
    sec_type = params.get("svirt_start_destroy_vm_sec_type", "dynamic")
    sec_model = params.get("svirt_start_destroy_vm_sec_model", "selinux")
    sec_label = params.get("svirt_start_destroy_vm_sec_label", None)
    sec_baselabel = params.get("svirt_start_destroy_vm_sec_baselabel", None)
    security_driver = params.get("security_driver", None)
    security_default_confined = params.get("security_default_confined", None)
    security_require_confined = params.get("security_require_confined", None)
    no_sec_model = 'yes' == params.get("no_sec_model", 'no')
    xattr_check = 'yes' == params.get("xattr_check", 'no')
    sec_relabel = params.get("svirt_start_destroy_vm_sec_relabel", "yes")
    sec_dict = {'type': sec_type, 'relabel': sec_relabel}
    sec_dict_list = []

    def _set_sec_model(model):
        """
        Set sec_dict_list base on given sec model type
        """
        sec_dict_copy = sec_dict.copy()
        sec_dict_copy['model'] = model
        if sec_type != "none":
            if sec_type == "dynamic" and sec_baselabel:
                sec_dict_copy['baselabel'] = sec_baselabel
            else:
                sec_dict_copy['label'] = sec_label
        sec_dict_list.append(sec_dict_copy)

    if not no_sec_model:
        if "," in sec_model:
            sec_models = sec_model.split(",")
            for model in sec_models:
                _set_sec_model(model)
        else:
            _set_sec_model(sec_model)
    else:
        sec_dict_list.append(sec_dict)

    logging.debug("sec_dict_list is: %s" % sec_dict_list)
    poweroff_with_destroy = ("destroy" == params.get(
        "svirt_start_destroy_vm_poweroff", "destroy"))
    # Get variables about VM and get a VM object and VMXML instance.
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
    backup_xml = vmxml.copy()

    # Get variables about image.
    img_label = params.get('svirt_start_destroy_disk_label')
    # Backup disk Labels.
    disks = vm.get_disk_devices()
    backup_labels_of_disks = {}
    backup_ownership_of_disks = {}
    for disk in list(disks.values()):
        disk_path = disk['source']
        backup_labels_of_disks[disk_path] = utils_selinux.get_context_of_file(
            filename=disk_path)
        stat_re = os.stat(disk_path)
        backup_ownership_of_disks[disk_path] = "%s:%s" % (stat_re.st_uid,
                                                          stat_re.st_gid)
    # Backup selinux of host.
    backup_sestatus = utils_selinux.get_status()

    qemu_conf = utils_config.LibvirtQemuConfig()
    libvirtd = utils_libvirtd.Libvirtd()

    def _resolve_label(label_string):
        labels = label_string.split(":")
        label_type = labels[2]
        if len(labels) == 4:
            label_range = labels[3]
        elif len(labels) > 4:
            label_range = "%s:%s" % (labels[3], labels[4])
        else:
            label_range = None
        return (label_type, label_range)

    def _check_label_equal(label1, label2):
        label1s = label1.split(":")
        label2s = label2.split(":")
        for i in range(len(label1s)):
            if label1s[i] != label2s[i]:
                return False
        return True

    try:
        # Set disk label
        (img_label_type, img_label_range) = _resolve_label(img_label)
        for disk in list(disks.values()):
            disk_path = disk['source']
            dir_path = "%s(/.*)?" % os.path.dirname(disk_path)
            try:
                utils_selinux.del_defcon(img_label_type, pathregex=dir_path)
            except Exception as err:
                logging.debug("Delete label failed: %s", err)
            # Using semanage set context persistently
            utils_selinux.set_defcon(context_type=img_label_type,
                                     pathregex=dir_path,
                                     context_range=img_label_range)
            utils_selinux.verify_defcon(pathname=disk_path,
                                        readonly=False,
                                        forcedesc=True)
            if sec_relabel == "no" and sec_type == 'none':
                os.chown(disk_path, 107, 107)

        # Set selinux of host.
        utils_selinux.set_status(host_sestatus)

        # Set qemu conf
        if security_driver:
            qemu_conf.set_string('security_driver', security_driver)
        if security_default_confined:
            qemu_conf.security_default_confined = security_default_confined
        if security_require_confined:
            qemu_conf.security_require_confined = security_require_confined
        if (security_driver or security_default_confined
                or security_require_confined):
            logging.debug("the qemu.conf content is: %s" % qemu_conf)
            libvirtd.restart()

        # Set the context of the VM.
        vmxml.set_seclabel(sec_dict_list)
        vmxml.sync()
        logging.debug("the domain xml is: %s" % vmxml.xmltreefile)

        # restart libvirtd
        libvirtd.restart()

        # Start VM to check the VM is able to access the image or not.
        try:
            # Need another guest to test the xattr added by libvirt
            if xattr_check:
                blklist = virsh.domblklist(vm_name, debug=True)
                target_disk = re.findall(r"[v,s]d[a-z]",
                                         blklist.stdout.strip())[0]
                guest_name = "%s_%s" % (vm_name, '1')
                cmd = "virt-clone --original %s --name %s " % (vm_name,
                                                               guest_name)
                cmd += "--auto-clone --skip-copy=%s" % target_disk
                process.run(cmd, shell=True, verbose=True)
            vm.start()
            # Start VM successfully.
            # VM with seclabel can access the image with the context.
            if status_error:
                test.fail("Test succeeded in negative case.")
            # Start another vm with the same disk image.
            # The xattr will not be changed.
            if xattr_check:
                virsh.start(guest_name, ignore_status=True, debug=True)
            # Check the label of VM and image when VM is running.
            vm_context = utils_selinux.get_context_of_process(vm.get_pid())
            if (sec_type == "static") and (not vm_context == sec_label):
                test.fail("Label of VM is not expected after "
                          "starting.\n"
                          "Detail: vm_context=%s, sec_label=%s" %
                          (vm_context, sec_label))
            disk_context = utils_selinux.get_context_of_file(
                filename=list(disks.values())[0]['source'])
            if (sec_relabel == "no") and (not disk_context == img_label):
                test.fail("Label of disk is not expected after VM "
                          "starting.\n"
                          "Detail: disk_context=%s, img_label=%s." %
                          (disk_context, img_label))
            if sec_relabel == "yes" and not no_sec_model:
                vmxml = VMXML.new_from_dumpxml(vm_name)
                imagelabel = vmxml.get_seclabel()[0]['imagelabel']
                # the disk context is 'system_u:object_r:svirt_image_t:s0',
                # when VM started, the MLS/MCS Range will be added automatically.
                # imagelabel turns to be 'system_u:object_r:svirt_image_t:s0:cxx,cxxx'
                # but we shouldn't check the MCS range.
                if not _check_label_equal(disk_context, imagelabel):
                    test.fail("Label of disk is not relabeled by "
                              "VM\nDetal: disk_context="
                              "%s, imagelabel=%s" % (disk_context, imagelabel))
                expected_results = "trusted.libvirt.security.ref_dac=\"1\"\n"
                expected_results += "trusted.libvirt.security.ref_selinux=\"1\""
                cmd = "getfattr -m trusted.libvirt.security -d %s " % list(
                    disks.values())[0]['source']
                utils_test.libvirt.check_cmd_output(cmd,
                                                    content=expected_results)

            # Check the label of disk after VM being destroyed.
            if poweroff_with_destroy:
                vm.destroy(gracefully=False)
            else:
                vm.wait_for_login()
                vm.shutdown()
            filename = list(disks.values())[0]['source']
            img_label_after = utils_selinux.get_context_of_file(filename)
            stat_re = os.stat(filename)
            ownership_of_disk = "%s:%s" % (stat_re.st_uid, stat_re.st_gid)
            logging.debug("The ownership of disk after guest starting is:\n")
            logging.debug(ownership_of_disk)
            logging.debug("The ownership of disk before guest starting is:\n")
            logging.debug(backup_ownership_of_disks[filename])
            if not (sec_relabel == "no" and sec_type == 'none'):
                if not libvirt_version.version_compare(5, 6, 0):
                    if img_label_after != img_label:
                        # Bug 547546 - RFE: the security drivers must remember original
                        # permissions/labels and restore them after
                        # https://bugzilla.redhat.com/show_bug.cgi?id=547546
                        err_msg = "Label of disk is not restored in VM shutting down.\n"
                        err_msg += "Detail: img_label_after=%s, " % img_label_after
                        err_msg += "img_label_before=%s.\n" % img_label
                        err_msg += "More info in https://bugzilla.redhat.com/show_bug"
                        err_msg += ".cgi?id=547546"
                        test.fail(err_msg)
                elif (img_label_after != img_label or ownership_of_disk !=
                      backup_ownership_of_disks[filename]):
                    err_msg = "Label of disk is not restored in VM shutting down.\n"
                    err_msg += "Detail: img_label_after=%s, %s " % (
                        img_label_after, ownership_of_disk)
                    err_msg += "img_label_before=%s, %s\n" % (
                        img_label, backup_ownership_of_disks[filename])
                    test.fail(err_msg)
            # The xattr should be cleaned after guest shutoff.
            cmd = "getfattr -m trusted.libvirt.security -d %s " % list(
                disks.values())[0]['source']
            utils_test.libvirt.check_cmd_output(cmd, content="")
        except virt_vm.VMStartError as e:
            # Starting VM failed.
            # VM with seclabel can not access the image with the context.
            if not status_error:
                test.fail("Test failed in positive case." "error: %s" % e)
    finally:
        # clean up
        for path, label in list(backup_labels_of_disks.items()):
            # Using semanage set context persistently
            dir_path = "%s(/.*)?" % os.path.dirname(path)
            (img_label_type, img_label_range) = _resolve_label(label)
            try:
                utils_selinux.del_defcon(img_label_type, pathregex=dir_path)
            except Exception as err:
                logging.debug("Delete label failed: %s", err)
            utils_selinux.set_defcon(context_type=img_label_type,
                                     pathregex=dir_path,
                                     context_range=img_label_range)
            utils_selinux.verify_defcon(pathname=path,
                                        readonly=False,
                                        forcedesc=True)
        for path, label in list(backup_ownership_of_disks.items()):
            label_list = label.split(":")
            os.chown(path, int(label_list[0]), int(label_list[1]))
        backup_xml.sync()
        if xattr_check:
            virsh.undefine(guest_name, ignore_status=True)
        utils_selinux.set_status(backup_sestatus)
        if (security_driver or security_default_confined
                or security_require_confined):
            qemu_conf.restore()
            libvirtd.restart()
Exemple #11
0
def run(test, params, env):
    """
    Test svirt in adding disk to VM.

    (1).Init variables for test.
    (2).Config qemu conf if need
    (3).Label the VM and disk with proper label.
    (4).Start VM and check the context.
    (5).Destroy VM and check the context.
    """
    # Get general variables.
    status_error = ('yes' == params.get("status_error", 'no'))
    host_sestatus = params.get("svirt_start_destroy_host_selinux", "enforcing")
    # Get variables about seclabel for VM.
    sec_type = params.get("svirt_start_destroy_vm_sec_type", "dynamic")
    sec_model = params.get("svirt_start_destroy_vm_sec_model", "selinux")
    sec_label = params.get("svirt_start_destroy_vm_sec_label", None)
    security_driver = params.get("security_driver", None)
    security_default_confined = params.get("security_default_confined", None)
    security_require_confined = params.get("security_require_confined", None)
    no_sec_model = 'yes' == params.get("no_sec_model", 'no')
    sec_relabel = params.get("svirt_start_destroy_vm_sec_relabel", "yes")
    sec_dict = {'type': sec_type, 'relabel': sec_relabel}
    sec_dict_list = []
    if not no_sec_model:
        if "," in sec_model:
            sec_models = sec_model.split(",")
            for model in sec_models:
                sec_dict['model'] = model
                if sec_type != "none":
                    sec_dict['label'] = sec_label
                sec_dict_copy = sec_dict.copy()
                sec_dict_list.append(sec_dict_copy)
        else:
            sec_dict['model'] = sec_model
            if sec_type != "none":
                sec_dict['label'] = sec_label
            sec_dict_list.append(sec_dict)
    else:
        sec_dict_list.append(sec_dict)

    logging.debug("sec_dict_list is: %s" % sec_dict_list)
    poweroff_with_destroy = ("destroy" == params.get(
        "svirt_start_destroy_vm_poweroff", "destroy"))
    # Get variables about VM and get a VM object and VMXML instance.
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    vmxml = VMXML.new_from_inactive_dumpxml(vm_name)
    backup_xml = vmxml.copy()

    # Get varialbles about image.
    img_label = params.get('svirt_start_destroy_disk_label')
    # Backup disk Labels.
    disks = vm.get_disk_devices()
    backup_labels_of_disks = {}
    backup_ownership_of_disks = {}
    for disk in disks.values():
        disk_path = disk['source']
        backup_labels_of_disks[disk_path] = utils_selinux.get_context_of_file(
            filename=disk_path)
        f = os.open(disk_path, 0)
        stat_re = os.fstat(f)
        backup_ownership_of_disks[disk_path] = "%s:%s" % (stat_re.st_uid,
                                                          stat_re.st_gid)
    # Backup selinux of host.
    backup_sestatus = utils_selinux.get_status()

    qemu_conf = utils_config.LibvirtQemuConfig()
    libvirtd = utils_libvirtd.Libvirtd()
    try:
        # Set disk label
        for disk in disks.values():
            disk_path = disk['source']
            utils_selinux.set_context_of_file(filename=disk_path,
                                              context=img_label)
            os.chown(disk_path, 107, 107)

        # Set selinux of host.
        utils_selinux.set_status(host_sestatus)

        # Set qemu conf
        if security_driver:
            qemu_conf.set_string('security_driver', security_driver)
        if security_default_confined:
            qemu_conf.security_default_confined = security_default_confined
        if security_require_confined:
            qemu_conf.security_require_confined = security_require_confined
        if (security_driver or security_default_confined
                or security_require_confined):
            logging.debug("the qemu.conf content is: %s" % qemu_conf)
            libvirtd.restart()

        # Set the context of the VM.
        vmxml.set_seclabel(sec_dict_list)
        vmxml.sync()
        logging.debug("the domain xml is: %s" % vmxml.xmltreefile)

        # Start VM to check the VM is able to access the image or not.
        try:
            vm.start()
            # Start VM successfully.
            # VM with seclabel can access the image with the context.
            if status_error:
                raise error.TestFail("Test succeeded in negative case.")
            # Check the label of VM and image when VM is running.
            vm_context = utils_selinux.get_context_of_process(vm.get_pid())
            if (sec_type == "static") and (not vm_context == sec_label):
                raise error.TestFail("Label of VM is not expected after "
                                     "starting.\n"
                                     "Detail: vm_context=%s, sec_label=%s" %
                                     (vm_context, sec_label))
            disk_context = utils_selinux.get_context_of_file(
                filename=disks.values()[0]['source'])
            if (sec_relabel == "no") and (not disk_context == img_label):
                raise error.TestFail("Label of disk is not expected after VM "
                                     "starting.\n"
                                     "Detail: disk_context=%s, img_label=%s." %
                                     (disk_context, img_label))
            if sec_relabel == "yes" and not no_sec_model:
                vmxml = VMXML.new_from_dumpxml(vm_name)
                imagelabel = vmxml.get_seclabel()[0]['imagelabel']
                if not disk_context == imagelabel:
                    raise error.TestFail("Label of disk is not relabeled by "
                                         "VM\nDetal: disk_context="
                                         "%s, imagelabel=%s" %
                                         (disk_context, imagelabel))
            # Check the label of disk after VM being destroyed.
            if poweroff_with_destroy:
                vm.destroy(gracefully=False)
            else:
                vm.wait_for_login()
                vm.shutdown()
            img_label_after = utils_selinux.get_context_of_file(
                filename=disks.values()[0]['source'])
            if (not img_label_after == img_label):
                # Bug 547546 - RFE: the security drivers must remember original
                # permissions/labels and restore them after
                # https://bugzilla.redhat.com/show_bug.cgi?id=547546
                err_msg = "Label of disk is not restored in VM shuting down.\n"
                err_msg += "Detail: img_label_after=%s, " % img_label_after
                err_msg += "img_label_before=%s.\n" % img_label
                err_msg += "More info in https://bugzilla.redhat.com/show_bug"
                err_msg += ".cgi?id=547546"
                raise error.TestFail(err_msg)
        except virt_vm.VMStartError, e:
            # Starting VM failed.
            # VM with seclabel can not access the image with the context.
            if not status_error:
                raise error.TestFail("Test failed in positive case."
                                     "error: %s" % e)
    finally:
        # clean up
        for path, label in backup_labels_of_disks.items():
            utils_selinux.set_context_of_file(filename=path, context=label)
        for path, label in backup_ownership_of_disks.items():
            label_list = label.split(":")
            os.chown(path, int(label_list[0]), int(label_list[1]))
        backup_xml.sync()
        utils_selinux.set_status(backup_sestatus)
        if (security_driver or security_default_confined
                or security_require_confined):
            qemu_conf.restore()
            libvirtd.restart()
Exemple #12
0
def run(test, params, env):
    """
    This case check error messages in libvirtd logging.

    Implemented test cases:
    with_iptables:  Start libvirtd when using iptables service as firewall.
    with_firewalld: Start libvirtd when using firewalld service as firewall.
    no_firewall:    Start libvirtd With both firewall services shut off.
    """
    def _error_handler(line, errors):
        """
        A callback function called when new error lines appears in libvirtd
        log, then this line is appended to list 'errors'

        :param errors: A list to contain all error lines.
        :param line: Newly found error line in libvirtd log.
        """
        errors.append(line)

    def _check_errors():
        """
        Check for unexpected error messages in libvirtd log.
        """
        logging.info('Checking errors in libvirtd log')
        accepted_error_patterns = [
            'Cannot access storage file',
            'Failed to autostart storage pool',
            'cannot open directory',
        ]

        if (not iptables_service and not firewalld_service
                and 'virt_t' not in libvirt_context):
            logging.info("virt_t is not in libvirtd process context. "
                         "Failures for setting iptables rules will be ignored")
            # libvirtd process started without virt_t will failed to set
            # iptables rules which is expected here
            accepted_error_patterns.append(
                '/sbin/iptables .* unexpected exit status 1')

        logging.debug("Accepted errors are: %s", accepted_error_patterns)

        if errors:
            logging.debug("Found errors in libvirt log:")
            for line in errors:
                logging.debug(line)

            unexpected_errors = []
            for line in errors:
                if any([re.search(p, line) for p in accepted_error_patterns]):
                    logging.debug('Error "%s" is acceptable', line)
                else:
                    unexpected_errors.append(line)
            if unexpected_errors:
                raise exceptions.TestFail(
                    "Found unexpected errors in libvirt log:\n%s" %
                    '\n'.join(unexpected_errors))

    iptables_service = params.get('iptables_service', 'off') == 'on'
    firewalld_service = params.get('firewalld_service', 'off') == 'on'

    # In RHEL7 iptables service is provided by a separated package
    # In RHEL6 iptables-services and firewalld is not supported
    # So try to install all required packages but ignore failures
    logging.info('Preparing firewall related packages')
    software_mgr = software_manager.SoftwareManager()
    for pkg in ['iptables', 'iptables-services', 'firewalld']:
        if not software_mgr.check_installed(pkg):
            software_mgr.install(pkg)

    # Backup services status
    service_mgr = service.ServiceManager()
    logging.info('Backing up firewall services status')
    backup_iptables_status = service_mgr.status('iptables')
    backup_firewalld_status = service_mgr.status('firewalld')

    # iptables-service got deprecated in newer distros
    if iptables_service and backup_iptables_status is None:
        raise exceptions.TestSkipError('iptables service not found')
    # firewalld service could not exists on many distros
    if firewalld_service and backup_firewalld_status is None:
        raise exceptions.TestSkipError('firewalld service not found')
    try:
        if iptables_service and firewalld_service:
            raise exceptions.TestError(
                'iptables service and firewalld service can not be started at '
                'the same time')

        # We should stop services first then start the other after.
        # Directly start one service will force the other service stop,
        # which will not be easy to handle.
        # Backup status should be compared with None to make sure that
        # service exists before action.
        logging.info('Changing firewall services status')
        if not iptables_service and backup_iptables_status is not None:
            process.run('iptables-save > /tmp/iptables.save', shell=True)
            service_mgr.stop('iptables')
        if not firewalld_service and backup_firewalld_status is not None:
            service_mgr.stop('firewalld')

        if iptables_service and backup_iptables_status is not None:
            service_mgr.start('iptables')
        if firewalld_service and backup_firewalld_status is not None:
            service_mgr.start('firewalld')
        errors = []
        # Run libvirt session and collect errors in log.
        libvirtd_session = utils_libvirtd.LibvirtdSession(
            service_name="virtnetworkd",
            logging_handler=_error_handler,
            logging_params=(errors, ),
            logging_pattern=r'[-\d]+ [.:+\d]+ [:\d]+ error :',
        )
        try:
            logging.info('Starting libvirtd session')
            libvirtd_session.start()
            time.sleep(3)

            libvirt_pid = libvirtd_session.tail.get_pid()
            sestatus = utils_selinux.get_status()
            if sestatus == "disabled":
                raise exceptions.TestSkipError("SELinux is in Disabled mode."
                                               "It must be in enforcing mode "
                                               "for test execution")
            libvirt_context = utils_selinux.get_context_of_process(libvirt_pid)
            logging.debug("The libvirtd process context is: %s",
                          libvirt_context)

        finally:
            libvirtd_session.exit()
        _check_errors()
    finally:
        logging.info('Recovering services status')
        #Restart socket service after starting process at foreground
        utils_libvirtd.Libvirtd("virtnetworkd.socket").restart()
        # If service do not exists, then backup status and current status
        # will all be none and nothing will be done
        if service_mgr.status('iptables') != backup_iptables_status:
            if backup_iptables_status:
                service_mgr.start('iptables')
                process.run('iptables-restore < /tmp/iptables.save',
                            shell=True)
            else:
                service_mgr.stop('iptables')
        if service_mgr.status('firewalld') != backup_firewalld_status:
            if backup_firewalld_status:
                service_mgr.start('firewalld')
            else:
                service_mgr.stop('firewalld')

        logging.info('Removing backup iptables')
        if os.path.exists("/tmp/iptables.save"):
            os.remove("/tmp/iptables.save")
Exemple #13
0
def run(test, params, env):
    """
    This case check error messages in libvirtd logging.

    Implemented test cases:
    with_iptables:  Start libvirtd when using iptables service as firewall.
    with_firewalld: Start libvirtd when using firewalld service as firewall.
    no_firewall:    Start libvirtd With both firewall services shut off.
    """
    def _error_handler(line, errors):
        """
        A callback function called when new error lines appares in libvirtd
        log, then this line is appended to list 'errors'

        :param errors: A list to contain all error lines.
        :param line: Newly found error line in libvirtd log.
        """
        errors.append(line)

    def _check_errors():
        """
        Check for unexpected error messages in libvirtd log.
        """
        logging.info('Checking errors in libvirtd log')
        accepted_error_patterns = [
            'Cannot access storage file',
        ]

        if (not iptables_service and not firewalld_service and
                'virt_t' not in libvirt_context):
            logging.info("virt_t is not in libvirtd process context. "
                         "Failures for setting iptables rules will be ignored")
            # libvirtd process started without virt_t will failed to set
            # iptables rules which is expected here
            accepted_error_patterns.append(
                '/sbin/iptables .* unexpected exit status 1')

        logging.debug("Accepted errors are: %s", accepted_error_patterns)

        if errors:
            logging.debug("Found errors in libvirt log:")
            for line in errors:
                logging.debug(line)

            unexpected_errors = []
            for line in errors:
                if any([re.search(p, line)
                        for p in accepted_error_patterns]):
                    logging.debug('Error "%s" is acceptable', line)
                else:
                    unexpected_errors.append(line)
            if unexpected_errors:
                raise exceptions.TestFail(
                    "Found unexpected errors in libvirt log:\n%s" %
                    '\n'.join(unexpected_errors))

    iptables_service = params.get('iptables_service', 'off') == 'on'
    firewalld_service = params.get('firewalld_service', 'off') == 'on'

    # In RHEL7 iptables service is provided by a separated package
    # In RHEL6 iptables-services and firewalld is not supported
    # So try to install all required packages but ignore failures
    logging.info('Preparing firewall related packages')
    software_mgr = software_manager.SoftwareManager()
    for pkg in ['iptables', 'iptables-services', 'firewalld']:
        if not software_mgr.check_installed(pkg):
            software_mgr.install(pkg)

    # Backup services status
    service_mgr = service.ServiceManager()
    logging.info('Backing up firewall services status')
    backup_iptables_status = service_mgr.status('iptables')
    backup_firewalld_status = service_mgr.status('firewalld')

    # iptables service should always exists
    if iptables_service and backup_iptables_status is None:
        raise exceptions.TestError('iptables service not found')
    # firewalld service could not exists on many distros
    if firewalld_service and backup_firewalld_status is None:
        raise exceptions.TestSkipError('firewalld service not found')
    try:
        if iptables_service and firewalld_service:
            raise exceptions.TestError(
                'iptables service and firewalld service can not be started at '
                'the same time')

        # We should stop services first then start the other after.
        # Directly start one service will force the other service stop,
        # which will not be easy to handle.
        # Backup status should be compared with None to make sure that
        # service exists before action.
        logging.info('Changing firewall services status')
        if not iptables_service and backup_iptables_status is not None:
            process.run('iptables-save > /tmp/iptables.save', shell=True)
            service_mgr.stop('iptables')
        if not firewalld_service and backup_firewalld_status is not None:
            service_mgr.stop('firewalld')

        if iptables_service and backup_iptables_status is not None:
            service_mgr.start('iptables')
        if firewalld_service and backup_firewalld_status is not None:
            service_mgr.start('firewalld')
        errors = []
        # Run libvirt session and collect errors in log.
        libvirtd_session = utils_libvirtd.LibvirtdSession(
            logging_handler=_error_handler,
            logging_params=(errors,),
            logging_pattern=r'[-\d]+ [.:+\d]+ [:\d]+ error :',
        )
        try:
            logging.info('Starting libvirtd session')
            libvirtd_session.start()
            time.sleep(3)

            libvirt_pid = libvirtd_session.tail.get_pid()
            libvirt_context = utils_selinux.get_context_of_process(libvirt_pid)
            logging.debug(
                "The libvirtd process context is: %s", libvirt_context)

        finally:
            libvirtd_session.exit()
        _check_errors()
    finally:
        logging.info('Recovering services status')
        # If service do not exists, then backup status and current status
        # will all be none and nothing will be done
        if service_mgr.status('iptables') != backup_iptables_status:
            if backup_iptables_status:
                service_mgr.start('iptables')
                process.run('iptables-restore < /tmp/iptables.save',
                            shell=True)
            else:
                service_mgr.stop('iptables')
        if service_mgr.status('firewalld') != backup_firewalld_status:
            if backup_firewalld_status:
                service_mgr.start('firewalld')
            else:
                service_mgr.stop('firewalld')

        logging.info('Removing backup iptables')
        if os.path.exists("/tmp/iptables.save"):
            os.remove("/tmp/iptables.save")