[libvirt] [PATCH v4 0/5] Apparmor support for less common devices

So far users added manual rules for most of these uncommon devices, but recent changes made some of the callbacks mandatory for hotplug so we should take shot at implementing them as those callbacks as well as for the initial start of a guest via virt-aa-helper. *Updates since v1* - Set(Memory|Input)Label: remove seclabel check already done in reload_profile - virt-aa-helper: check pointers before accessing them - add tests for new virt-aa-helper supported xml elements - extend tests to check for expected content (new patch in series) *Updates since v2* - Restore(Memory|Input)Label: drop secdef/relabel check - Set(Memory|Input)Label: check more pointers to be valid before using them *Updates since v3* - added the Acked-by of Jamie Strandboge on patches 1-4 - reuse the already existing tmpdir in virt-aa-helper-test for better cleanup Christian Ehrhardt (5): security, apparmor: add (Set|Restore)MemoryLabel security, apparmor: add (Set|Restore)InputLabel virt-aa-helper: generate rules for passthrough input devices virt-aa-helper: generate rules for nvdimm memory virt-aa-helper: test: check for expected profile content src/security/security_apparmor.c | 94 ++++++++++++++++++++++++++++++++++++++++ src/security/virt-aa-helper.c | 16 +++++++ tests/virt-aa-helper-test | 87 ++++++++++++++++++++++--------------- 3 files changed, 163 insertions(+), 34 deletions(-) -- 2.7.4

