diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index a280156138ed..0c8e77b69893 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -56,6 +56,7 @@ static struct file_system_type anon_inode_fs_type = {
 };
 
 static struct inode *anon_inode_make_secure_inode(
+	enum lsm_anon_inode_type type,
 	const char *name,
 	const struct inode *context_inode)
 {
@@ -67,7 +68,8 @@ static struct inode *anon_inode_make_secure_inode(
 	if (IS_ERR(inode))
 		return inode;
 	inode->i_flags &= ~S_PRIVATE;
-	error =	security_inode_init_security_anon(inode, &qname, context_inode);
+	error =	security_inode_init_security_anon(inode, type, &qname,
+						  context_inode);
 	if (error) {
 		iput(inode);
 		return ERR_PTR(error);
@@ -75,11 +77,11 @@ static struct inode *anon_inode_make_secure_inode(
 	return inode;
 }
 
-static struct file *__anon_inode_getfile(const char *name,
+static struct file *__anon_inode_getfile(enum lsm_anon_inode_type type,
+					 const char *name,
 					 const struct file_operations *fops,
 					 void *priv, int flags,
-					 const struct inode *context_inode,
-					 bool secure)
+					 const struct inode *context_inode)
 {
 	struct inode *inode;
 	struct file *file;
@@ -87,8 +89,8 @@ static struct file *__anon_inode_getfile(const char *name,
 	if (fops->owner && !try_module_get(fops->owner))
 		return ERR_PTR(-ENOENT);
 
-	if (secure) {
-		inode =	anon_inode_make_secure_inode(name, context_inode);
+	if (type != LSM_ANON_INODE_NONE) {
+		inode =	anon_inode_make_secure_inode(type, name, context_inode);
 		if (IS_ERR(inode)) {
 			file = ERR_CAST(inode);
 			goto err;
@@ -144,15 +146,16 @@ struct file *anon_inode_getfile(const char *name,
 				const struct file_operations *fops,
 				void *priv, int flags)
 {
-	return __anon_inode_getfile(name, fops, priv, flags, NULL, false);
+	return __anon_inode_getfile(LSM_ANON_INODE_NONE, name, fops, priv,
+				    flags, NULL);
 }
 EXPORT_SYMBOL_GPL(anon_inode_getfile);
 
-static int __anon_inode_getfd(const char *name,
+static int __anon_inode_getfd(enum lsm_anon_inode_type type,
+			      const char *name,
 			      const struct file_operations *fops,
 			      void *priv, int flags,
-			      const struct inode *context_inode,
-			      bool secure)
+			      const struct inode *context_inode)
 {
 	int error, fd;
 	struct file *file;
@@ -162,8 +165,8 @@ static int __anon_inode_getfd(const char *name,
 		return error;
 	fd = error;
 
-	file = __anon_inode_getfile(name, fops, priv, flags, context_inode,
-				    secure);
+	file = __anon_inode_getfile(type, name, fops, priv, flags,
+				    context_inode);
 	if (IS_ERR(file)) {
 		error = PTR_ERR(file);
 		goto err_put_unused_fd;
@@ -197,7 +200,8 @@ err_put_unused_fd:
 int anon_inode_getfd(const char *name, const struct file_operations *fops,
 		     void *priv, int flags)
 {
-	return __anon_inode_getfd(name, fops, priv, flags, NULL, false);
+	return __anon_inode_getfd(LSM_ANON_INODE_NONE, name, fops, priv,
+				  flags, NULL);
 }
 EXPORT_SYMBOL_GPL(anon_inode_getfd);
 
@@ -207,7 +211,9 @@ EXPORT_SYMBOL_GPL(anon_inode_getfd);
  * the inode_init_security_anon() LSM hook. This allows the inode to have its
  * own security context and for a LSM to reject creation of the inode.
  *
- * @name:    [in]    name of the "class" of the new file
+ * @type:    [in]    type of the file recognizable by LSMs
+ * @name:    [in]    name of the "class" of the new file (may be more specific
+ *                   than @type)
  * @fops:    [in]    file operations for the new file
  * @priv:    [in]    private data for the new file (will be file's private_data)
  * @flags:   [in]    flags
@@ -217,11 +223,15 @@ EXPORT_SYMBOL_GPL(anon_inode_getfd);
  * The LSM may use @context_inode in inode_init_security_anon(), but a
  * reference to it is not held.
  */
-int anon_inode_getfd_secure(const char *name, const struct file_operations *fops,
+int anon_inode_getfd_secure(enum lsm_anon_inode_type type, const char *name,
+			    const struct file_operations *fops,
 			    void *priv, int flags,
 			    const struct inode *context_inode)
 {
-	return __anon_inode_getfd(name, fops, priv, flags, context_inode, true);
+	/* The caller must pass a valid type! */
+	if (WARN_ON(type <= LSM_ANON_INODE_NONE || type > LSM_ANON_INODE_MAX))
+		return -EINVAL;
+	return __anon_inode_getfd(type, name, fops, priv, flags, context_inode);
 }
 EXPORT_SYMBOL_GPL(anon_inode_getfd_secure);
 
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index 0be8cdd4425a..003f65d752c4 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -985,7 +985,8 @@ static int resolve_userfault_fork(struct userfaultfd_ctx *new,
 {
 	int fd;
 
-	fd = anon_inode_getfd_secure("[userfaultfd]", &userfaultfd_fops, new,
+	fd = anon_inode_getfd_secure(LSM_ANON_INODE_USERFAULTFD,
+			"[userfaultfd]", &userfaultfd_fops, new,
 			O_RDWR | (new->flags & UFFD_SHARED_FCNTL_FLAGS), inode);
 	if (fd < 0)
 		return fd;
@@ -2000,7 +2001,8 @@ SYSCALL_DEFINE1(userfaultfd, int, flags)
 	/* prevent the mm struct to be freed */
 	mmgrab(ctx->mm);
 
-	fd = anon_inode_getfd_secure("[userfaultfd]", &userfaultfd_fops, ctx,
+	fd = anon_inode_getfd_secure(LSM_ANON_INODE_USERFAULTFD,
+			"[userfaultfd]", &userfaultfd_fops, ctx,
 			O_RDWR | (flags & UFFD_SHARED_FCNTL_FLAGS), NULL);
 	if (fd < 0) {
 		mmdrop(ctx->mm);
diff --git a/include/linux/anon_inodes.h b/include/linux/anon_inodes.h
index 71881a2b6f78..37137e994ceb 100644
--- a/include/linux/anon_inodes.h
+++ b/include/linux/anon_inodes.h
@@ -9,6 +9,8 @@
 #ifndef _LINUX_ANON_INODES_H
 #define _LINUX_ANON_INODES_H
 
+#include <linux/security.h>
+
 struct file_operations;
 struct inode;
 
@@ -17,7 +19,7 @@ struct file *anon_inode_getfile(const char *name,
 				void *priv, int flags);
 int anon_inode_getfd(const char *name, const struct file_operations *fops,
 		     void *priv, int flags);
-int anon_inode_getfd_secure(const char *name,
+int anon_inode_getfd_secure(enum lsm_anon_inode_type type, const char *name,
 			    const struct file_operations *fops,
 			    void *priv, int flags,
 			    const struct inode *context_inode);
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 61f04f7dc1a4..ba03a7d0bf1a 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -115,7 +115,8 @@ LSM_HOOK(int, 0, inode_init_security, struct inode *inode,
 	 struct inode *dir, const struct qstr *qstr, const char **name,
 	 void **value, size_t *len)
 LSM_HOOK(int, 0, inode_init_security_anon, struct inode *inode,
-	 const struct qstr *name, const struct inode *context_inode)
+	 enum lsm_anon_inode_type type, const struct qstr *name,
+	 const struct inode *context_inode)
 LSM_HOOK(int, 0, inode_create, struct inode *dir, struct dentry *dentry,
 	 umode_t mode)
 LSM_HOOK(int, 0, inode_link, struct dentry *old_dentry, struct inode *dir,
diff --git a/include/linux/security.h b/include/linux/security.h
index 9aeda3f9e838..7c5117676f29 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -79,6 +79,23 @@ enum lsm_event {
 	LSM_POLICY_CHANGE,
 };
 
+/*
+ * Types of anonymous inodes that may be interesting to LSMs.
+ * Passed to anon_inode_getfd_secure() and
+ * security_inode_init_security_anon().
+ */
+enum lsm_anon_inode_type {
+	/* anon inodes invisible to the LSMs */
+	LSM_ANON_INODE_NONE = 0,
+	/* userfaultfd anon inodes */
+	LSM_ANON_INODE_USERFAULTFD,
+	/* (add new types above this line) */
+
+	__LSM_ANON_INODE_MAX,
+	/* max value used for asserts */
+	LSM_ANON_INODE_MAX = __LSM_ANON_INODE_MAX - 1,
+};
+
 /*
  * These are reasons that can be passed to the security_locked_down()
  * LSM hook. Lockdown reasons that protect kernel integrity (ie, the
@@ -329,6 +346,7 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
 				 const struct qstr *qstr,
 				 initxattrs initxattrs, void *fs_data);
 int security_inode_init_security_anon(struct inode *inode,
+				      enum lsm_anon_inode_type type,
 				      const struct qstr *name,
 				      const struct inode *context_inode);
 int security_old_inode_init_security(struct inode *inode, struct inode *dir,
@@ -759,6 +777,7 @@ static inline int security_inode_init_security(struct inode *inode,
 }
 
 static inline int security_inode_init_security_anon(struct inode *inode,
+						    enum lsm_anon_inode_type type,
 						    const struct qstr *name,
 						    const struct inode *context_inode)
 {
diff --git a/security/security.c b/security/security.c
index 94383f83ba42..3786932c576c 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1067,10 +1067,11 @@ out:
 EXPORT_SYMBOL(security_inode_init_security);
 
 int security_inode_init_security_anon(struct inode *inode,
+				      enum lsm_anon_inode_type type,
 				      const struct qstr *name,
 				      const struct inode *context_inode)
 {
-	return call_int_hook(inode_init_security_anon, 0, inode, name,
+	return call_int_hook(inode_init_security_anon, 0, inode, type, name,
 			     context_inode);
 }
 
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 92f909a2e8f7..dc57ba21d8ff 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3048,6 +3048,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
 }
 
 static int selinux_inode_init_security_anon(struct inode *inode,
+					    enum lsm_anon_inode_type type,
 					    const struct qstr *name,
 					    const struct inode *context_inode)
 {
