Merge "Revert "Add /bootstrap-apex"" into main
diff --git a/build/soong/selinux_contexts.go b/build/soong/selinux_contexts.go
index 2416dc9..644a2dd 100644
--- a/build/soong/selinux_contexts.go
+++ b/build/soong/selinux_contexts.go
@@ -434,12 +434,16 @@
 		Text("|| true)") // to make ninja happy even when result is empty
 
 	rule.Temporary(neverallowFile)
-	rule.Command().BuiltTool("checkseapp").
+	checkCmd := rule.Command().BuiltTool("checkseapp").
 		FlagWithInput("-p ", android.PathForModuleSrc(ctx, proptools.String(m.seappProperties.Sepolicy))).
 		FlagWithOutput("-o ", ret).
 		Inputs(inputs).
 		Input(neverallowFile)
 
+	if ctx.SocSpecific() || ctx.DeviceSpecific() {
+		checkCmd.Flag("-c") // check coredomain
+	}
+
 	rule.Build("seapp_contexts", "Building seapp_contexts: "+m.Name())
 	return ret
 }
diff --git a/build/soong/service_fuzzer_bindings.go b/build/soong/service_fuzzer_bindings.go
index b73db7e..f7e67d8 100644
--- a/build/soong/service_fuzzer_bindings.go
+++ b/build/soong/service_fuzzer_bindings.go
@@ -51,6 +51,7 @@
 		"android.hardware.broadcastradio.IBroadcastRadio/dab":                     EXCEPTION_NO_FUZZER,
 		"android.hardware.bluetooth.IBluetoothHci/default":                        EXCEPTION_NO_FUZZER,
 		"android.hardware.camera.provider.ICameraProvider/internal/0":             EXCEPTION_NO_FUZZER,
+		"android.hardware.camera.provider.ICameraProvider/virtual/0":              EXCEPTION_NO_FUZZER,
 		"android.hardware.cas.IMediaCasService/default":                           EXCEPTION_NO_FUZZER,
 		"android.hardware.confirmationui.IConfirmationUI/default":                 []string{"android.hardware.confirmationui-service.trusty_fuzzer"},
 		"android.hardware.contexthub.IContextHub/default":                         EXCEPTION_NO_FUZZER,
@@ -449,6 +450,7 @@
 		"vibrator":                     EXCEPTION_NO_FUZZER,
 		"vibrator_manager":             EXCEPTION_NO_FUZZER,
 		"virtualdevice":                EXCEPTION_NO_FUZZER,
+		"virtual_camera_service":       EXCEPTION_NO_FUZZER,
 		"virtual_touchpad":             EXCEPTION_NO_FUZZER,
 		"voiceinteraction":             EXCEPTION_NO_FUZZER,
 		"vold":                         []string{"vold_native_service_fuzzer"},
diff --git a/microdroid/system/private/microdroid_payload.te b/microdroid/system/private/microdroid_payload.te
index 239360f..380a439 100644
--- a/microdroid/system/private/microdroid_payload.te
+++ b/microdroid/system/private/microdroid_payload.te
@@ -8,13 +8,6 @@
 # microdroid_launcher is launched by microdroid_manager with fork/execvp.
 allow microdroid_payload microdroid_manager:fd use;
 