Recent changes have made implementing this mandatory to hot add any memory. Implementing this in apparmor fixes this as well as allows hot-add of nvdimm tpye memory with an nvdimmPath set generating a AppArmor rule for that path. Example hot adding: <memory model='nvdimm'> <source> <path>/tmp/nvdimm-test</path> </source> <target> <size unit='KiB'>524288</size> <node>0</node> </target> </memory> Creates now: "/tmp/nvdimm-test" rwk, Fixes: https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/1755153 Acked-by: Jamie Strandboge <jamie@canonical.com> Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> --- src/security/security_apparmor.c | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c index a989992..18908c8 100644 --- a/src/security/security_apparmor.c +++ b/src/security/security_apparmor.c @@ -718,6 +718,49 @@ AppArmorRestoreSecurityDiskLabel(virSecurityManagerPtr mgr, /* Called when hotplugging */ static int +AppArmorSetMemoryLabel(virSecurityManagerPtr mgr, + virDomainDefPtr def, + virDomainMemoryDefPtr mem) +{ + if (mem == NULL) + return 0; + + switch ((virDomainMemoryModel) mem->model) { + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + if (mem->nvdimmPath == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("%s: nvdimm without a path"), + __func__); + return -1; + } + if (!virFileExists(mem->nvdimmPath)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("%s: \'%s\' does not exist"), + __func__, mem->nvdimmPath); + return -1; + } + return reload_profile(mgr, def, mem->nvdimmPath, true); + break; + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + break; + } + + return 0; +} + + +static int +AppArmorRestoreMemoryLabel(virSecurityManagerPtr mgr, + virDomainDefPtr def, + virDomainMemoryDefPtr mem ATTRIBUTE_UNUSED) +{ + return reload_profile(mgr, def, NULL, false); +} + +/* Called when hotplugging */ +static int AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr, virDomainDefPtr def, virStorageSourcePtr src) @@ -1115,6 +1158,9 @@ virSecurityDriver virAppArmorSecurityDriver = { .domainSetSecurityImageLabel = AppArmorSetSecurityImageLabel, .domainRestoreSecurityImageLabel = AppArmorRestoreSecurityImageLabel, + .domainSetSecurityMemoryLabel = AppArmorSetMemoryLabel, + .domainRestoreSecurityMemoryLabel = AppArmorRestoreMemoryLabel, + .domainSetSecurityDaemonSocketLabel = AppArmorSetSecurityDaemonSocketLabel, .domainSetSecuritySocketLabel = AppArmorSetSecuritySocketLabel, .domainClearSecuritySocketLabel = AppArmorClearSecuritySocketLabel, -- 2.7.4

d8116b5a "security: Introduce functions for input device hot(un)plug" implemented the code (Set|Restore)InputLabel for several security modules, this patch adds an AppArmor implementation for it as well. That fixes hot-plugging event input devices by generating a rule for the path that needs to be accessed. Example hot adding: <input type='passthrough' bus='virtio'> <source evdev='/dev/input/event0' /> </input> Creates now: "/dev/input/event0" rwk, Fixes: https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/1755153 Acked-by: Jamie Strandboge <jamie@canonical.com> Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> --- src/security/security_apparmor.c | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c index 18908c8..92acc9e 100644 --- a/src/security/security_apparmor.c +++ b/src/security/security_apparmor.c @@ -761,6 +761,51 @@ AppArmorRestoreMemoryLabel(virSecurityManagerPtr mgr, /* Called when hotplugging */ static int +AppArmorSetInputLabel(virSecurityManagerPtr mgr, + virDomainDefPtr def, + virDomainInputDefPtr input) +{ + if (input == NULL) + return 0; + + switch ((virDomainInputType) input->type) { + case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH: + if (input->source.evdev == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("%s: passthrough input device has no source"), + __func__); + return -1; + } + if (!virFileExists(input->source.evdev)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("%s: \'%s\' does not exist"), + __func__, input->source.evdev); + return -1; + } + return reload_profile(mgr, def, input->source.evdev, true); + break; + + case VIR_DOMAIN_INPUT_TYPE_MOUSE: + case VIR_DOMAIN_INPUT_TYPE_TABLET: + case VIR_DOMAIN_INPUT_TYPE_KBD: + case VIR_DOMAIN_INPUT_TYPE_LAST: + break; + } + + return 0; +} + + +static int +AppArmorRestoreInputLabel(virSecurityManagerPtr mgr, + virDomainDefPtr def, + virDomainInputDefPtr input ATTRIBUTE_UNUSED) +{ + return reload_profile(mgr, def, NULL, false); +} + +/* Called when hotplugging */ +static int AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr, virDomainDefPtr def, virStorageSourcePtr src) @@ -1161,6 +1206,9 @@ virSecurityDriver virAppArmorSecurityDriver = { .domainSetSecurityMemoryLabel = AppArmorSetMemoryLabel, .domainRestoreSecurityMemoryLabel = AppArmorRestoreMemoryLabel, + .domainSetSecurityInputLabel = AppArmorSetInputLabel, + .domainRestoreSecurityInputLabel = AppArmorRestoreInputLabel, + .domainSetSecurityDaemonSocketLabel = AppArmorSetSecurityDaemonSocketLabel, .domainSetSecuritySocketLabel = AppArmorSetSecuritySocketLabel, .domainClearSecuritySocketLabel = AppArmorClearSecuritySocketLabel, -- 2.7.4

Input devices can passthrough an event device. This currently works only via hotplug where the AppArmor label is created via the domain label callbacks. This adds the virt-aa-helper support for passthrough input devices to generate rules for the needed paths from the initial guest definition as well. Example in domain xml: <input type='passthrough' bus='virtio'> <source evdev='/dev/input/event0' /> </input> Works to start now and creates: "/dev/input/event0" rw, Fixes: https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/1757085 Acked-by: Jamie Strandboge <jamie@canonical.com> Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> --- src/security/virt-aa-helper.c | 8 ++++++++ tests/virt-aa-helper-test | 3 +++ 2 files changed, 11 insertions(+) diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index 456cfce..ad1371d 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -1157,6 +1157,14 @@ get_files(vahControl * ctl) } } + for (i = 0; i < ctl->def->ninputs; i++) { + if (ctl->def->inputs[i] && + ctl->def->inputs[i]->type == VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH) { + if (vah_add_file(&buf, ctl->def->inputs[i]->source.evdev, "rw") != 0) + goto cleanup; + } + } + for (i = 0; i < ctl->def->nnets; i++) { if (ctl->def->nets[i] && ctl->def->nets[i]->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER && diff --git a/tests/virt-aa-helper-test b/tests/virt-aa-helper-test index 1e96b8e..054269c 100755 --- a/tests/virt-aa-helper-test +++ b/tests/virt-aa-helper-test @@ -359,6 +359,9 @@ testme "0" "hugepages" "-r -u $valid_uuid -F /run/hugepages/kvm/\*\*" "$test_xml sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,<graphics.*>,<graphics type='vnc' socket='/var/lib/libvirt/qemu/myself.vnc'><listen type='address' address='0.0.0.0'/></graphics>,g" "$template_xml" > "$test_xml" testme "0" "vnc socket" "-r -u $valid_uuid" "$test_xml" +sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<input type='passthrough' bus='virtio'><source evdev='$disk2' /></input></devices>,g" "$template_xml" > "$test_xml" +testme "0" "input dev passthrough" "-r -u $valid_uuid" "$test_xml" + testme "0" "help" "-h" echo "" >$output -- 2.7.4

nvdimm memory is backed by a path on the host. This currently works only via hotplug where the AppArmor label is created via the domain label callbacks. This adds the virt-aa-helper support for nvdimm memory devices to generate rules for the needed paths from the initial guest definition as well. Example in domain xml: <memory model='nvdimm'> <source> <path>/tmp/nvdimm-base</path> </source> <target> <size unit='KiB'>524288</size> <node>0</node> </target> </memory> Works to start now and creates: "/tmp/nvdimm-base" rw, Fixes: https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/1757085 Acked-by: Jamie Strandboge <jamie@canonical.com> Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> --- src/security/virt-aa-helper.c | 8 ++++++++ tests/virt-aa-helper-test | 3 +++ 2 files changed, 11 insertions(+) diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index ad1371d..a1bc109 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -1177,6 +1177,14 @@ get_files(vahControl * ctl) } } + for (i = 0; i < ctl->def->nmems; i++) { + if (ctl->def->mems[i] && + ctl->def->mems[i]->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM) { + if (vah_add_file(&buf, ctl->def->mems[i]->nvdimmPath, "rw") != 0) + goto cleanup; + } + } + if (ctl->def->virtType == VIR_DOMAIN_VIRT_KVM) { for (i = 0; i < ctl->def->nnets; i++) { virDomainNetDefPtr net = ctl->def->nets[i]; diff --git a/tests/virt-aa-helper-test b/tests/virt-aa-helper-test index 054269c..7c839e4 100755 --- a/tests/virt-aa-helper-test +++ b/tests/virt-aa-helper-test @@ -362,6 +362,9 @@ testme "0" "vnc socket" "-r -u $valid_uuid" "$test_xml" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<input type='passthrough' bus='virtio'><source evdev='$disk2' /></input></devices>,g" "$template_xml" > "$test_xml" testme "0" "input dev passthrough" "-r -u $valid_uuid" "$test_xml" +sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,<memory>524288</memory>,<memory>1048576</memory>,g" -e "s,</devices>,<memory model='nvdimm'><source><path>$disk2</path></source><target><size unit='KiB'>524288</size><node>0</node></target></memory></devices>,g" "$template_xml" > "$test_xml" +testme "0" "nvdimm" "-r -u $valid_uuid" "$test_xml" + testme "0" "help" "-h" echo "" >$output -- 2.7.4

So far the virt-aa-helper tests only checked the return code and thereby catched aborts like issues failing to parse the XML. But there is one category of virt-aa-helper issues so far untested - not generating the expected rule. This adds a basic grep based checks after each test to match against the rule that is expected to be added by the test. Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> --- tests/virt-aa-helper-test | 85 +++++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/tests/virt-aa-helper-test b/tests/virt-aa-helper-test index 7c839e4..fb40057 100755 --- a/tests/virt-aa-helper-test +++ b/tests/virt-aa-helper-test @@ -108,6 +108,9 @@ testme() { outstr="$2" args="$3" input="" + checkrule="$5" + + tmpout="$tmpdir/checkrule.out" if [ -n "$4" ]; then input="$4" @@ -127,13 +130,23 @@ testme() { echo "': " >$output set +e if [ -n "$input" ]; then - LD_LIBRARY_PATH="$ld_library_path" $exe $extra_args $args < $input >$output 2>&1 + LD_LIBRARY_PATH="$ld_library_path" $exe $extra_args $args < $input >"$tmpout" 2>&1 else - LD_LIBRARY_PATH="$ld_library_path" $exe $extra_args $args >$output 2>&1 + LD_LIBRARY_PATH="$ld_library_path" $exe $extra_args $args >"$tmpout" 2>&1 fi rc="$?" + cat "$tmpout" >"$output" + + rule_missing=0 + if [ -n "$checkrule" ]; then + if ! grep -q "$checkrule" "$tmpout"; then + echo "FAIL: missing rule '$checkrule'" >"$output" + rule_missing=1 + fi + fi + set -e - if [ "$rc" = "$expected" ]; then + if [ "$rc" = "$expected" ] && [ $rule_missing -eq 0 ]; then echo "pass" >$output else echo "FAIL: exited with '$rc'" >$output @@ -234,19 +247,19 @@ testme "1" "-c with invalid domain name char *" "-c -u $valid_uuid" "$test_xml" echo "Expected pass:" >$output sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" "$template_xml" > "$test_xml" -testme "0" "create (x86_64)" "-c -u $valid_uuid" "$test_xml" +testme "0" "create (x86_64)" "-c -u $valid_uuid" "$test_xml" "$disk1.*rwk,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,arch='x86_64',arch='i686',g" "$template_xml" > "$test_xml" -testme "0" "create (i686)" "-c -u $valid_uuid" "$test_xml" +testme "0" "create (i686)" "-c -u $valid_uuid" "$test_xml" "$disk1.*rwk,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,arch='x86_64',arch='ppc',g" "$template_xml" > "$test_xml" -testme "0" "create (ppc)" "-c -u $valid_uuid" "$test_xml" +testme "0" "create (ppc)" "-c -u $valid_uuid" "$test_xml" "$disk1.*rwk,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</disk>,</disk><disk type='file' device='disk'><driver name='qemu' type='raw'/><source file='$disk2'/><target dev='hdb' bus='ide'/></disk>,g" "$template_xml" > "$test_xml" -testme "0" "create multiple disks" "-c -u $valid_uuid" "$test_xml" +testme "0" "create multiple disks" "-c -u $valid_uuid" "$test_xml" "$disk1.*rwk,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###',${disk1}'/><readonly,g" "$template_xml" > "$test_xml" -testme "0" "create (readonly)" "-c -u $valid_uuid" "$test_xml" +testme "0" "create (readonly)" "-c -u $valid_uuid" "$test_xml" "$disk1.*rk,$" if [ "$test_hostdev" = "yes" ]; then sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</disk>,</disk><hostdev mode='subsystem' type='usb'><source><address bus='002' device='004'/></source></hostdev>,g" "$template_xml" > "$test_xml" @@ -257,73 +270,73 @@ if [ "$test_hostdev" = "yes" ]; then fi sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$nonexistent,g" "$template_xml" > "$test_xml" -testme "0" "create (non-existent disk)" "-c -u $valid_uuid" "$test_xml" +testme "0" "create (non-existent disk)" "-c -u $valid_uuid" "$test_xml" "$nonexistent.*rwk,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$relative_disk1,g" "$template_xml" > "$test_xml" -testme "0" "create (relative path)" "-c -u $valid_uuid" "$test_xml" +testme "0" "create (relative path)" "-c -u $valid_uuid" "$test_xml" "$disk1.*rwk,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk2,g" "$template_xml" > "$test_xml" -testme "0" "replace" "-r -u $valid_uuid" "$test_xml" +testme "0" "replace" "-r -u $valid_uuid" "$test_xml" "$disk2.*rwk,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$nonexistent,g" "$template_xml" > "$test_xml" -testme "0" "replace (non-existent disk)" "-r -u $valid_uuid" "$test_xml" +testme "0" "replace (non-existent disk)" "-r -u $valid_uuid" "$test_xml" "$nonexistent.*rwk,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" "$template_xml" > "$test_xml" -testme "0" "replace (adding disk)" "-r -u $valid_uuid -f $disk2" "$test_xml" +testme "0" "replace (adding disk)" "-r -u $valid_uuid -f $disk2" "$test_xml" "$disk2.*rwk,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" "$template_xml" > "$test_xml" -testme "0" "replace (adding non-existent disk)" "-r -u $valid_uuid -f $nonexistent" "$test_xml" +testme "0" "replace (adding non-existent disk)" "-r -u $valid_uuid -f $nonexistent" "$test_xml" "$nonexistent.*rwk,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" "$template_xml" > "$test_xml" -testme "0" "replace (appending disk)" "-r -u $valid_uuid -F $disk2" "$test_xml" +testme "0" "replace (appending disk)" "-r -u $valid_uuid -F $disk2" "$test_xml" "$disk2.*rwk,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" "$template_xml" > "$test_xml" -testme "0" "replace (appending non-existent disk)" "-r -u $valid_uuid -F $nonexistent" "$test_xml" +testme "0" "replace (appending non-existent disk)" "-r -u $valid_uuid -F $nonexistent" "$test_xml" "$nonexistent.*rwk,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<disk type='block' device='cdrom'><target dev='hdc' bus='ide'/><readonly/></disk></devices>,g" "$template_xml" > "$test_xml" testme "0" "disk (empty cdrom)" "-r -u $valid_uuid" "$test_xml" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<serial type='file'><source path='$tmpdir/serial.log'/><target port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" -testme "0" "serial" "-r -u $valid_uuid" "$test_xml" +testme "0" "serial" "-r -u $valid_uuid" "$test_xml" "$tmpdir/serial.log.*rw,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<serial type='pty'><target port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" testme "0" "serial (pty)" "-r -u $valid_uuid" "$test_xml" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<serial type='dev'><source path='/dev/ttyS0'/><target port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" -testme "0" "serial (dev)" "-r -u $valid_uuid" "$test_xml" +testme "0" "serial (dev)" "-r -u $valid_uuid" "$test_xml" "/dev/ttyS0.*rw,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<serial type='pipe'><source path='$tmpdir/serial.pipe'/><target port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" -mkfifo "$tmpdir/serial.pipe.in" "$tmpdir/serial.pipe.out" +mkfifo "$tmpdir/serial.pipe.in" "$tmpdir/serial.pipe.out" "$tmpdir/serial.pipe.in.*rw,$" testme "0" "serial (pipe)" "-r -u $valid_uuid" "$test_xml" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<console type='file'><source path='$tmpdir/console.log'/><target port='0'/></console></devices>,g" "$template_xml" > "$test_xml" touch "$tmpdir/console.log" -testme "0" "console" "-r -u $valid_uuid" "$test_xml" +testme "0" "console" "-r -u $valid_uuid" "$test_xml" "$tmpdir/console.log.*rw,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<console type='pty'><target port='0'/></console></devices>,g" "$template_xml" > "$test_xml" testme "0" "console (pty)" "-r -u $valid_uuid" "$test_xml" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<console type='pipe'><source path='$tmpdir/console.pipe'/><target port='0'/></console></devices>,g" "$template_xml" > "$test_xml" mkfifo "$tmpdir/console.pipe.in" "$tmpdir/console.pipe.out" -testme "0" "console (pipe)" "-r -u $valid_uuid" "$test_xml" +testme "0" "console (pipe)" "-r -u $valid_uuid" "$test_xml" "$tmpdir/console.pipe.out.*rw,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<parallel type='pty'><source path='/dev/pts/0'/><target port='0'/></parallel></devices>,g" "$template_xml" > "$test_xml" -testme "0" "parallel (pty)" "-r -u $valid_uuid" "$test_xml" +testme "0" "parallel (pty)" "-r -u $valid_uuid" "$test_xml" "/dev/pts/0.*rw,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<parallel type='pipe'><source path='$tmpdir/parallel.pipe'/><target port='0'/></parallel></devices>,g" "$template_xml" > "$test_xml" mkfifo "$tmpdir/parallel.pipe.in" "$tmpdir/parallel.pipe.out" -testme "0" "parallel (pipe)" "-r -u $valid_uuid" "$test_xml" +testme "0" "parallel (pipe)" "-r -u $valid_uuid" "$test_xml" "$tmpdir/parallel.pipe.in.*rw,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<channel type='unix'><source mode='bind' path='$tmpdir/guestfwd'/><target type='guestfwd' address='10.0.2.1' port='4600'/></channel></devices>,g" "$template_xml" > "$test_xml" touch "$tmpdir/guestfwd" -testme "0" "channel (unix)" "-r -u $valid_uuid" "$test_xml" +testme "0" "channel (unix)" "-r -u $valid_uuid" "$test_xml" "$tmpdir/guestfwd.*rw,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<channel type='pty'><target type='virtio'/></channel></devices>,g" "$template_xml" > "$test_xml" testme "0" "channel (pty)" "-r -u $valid_uuid" "$test_xml" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</os>,<kernel>$tmpdir/kernel</kernel></os>,g" "$template_xml" > "$test_xml" touch "$tmpdir/kernel" -testme "0" "kernel" "-r -u $valid_uuid" "$test_xml" +testme "0" "kernel" "-r -u $valid_uuid" "$test_xml" "$tmpdir/kernel.*r,$" testfw "ovmf (old path)" "/usr/share/ovmf/OVMF.fd" testfw "OVMF (new path)" "/usr/share/OVMF/OVMF_CODE.fd" @@ -333,37 +346,37 @@ testfw "qemu-efi" "/usr/share/qemu-efi/QEMU_EFI.fd" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</os>,<initrd>$tmpdir/initrd</initrd></os>,g" "$template_xml" > "$test_xml" touch "$tmpdir/initrd" -testme "0" "initrd" "-r -u $valid_uuid" "$test_xml" +testme "0" "initrd" "-r -u $valid_uuid" "$test_xml" "$tmpdir/initrd.*r,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</os>,<kernel>/boot/kernel</kernel></os>,g" "$template_xml" > "$test_xml" -testme "0" "kernel in /boot" "-r -u $valid_uuid" "$test_xml" +testme "0" "kernel in /boot" "-r -u $valid_uuid" "$test_xml" "/boot/kernel.*r,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</os>,<initrd>/boot/initrd</initrd></os>,g" "$template_xml" > "$test_xml" -testme "0" "initrd in /boot" "-r -u $valid_uuid" "$test_xml" +testme "0" "initrd in /boot" "-r -u $valid_uuid" "$test_xml" "/boot/initrd.*r,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</os>,<kernel>/vmlinuz</kernel></os>,g" "$template_xml" > "$test_xml" -testme "0" "kernel is /vmlinuz" "-r -u $valid_uuid" "$test_xml" +testme "0" "kernel is /vmlinuz" "-r -u $valid_uuid" "$test_xml" "/vmlinuz.*r,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</os>,<initrd>/initrd/ramdisk</initrd></os>,g" "$template_xml" > "$test_xml" -testme "0" "initrd is /initrd/ramdisk" "-r -u $valid_uuid" "$test_xml" +testme "0" "initrd is /initrd/ramdisk" "-r -u $valid_uuid" "$test_xml" "/initrd/ramdisk.*r,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</os>,<initrd>/initrd.img</initrd></os>,g" "$template_xml" > "$test_xml" -testme "0" "initrd is /initrd.img" "-r -u $valid_uuid" "$test_xml" +testme "0" "initrd is /initrd.img" "-r -u $valid_uuid" "$test_xml" "/initrd.img.*r,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,<graphics*,<graphics type='sdl' display=':0.0' xauth='/home/myself/.Xauthority'/>,g" "$template_xml" > "$test_xml" -testme "0" "sdl Xauthority" "-r -u $valid_uuid" "$test_xml" +testme "0" "sdl Xauthority" "-r -u $valid_uuid" "$test_xml" "/home/myself/.Xauthority.*r,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" "$template_xml" > "$test_xml" -testme "0" "hugepages" "-r -u $valid_uuid -F /run/hugepages/kvm/\*\*" "$test_xml" +testme "0" "hugepages" "-r -u $valid_uuid -F /run/hugepages/kvm/\*\*" "$test_xml" "/run/hugepages/kvm/.*rwk,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,<graphics.*>,<graphics type='vnc' socket='/var/lib/libvirt/qemu/myself.vnc'><listen type='address' address='0.0.0.0'/></graphics>,g" "$template_xml" > "$test_xml" -testme "0" "vnc socket" "-r -u $valid_uuid" "$test_xml" +testme "0" "vnc socket" "-r -u $valid_uuid" "$test_xml" "/var/lib/libvirt/qemu/myself.vnc.*rw,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<input type='passthrough' bus='virtio'><source evdev='$disk2' /></input></devices>,g" "$template_xml" > "$test_xml" -testme "0" "input dev passthrough" "-r -u $valid_uuid" "$test_xml" +testme "0" "input dev passthrough" "-r -u $valid_uuid" "$test_xml" "$disk2.*rw,$" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,<memory>524288</memory>,<memory>1048576</memory>,g" -e "s,</devices>,<memory model='nvdimm'><source><path>$disk2</path></source><target><size unit='KiB'>524288</size><node>0</node></target></memory></devices>,g" "$template_xml" > "$test_xml" -testme "0" "nvdimm" "-r -u $valid_uuid" "$test_xml" +testme "0" "nvdimm" "-r -u $valid_uuid" "$test_xml" "$disk2.*rw,$" testme "0" "help" "-h" -- 2.7.4

On Wed, 2018-03-21 at 22:22 +0100, Christian Ehrhardt wrote: > So far the virt-aa-helper tests only checked the return code and > thereby > catched aborts like issues failing to parse the XML. But there is one > category of virt-aa-helper issues so far untested - not generating > the > expected rule. > > This adds a basic grep based checks after each test to match against > the > rule that is expected to be added by the test. > > Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> > --- > tests/virt-aa-helper-test | 85 +++++++++++++++++++++++++++-------- > ------------ > 1 file changed, 49 insertions(+), 36 deletions(-) > > diff --git a/tests/virt-aa-helper-test b/tests/virt-aa-helper-test > index 7c839e4..fb40057 100755 > --- a/tests/virt-aa-helper-test > +++ b/tests/virt-aa-helper-test > @@ -108,6 +108,9 @@ testme() { > outstr="$2" > args="$3" > input="" > + checkrule="$5" > + > + tmpout="$tmpdir/checkrule.out" > > if [ -n "$4" ]; then > input="$4" > @@ -127,13 +130,23 @@ testme() { > echo "': " >$output > set +e > if [ -n "$input" ]; then > - LD_LIBRARY_PATH="$ld_library_path" $exe $extra_args $args < > $input >$output 2>&1 > + LD_LIBRARY_PATH="$ld_library_path" $exe $extra_args $args < > $input >"$tmpout" 2>&1 > else > - LD_LIBRARY_PATH="$ld_library_path" $exe $extra_args $args > >$output 2>&1 > + LD_LIBRARY_PATH="$ld_library_path" $exe $extra_args $args > >"$tmpout" 2>&1 > fi > rc="$?" > + cat "$tmpout" >"$output" Thanks for the reminder in the previous email on how $output works and why this is ok. > + > + rule_missing=0 > + if [ -n "$checkrule" ]; then > + if ! grep -q "$checkrule" "$tmpout"; then > + echo "FAIL: missing rule '$checkrule'" >"$output" > + rule_missing=1 > + fi > + fi > + > set -e > - if [ "$rc" = "$expected" ]; then > + if [ "$rc" = "$expected" ] && [ $rule_missing -eq 0 ]; then > echo "pass" >$output > else > echo "FAIL: exited with '$rc'" >$output > @@ -234,19 +247,19 @@ testme "1" "-c with invalid domain name char *" > "-c -u $valid_uuid" "$test_xml" > > echo "Expected pass:" >$output > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" > "$template_xml" > "$test_xml" > -testme "0" "create (x86_64)" "-c -u $valid_uuid" "$test_xml" > +testme "0" "create (x86_64)" "-c -u $valid_uuid" "$test_xml" > "$disk1.*rwk,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,arch='x86_64',arch='i686',g" "$template_xml" > "$test_xml" > -testme "0" "create (i686)" "-c -u $valid_uuid" "$test_xml" > +testme "0" "create (i686)" "-c -u $valid_uuid" "$test_xml" > "$disk1.*rwk,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,arch='x86_64',arch='ppc',g" "$template_xml" > "$test_xml" > -testme "0" "create (ppc)" "-c -u $valid_uuid" "$test_xml" > +testme "0" "create (ppc)" "-c -u $valid_uuid" "$test_xml" > "$disk1.*rwk,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</disk>,</disk><disk type='file' device='disk'><driver name='qemu' > type='raw'/><source file='$disk2'/><target dev='hdb' > bus='ide'/></disk>,g" "$template_xml" > "$test_xml" > -testme "0" "create multiple disks" "-c -u $valid_uuid" "$test_xml" > +testme "0" "create multiple disks" "-c -u $valid_uuid" "$test_xml" > "$disk1.*rwk,$" > > sed -e "s,###UUID###,$uuid,g" -e > "s,###DISK###',${disk1}'/><readonly,g" "$template_xml" > "$test_xml" > -testme "0" "create (readonly)" "-c -u $valid_uuid" "$test_xml" > +testme "0" "create (readonly)" "-c -u $valid_uuid" "$test_xml" > "$disk1.*rk,$" > > if [ "$test_hostdev" = "yes" ]; then > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</disk>,</disk><hostdev mode='subsystem' > type='usb'><source><address bus='002' > device='004'/></source></hostdev>,g" "$template_xml" > "$test_xml" > @@ -257,73 +270,73 @@ if [ "$test_hostdev" = "yes" ]; then > fi > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$nonexistent,g" > "$template_xml" > "$test_xml" > -testme "0" "create (non-existent disk)" "-c -u $valid_uuid" > "$test_xml" > +testme "0" "create (non-existent disk)" "-c -u $valid_uuid" > "$test_xml" "$nonexistent.*rwk,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$relative_disk1,g" > "$template_xml" > "$test_xml" > -testme "0" "create (relative path)" "-c -u $valid_uuid" "$test_xml" > +testme "0" "create (relative path)" "-c -u $valid_uuid" "$test_xml" > "$disk1.*rwk,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk2,g" > "$template_xml" > "$test_xml" > -testme "0" "replace" "-r -u $valid_uuid" "$test_xml" > +testme "0" "replace" "-r -u $valid_uuid" "$test_xml" "$disk2.*rwk,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$nonexistent,g" > "$template_xml" > "$test_xml" > -testme "0" "replace (non-existent disk)" "-r -u $valid_uuid" > "$test_xml" > +testme "0" "replace (non-existent disk)" "-r -u $valid_uuid" > "$test_xml" "$nonexistent.*rwk,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" > "$template_xml" > "$test_xml" > -testme "0" "replace (adding disk)" "-r -u $valid_uuid -f $disk2" > "$test_xml" > +testme "0" "replace (adding disk)" "-r -u $valid_uuid -f $disk2" > "$test_xml" "$disk2.*rwk,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" > "$template_xml" > "$test_xml" > -testme "0" "replace (adding non-existent disk)" "-r -u $valid_uuid > -f $nonexistent" "$test_xml" > +testme "0" "replace (adding non-existent disk)" "-r -u $valid_uuid > -f $nonexistent" "$test_xml" "$nonexistent.*rwk,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" > "$template_xml" > "$test_xml" > -testme "0" "replace (appending disk)" "-r -u $valid_uuid -F $disk2" > "$test_xml" > +testme "0" "replace (appending disk)" "-r -u $valid_uuid -F $disk2" > "$test_xml" "$disk2.*rwk,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" > "$template_xml" > "$test_xml" > -testme "0" "replace (appending non-existent disk)" "-r -u > $valid_uuid -F $nonexistent" "$test_xml" > +testme "0" "replace (appending non-existent disk)" "-r -u > $valid_uuid -F $nonexistent" "$test_xml" "$nonexistent.*rwk,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</devices>,<disk type='block' device='cdrom'><target dev='hdc' > bus='ide'/><readonly/></disk></devices>,g" "$template_xml" > > "$test_xml" > testme "0" "disk (empty cdrom)" "-r -u $valid_uuid" "$test_xml" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</devices>,<serial type='file'><source > path='$tmpdir/serial.log'/><target port='0'/></serial></devices>,g" > "$template_xml" > "$test_xml" > -testme "0" "serial" "-r -u $valid_uuid" "$test_xml" > +testme "0" "serial" "-r -u $valid_uuid" "$test_xml" > "$tmpdir/serial.log.*rw,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</devices>,<serial type='pty'><target > port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" > testme "0" "serial (pty)" "-r -u $valid_uuid" "$test_xml" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</devices>,<serial type='dev'><source path='/dev/ttyS0'/><target > port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" > -testme "0" "serial (dev)" "-r -u $valid_uuid" "$test_xml" > +testme "0" "serial (dev)" "-r -u $valid_uuid" "$test_xml" > "/dev/ttyS0.*rw,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</devices>,<serial type='pipe'><source > path='$tmpdir/serial.pipe'/><target port='0'/></serial></devices>,g" > "$template_xml" > "$test_xml" > -mkfifo "$tmpdir/serial.pipe.in" "$tmpdir/serial.pipe.out" > +mkfifo "$tmpdir/serial.pipe.in" "$tmpdir/serial.pipe.out" > "$tmpdir/serial.pipe.in.*rw,$" > testme "0" "serial (pipe)" "-r -u $valid_uuid" "$test_xml" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</devices>,<console type='file'><source > path='$tmpdir/console.log'/><target port='0'/></console></devices>,g" > "$template_xml" > "$test_xml" > touch "$tmpdir/console.log" > -testme "0" "console" "-r -u $valid_uuid" "$test_xml" > +testme "0" "console" "-r -u $valid_uuid" "$test_xml" > "$tmpdir/console.log.*rw,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</devices>,<console type='pty'><target > port='0'/></console></devices>,g" "$template_xml" > "$test_xml" > testme "0" "console (pty)" "-r -u $valid_uuid" "$test_xml" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</devices>,<console type='pipe'><source > path='$tmpdir/console.pipe'/><target > port='0'/></console></devices>,g" "$template_xml" > "$test_xml" > mkfifo "$tmpdir/console.pipe.in" "$tmpdir/console.pipe.out" > -testme "0" "console (pipe)" "-r -u $valid_uuid" "$test_xml" > +testme "0" "console (pipe)" "-r -u $valid_uuid" "$test_xml" > "$tmpdir/console.pipe.out.*rw,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</devices>,<parallel type='pty'><source path='/dev/pts/0'/><target > port='0'/></parallel></devices>,g" "$template_xml" > "$test_xml" > -testme "0" "parallel (pty)" "-r -u $valid_uuid" "$test_xml" > +testme "0" "parallel (pty)" "-r -u $valid_uuid" "$test_xml" > "/dev/pts/0.*rw,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</devices>,<parallel type='pipe'><source > path='$tmpdir/parallel.pipe'/><target > port='0'/></parallel></devices>,g" "$template_xml" > "$test_xml" > mkfifo "$tmpdir/parallel.pipe.in" "$tmpdir/parallel.pipe.out" > -testme "0" "parallel (pipe)" "-r -u $valid_uuid" "$test_xml" > +testme "0" "parallel (pipe)" "-r -u $valid_uuid" "$test_xml" > "$tmpdir/parallel.pipe.in.*rw,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</devices>,<channel type='unix'><source mode='bind' > path='$tmpdir/guestfwd'/><target type='guestfwd' address='10.0.2.1' > port='4600'/></channel></devices>,g" "$template_xml" > "$test_xml" > touch "$tmpdir/guestfwd" > -testme "0" "channel (unix)" "-r -u $valid_uuid" "$test_xml" > +testme "0" "channel (unix)" "-r -u $valid_uuid" "$test_xml" > "$tmpdir/guestfwd.*rw,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</devices>,<channel type='pty'><target > type='virtio'/></channel></devices>,g" "$template_xml" > "$test_xml" > testme "0" "channel (pty)" "-r -u $valid_uuid" "$test_xml" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</os>,<kernel>$tmpdir/kernel</kernel></os>,g" "$template_xml" > > "$test_xml" > touch "$tmpdir/kernel" > -testme "0" "kernel" "-r -u $valid_uuid" "$test_xml" > +testme "0" "kernel" "-r -u $valid_uuid" "$test_xml" > "$tmpdir/kernel.*r,$" > > testfw "ovmf (old path)" "/usr/share/ovmf/OVMF.fd" > testfw "OVMF (new path)" "/usr/share/OVMF/OVMF_CODE.fd" > @@ -333,37 +346,37 @@ testfw "qemu-efi" "/usr/share/qemu- > efi/QEMU_EFI.fd" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</os>,<initrd>$tmpdir/initrd</initrd></os>,g" "$template_xml" > > "$test_xml" > touch "$tmpdir/initrd" > -testme "0" "initrd" "-r -u $valid_uuid" "$test_xml" > +testme "0" "initrd" "-r -u $valid_uuid" "$test_xml" > "$tmpdir/initrd.*r,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</os>,<kernel>/boot/kernel</kernel></os>,g" "$template_xml" > > "$test_xml" > -testme "0" "kernel in /boot" "-r -u $valid_uuid" "$test_xml" > +testme "0" "kernel in /boot" "-r -u $valid_uuid" "$test_xml" > "/boot/kernel.*r,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</os>,<initrd>/boot/initrd</initrd></os>,g" "$template_xml" > > "$test_xml" > -testme "0" "initrd in /boot" "-r -u $valid_uuid" "$test_xml" > +testme "0" "initrd in /boot" "-r -u $valid_uuid" "$test_xml" > "/boot/initrd.*r,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</os>,<kernel>/vmlinuz</kernel></os>,g" "$template_xml" > > "$test_xml" > -testme "0" "kernel is /vmlinuz" "-r -u $valid_uuid" "$test_xml" > +testme "0" "kernel is /vmlinuz" "-r -u $valid_uuid" "$test_xml" > "/vmlinuz.*r,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</os>,<initrd>/initrd/ramdisk</initrd></os>,g" "$template_xml" > > "$test_xml" > -testme "0" "initrd is /initrd/ramdisk" "-r -u $valid_uuid" > "$test_xml" > +testme "0" "initrd is /initrd/ramdisk" "-r -u $valid_uuid" > "$test_xml" "/initrd/ramdisk.*r,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</os>,<initrd>/initrd.img</initrd></os>,g" "$template_xml" > > "$test_xml" > -testme "0" "initrd is /initrd.img" "-r -u $valid_uuid" "$test_xml" > +testme "0" "initrd is /initrd.img" "-r -u $valid_uuid" "$test_xml" > "/initrd.img.*r,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,<graphics*,<graphics type='sdl' display=':0.0' > xauth='/home/myself/.Xauthority'/>,g" "$template_xml" > "$test_xml" > -testme "0" "sdl Xauthority" "-r -u $valid_uuid" "$test_xml" > +testme "0" "sdl Xauthority" "-r -u $valid_uuid" "$test_xml" > "/home/myself/.Xauthority.*r,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" > "$template_xml" > "$test_xml" > -testme "0" "hugepages" "-r -u $valid_uuid -F > /run/hugepages/kvm/\*\*" "$test_xml" > +testme "0" "hugepages" "-r -u $valid_uuid -F > /run/hugepages/kvm/\*\*" "$test_xml" "/run/hugepages/kvm/.*rwk,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,<graphics.*>,<graphics type='vnc' > socket='/var/lib/libvirt/qemu/myself.vnc'><listen type='address' > address='0.0.0.0'/></graphics>,g" "$template_xml" > "$test_xml" > -testme "0" "vnc socket" "-r -u $valid_uuid" "$test_xml" > +testme "0" "vnc socket" "-r -u $valid_uuid" "$test_xml" > "/var/lib/libvirt/qemu/myself.vnc.*rw,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,</devices>,<input type='passthrough' bus='virtio'><source > evdev='$disk2' /></input></devices>,g" "$template_xml" > "$test_xml" > -testme "0" "input dev passthrough" "-r -u $valid_uuid" "$test_xml" > +testme "0" "input dev passthrough" "-r -u $valid_uuid" "$test_xml" > "$disk2.*rw,$" > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > "s,<memory>524288</memory>,<memory>1048576</memory>,g" -e > "s,</devices>,<memory > model='nvdimm'><source><path>$disk2</path></source><target><size > unit='KiB'>524288</size><node>0</node></target></memory></devices>,g" > "$template_xml" > "$test_xml" > -testme "0" "nvdimm" "-r -u $valid_uuid" "$test_xml" > +testme "0" "nvdimm" "-r -u $valid_uuid" "$test_xml" "$disk2.*rw,$" > > testme "0" "help" "-h" +1 to commit. Thanks! -- Jamie Strandboge | http://www.canonical.com

On Thu, Mar 22, 2018 at 5:35 PM, Jamie Strandboge <jamie@canonical.com> wrote: > On Wed, 2018-03-21 at 22:22 +0100, Christian Ehrhardt wrote: > > So far the virt-aa-helper tests only checked the return code and > > thereby > > catched aborts like issues failing to parse the XML. But there is one > > category of virt-aa-helper issues so far untested - not generating > > the > > expected rule. > > > > This adds a basic grep based checks after each test to match against > > the > > rule that is expected to be added by the test. > > > > Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> > > --- > > tests/virt-aa-helper-test | 85 +++++++++++++++++++++++++++-------- > > ------------ > > 1 file changed, 49 insertions(+), 36 deletions(-) > > > > diff --git a/tests/virt-aa-helper-test b/tests/virt-aa-helper-test > > index 7c839e4..fb40057 100755 > > --- a/tests/virt-aa-helper-test > > +++ b/tests/virt-aa-helper-test > > @@ -108,6 +108,9 @@ testme() { > > outstr="$2" > > args="$3" > > input="" > > + checkrule="$5" > > + > > + tmpout="$tmpdir/checkrule.out" > > > > if [ -n "$4" ]; then > > input="$4" > > @@ -127,13 +130,23 @@ testme() { > > echo "': " >$output > > set +e > > if [ -n "$input" ]; then > > - LD_LIBRARY_PATH="$ld_library_path" $exe $extra_args $args < > > $input >$output 2>&1 > > + LD_LIBRARY_PATH="$ld_library_path" $exe $extra_args $args < > > $input >"$tmpout" 2>&1 > > else > > - LD_LIBRARY_PATH="$ld_library_path" $exe $extra_args $args > > >$output 2>&1 > > + LD_LIBRARY_PATH="$ld_library_path" $exe $extra_args $args > > >"$tmpout" 2>&1 > > fi > > rc="$?" > > + cat "$tmpout" >"$output" > > Thanks for the reminder in the previous email on how $output works and > why this is ok. > > > + > > + rule_missing=0 > > + if [ -n "$checkrule" ]; then > > + if ! grep -q "$checkrule" "$tmpout"; then > > + echo "FAIL: missing rule '$checkrule'" >"$output" > > + rule_missing=1 > > + fi > > + fi > > + > > set -e > > - if [ "$rc" = "$expected" ]; then > > + if [ "$rc" = "$expected" ] && [ $rule_missing -eq 0 ]; then > > echo "pass" >$output > > else > > echo "FAIL: exited with '$rc'" >$output > > @@ -234,19 +247,19 @@ testme "1" "-c with invalid domain name char *" > > "-c -u $valid_uuid" "$test_xml" > > > > echo "Expected pass:" >$output > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" > > "$template_xml" > "$test_xml" > > -testme "0" "create (x86_64)" "-c -u $valid_uuid" "$test_xml" > > +testme "0" "create (x86_64)" "-c -u $valid_uuid" "$test_xml" > > "$disk1.*rwk,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,arch='x86_64',arch='i686',g" "$template_xml" > "$test_xml" > > -testme "0" "create (i686)" "-c -u $valid_uuid" "$test_xml" > > +testme "0" "create (i686)" "-c -u $valid_uuid" "$test_xml" > > "$disk1.*rwk,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,arch='x86_64',arch='ppc',g" "$template_xml" > "$test_xml" > > -testme "0" "create (ppc)" "-c -u $valid_uuid" "$test_xml" > > +testme "0" "create (ppc)" "-c -u $valid_uuid" "$test_xml" > > "$disk1.*rwk,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</disk>,</disk><disk type='file' device='disk'><driver name='qemu' > > type='raw'/><source file='$disk2'/><target dev='hdb' > > bus='ide'/></disk>,g" "$template_xml" > "$test_xml" > > -testme "0" "create multiple disks" "-c -u $valid_uuid" "$test_xml" > > +testme "0" "create multiple disks" "-c -u $valid_uuid" "$test_xml" > > "$disk1.*rwk,$" > > > > sed -e "s,###UUID###,$uuid,g" -e > > "s,###DISK###',${disk1}'/><readonly,g" "$template_xml" > "$test_xml" > > -testme "0" "create (readonly)" "-c -u $valid_uuid" "$test_xml" > > +testme "0" "create (readonly)" "-c -u $valid_uuid" "$test_xml" > > "$disk1.*rk,$" > > > > if [ "$test_hostdev" = "yes" ]; then > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</disk>,</disk><hostdev mode='subsystem' > > type='usb'><source><address bus='002' > > device='004'/></source></hostdev>,g" "$template_xml" > "$test_xml" > > @@ -257,73 +270,73 @@ if [ "$test_hostdev" = "yes" ]; then > > fi > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$nonexistent,g" > > "$template_xml" > "$test_xml" > > -testme "0" "create (non-existent disk)" "-c -u $valid_uuid" > > "$test_xml" > > +testme "0" "create (non-existent disk)" "-c -u $valid_uuid" > > "$test_xml" "$nonexistent.*rwk,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$relative_disk1,g" > > "$template_xml" > "$test_xml" > > -testme "0" "create (relative path)" "-c -u $valid_uuid" "$test_xml" > > +testme "0" "create (relative path)" "-c -u $valid_uuid" "$test_xml" > > "$disk1.*rwk,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk2,g" > > "$template_xml" > "$test_xml" > > -testme "0" "replace" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "replace" "-r -u $valid_uuid" "$test_xml" "$disk2.*rwk,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$nonexistent,g" > > "$template_xml" > "$test_xml" > > -testme "0" "replace (non-existent disk)" "-r -u $valid_uuid" > > "$test_xml" > > +testme "0" "replace (non-existent disk)" "-r -u $valid_uuid" > > "$test_xml" "$nonexistent.*rwk,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" > > "$template_xml" > "$test_xml" > > -testme "0" "replace (adding disk)" "-r -u $valid_uuid -f $disk2" > > "$test_xml" > > +testme "0" "replace (adding disk)" "-r -u $valid_uuid -f $disk2" > > "$test_xml" "$disk2.*rwk,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" > > "$template_xml" > "$test_xml" > > -testme "0" "replace (adding non-existent disk)" "-r -u $valid_uuid > > -f $nonexistent" "$test_xml" > > +testme "0" "replace (adding non-existent disk)" "-r -u $valid_uuid > > -f $nonexistent" "$test_xml" "$nonexistent.*rwk,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" > > "$template_xml" > "$test_xml" > > -testme "0" "replace (appending disk)" "-r -u $valid_uuid -F $disk2" > > "$test_xml" > > +testme "0" "replace (appending disk)" "-r -u $valid_uuid -F $disk2" > > "$test_xml" "$disk2.*rwk,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" > > "$template_xml" > "$test_xml" > > -testme "0" "replace (appending non-existent disk)" "-r -u > > $valid_uuid -F $nonexistent" "$test_xml" > > +testme "0" "replace (appending non-existent disk)" "-r -u > > $valid_uuid -F $nonexistent" "$test_xml" "$nonexistent.*rwk,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</devices>,<disk type='block' device='cdrom'><target dev='hdc' > > bus='ide'/><readonly/></disk></devices>,g" "$template_xml" > > > "$test_xml" > > testme "0" "disk (empty cdrom)" "-r -u $valid_uuid" "$test_xml" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</devices>,<serial type='file'><source > > path='$tmpdir/serial.log'/><target port='0'/></serial></devices>,g" > > "$template_xml" > "$test_xml" > > -testme "0" "serial" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "serial" "-r -u $valid_uuid" "$test_xml" > > "$tmpdir/serial.log.*rw,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</devices>,<serial type='pty'><target > > port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" > > testme "0" "serial (pty)" "-r -u $valid_uuid" "$test_xml" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</devices>,<serial type='dev'><source path='/dev/ttyS0'/><target > > port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" > > -testme "0" "serial (dev)" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "serial (dev)" "-r -u $valid_uuid" "$test_xml" > > "/dev/ttyS0.*rw,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</devices>,<serial type='pipe'><source > > path='$tmpdir/serial.pipe'/><target port='0'/></serial></devices>,g" > > "$template_xml" > "$test_xml" > > -mkfifo "$tmpdir/serial.pipe.in" "$tmpdir/serial.pipe.out" > > +mkfifo "$tmpdir/serial.pipe.in" "$tmpdir/serial.pipe.out" > > "$tmpdir/serial.pipe.in.*rw,$" > > testme "0" "serial (pipe)" "-r -u $valid_uuid" "$test_xml" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</devices>,<console type='file'><source > > path='$tmpdir/console.log'/><target port='0'/></console></devices>,g" > > "$template_xml" > "$test_xml" > > touch "$tmpdir/console.log" > > -testme "0" "console" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "console" "-r -u $valid_uuid" "$test_xml" > > "$tmpdir/console.log.*rw,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</devices>,<console type='pty'><target > > port='0'/></console></devices>,g" "$template_xml" > "$test_xml" > > testme "0" "console (pty)" "-r -u $valid_uuid" "$test_xml" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</devices>,<console type='pipe'><source > > path='$tmpdir/console.pipe'/><target > > port='0'/></console></devices>,g" "$template_xml" > "$test_xml" > > mkfifo "$tmpdir/console.pipe.in" "$tmpdir/console.pipe.out" > > -testme "0" "console (pipe)" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "console (pipe)" "-r -u $valid_uuid" "$test_xml" > > "$tmpdir/console.pipe.out.*rw,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</devices>,<parallel type='pty'><source path='/dev/pts/0'/><target > > port='0'/></parallel></devices>,g" "$template_xml" > "$test_xml" > > -testme "0" "parallel (pty)" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "parallel (pty)" "-r -u $valid_uuid" "$test_xml" > > "/dev/pts/0.*rw,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</devices>,<parallel type='pipe'><source > > path='$tmpdir/parallel.pipe'/><target > > port='0'/></parallel></devices>,g" "$template_xml" > "$test_xml" > > mkfifo "$tmpdir/parallel.pipe.in" "$tmpdir/parallel.pipe.out" > > -testme "0" "parallel (pipe)" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "parallel (pipe)" "-r -u $valid_uuid" "$test_xml" > > "$tmpdir/parallel.pipe.in.*rw,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</devices>,<channel type='unix'><source mode='bind' > > path='$tmpdir/guestfwd'/><target type='guestfwd' address='10.0.2.1' > > port='4600'/></channel></devices>,g" "$template_xml" > "$test_xml" > > touch "$tmpdir/guestfwd" > > -testme "0" "channel (unix)" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "channel (unix)" "-r -u $valid_uuid" "$test_xml" > > "$tmpdir/guestfwd.*rw,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</devices>,<channel type='pty'><target > > type='virtio'/></channel></devices>,g" "$template_xml" > "$test_xml" > > testme "0" "channel (pty)" "-r -u $valid_uuid" "$test_xml" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</os>,<kernel>$tmpdir/kernel</kernel></os>,g" "$template_xml" > > > "$test_xml" > > touch "$tmpdir/kernel" > > -testme "0" "kernel" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "kernel" "-r -u $valid_uuid" "$test_xml" > > "$tmpdir/kernel.*r,$" > > > > testfw "ovmf (old path)" "/usr/share/ovmf/OVMF.fd" > > testfw "OVMF (new path)" "/usr/share/OVMF/OVMF_CODE.fd" > > @@ -333,37 +346,37 @@ testfw "qemu-efi" "/usr/share/qemu- > > efi/QEMU_EFI.fd" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</os>,<initrd>$tmpdir/initrd</initrd></os>,g" "$template_xml" > > > "$test_xml" > > touch "$tmpdir/initrd" > > -testme "0" "initrd" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "initrd" "-r -u $valid_uuid" "$test_xml" > > "$tmpdir/initrd.*r,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</os>,<kernel>/boot/kernel</kernel></os>,g" "$template_xml" > > > "$test_xml" > > -testme "0" "kernel in /boot" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "kernel in /boot" "-r -u $valid_uuid" "$test_xml" > > "/boot/kernel.*r,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</os>,<initrd>/boot/initrd</initrd></os>,g" "$template_xml" > > > "$test_xml" > > -testme "0" "initrd in /boot" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "initrd in /boot" "-r -u $valid_uuid" "$test_xml" > > "/boot/initrd.*r,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</os>,<kernel>/vmlinuz</kernel></os>,g" "$template_xml" > > > "$test_xml" > > -testme "0" "kernel is /vmlinuz" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "kernel is /vmlinuz" "-r -u $valid_uuid" "$test_xml" > > "/vmlinuz.*r,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</os>,<initrd>/initrd/ramdisk</initrd></os>,g" "$template_xml" > > > "$test_xml" > > -testme "0" "initrd is /initrd/ramdisk" "-r -u $valid_uuid" > > "$test_xml" > > +testme "0" "initrd is /initrd/ramdisk" "-r -u $valid_uuid" > > "$test_xml" "/initrd/ramdisk.*r,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</os>,<initrd>/initrd.img</initrd></os>,g" "$template_xml" > > > "$test_xml" > > -testme "0" "initrd is /initrd.img" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "initrd is /initrd.img" "-r -u $valid_uuid" "$test_xml" > > "/initrd.img.*r,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,<graphics*,<graphics type='sdl' display=':0.0' > > xauth='/home/myself/.Xauthority'/>,g" "$template_xml" > "$test_xml" > > -testme "0" "sdl Xauthority" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "sdl Xauthority" "-r -u $valid_uuid" "$test_xml" > > "/home/myself/.Xauthority.*r,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" > > "$template_xml" > "$test_xml" > > -testme "0" "hugepages" "-r -u $valid_uuid -F > > /run/hugepages/kvm/\*\*" "$test_xml" > > +testme "0" "hugepages" "-r -u $valid_uuid -F > > /run/hugepages/kvm/\*\*" "$test_xml" "/run/hugepages/kvm/.*rwk,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,<graphics.*>,<graphics type='vnc' > > socket='/var/lib/libvirt/qemu/myself.vnc'><listen type='address' > > address='0.0.0.0'/></graphics>,g" "$template_xml" > "$test_xml" > > -testme "0" "vnc socket" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "vnc socket" "-r -u $valid_uuid" "$test_xml" > > "/var/lib/libvirt/qemu/myself.vnc.*rw,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,</devices>,<input type='passthrough' bus='virtio'><source > > evdev='$disk2' /></input></devices>,g" "$template_xml" > "$test_xml" > > -testme "0" "input dev passthrough" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "input dev passthrough" "-r -u $valid_uuid" "$test_xml" > > "$disk2.*rw,$" > > > > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e > > "s,<memory>524288</memory>,<memory>1048576</memory>,g" -e > > "s,</devices>,<memory > > model='nvdimm'><source><path>$disk2</path></source><target><size > > unit='KiB'>524288</size><node>0</node></target></memory></devices>,g" > > "$template_xml" > "$test_xml" > > -testme "0" "nvdimm" "-r -u $valid_uuid" "$test_xml" > > +testme "0" "nvdimm" "-r -u $valid_uuid" "$test_xml" "$disk2.*rw,$" > > > > testme "0" "help" "-h" > > > +1 to commit. Thanks! Thanks, added your ack and pushed > -- > Jamie Strandboge | http://www.canonical.com > -- Christian Ehrhardt Software Engineer, Ubuntu Server Canonical Ltd

On Wed, Mar 21, 2018 at 10:22 PM, Christian Ehrhardt < christian.ehrhardt@canonical.com> wrote:
So far users added manual rules for most of these uncommon devices, but recent changes made some of the callbacks mandatory for hotplug so we should take shot at implementing them as those callbacks as well as for the initial start of a guest via virt-aa-helper.
*Updates since v1* - Set(Memory|Input)Label: remove seclabel check already done in reload_profile - virt-aa-helper: check pointers before accessing them - add tests for new virt-aa-helper supported xml elements - extend tests to check for expected content (new patch in series)
*Updates since v2* - Restore(Memory|Input)Label: drop secdef/relabel check - Set(Memory|Input)Label: check more pointers to be valid before using them
*Updates since v3* - added the Acked-by of Jamie Strandboge on patches 1-4 - reuse the already existing tmpdir in virt-aa-helper-test for better cleanup
Christian Ehrhardt (5): security, apparmor: add (Set|Restore)MemoryLabel security, apparmor: add (Set|Restore)InputLabel virt-aa-helper: generate rules for passthrough input devices virt-aa-helper: generate rules for nvdimm memory
Rebased (no change), retested and pushed patches 1-4 being up a few days and having acks.
virt-aa-helper: test: check for expected profile content
Keeping this last one up for more review to either push or reiterate on it after more review. src/security/security_apparmor.c | 94 ++++++++++++++++++++++++++++++
++++++++++ src/security/virt-aa-helper.c | 16 +++++++ tests/virt-aa-helper-test | 87 ++++++++++++++++++++++-------- ------- 3 files changed, 163 insertions(+), 34 deletions(-)
-- 2.7.4
-- Christian Ehrhardt Software Engineer, Ubuntu Server Canonical Ltd
participants (2)
-
Christian Ehrhardt
-
Jamie Strandboge