diff --git a/tests/Makefile.am b/tests/Makefile.am
index a0463b7b5b5..9a7d8a1f989 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -2,7 +2,7 @@ check_SCRIPTS =
 TESTS = $(check_SCRIPTS)
 
 check_SCRIPTS += ima_hash.test sign_verify.test boot_aggregate.test \
-		 fsverity.test portable_signatures.test
+		 fsverity.test portable_signatures.test ima_policy_check.test
 
 .PHONY: check_logs
 check_logs:
diff --git a/tests/ima_policy_check.awk b/tests/ima_policy_check.awk
new file mode 100755
index 00000000000..bb39153c182
--- /dev/null
+++ b/tests/ima_policy_check.awk
@@ -0,0 +1,142 @@
+#! /usr/bin/awk -f
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2023 Roberto Sassu <roberto.sassu@huawei.com>
+#
+# Check possible interference of a new rule with the existing IMA policy.
+
+# Documentation/ABI/testing/ima_policy (Linux kernel)
+# base:	[[func=] [mask=] [fsmagic=] [fsuuid=] [fsname=]
+#	[uid=] [euid=] [gid=] [egid=]
+#	[fowner=] [fgroup=]]
+# lsm:	[[subj_user=] [subj_role=] [subj_type=]
+#	[obj_user=] [obj_role=] [obj_type=]]
+# option:	[digest_type=] [template=] [permit_directio]
+#		[appraise_type=] [appraise_flag=]
+#		[appraise_algos=] [keyrings=]
+#
+# Non interference if:
+# - non-overlapping rules (different values for policy keywords)
+# - overlapping rules with same action and same policy options
+#
+# Rules overlap if they have different policy keywords or same policy keywords
+# and same values.
+#
+# The same policy options and value requirement is needed as otherwise tests
+# might match an overlapping rule with undesired/missing policy options.
+#
+# Rules with MMAP_CHECK and MMAP_CHECK_REQPROT are considered as an exception.
+# They overlap, despite they have a different name. In addition, combinations of
+# them are reported as interference, since they are matched depending on
+# external factors, not inferrable from the policy (a MMAP_CHECK rule might
+# cause a measurement, while a MMAP_CHECK_REQPROT one might not).
+#
+# More/less specific rules are considered as overlapping.
+#
+# Overlapping rules must have the same policy options, or tests might match
+# policy rules set by other tests with undesired policy options.
+
+BEGIN {
+	keywords_str="func mask fsmagic fsuuid fsname uid euid gid egid fowner fgroup subj_user subj_role subj_type obj_user obj_role obj_type";
+	split(keywords_str, keywords_array, " ");
+	options_str="digest_type template permit_directio appraise_type appraise_flag appraise_algos keyrings";
+	split(options_str, options_array, " ");
+	key_type_unknown=0;
+	key_type_keyword=1;
+	key_type_option=2;
+	for (keyword in keywords_array)
+		key_types[keywords_array[keyword]]=key_type_keyword;
+	for (option in options_array)
+		key_types[options_array[option]]=key_type_option;
+	new_rule=1;
+	mmap_check_interference=0;
+}
+{
+	if (new_rule) {
+		new_rule_action=$1;
+		# Strip dont_ from the action of the new rule.
+		new_rule_action_sub=new_rule_action;
+		gsub(/dont_/, "", new_rule_action_sub);
+	} else {
+		current_action=$1;
+		# Strip dont_ from the action of the current rule.
+		current_action_sub=current_action;
+		gsub(/dont_/, "", current_action_sub);
+		# Unrelated action, ignore.
+		if (new_rule_action_sub != current_action_sub) {
+			next;
+		}
+		# Store policy options of the new rule into an array, to compare with the options of the current rule.
+		delete new_rule_extra_options;
+		for (key in new_rule_array) {
+			if (key_types[key] == key_type_option) {
+				new_rule_extra_options[key]=new_rule_array[key];
+			}
+		}
+		current_rule_extra_options=0;
+	}
+	for (i=2; i<=NF; i++) {
+		# Parse key/value pair.
+		split($i, key_value_array, "=");
+		key=key_value_array[1];
+		value=key_value_array[2];
+		if (key == "func") {
+			# Normalize values of IMA hooks.
+			if (value == "FILE_MMAP") {
+				value="MMAP_CHECK";
+			} else if (value == "PATH_CHECK") {
+				value="FILE_CHECK";
+			}
+		}
+		# Store key/value pair from the new rule into an array.
+		if (new_rule) {
+			# Check if the key is valid.
+			if (key_types[key] == key_type_unknown) {
+				exit 1;
+			}
+			new_rule_array[key]=value;
+		} else {
+			if (key_types[key] == key_type_keyword) {
+				# No overlap and no operators, no interference.
+				if (key in new_rule_array && new_rule_array[key] != value && value !~ /^[<,>,^]/) {
+					# Exception: MMAP_CHECK and MMAP_CHECK_REQPROT overlap and have different behavior, interference if overlap (cannot be determined yet).
+					if (key == "func" && new_rule_array[key] ~ /MMAP_CHECK/ && value ~ /MMAP_CHECK/) {
+						mmap_check_interference=1;
+						continue;
+					}
+					next;
+				}
+			} else if (key_types[key] == key_type_option) {
+				# Possible overlap and different policy options, interference if overlap (cannot be determined yet).
+				if (!(key in new_rule_extra_options)) {
+					current_rule_extra_options=1;
+				# Possible overlap, same policy option and same value, current option can be deleted from the new_rule_extra_options array.
+				} else if (new_rule_extra_options[key] == value) {
+					delete new_rule_extra_options[key];
+				}
+				# Possible overlap and same policy option but with different value, interference if overlap (cannot be determined yet).
+			}
+		}
+	}
+	# Always ok to parse a new rule.
+	if (new_rule) {
+		new_rule=0;
+		next;
+	}
+	# Overlap and different related action, interference.
+	if (current_action != new_rule_action) {
+		exit 1;
+	}
+	# Overlap and different policy options or different option values, interference.
+	for (key in new_rule_extra_options) {
+		exit 1;
+	}
+	if (current_rule_extra_options) {
+		exit 1;
+	}
+	# Overlap and MMAP_CHECK/MMAP_CHECK_REQPROT, interference.
+	if (mmap_check_interference) {
+		exit 1;
+	}
+	# Overlap with same related action and same policy options, ok.
+}
diff --git a/tests/ima_policy_check.test b/tests/ima_policy_check.test
new file mode 100755
index 00000000000..f1e79ca451f
--- /dev/null
+++ b/tests/ima_policy_check.test
@@ -0,0 +1,319 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2023 Roberto Sassu <roberto.sassu@huawei.com>
+#
+# Test for ima_policy_check.awk
+
+trap '_report_exit_and_cleanup' SIGINT SIGTERM EXIT
+
+cd "$(dirname "$0")" || exit 1
+. ./functions.sh
+
+export PATH=$PWD:$PATH
+
+# Base VERBOSE on the environment variable, if set.
+VERBOSE="${VERBOSE:-0}"
+
+check_interference() {
+	echo -e "\nTest: $1"
+	echo "New rule: $2"
+	echo "IMA policy: $3"
+
+	if [ "$TFAIL" != "yes" ]; then
+		echo -n "Result (expect no interference): "
+	else
+		echo -n "Result (expect interference): "
+	fi
+
+	if ! echo -e "$2\n$3" | ima_policy_check.awk; then
+		if [ "$TFAIL" != "yes" ]; then
+			echo "${RED}interference${NORM}"
+		else
+			echo "${GREEN}interference${NORM}"
+		fi
+		return "$FAIL"
+	fi
+
+	if [ "$TFAIL" != "yes" ]; then
+		echo "${GREEN}no interference${NORM}"
+	else
+		echo "${RED}no interference${NORM}"
+	fi
+	return "$OK"
+}
+
+# Basic check.
+desc="empty IMA policy"
+rule="measure func=FILE_CHECK"
+ima_policy=""
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+# Wrong new rule.
+desc="Wrong new rule"
+rule="measure fun=FILE_CHECK"
+ima_policy=""
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+# Unrelated/related actions.
+desc="unrelated actions measure/appraise"
+rule="measure func=FILE_CHECK"
+ima_policy="appraise func=FILE_CHECK"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="unrelated actions appraise/measure"
+rule="appraise func=FILE_CHECK"
+ima_policy="measure func=FILE_CHECK"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="unrelated actions appraise/dont_measure"
+rule="appraise func=FILE_CHECK"
+ima_policy="dont_measure func=FILE_CHECK"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="related actions measure/dont_measure"
+rule="measure func=FILE_CHECK"
+ima_policy="dont_measure func=FILE_CHECK"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="related actions dont_measure/measure"
+rule="measure func=FILE_CHECK"
+ima_policy="dont_measure func=FILE_CHECK"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="related actions dont_appraise/appraise"
+rule="dont_appraise func=FILE_CHECK"
+ima_policy="appraise func=FILE_CHECK"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+# Unrelated rules by different values for policy keywords.
+desc="same action, unrelated by func"
+rule="measure func=FILE_CHECK"
+ima_policy="measure func=MMAP_CHECK"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="different action, unrelated by func"
+rule="measure func=FILE_CHECK"
+ima_policy="dont_measure func=MMAP_CHECK"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="different action, unrelated by mask"
+rule="measure func=FILE_CHECK mask=MAY_EXEC"
+ima_policy="dont_measure func=FILE_CHECK mask=MAY_READ"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="different action, unrelated by fowner"
+rule="measure func=FILE_CHECK fowner=1 mask=MAY_EXEC"
+ima_policy="dont_measure func=FILE_CHECK mask=MAY_EXEC fowner=0"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+# Unrelated rules with different policy options.
+desc="different action, unrelated by fowner, different policy options"
+rule="measure func=FILE_CHECK fowner=1 mask=MAY_EXEC"
+ima_policy="dont_measure func=FILE_CHECK mask=MAY_EXEC fowner=0 permit_directio"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, unrelated by fowner, different policy options"
+rule="measure func=FILE_CHECK fowner=1 mask=MAY_EXEC"
+ima_policy="measure func=FILE_CHECK mask=MAY_EXEC fowner=0 permit_directio"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+# Related rules by different policy keywords.
+desc="same action, add with uid, existing with func, no policy options"
+rule="measure uid=0"
+ima_policy="measure func=FILE_CHECK"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="different action, add with uid, existing with func, no policy options"
+rule="measure uid=0"
+ima_policy="dont_measure func=FILE_CHECK"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with uid, existing with func, different policy options"
+rule="measure uid=0 permit_directio"
+ima_policy="measure func=FILE_CHECK"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with uid, existing with func, different policy options"
+rule="measure uid=0"
+ima_policy="measure func=FILE_CHECK permit_directio"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with uid, existing with func, same policy options"
+rule="measure uid=0 permit_directio"
+ima_policy="measure func=FILE_CHECK permit_directio"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+# Related rules by same policy keywords and same value, with policy options.
+desc="same action, add with func, existing with func, same policy options"
+rule="measure func=FILE_CHECK permit_directio"
+ima_policy="measure func=FILE_CHECK permit_directio"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func, existing with func, different policy options"
+rule="measure func=FILE_CHECK"
+ima_policy="measure func=FILE_CHECK permit_directio"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func, existing with func, different policy options"
+rule="measure func=FILE_CHECK permit_directio"
+ima_policy="measure func=FILE_CHECK"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="different action, add with func, existing with func, no policy options"
+rule="measure func=FILE_CHECK"
+ima_policy="dont_measure func=FILE_CHECK"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="different action, add with func, existing with func, no policy options"
+rule="dont_measure func=FILE_CHECK"
+ima_policy="measure func=FILE_CHECK"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="different action, add with func, existing with func, same policy options"
+rule="dont_measure func=FILE_CHECK permit_directio"
+ima_policy="measure func=FILE_CHECK permit_directio"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="different action, add with func, existing with func, same policy options"
+rule="measure func=FILE_CHECK permit_directio"
+ima_policy="dont_measure func=FILE_CHECK permit_directio"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+# Related rules by same policy keywords and different value but with unsupported operator.
+desc="different action, add with func and uid, existing with func and different uid"
+rule="dont_measure func=FILE_CHECK uid=>0"
+ima_policy="measure func=FILE_CHECK uid=>1"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func and uid, existing with func and different uid"
+rule="measure func=FILE_CHECK uid=>0"
+ima_policy="measure func=FILE_CHECK uid=>1"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func and uid, existing with func and different uid, different policy options"
+rule="measure func=FILE_CHECK uid=>0 permit_directio"
+ima_policy="measure func=FILE_CHECK uid=>1"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func and uid, existing with func and different uid, same policy options"
+rule="measure func=FILE_CHECK uid=>0 permit_directio"
+ima_policy="measure func=FILE_CHECK uid=>1 permit_directio"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+# Related rules by subset/superset policy keywords.
+desc="different action, add with func and uid, existing with func"
+rule="dont_measure func=FILE_CHECK uid=0"
+ima_policy="measure func=FILE_CHECK"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func and uid, existing with func"
+rule="measure func=FILE_CHECK uid=0"
+ima_policy="measure func=FILE_CHECK"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func and uid, existing with func"
+rule="dont_measure func=FILE_CHECK uid=0"
+ima_policy="dont_measure func=FILE_CHECK"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func and uid, existing with func, different policy options"
+rule="measure func=FILE_CHECK uid=0"
+ima_policy="measure func=FILE_CHECK permit_directio"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func and uid, existing with func, same policy options"
+rule="measure func=FILE_CHECK uid=0 permit_directio"
+ima_policy="measure func=FILE_CHECK permit_directio"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func, existing with func and uid, same policy options (multiple)"
+rule="measure func=FILE_CHECK uid=0 permit_directio appraise_type=imasig"
+ima_policy="measure func=FILE_CHECK permit_directio appraise_type=imasig"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="different action, add with func, existing with func and uid"
+rule="dont_measure func=FILE_CHECK"
+ima_policy="measure func=FILE_CHECK uid=0"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func, existing with func and uid"
+rule="measure func=FILE_CHECK"
+ima_policy="measure func=FILE_CHECK uid=0"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func, existing with func and uid"
+rule="dont_measure func=FILE_CHECK"
+ima_policy="dont_measure func=FILE_CHECK uid=0"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func and uid, existing with func, different policy options"
+rule="measure func=FILE_CHECK"
+ima_policy="measure func=FILE_CHECK uid=0 permit_directio"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func, existing with func and uid, same policy options"
+rule="measure func=FILE_CHECK permit_directio"
+ima_policy="measure func=FILE_CHECK uid=0 permit_directio"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, add with func, existing with func and uid, same policy options (multiple)"
+rule="measure func=FILE_CHECK permit_directio appraise_type=imasig"
+ima_policy="measure func=FILE_CHECK uid=0 permit_directio appraise_type=imasig"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+# Different policy options in a non-overlapping rule.
+desc="same action, add with func, existing with func and uid, no policy options"
+rule="measure func=FILE_CHECK uid=1"
+ima_policy="measure func=FILE_CHECK permit_directio uid=0"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+# Same policy option with different value in an overlapping rule.
+desc="same action, add with func, existing with func and uid, same policy option with different value"
+rule="measure func=FILE_CHECK permit_directio appraise_type=imasig"
+ima_policy="measure func=FILE_CHECK uid=0 permit_directio appraise_type=sigv3"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+# Same policy option with different value in an non-overlapping rule.
+desc="same action, add with func and uid, existing with func and different uid, same policy option with different value"
+rule="measure func=FILE_CHECK uid=1 permit_directio appraise_type=imasig"
+ima_policy="measure func=FILE_CHECK uid=0 permit_directio appraise_type=sigv3"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+# Same policy option with different value in an non-overlapping rule, uid is the last.
+desc="same action, add with func and uid, existing with func and different uid, same policy option with different value"
+rule="measure func=FILE_CHECK permit_directio appraise_type=imasig uid=1"
+ima_policy="measure func=FILE_CHECK permit_directio appraise_type=sigv3 uid=0"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+# MMAP_CHECK and MMAP_CHECK_REQPROT hooks.
+desc="same action, MMAP_CHECK and MMAP_CHECK_REQPROT hooks"
+rule="measure func=MMAP_CHECK"
+ima_policy="measure func=MMAP_CHECK_REQPROT"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="different action, MMAP_CHECK and MMAP_CHECK_REQPROT hooks"
+rule="measure func=MMAP_CHECK"
+ima_policy="dont_measure func=MMAP_CHECK_REQPROT"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, MMAP_CHECK and MMAP_CHECK_REQPROT hooks, overlapping rules and IMA policy more specific"
+rule="measure func=MMAP_CHECK"
+ima_policy="measure func=MMAP_CHECK_REQPROT uid=0"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, MMAP_CHECK and MMAP_CHECK_REQPROT hooks, non-overlapping rules"
+rule="measure func=MMAP_CHECK uid=1"
+ima_policy="measure func=MMAP_CHECK_REQPROT uid=0"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+desc="same action, same hook MMAP_CHECK"
+rule="measure func=MMAP_CHECK"
+ima_policy="measure func=MMAP_CHECK"
+expect_pass check_interference "$desc" "$rule" "$ima_policy"
+
+# Hook aliases.
+desc="different action, FILE_CHECK hook and its alias"
+rule="measure func=FILE_CHECK"
+ima_policy="dont_measure func=PATH_CHECK"
+expect_fail check_interference "$desc" "$rule" "$ima_policy"