-# Allow to use FDs inherited from the shell. This includes the FD opened for
-# the microdroid_launcher executable itself and the FD for adb connection.
-# TODO(b/186396070) remove this when this is executed from microdroid_manager
-userdebug_or_eng(`
-  allow microdroid_payload shell:fd use;
-')
-
 # Allow to use terminal
 allow microdroid_payload devpts:chr_file rw_file_perms;
 
diff --git a/microdroid/system/private/shell.te b/microdroid/system/private/shell.te
index 038be00..5267348 100644
--- a/microdroid/system/private/shell.te
+++ b/microdroid/system/private/shell.te
@@ -7,11 +7,6 @@
 # Allow shell to run adb shell cmd stats commands. Needed for CTS.
 binder_call(shell, statsd);
 
-# Allow shell to launch microdroid_launcher in its own domain
-# TODO(b/186396070) remove this when microdroid_manager can do this
-domain_auto_trans(shell, microdroid_app_exec, microdroid_app)
-domain_auto_trans(shell, microdroid_manager_exec, microdroid_manager)
-
 # Connect to adbd and use a socket transferred from it.
 # This is used for e.g. adb backup/restore.
 allow shell adbd:unix_stream_socket connectto;
diff --git a/private/bootanim.te b/private/bootanim.te
index f4fb0bc..2b3c807 100644
--- a/private/bootanim.te
+++ b/private/bootanim.te
@@ -16,5 +16,5 @@
 # Allow updating boot animation status.
 set_prop(bootanim, bootanim_system_prop)
 
-# Allow accessing /data/bootanim
+# Allow accessing /data/misc/bootanim
 r_dir_file(bootanim, bootanim_data_file)
diff --git a/private/compat/33.0/33.0.ignore.cil b/private/compat/33.0/33.0.ignore.cil
index 7a5ca9a..4c6492f 100644
--- a/private/compat/33.0/33.0.ignore.cil
+++ b/private/compat/33.0/33.0.ignore.cil
@@ -18,6 +18,7 @@
     credential_service
     device_as_webcam
     device_config_camera_native_prop
+    device_config_core_experiments_team_internal_prop
     device_config_edgetpu_native_prop
     device_config_memory_safety_native_boot_prop
     device_config_memory_safety_native_prop
diff --git a/private/compat/34.0/34.0.ignore.cil b/private/compat/34.0/34.0.ignore.cil
index aae1ac1..47d6719 100644
--- a/private/compat/34.0/34.0.ignore.cil
+++ b/private/compat/34.0/34.0.ignore.cil
@@ -8,4 +8,5 @@
     ota_build_prop
     snapuserd_log_data_file
     hal_threadnetwork_service
+    virtual_camera_service
   ))
diff --git a/private/dex2oat.te b/private/dex2oat.te
index 379e32c..18600d8 100644
--- a/private/dex2oat.te
+++ b/private/dex2oat.te
@@ -84,7 +84,7 @@
 
 # Allow dex2oat access to /postinstall/apex.
 allow dex2oat postinstall_apex_mnt_dir:dir { getattr search };
-allow dex2oat postinstall_apex_mnt_dir:file r_file_perms;
+allow dex2oat postinstall_apex_mnt_dir:{ file lnk_file } r_file_perms;
 
 # Allow dex2oat access to files in /data/ota.
 allow dex2oat ota_data_file:dir ra_dir_perms;
diff --git a/private/file.te b/private/file.te
index e48fc4c..129b1ea 100644
--- a/private/file.te
+++ b/private/file.te
@@ -98,7 +98,7 @@
 # /data/system/environ
 type environ_system_data_file, file_type, data_file_type, core_data_file_type;
 
-# /data/bootanim
+# /data/misc/bootanim
 type bootanim_data_file, file_type, data_file_type, core_data_file_type;
 
 # /dev/kvm
diff --git a/private/file_contexts b/private/file_contexts
index 123e4ed..0bae96e 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -737,7 +737,7 @@
 /data/incremental/MT_[^/]+/mount/.blocks_written        u:object_r:incremental_control_file:s0
 
 # Boot animation data
-/data/bootanim(/.*)? u:object_r:bootanim_data_file:s0
+/data/misc/bootanim(/.*)? u:object_r:bootanim_data_file:s0
 #############################
 # Expanded data files
 #
diff --git a/private/flags_health_check.te b/private/flags_health_check.te
index 9480b40..9afaba0 100644
--- a/private/flags_health_check.te
+++ b/private/flags_health_check.te
@@ -3,6 +3,7 @@
 init_daemon_domain(flags_health_check)
 
 set_prop(flags_health_check, device_config_boot_count_prop)
+set_prop(flags_health_check, device_config_core_experiments_team_internal_prop)
 set_prop(flags_health_check, device_config_edgetpu_native_prop)
 set_prop(flags_health_check, device_config_reset_performed_prop)
 set_prop(flags_health_check, device_config_runtime_native_boot_prop)
diff --git a/private/property.te b/private/property.te
index 66c9cea..8d99e66 100644
--- a/private/property.te
+++ b/private/property.te
@@ -2,6 +2,7 @@
 system_internal_prop(adbd_prop)
 system_internal_prop(apexd_payload_metadata_prop)
 system_internal_prop(ctl_snapuserd_prop)
+system_internal_prop(device_config_core_experiments_team_internal_prop)
 system_internal_prop(device_config_lmkd_native_prop)
 system_internal_prop(device_config_mglru_native_prop)
 system_internal_prop(device_config_profcollect_native_boot_prop)
@@ -51,6 +52,8 @@
 system_internal_prop(virtualizationservice_prop)
 system_internal_prop(ctl_apex_load_prop)
 
+system_internal_prop(sensors_config_prop)
+
 # Properties which can't be written outside system
 system_restricted_prop(device_config_virtualization_framework_native_prop)
 system_restricted_prop(log_file_logger_prop)
diff --git a/private/property_contexts b/private/property_contexts
index 5c08328..3400597 100644
--- a/private/property_contexts
+++ b/private/property_contexts
@@ -253,6 +253,7 @@
 persist.device_config.camera_native.                u:object_r:device_config_camera_native_prop:s0
 persist.device_config.configuration.                u:object_r:device_config_configuration_prop:s0
 persist.device_config.connectivity.                 u:object_r:device_config_connectivity_prop:s0
+persist.device_config.core_experiments_team_internal.  u:object_r:device_config_core_experiments_team_internal_prop:s0
 persist.device_config.edgetpu_native.               u:object_r:device_config_edgetpu_native_prop:s0
 persist.device_config.input_native_boot.            u:object_r:device_config_input_native_boot_prop:s0
 persist.device_config.lmkd_native.                  u:object_r:device_config_lmkd_native_prop:s0
@@ -1567,3 +1568,6 @@
 # Properties for Quick Start setup.
 ro.quick_start.oem_id u:object_r:quick_start_prop:s0 exact string
 ro.quick_start.device_id u:object_r:quick_start_prop:s0 exact string
+
+# Properties for sensor service
+sensors.aosp_low_power_sensor_fusion.maximum_rate u:object_r:sensors_config_prop:s0 exact uint
diff --git a/private/rs.te b/private/rs.te
index 906373b..2674c0e 100644
--- a/private/rs.te
+++ b/private/rs.te
@@ -32,6 +32,10 @@
 # File descriptors passed from app to renderscript
 allow rs { untrusted_app_all ephemeral_app priv_app }:fd use;
 
+# See b/291211299. Since rs is deprecated, this shouldn't be too dangerous, since new
+# renderscript usages shouldn't be popping up.
+dontaudit rs { zygote surfaceflinger hal_graphics_allocator }:fd use;
+
 # rs can access app data, so ensure it can only be entered via an app domain and cannot have
 # CAP_DAC_OVERRIDE.
 neverallow rs rs:capability_class_set *;
diff --git a/private/seapp_contexts b/private/seapp_contexts
index c22c046..bc68209 100644
--- a/private/seapp_contexts
+++ b/private/seapp_contexts
@@ -69,6 +69,8 @@
 #              minTargetSdkVersion= integer. Note that minTargetSdkVersion=
 #              defaults to 0 if unspecified.
 #       (8) fromRunAs=true before fromRunAs=false.
+#       (9) Platform seapp_contexts files (system, system_ext, product) before
+#              vendor seapp_contexts files (vendor, odm).
 # (A fixed selector is more specific than a prefix, i.e. ending in *, and a
 # longer prefix is more specific than a shorter prefix.)
 # Apps are checked against entries in precedence order until the first match,
@@ -159,6 +161,7 @@
 user=_app seinfo=platform name=com.android.traceur domain=traceur_app type=app_data_file levelFrom=all
 user=system seinfo=platform domain=system_app type=system_app_data_file
 user=system seinfo=platform isPrivApp=true name=com.android.DeviceAsWebcam domain=device_as_webcam type=system_app_data_file levelFrom=all
+user=system seinfo=platform isPrivApp=true name=com.android.virtualcamera domain=virtual_camera type=app_data_file levelFrom=all
 user=bluetooth seinfo=bluetooth domain=bluetooth type=bluetooth_data_file
 user=network_stack seinfo=network_stack domain=network_stack type=radio_data_file
 user=nfc seinfo=platform domain=nfc type=nfc_data_file
diff --git a/private/service_contexts b/private/service_contexts
index a731dfd..94f913d 100644
--- a/private/service_contexts
+++ b/private/service_contexts
@@ -33,6 +33,7 @@
 # The instance here is internal/0 following naming convention for ICameraProvider.
 # It advertises internal camera devices.
 android.hardware.camera.provider.ICameraProvider/internal/0          u:object_r:hal_camera_service:s0
+android.hardware.camera.provider.ICameraProvider/virtual/0           u:object_r:virtual_camera_service:s0
 android.hardware.cas.IMediaCasService/default                        u:object_r:hal_cas_service:s0
 android.hardware.confirmationui.IConfirmationUI/default              u:object_r:hal_confirmationui_service:s0
 android.hardware.contexthub.IContextHub/default                      u:object_r:hal_contexthub_service:s0
diff --git a/private/system_server.te b/private/system_server.te
index e78a734..cacb3c8 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -743,6 +743,7 @@
 set_prop(system_server, cppreopt_prop)
 
 # server configurable flags properties
+set_prop(system_server, device_config_core_experiments_team_internal_prop)
 set_prop(system_server, device_config_edgetpu_native_prop)
 set_prop(system_server, device_config_input_native_boot_prop)
 set_prop(system_server, device_config_netd_native_prop)
@@ -854,6 +855,10 @@
 # Allow the heap dump ART plugin to the count of sessions waiting for OOME
 get_prop(system_server, traced_oome_heap_session_count_prop)
 
+# Allow the sensor service (running in the system service) to read sensor
+# configuration properties
+get_prop(system_server, sensors_config_prop)
+
 # Create a socket for connections from debuggerd.
 allow system_server system_ndebug_socket:sock_file create_file_perms;
 
@@ -954,6 +959,7 @@
 allow system_server storaged_service:service_manager find;
 allow system_server surfaceflinger_service:service_manager find;
 allow system_server update_engine_service:service_manager find;
+allow system_server virtual_camera_service:service_manager find;
 allow system_server vold_service:service_manager find;
 allow system_server wifinl80211_service:service_manager find;
 allow system_server logd_service:service_manager find;
@@ -1308,6 +1314,7 @@
   -system_server
   -flags_health_check
 } {
+  device_config_core_experiments_team_internal_prop
   device_config_activity_manager_native_boot_prop
   device_config_connectivity_prop
   device_config_input_native_boot_prop
diff --git a/private/virtual_camera.te b/private/virtual_camera.te
new file mode 100644
index 0000000..c39625d
--- /dev/null
+++ b/private/virtual_camera.te
@@ -0,0 +1,16 @@
+# virtual_camera - virtual camera daemon
+
+type virtual_camera, domain, coredomain;
+
+app_domain(virtual_camera)
+
+allow virtual_camera system_app_data_file:dir create_dir_perms;
+allow virtual_camera system_app_data_file:file create_file_perms;
+
+allow virtual_camera activity_service:service_manager find;
+
+# hal_server_domain adds this rule to prevent any other domain from adding
+# a virtual_camera_service. We cannot mix app_domain and hal_server_domain
+# so we use app_domain and manully add the neverallow
+allow virtual_camera virtual_camera_service:service_manager add;
+neverallow { domain -virtual_camera} virtual_camera_service:service_manager add;
diff --git a/public/cameraserver.te b/public/cameraserver.te
index c88e3f0..8a4016c 100644
--- a/public/cameraserver.te
+++ b/public/cameraserver.te
@@ -37,6 +37,7 @@
 
 allow cameraserver hidl_token_hwservice:hwservice_manager find;
 allow cameraserver hal_camera_service:service_manager find;
+allow cameraserver virtual_camera_service:service_manager find;
 
 # Allow to talk with surfaceflinger through unix stream socket
 allow cameraserver surfaceflinger:unix_stream_socket { read write };
diff --git a/public/service.te b/public/service.te
index fc966b1..fa19abc 100644
--- a/public/service.te
+++ b/public/service.te
@@ -49,6 +49,7 @@
 type update_engine_service,     service_manager_type;
 type update_engine_stable_service, service_manager_type;
 type virtualization_service,    service_manager_type;
+type virtual_camera_service,    service_manager_type;
 type virtual_touchpad_service,  service_manager_type;
 type vold_service,              service_manager_type;
 type vr_hwc_service,            service_manager_type;
diff --git a/tools/check_seapp.c b/tools/check_seapp.c
index 0d7a4d1..862ecce 100644
--- a/tools/check_seapp.c
+++ b/tools/check_seapp.c
@@ -21,6 +21,7 @@
 #define log_info(fmt, ...) if (logging_verbose ) { log_msg(stdout, "Info: ", fmt, ##__VA_ARGS__); }
 
 #define APP_DATA_REQUIRED_ATTRIB "app_data_file_type"
+#define COREDOMAIN "coredomain"
 
 /**
  * Initializes an empty, static list.
@@ -61,6 +62,7 @@
 typedef struct list list;
 typedef struct key_map_regex key_map_regex;
 typedef struct file_info file_info;
+typedef struct coredomain_violation_entry coredomain_violation_entry;
 
 enum map_match {
 	map_no_matches,
@@ -106,7 +108,7 @@
 	key_dir dir;
 	char *data;
 	key_map_regex regex;
-	bool (*fn_validate)(char *value, char **errmsg);
+	bool (*fn_validate)(char *value, const char *filename, int lineno, char **errmsg);
 };
 
 /**
@@ -149,6 +151,7 @@
 	sepol_policy_file_t *pf;
 	sepol_handle_t *handle;
 	sepol_context_t *con;
+	bool vendor;
 };
 
 struct file_info {
@@ -157,6 +160,14 @@
 	list_element listify;
 };
 
+struct coredomain_violation_entry {
+	list_element listify;
+	char *domain;
+	char *filename;
+	int lineno;
+};
+
+static void coredomain_violation_list_freefn(list_element *e);
 static void input_file_list_freefn(list_element *e);
 static void line_order_list_freefn(list_element *e);
 static void rule_map_free(rule_map *rm, bool is_in_htable);
@@ -169,13 +180,16 @@
 
 static list input_file_list = list_init(input_file_list_freefn);
 
+static list coredomain_violation_list = list_init(coredomain_violation_list_freefn);
+
 static policy_info pol = {
 	.policy_file_name = NULL,
 	.policy_file = NULL,
 	.db = NULL,
 	.pf = NULL,
 	.handle = NULL,
-	.con = NULL
+	.con = NULL,
+	.vendor = false
 };
 
 /**
@@ -192,12 +206,12 @@
 static list nallow_list = list_init(line_order_list_freefn);
 
 /* validation call backs */
-static bool validate_bool(char *value, char **errmsg);
-static bool validate_levelFrom(char *value, char **errmsg);
-static bool validate_domain(char *value, char **errmsg);
-static bool validate_type(char *value, char **errmsg);
-static bool validate_selinux_level(char *value, char **errmsg);
-static bool validate_uint(char *value, char **errmsg);
+static bool validate_bool(char *value, const char *filename, int lineno, char **errmsg);
+static bool validate_levelFrom(char *value, const char *filename, int lineno, char **errmsg);
+static bool validate_domain(char *value, const char *filename, int lineno, char **errmsg);
+static bool validate_type(char *value, const char *filename, int lineno, char **errmsg);
+static bool validate_selinux_level(char *value, const char *filename, int lineno, char **errmsg);
+static bool validate_uint(char *value, const char *filename, int lineno, char **errmsg);
 
 /**
  * The heart of the mapping process, this must be updated if a new key value pair is added
@@ -278,6 +292,14 @@
 	free(f);
 }
 
+static void coredomain_violation_list_freefn(list_element *e) {
+	coredomain_violation_entry *c = list_entry(e, typeof(*c), listify);
+
+	free(c->domain);
+	free(c->filename);
+	free(c);
+}
+
 /**
  * Send a logging message to a file
  * @param out
@@ -377,8 +399,11 @@
 	return true;
 }
 
-static bool validate_bool(char *value, char **errmsg) {
-
+static bool validate_bool(
+		char *value,
+		__attribute__ ((unused)) const char *filename,
+		__attribute__ ((unused)) int lineno,
+		char **errmsg) {
 	if (!strcmp("true", value) || !strcmp("false", value)) {
 		return true;
 	}
@@ -387,8 +412,11 @@
 	return false;
 }
 
-static bool validate_levelFrom(char *value, char **errmsg) {
-
+static bool validate_levelFrom(
+		char *value,
+		__attribute__ ((unused)) const char *filename,
+		__attribute__ ((unused)) int lineno,
+		char **errmsg) {
 	if (strcasecmp(value, "none") && strcasecmp(value, "all") &&
 		strcasecmp(value, "app") && strcasecmp(value, "user")) {
 		*errmsg = "Expecting one of: \"none\", \"all\", \"app\" or \"user\"";
@@ -397,7 +425,7 @@
 	return true;
 }
 
-static bool validate_domain(char *value, char **errmsg) {
+static bool validate_domain(char *value, const char *filename, int lineno, char **errmsg) {
 
 #if defined(LINK_SEPOL_STATIC)
 	/*
@@ -408,17 +436,37 @@
 		return true;
 	}
 
-	if (!find_type(pol.db, value, TYPE_TYPE)) {
+	type_datum_t *type_dat = find_type(pol.db, value, TYPE_TYPE);
+	if (!type_dat) {
 		*errmsg = "Expecting a valid SELinux type";
 		return false;
 	}
+
+	if (pol.vendor) {
+		type_datum_t *attrib_dat = find_type(pol.db, COREDOMAIN, TYPE_ATTRIB);
+		if (!attrib_dat) {
+			*errmsg = "The attribute " COREDOMAIN " is not defined in the policy";
+			return false;
+		}
+
+		if (type_has_attribute(pol.db, type_dat, attrib_dat)) {
+			coredomain_violation_entry *entry = (coredomain_violation_entry *)malloc(sizeof(*entry));
+			entry->domain = strdup(value);
+			entry->filename = strdup(filename);
+			entry->lineno = lineno;
+			list_append(&coredomain_violation_list, &entry->listify);
+		}
+	}
 #endif
 
 	return true;
 }
 
-static bool validate_type(char *value, char **errmsg) {
-
+static bool validate_type(
+		char *value,
+		__attribute__ ((unused)) const char *filename,
+		__attribute__ ((unused)) int lineno,
+		char **errmsg) {
 #if defined(LINK_SEPOL_STATIC)
 	/*
 	 * No policy file present means we cannot check
@@ -451,8 +499,11 @@
 	return true;
 }
 
-static bool validate_selinux_level(char *value, char **errmsg) {
-
+static bool validate_selinux_level(
+		char *value,
+		__attribute__ ((unused)) const char *filename,
+		__attribute__ ((unused)) int lineno,
+		char **errmsg) {
 	/*
 	 * No policy file present means we cannot check
 	 * SE Linux MLS
@@ -470,8 +521,11 @@
 	return true;
 }
 
-static bool validate_uint(char *value, char **errmsg) {
-
+static bool validate_uint(
+		char *value,
+		__attribute__ ((unused)) const char *filename,
+		__attribute__ ((unused)) int lineno,
+		char **errmsg) {
 	char *endptr;
 	long longvalue;
 	longvalue = strtol(value, &endptr, 10);
@@ -528,7 +582,7 @@
 
 	/* If the key has a validation routine, call it */
 	if (m->fn_validate) {
-		rc = m->fn_validate(value, &errmsg);
+		rc = m->fn_validate(value, filename, lineno, &errmsg);
 
 		if (!rc) {
 			log_error("Could not validate key \"%s\" for value \"%s\" on line: %d in file: \"%s\": %s\n", key, value,
@@ -996,7 +1050,7 @@
 	int c;
 	file_info *input_file;
 
-	while ((c = getopt(argc, argv, "ho:p:v")) != -1) {
+	while ((c = getopt(argc, argv, "ho:p:vc")) != -1) {
 		switch (c) {
 		case 'h':
 			usage();
@@ -1010,6 +1064,9 @@
 		case 'v':
 			log_set_verbose();
 			break;
+		case 'c':
+			pol.vendor = true;
+			break;
 		case '?':
 			if (optopt == 'o' || optopt == 'p')
 				log_error("Option -%c requires an argument.\n", optopt);
@@ -1228,6 +1285,7 @@
 	bool found_issues = false;
 	hash_entry *e;
 	rule_map *r;
+	coredomain_violation_entry *c;
 	list_for_each(&line_order_list, cursor) {
 		e = list_entry(cursor, typeof(*e), listify);
 		rule_map_validate(e->r);
@@ -1247,6 +1305,12 @@
 		}
 	}
 
+	list_for_each(&coredomain_violation_list, cursor) {
+		c = list_entry(cursor, typeof(*c), listify);
+		fprintf(stderr, "Forbidden attribute " COREDOMAIN " assigned to domain \"%s\" in "
+                        "File \"%s\" on line %d\n", c->domain, c->filename, c->lineno);
+	}
+
 	if (found_issues) {
 		exit(EXIT_FAILURE);
 	}
@@ -1305,6 +1369,7 @@
 	list_free(&input_file_list);
 	list_free(&line_order_list);
 	list_free(&nallow_list);
+	list_free(&coredomain_violation_list);
 	hdestroy();
 }