summaryrefslogtreecommitdiffstats
path: root/sys/fs/devfs
diff options
context:
space:
mode:
authordd <dd@FreeBSD.org>2002-07-28 03:52:44 +0000
committerdd <dd@FreeBSD.org>2002-07-28 03:52:44 +0000
commita22e9df072960393e48b7c9b5da2cc85e7dcab54 (patch)
treeb5d70b8734293c58d7a5d02779d2414f8b9db511 /sys/fs/devfs
parent5a6eb0ca5faa6cb454026bf21087d0fcc0947fff (diff)
downloadFreeBSD-src-a22e9df072960393e48b7c9b5da2cc85e7dcab54.zip
FreeBSD-src-a22e9df072960393e48b7c9b5da2cc85e7dcab54.tar.gz
Unimplement panic(8) by making sure that we don't recurse into a
ruleset. If we do, that means there's a ruleset loop (10 includes 20 include 30 includes 10), which will quickly cause a double fault due to stack overflow (since "include" is implemented by recursion). (Previously, we only checked that X didn't include X.)
Diffstat (limited to 'sys/fs/devfs')
-rw-r--r--sys/fs/devfs/devfs_rule.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/fs/devfs/devfs_rule.c b/sys/fs/devfs/devfs_rule.c
index 3f19da2..74da699 100644
--- a/sys/fs/devfs/devfs_rule.c
+++ b/sys/fs/devfs/devfs_rule.c
@@ -97,6 +97,7 @@ struct devfs_ruleset {
int ds_refcount;
int ds_flags;
#define DS_IMMUTABLE 0x001
+ int ds_running;
};
static devfs_rid devfs_rid_input(devfs_rid rid, struct devfs_mount *dm);
@@ -679,11 +680,10 @@ devfs_rule_run(struct devfs_krule *dk, struct devfs_dirent *de)
if (dr->dr_iacts & DRA_INCSET) {
ds = devfs_ruleset_bynum(dk->dk_rule.dr_incset);
KASSERT(ds != NULL, ("DRA_INCSET but bad dr_incset"));
- if (dk->dk_ruleset == ds) {
- /* XXX: Do a better job of detecting loops. */
- printf("Warning: Ruleset %d including itself!\n",
- dk->dk_ruleset->ds_number);
- } else
+ if (ds->ds_running)
+ printf("Warning: avoiding loop through ruleset %d\n",
+ ds->ds_number);
+ else
devfs_ruleset_applyde(ds, de);
}
}
@@ -696,9 +696,12 @@ devfs_ruleset_applyde(struct devfs_ruleset *ds, struct devfs_dirent *de)
{
struct devfs_krule *dk;
+ KASSERT(!ds->ds_running,("ruleset %d already running", ds->ds_number));
+ ds->ds_running = 1;
SLIST_FOREACH(dk, &ds->ds_rules, dk_list) {
devfs_rule_applyde(dk, de);
}
+ ds->ds_running = 0;
}
/*
@@ -709,6 +712,8 @@ devfs_ruleset_applydm(struct devfs_ruleset *ds, struct devfs_mount *dm)
{
struct devfs_krule *dk;
+ KASSERT(!ds->ds_running,("ruleset %d already running", ds->ds_number));
+ ds->ds_running = 1;
/*
* XXX: Does it matter whether we do
*
@@ -728,6 +733,7 @@ devfs_ruleset_applydm(struct devfs_ruleset *ds, struct devfs_mount *dm)
SLIST_FOREACH(dk, &ds->ds_rules, dk_list) {
devfs_rule_applydm(dk, dm);
}
+ ds->ds_running = 0;
}
/*
OpenPOWER on IntegriCloud