git: 4e2121c10afc - main - mac_ddb: add some validation functions

From: Allan Jude <allanjude_at_FreeBSD.org>
Date: Mon, 18 Jul 2022 22:06:57 UTC
The branch main has been updated by allanjude:

URL: https://cgit.FreeBSD.org/src/commit/?id=4e2121c10afc3d9273368eae776fe31d0c68ba6a

commit 4e2121c10afc3d9273368eae776fe31d0c68ba6a
Author:     Mitchell Horne <mhorne@FreeBSD.org>
AuthorDate: 2022-07-18 21:25:00 +0000
Commit:     Allan Jude <allanjude@FreeBSD.org>
CommitDate: 2022-07-18 22:06:22 +0000

    mac_ddb: add some validation functions
    
    These global objects are easy to validate, so provide the helper
    functions to do so and include these commands in the allow lists.
    
    Reviewed by:    markj
    Sponsored by:   Juniper Networks, Inc.
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D35372
---
 sys/security/mac_ddb/mac_ddb.c | 101 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)

diff --git a/sys/security/mac_ddb/mac_ddb.c b/sys/security/mac_ddb/mac_ddb.c
index 8f07a664b7eb..89cba3145945 100644
--- a/sys/security/mac_ddb/mac_ddb.c
+++ b/sys/security/mac_ddb/mac_ddb.c
@@ -29,11 +29,17 @@
  */
 
 #include <sys/param.h>
+#include <sys/jail.h>
 #include <sys/kdb.h>
 #include <sys/module.h>
+#include <sys/mount.h>
 #include <sys/proc.h>
+#include <sys/queue.h>
+#include <sys/rman.h>
 #include <sys/sysctl.h>
 
+#include <net/vnet.h>
+
 #include <ddb/ddb.h>
 #include <ddb/db_command.h>
 
@@ -67,6 +73,11 @@ typedef int db_validation_fn_t(db_expr_t addr, bool have_addr, db_expr_t count,
     char *modif);
 
 static db_validation_fn_t	db_thread_valid;
+static db_validation_fn_t	db_show_ffs_valid;
+static db_validation_fn_t	db_show_prison_valid;
+static db_validation_fn_t	db_show_proc_valid;
+static db_validation_fn_t	db_show_rman_valid;
+static db_validation_fn_t	db_show_vnet_valid;
 
 struct cmd_list_item {
 	const char *name;
@@ -80,7 +91,12 @@ static const struct cmd_list_item command_list[] = {
 
 /* List of ddb(4) 'show' commands which are allowed by this policy. */
 static const struct cmd_list_item show_command_list[] = {
+	{ "ffs",	db_show_ffs_valid },
+	{ "prison",	db_show_prison_valid },
+	{ "proc",	db_show_proc_valid },
+	{ "rman",	db_show_rman_valid },
 	{ "thread",	db_thread_valid },
+	{ "vnet",	db_show_vnet_valid },
 };
 
 static int
@@ -103,6 +119,91 @@ db_thread_valid(db_expr_t addr, bool have_addr, db_expr_t count, char *modif)
 	return (EACCES);
 }
 
+static int
+db_show_ffs_valid(db_expr_t addr, bool have_addr, db_expr_t count, char *modif)
+{
+	struct mount *mp;
+
+	/* No addr will show all mounts. */
+	if (!have_addr)
+		return (0);
+
+	TAILQ_FOREACH(mp, &mountlist, mnt_list)
+		if ((void *)mp == (void *)addr)
+			return (0);
+
+	return (EACCES);
+}
+
+static int
+db_show_prison_valid(db_expr_t addr, bool have_addr, db_expr_t count,
+    char *modif)
+{
+	struct prison *pr;
+	int pr_id;
+
+	if (!have_addr || addr == 0)
+		return (0);
+
+	/* prison can match by pointer address or ID. */
+	pr_id = (int)addr;
+	TAILQ_FOREACH(pr, &allprison, pr_list)
+		if (pr->pr_id == pr_id || (void *)pr == (void *)addr)
+			return (0);
+
+	return (EACCES);
+}
+
+static int
+db_show_proc_valid(db_expr_t addr, bool have_addr, db_expr_t count,
+    char *modif)
+{
+	struct proc *p;
+	int i;
+
+	/* Default will show the current proc. */
+	if (!have_addr)
+		return (0);
+
+	for (i = 0; i <= pidhash; i++) {
+		LIST_FOREACH(p, &pidhashtbl[i], p_hash) {
+			if ((void *)p == (void *)addr)
+				return (0);
+		}
+	}
+
+	return (EACCES);
+}
+
+static int
+db_show_rman_valid(db_expr_t addr, bool have_addr, db_expr_t count, char *modif)
+{
+	struct rman *rm;
+
+	TAILQ_FOREACH(rm, &rman_head, rm_link) {
+		if ((void *)rm == (void *)rm)
+			return (0);
+	}
+
+	return (EACCES);
+}
+
+static int
+db_show_vnet_valid(db_expr_t addr, bool have_addr, db_expr_t count, char *modif)
+{
+	VNET_ITERATOR_DECL(vnet);
+
+	if (!have_addr)
+		return (0);
+
+	VNET_FOREACH(vnet) {
+		if ((void *)vnet == (void *)addr)
+			return (0);
+	}
+
+	return (EACCES);
+}
+
 static int
 command_match(struct db_command *cmd, struct cmd_list_item item)
 {