Author: Jamie Strandboge <jamie@canonical.com>
Description: update AppArmor security driver to adjust profile for save/restore
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=529363
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/457716

Index: libvirt-0.7.7/src/security/security_apparmor.c
===================================================================
--- libvirt-0.7.7.orig/src/security/security_apparmor.c	2010-03-31 11:20:48.000000000 -0500
+++ libvirt-0.7.7/src/security/security_apparmor.c	2010-03-31 11:31:39.000000000 -0500
@@ -149,7 +149,7 @@
  */
 static int
 load_profile(const char *profile, virDomainObjPtr vm,
-             virDomainDiskDefPtr disk)
+             const char *fn)
 {
     int rc = -1, status, ret;
     bool create = true;
@@ -175,9 +175,9 @@
         };
         ret = virExec(argv, NULL, NULL, &child,
                       pipefd[0], NULL, NULL, VIR_EXEC_NONE);
-    } else if (disk && disk->src) {
+    } else if (fn) {
         const char *const argv[] = {
-            VIRT_AA_HELPER, "-r", "-u", profile, "-f", disk->src, NULL
+            VIRT_AA_HELPER, "-r", "-u", profile, "-f", fn, NULL
         };
         ret = virExec(argv, NULL, NULL, &child,
                       pipefd[0], NULL, NULL, VIR_EXEC_NONE);
@@ -277,6 +277,40 @@
     return rc;
 }
 
+/* reload the profile, adding read/write file specified by fn if it is not
+ * NULL.
+ */
+static int
+reload_profile(virDomainObjPtr vm, const char *fn)
+{
+    const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+    int rc = -1;
+    char *profile_name = NULL;
+
+    if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
+        return 0;
+
+    if ((profile_name = get_profile_name(vm)) == NULL)
+        return rc;
+
+    /* Update the profile only if it is loaded */
+    if (profile_loaded(secdef->imagelabel) >= 0) {
+        if (load_profile(secdef->imagelabel, vm, fn) < 0) {
+            virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+                                   _("cannot update AppArmor profile "
+                                     "\'%s\'"),
+                                   secdef->imagelabel);
+            goto clean;
+        }
+    }
+
+    rc = 0;
+  clean:
+    VIR_FREE(profile_name);
+
+    return rc;
+}
+
 /* Called on libvirtd startup to see if AppArmor is available */
 static int
 AppArmorSecurityDriverProbe(void)
@@ -377,14 +411,14 @@
 }
 
 static int
-AppArmorSetSecurityAllLabel(virDomainObjPtr vm)
+AppArmorSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path)
 {
     if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
         return 0;
 
     /* if the profile is not already loaded, then load one */
     if (profile_loaded(vm->def->seclabel.label) < 0) {
-        if (load_profile(vm->def->seclabel.label, vm, NULL) < 0) {
+        if (load_profile(vm->def->seclabel.label, vm, stdin_path) < 0) {
             virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
                                    _("cannot generate AppArmor profile "
                                    "\'%s\'"), vm->def->seclabel.label);
@@ -501,32 +535,7 @@
 AppArmorRestoreSecurityImageLabel(virDomainObjPtr vm,
                                   virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
 {
-    const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
-    int rc = -1;
-    char *profile_name = NULL;
-
-    if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
-        return 0;
-
-    if ((profile_name = get_profile_name(vm)) == NULL)
-        return rc;
-
-    /* Update the profile only if it is loaded */
-    if (profile_loaded(secdef->imagelabel) >= 0) {
-        if (load_profile(secdef->imagelabel, vm, NULL) < 0) {
-            virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
-                                   _("cannot update AppArmor profile "
-                                     "\'%s\'"),
-                                   secdef->imagelabel);
-            goto clean;
-        }
-    }
-
-    rc = 0;
-  clean:
-    VIR_FREE(profile_name);
-
-    return rc;
+    return reload_profile(vm, NULL);
 }
 
 /* Called when hotplugging */
@@ -556,7 +565,7 @@
 
         /* update the profile only if it is loaded */
         if (profile_loaded(secdef->imagelabel) >= 0) {
-            if (load_profile(secdef->imagelabel, vm, disk) < 0) {
+            if (load_profile(secdef->imagelabel, vm, disk->src) < 0) {
                 virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
                                      _("cannot update AppArmor profile "
                                      "\'%s\'"),
@@ -623,6 +632,21 @@
     return 0;
 }
 
+static int
+AppArmorSetSavedStateLabel(virDomainObjPtr vm,
+                          const char *savefile)
+{
+    return reload_profile(vm, savefile);
+}
+
+
+static int
+AppArmorRestoreSavedStateLabel(virDomainObjPtr vm,
+                               const char *savefile ATTRIBUTE_UNUSED)
+{
+    return reload_profile(vm, NULL);
+}
+
 virSecurityDriver virAppArmorSecurityDriver = {
     .name = SECURITY_APPARMOR_NAME,
     .probe = AppArmorSecurityDriverProbe,
@@ -639,4 +663,6 @@
     .domainSetSecurityAllLabel = AppArmorSetSecurityAllLabel,
     .domainSetSecurityHostdevLabel = AppArmorSetSecurityHostdevLabel,
     .domainRestoreSecurityHostdevLabel = AppArmorRestoreSecurityHostdevLabel,
+    .domainSetSavedStateLabel = AppArmorSetSavedStateLabel,
+    .domainRestoreSavedStateLabel = AppArmorRestoreSavedStateLabel,
 };
