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
This commit is contained in:
Mitchell Horne 2022-07-18 17:25:00 -04:00 committed by Allan Jude
parent 287d467c5d
commit 4e2121c10a

View File

@ -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)
{