diff --git a/policy/Makefile b/policy/Makefile
index 91364d5..33951a5 100644
--- a/policy/Makefile
+++ b/policy/Makefile
@@ -41,7 +41,13 @@ CIL_TARGETS = test_mlsconstrain.cil test_overlay_defaultrange.cil
 ifeq ($(shell [ $(MOD_POL_VERS) -ge 18 -a $(MAX_KERNEL_POLICY) -ge 30 ] && echo true),true)
 CIL_TARGETS += test_userfaultfd.cil
 TARGETS += test_userfaultfd.te
-endif
+ifeq ($(shell cat $(SELINUXFS)/policy_capabilities/extended_anon_inode_class \
+	2>/dev/null || echo 0),1)
+CIL_TARGETS += test_anon_inode_extended.cil
+else
+CIL_TARGETS += test_anon_inode_legacy.cil
+endif # policy_capabilities/extended_anon_inode_class
+endif # extended permissions
 ifeq ($(shell [ $(MAX_KERNEL_POLICY) -ge 32 ] && echo true),true)
 ifeq ($(shell [ $(POL_VERS) -ge 32 ] && echo true),true)
 # If other MLS tests get written this can be moved outside of the glblub test
diff --git a/policy/test_anon_inode_extended.cil b/policy/test_anon_inode_extended.cil
new file mode 100644
index 0000000..af5b0d2
--- /dev/null
+++ b/policy/test_anon_inode_extended.cil
@@ -0,0 +1 @@
+(tunable extended_anon_inode true)
diff --git a/policy/test_anon_inode_legacy.cil b/policy/test_anon_inode_legacy.cil
new file mode 100644
index 0000000..4c81e91
--- /dev/null
+++ b/policy/test_anon_inode_legacy.cil
@@ -0,0 +1 @@
+(tunable extended_anon_inode false)
diff --git a/policy/test_userfaultfd.cil b/policy/test_userfaultfd.cil
index 18d5f3f..01fe2fa 100644
--- a/policy/test_userfaultfd.cil
+++ b/policy/test_userfaultfd.cil
@@ -1,52 +1,75 @@
-; Define new class anon_inode
-(class anon_inode ())
-(classcommon anon_inode file)
-(classorder (unordered anon_inode))
-
-; Allow all anonymous inodes
-(typeattributeset cil_gen_require test_notransition_uffd_t)
-(allow test_notransition_uffd_t self (anon_inode (create getattr ioctl read)))
-
-(typeattributeset cil_gen_require uffd_t)
-
-; Allow all operations on UFFD
-(typeattributeset cil_gen_require test_uffd_t)
-(typetransition test_uffd_t test_uffd_t anon_inode "[userfaultfd]" uffd_t)
-(allow test_uffd_t uffd_t (anon_inode (create getattr ioctl read)))
-
-; Don't allow any operation on UFFD
-(typeattributeset cil_gen_require test_nocreate_uffd_t)
-(typetransition test_nocreate_uffd_t test_nocreate_uffd_t anon_inode "[userfaultfd]" uffd_t)
-
-; Don't allow getattr operation on UFFD
-(typeattributeset cil_gen_require test_nogetattr_uffd_t)
-(typetransition test_nogetattr_uffd_t test_nogetattr_uffd_t anon_inode "[userfaultfd]" uffd_t)
-(allow test_nogetattr_uffd_t uffd_t (anon_inode (create)))
-
-; Don't allow any ioctl operation on UFFD
-(typeattributeset cil_gen_require test_noioctl_uffd_t)
-(typetransition test_noioctl_uffd_t test_noioctl_uffd_t anon_inode "[userfaultfd]" uffd_t)
-(allow test_noioctl_uffd_t uffd_t (anon_inode (create getattr)))
-
-; Only allow UFFDIO_API ioctl
-(typeattributeset cil_gen_require test_api_ioctl_uffd_t)
-(typetransition test_api_ioctl_uffd_t test_api_ioctl_uffd_t anon_inode "[userfaultfd]" uffd_t)
-(allow test_api_ioctl_uffd_t uffd_t (anon_inode (create getattr ioctl read)))
-(allowx test_api_ioctl_uffd_t uffd_t (ioctl anon_inode ((0xaa3f))))
-
-; Only allow UFFDIO_API and UFFDIO_REGISTER ioctls
-(typeattributeset cil_gen_require test_register_ioctl_uffd_t)
-(typetransition test_register_ioctl_uffd_t test_register_ioctl_uffd_t anon_inode "[userfaultfd]" uffd_t)
-(allow test_register_ioctl_uffd_t uffd_t (anon_inode (create getattr ioctl read)))
-(allowx test_register_ioctl_uffd_t uffd_t (ioctl anon_inode ((0xaa3f 0xaa00))))
-
-; Only allow UFFDIO_API, UFFDIO_REGISTER and UFFDIO_COPY ioctls, which are most used.
-(typeattributeset cil_gen_require test_copy_ioctl_uffd_t)
-(typetransition test_copy_ioctl_uffd_t test_copy_ioctl_uffd_t anon_inode "[userfaultfd]" uffd_t)
-(allow test_copy_ioctl_uffd_t uffd_t (anon_inode (create getattr ioctl read)))
-(allowx test_copy_ioctl_uffd_t uffd_t (ioctl anon_inode ((0xaa3f 0xaa00 0xaa03))))
-
-; Don't allow read operation on UFFD.
-(typeattributeset cil_gen_require test_noread_uffd_t)
-(typetransition test_noread_uffd_t test_noread_uffd_t anon_inode "[userfaultfd]" uffd_t)
-(allow test_noread_uffd_t uffd_t (anon_inode (create getattr ioctl)))
+(macro build_uffd_policy ((class uffd_class))
+	; Allow all anonymous inodes
+	(typeattributeset cil_gen_require test_notransition_uffd_t)
+	(allow test_notransition_uffd_t self (uffd_class (create getattr ioctl read)))
+
+	(typeattributeset cil_gen_require uffd_t)
+
+	; Allow all operations on UFFD
+	(typeattributeset cil_gen_require test_uffd_t)
+	(call uffd_transition (test_uffd_t uffd_t))
+	(allow test_uffd_t uffd_t (uffd_class (create getattr ioctl read)))
+
+	; Don't allow any operation on UFFD
+	(typeattributeset cil_gen_require test_nocreate_uffd_t)
+	(call uffd_transition (test_nocreate_uffd_t uffd_t))
+
+	; Don't allow getattr operation on UFFD
+	(typeattributeset cil_gen_require test_nogetattr_uffd_t)
+	(call uffd_transition (test_nogetattr_uffd_t uffd_t))
+	(allow test_nogetattr_uffd_t uffd_t (uffd_class (create)))
+
+	; Don't allow any ioctl operation on UFFD
+	(typeattributeset cil_gen_require test_noioctl_uffd_t)
+	(call uffd_transition (test_noioctl_uffd_t uffd_t))
+	(allow test_noioctl_uffd_t uffd_t (uffd_class (create getattr)))
+
+	; Only allow UFFDIO_API ioctl
+	(typeattributeset cil_gen_require test_api_ioctl_uffd_t)
+	(call uffd_transition (test_api_ioctl_uffd_t uffd_t))
+	(allow test_api_ioctl_uffd_t uffd_t (uffd_class (create getattr ioctl read)))
+	(allowx test_api_ioctl_uffd_t uffd_t (ioctl uffd_class ((0xaa3f))))
+
+	; Only allow UFFDIO_API and UFFDIO_REGISTER ioctls
+	(typeattributeset cil_gen_require test_register_ioctl_uffd_t)
+	(call uffd_transition (test_register_ioctl_uffd_t uffd_t))
+	(allow test_register_ioctl_uffd_t uffd_t (uffd_class (create getattr ioctl read)))
+	(allowx test_register_ioctl_uffd_t uffd_t (ioctl uffd_class ((0xaa3f 0xaa00))))
+
+	; Only allow UFFDIO_API, UFFDIO_REGISTER and UFFDIO_COPY ioctls, which are most used.
+	(typeattributeset cil_gen_require test_copy_ioctl_uffd_t)
+	(call uffd_transition (test_copy_ioctl_uffd_t uffd_t))
+	(allow test_copy_ioctl_uffd_t uffd_t (uffd_class (create getattr ioctl read)))
+	(allowx test_copy_ioctl_uffd_t uffd_t (ioctl uffd_class ((0xaa3f 0xaa00 0xaa03))))
+
+	; Don't allow read operation on UFFD.
+	(typeattributeset cil_gen_require test_noread_uffd_t)
+	(call uffd_transition (test_noread_uffd_t uffd_t))
+	(allow test_noread_uffd_t uffd_t (uffd_class (create getattr ioctl)))
+)
+
+(tunableif extended_anon_inode
+	(true
+		; Extended anon_inode support - use the userfaultfd class
+		(class userfaultfd ())
+		(classcommon userfaultfd file)
+		(classorder (unordered userfaultfd))
+
+		(macro uffd_transition ((type S) (type T))
+			(typetransition S S userfaultfd T)
+		)
+		(call build_uffd_policy (userfaultfd))
+	)
+	(false
+		; Legacy anon_inode support - use the anon_inode class
+		; + named transition
+		(class anon_inode ())
+		(classcommon anon_inode file)
+		(classorder (unordered anon_inode))
+
+		(macro uffd_transition ((type S) (type T))
+			(typetransition S S anon_inode "[userfaultfd]" T)
+		)
+		(call build_uffd_policy (anon_inode))
+	)
+)
