diff options
author | dd <dd@FreeBSD.org> | 2002-07-28 03:52:44 +0000 |
---|---|---|
committer | dd <dd@FreeBSD.org> | 2002-07-28 03:52:44 +0000 |
commit | a22e9df072960393e48b7c9b5da2cc85e7dcab54 (patch) | |
tree | b5d70b8734293c58d7a5d02779d2414f8b9db511 | |
parent | 5a6eb0ca5faa6cb454026bf21087d0fcc0947fff (diff) | |
download | FreeBSD-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.)
-rw-r--r-- | sys/fs/devfs/devfs_rule.c | 16 |
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; } /* |