diff options
author | phk <phk@FreeBSD.org> | 2002-04-23 11:48:45 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2002-04-23 11:48:45 +0000 |
commit | 90094c67a16d89b3653201488f9e98ee89d6623a (patch) | |
tree | 754de5091c1790b87d24d309621fe77cb2ad731e | |
parent | ba95eb1f7bc0c8e89dee499da75356dc54782d32 (diff) | |
download | FreeBSD-src-90094c67a16d89b3653201488f9e98ee89d6623a.zip FreeBSD-src-90094c67a16d89b3653201488f9e98ee89d6623a.tar.gz |
Introduce some serious paranoia to try to catch a memory overwrite problem
as early as possible.
Sponsored by: DARPA & NAI Labs
-rw-r--r-- | sys/geom/geom.h | 17 | ||||
-rw-r--r-- | sys/geom/geom_dump.c | 1 | ||||
-rw-r--r-- | sys/geom/geom_enc.c | 1 | ||||
-rw-r--r-- | sys/geom/geom_slice.c | 2 | ||||
-rw-r--r-- | sys/geom/geom_subr.c | 48 |
5 files changed, 63 insertions, 6 deletions
diff --git a/sys/geom/geom.h b/sys/geom/geom.h index f6e65bd..d707a34 100644 --- a/sys/geom/geom.h +++ b/sys/geom/geom.h @@ -95,14 +95,16 @@ struct g_class { LIST_ENTRY(g_class) class; LIST_HEAD(,g_geom) geom; struct g_event *event; + u_int protect; }; -#define G_CLASS_INITSTUFF { 0, 0 }, { 0 }, 0 +#define G_CLASS_INITSTUFF { 0, 0 }, { 0 }, 0, 0 /* * The g_geom is an instance of a g_class. */ struct g_geom { + u_int protect; char *name; struct g_class *class; LIST_ENTRY(g_geom) geom; @@ -139,6 +141,7 @@ struct g_bioq { */ struct g_consumer { + u_int protect; struct g_geom *geom; LIST_ENTRY(g_consumer) consumer; struct g_provider *provider; @@ -154,6 +157,7 @@ struct g_consumer { * A g_provider is a "logical disk". */ struct g_provider { + u_int protect; char *name; LIST_ENTRY(g_provider) provider; struct g_geom *geom; @@ -205,6 +209,7 @@ struct g_geom * g_insert_geom(char *class, struct g_consumer *cp); struct g_consumer * g_new_consumer(struct g_geom *gp); struct g_geom * g_new_geomf(struct g_class *mp, char *fmt, ...); struct g_provider * g_new_providerf(struct g_geom *gp, char *fmt, ...); +void g_sanity(void *ptr); void g_spoil(struct g_provider *pp, struct g_consumer *cp); int g_std_access(struct g_provider *pp, int dr, int dw, int de); void g_std_done(struct bio *bp); @@ -247,12 +252,16 @@ g_malloc(int size, int flags) mtx_lock(&Giant); p = malloc(size, M_GEOM, flags); mtx_unlock(&Giant); + g_sanity(p); + /* printf("malloc(%d, %x) -> %p\n", size, flags, p); */ return (p); } static __inline void g_free(void *ptr) { + g_sanity(ptr); + /* printf("free(%p)\n", ptr); */ mtx_lock(&Giant); free(ptr, M_GEOM); mtx_unlock(&Giant); @@ -260,8 +269,8 @@ g_free(void *ptr) extern struct sx topology_lock; #define g_topology_lock() do { mtx_assert(&Giant, MA_NOTOWNED); sx_xlock(&topology_lock); } while (0) -#define g_topology_unlock() sx_xunlock(&topology_lock) -#define g_topology_assert() sx_assert(&topology_lock, SX_XLOCKED) +#define g_topology_unlock() do { g_sanity(NULL); sx_xunlock(&topology_lock); } while (0) +#define g_topology_assert() do { g_sanity(NULL); sx_assert(&topology_lock, SX_XLOCKED); } while (0) #define DECLARE_GEOM_CLASS(class, name) \ static void \ @@ -273,6 +282,6 @@ extern struct sx topology_lock; } \ SYSINIT(name, SI_SUB_PSEUDO, SI_ORDER_FIRST, name##init, NULL); -#endif +#endif /* _KERNEL */ #endif /* _GEOM_GEOM_H_ */ diff --git a/sys/geom/geom_dump.c b/sys/geom/geom_dump.c index 6139763..5952e24 100644 --- a/sys/geom/geom_dump.c +++ b/sys/geom/geom_dump.c @@ -235,6 +235,7 @@ g_trace(int level, char *fmt, ...) va_list ap; struct sbuf *sb; + g_sanity(NULL); if (!(g_debugflags & level)) return; va_start(ap, fmt); diff --git a/sys/geom/geom_enc.c b/sys/geom/geom_enc.c index 54ea938..657ac8c 100644 --- a/sys/geom/geom_enc.c +++ b/sys/geom/geom_enc.c @@ -57,6 +57,7 @@ #include <sys/param.h> #ifdef _KERNEL #include <sys/malloc.h> +#include <sys/systm.h> #endif #include <geom/geom.h> #include <geom/geom_int.h> diff --git a/sys/geom/geom_slice.c b/sys/geom/geom_slice.c index 513ed26..4b1dc9b 100644 --- a/sys/geom/geom_slice.c +++ b/sys/geom/geom_slice.c @@ -173,6 +173,7 @@ g_slice_start(struct bio *bp) g_haveattr_off_t(bp, "GEOM::frontstuff", t); return; } +#ifdef _KERNEL if (!strcmp("GEOM::kerneldump", bp->bio_attribute)) { struct g_kerneldump *gkd; @@ -182,6 +183,7 @@ g_slice_start(struct bio *bp) gkd->length = gsp->slices[index].length; /* now, pass it on downwards... */ } +#endif bp2 = g_clone_bio(bp); bp2->bio_done = g_std_done; g_io_request(bp2, cp); diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c index 1bc2ced..34fefcb 100644 --- a/sys/geom/geom_subr.c +++ b/sys/geom/geom_subr.c @@ -76,6 +76,7 @@ g_add_class(struct g_class *mp) g_ignition++; g_init(); } + mp->protect = 0x020016600; g_topology_lock(); g_trace(G_T_TOPOLOGY, "g_add_class(%s)", mp->name); LIST_INIT(&mp->geom); @@ -99,8 +100,9 @@ g_new_geomf(struct g_class *mp, char *fmt, ...) sbuf_vprintf(sb, fmt, ap); sbuf_finish(sb); mtx_unlock(&Giant); - gp = g_malloc(sizeof *gp + sbuf_len(sb) + 1, M_WAITOK | M_ZERO); - gp->name = (char *)(gp + 1); + gp = g_malloc(sizeof *gp, M_WAITOK | M_ZERO); + gp->protect = 0x020016601; + gp->name = g_malloc(sbuf_len(sb) + 1, M_WAITOK | M_ZERO); gp->class = mp; gp->rank = 1; LIST_INIT(&gp->consumer); @@ -127,6 +129,7 @@ g_destroy_geom(struct g_geom *gp) gp->name, LIST_FIRST(&gp->consumer))); LIST_REMOVE(gp, geom); TAILQ_REMOVE(&geoms, gp, geoms); + g_free(gp->name); g_free(gp); } @@ -141,6 +144,7 @@ g_new_consumer(struct g_geom *gp) gp->name, gp->class->name)); cp = g_malloc(sizeof *cp, M_WAITOK | M_ZERO); + cp->protect = 0x020016602; cp->geom = gp; LIST_INSERT_HEAD(&gp->consumer, cp, consumer); return(cp); @@ -176,6 +180,7 @@ g_new_providerf(struct g_geom *gp, char *fmt, ...) sbuf_finish(sb); mtx_unlock(&Giant); pp = g_malloc(sizeof *pp + sbuf_len(sb) + 1, M_WAITOK | M_ZERO); + pp->protect = 0x020016603; pp->name = (char *)(pp + 1); strcpy(pp->name, sbuf_data(sb)); sbuf_delete(sb); @@ -653,3 +658,42 @@ g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len) return (EINVAL); return (0); } + +/* + * Check if the given pointer is a live object + */ + +void +g_sanity(void *ptr) +{ + struct g_class *mp; + struct g_geom *gp; + struct g_consumer *cp; + struct g_provider *pp; + + LIST_FOREACH(mp, &g_classes, class) { + KASSERT(mp != ptr, ("Ptr is live class")); + KASSERT(mp->protect == 0x20016600, + ("corrupt class %p %x", mp, mp->protect)); + LIST_FOREACH(gp, &mp->geom, geom) { + KASSERT(gp != ptr, ("Ptr is live geom")); + KASSERT(gp->protect == 0x20016601, + ("corrupt geom, %p %x", gp, gp->protect)); + KASSERT(gp->name != ptr, ("Ptr is live geom's name")); + LIST_FOREACH(cp, &gp->consumer, consumer) { + KASSERT(cp != ptr, ("Ptr is live consumer")); + KASSERT(cp->protect == 0x20016602, + ("corrupt consumer %p %x", + cp, cp->protect)); + } + LIST_FOREACH(pp, &gp->provider, provider) { + KASSERT(pp != ptr, ("Ptr is live provider")); + KASSERT(pp->protect == 0x20016603, + ("corrupt provider %p %x", + pp, pp->protect)); + } + } + } +} + + |