[PATCH 02/13] Create and use a smp_signspace structure to have range checking on the growing signed data structures.
Martin Blix Grydeland
martin at varnish-software.com
Mon Oct 1 12:26:09 CEST 2012
---
bin/varnishd/storage/storage_persistent.c | 23 +++---
bin/varnishd/storage/storage_persistent.h | 35 +++++++--
bin/varnishd/storage/storage_persistent_silo.c | 10 +--
bin/varnishd/storage/storage_persistent_subr.c | 90 ++++++++++++++++++++----
4 files changed, 126 insertions(+), 32 deletions(-)
diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c
index 5d31caf..b54f497 100644
--- a/bin/varnishd/storage/storage_persistent.c
+++ b/bin/varnishd/storage/storage_persistent.c
@@ -68,13 +68,14 @@ static VTAILQ_HEAD(,smp_sc) silos = VTAILQ_HEAD_INITIALIZER(silos);
*/
static void
-smp_appendban(struct smp_sc *sc, struct smp_signctx *ctx,
+smp_appendban(struct smp_sc *sc, struct smp_signspace *spc,
uint32_t len, const uint8_t *ban)
{
uint8_t *ptr, *ptr2;
(void)sc;
- ptr = ptr2 = SIGN_END(ctx);
+ ptr = ptr2 = SIGNSPACE_FRONT(spc);
+ assert(SIGNSPACE_FREE(spc) >= 4 + 4 + len);
memcpy(ptr, "BAN", 4);
ptr += 4;
@@ -85,7 +86,7 @@ smp_appendban(struct smp_sc *sc, struct smp_signctx *ctx,
memcpy(ptr, ban, len);
ptr += len;
- smp_append_sign(ctx, ptr2, ptr - ptr2);
+ smp_append_signspace(spc, ptr - ptr2);
}
/* Trust that cache_ban.c takes care of locking */
@@ -106,7 +107,7 @@ SMP_NewBan(const uint8_t *ban, unsigned ln)
*/
static int
-smp_open_bans(struct smp_sc *sc, struct smp_signctx *ctx)
+smp_open_bans(struct smp_sc *sc, struct smp_signspace *spc)
{
uint8_t *ptr, *pe;
uint32_t length;
@@ -114,11 +115,11 @@ smp_open_bans(struct smp_sc *sc, struct smp_signctx *ctx)
ASSERT_CLI();
(void)sc;
- i = smp_chk_sign(ctx);
+ i = smp_chk_signspace(spc);
if (i)
return (i);
- ptr = SIGN_DATA(ctx);
- pe = ptr + ctx->ss->length;
+ ptr = SIGNSPACE_DATA(spc);
+ pe = SIGNSPACE_FRONT(spc);
while (ptr < pe) {
if (memcmp(ptr, "BAN", 4)) {
@@ -148,7 +149,7 @@ smp_open_bans(struct smp_sc *sc, struct smp_signctx *ctx)
*/
static int
-smp_open_segs(struct smp_sc *sc, struct smp_signctx *ctx)
+smp_open_segs(struct smp_sc *sc, struct smp_signspace *spc)
{
uint64_t length, l;
struct smp_segptr *ss, *se;
@@ -156,12 +157,12 @@ smp_open_segs(struct smp_sc *sc, struct smp_signctx *ctx)
int i, n = 0;
ASSERT_CLI();
- i = smp_chk_sign(ctx);
+ i = smp_chk_signspace(spc);
if (i)
return (i);
- ss = SIGN_DATA(ctx);
- length = ctx->ss->length;
+ ss = SIGNSPACE_DATA(spc);
+ length = SIGNSPACE_LEN(spc);
if (length == 0) {
/* No segments */
diff --git a/bin/varnishd/storage/storage_persistent.h b/bin/varnishd/storage/storage_persistent.h
index c817faf..ec97d3e 100644
--- a/bin/varnishd/storage/storage_persistent.h
+++ b/bin/varnishd/storage/storage_persistent.h
@@ -55,6 +55,21 @@ struct smp_signctx {
const char *id;
};
+/*
+ * A space wrapped by a signature
+ *
+ * A signspace is a chunk of the silo that is wrapped by a
+ * signature. It has attributes for size, so range checking can be
+ * performed.
+ *
+ */
+
+struct smp_signspace {
+ struct smp_signctx ctx;
+ uint8_t *start;
+ uint64_t size;
+};
+
struct smp_sc;
/* XXX: name confusion with on-media version ? */
@@ -116,10 +131,10 @@ struct smp_sc {
VTAILQ_ENTRY(smp_sc) list;
struct smp_signctx idn;
- struct smp_signctx ban1;
- struct smp_signctx ban2;
- struct smp_signctx seg1;
- struct smp_signctx seg2;
+ struct smp_signspace ban1;
+ struct smp_signspace ban2;
+ struct smp_signspace seg1;
+ struct smp_signspace seg2;
struct ban *tailban;
@@ -161,6 +176,11 @@ struct smp_sc {
#define SIGN_DATA(ctx) ((void *)((ctx)->ss + 1))
#define SIGN_END(ctx) ((void *)((int8_t *)SIGN_DATA(ctx) + (ctx)->ss->length))
+#define SIGNSPACE_DATA(spc) (SIGN_DATA(&(spc)->ctx))
+#define SIGNSPACE_FRONT(spc) (SIGN_END(&(spc)->ctx))
+#define SIGNSPACE_LEN(spc) ((spc)->ctx.ss->length)
+#define SIGNSPACE_FREE(spc) ((spc)->size - SIGNSPACE_LEN(spc))
+
/* storage_persistent_mgt.c */
void smp_mgt_init(struct stevedore *parent, int ac, char * const *av);
@@ -181,6 +201,13 @@ int smp_chk_sign(struct smp_signctx *ctx);
void smp_append_sign(struct smp_signctx *ctx, const void *ptr, uint32_t len);
void smp_reset_sign(struct smp_signctx *ctx);
void smp_sync_sign(const struct smp_signctx *ctx);
+
+void smp_def_signspace(const struct smp_sc *sc, struct smp_signspace *spc,
+ uint64_t off, uint64_t size, const char *id);
+int smp_chk_signspace(struct smp_signspace *spc);
+void smp_append_signspace(struct smp_signspace *spc, uint32_t len);
+void smp_reset_signspace(struct smp_signspace *spc);
+
void smp_newsilo(struct smp_sc *sc);
int smp_valid_silo(struct smp_sc *sc);
diff --git a/bin/varnishd/storage/storage_persistent_silo.c b/bin/varnishd/storage/storage_persistent_silo.c
index ff53af8..6ed80d2 100644
--- a/bin/varnishd/storage/storage_persistent_silo.c
+++ b/bin/varnishd/storage/storage_persistent_silo.c
@@ -58,15 +58,15 @@
*/
static void
-smp_save_seg(const struct smp_sc *sc, struct smp_signctx *ctx)
+smp_save_seg(const struct smp_sc *sc, struct smp_signspace *spc)
{
struct smp_segptr *ss;
struct smp_seg *sg;
uint64_t length;
Lck_AssertHeld(&sc->mtx);
- smp_reset_sign(ctx);
- ss = SIGN_DATA(ctx);
+ smp_reset_signspace(spc);
+ ss = SIGNSPACE_DATA(spc);
length = 0;
VTAILQ_FOREACH(sg, &sc->segments, list) {
assert(sg->p.offset < sc->mediasize);
@@ -75,8 +75,8 @@ smp_save_seg(const struct smp_sc *sc, struct smp_signctx *ctx)
ss++;
length += sizeof *ss;
}
- smp_append_sign(ctx, SIGN_DATA(ctx), length);
- smp_sync_sign(ctx);
+ smp_append_signspace(spc, length);
+ smp_sync_sign(&spc->ctx);
}
void
diff --git a/bin/varnishd/storage/storage_persistent_subr.c b/bin/varnishd/storage/storage_persistent_subr.c
index 004bba3..ac93544 100644
--- a/bin/varnishd/storage/storage_persistent_subr.c
+++ b/bin/varnishd/storage/storage_persistent_subr.c
@@ -179,6 +179,64 @@ smp_new_sign(const struct smp_sc *sc, struct smp_signctx *ctx,
}
/*--------------------------------------------------------------------
+ * Define a signature space by location, size and identifier
+ */
+
+void
+smp_def_signspace(const struct smp_sc *sc, struct smp_signspace *spc,
+ uint64_t off, uint64_t size, const char *id)
+{
+ smp_def_sign(sc, &spc->ctx, off, id);
+ spc->start = SIGN_DATA(&spc->ctx);
+ spc->size = size - SMP_SIGN_SPACE;
+}
+
+/*--------------------------------------------------------------------
+ * Check that a signspace's signature space is good, leave state ready
+ * for append
+ */
+
+int
+smp_chk_signspace(struct smp_signspace *spc)
+{
+ return (smp_chk_sign(&spc->ctx));
+}
+
+/*--------------------------------------------------------------------
+ * Append data to a signature space
+ */
+
+void
+smp_append_signspace(struct smp_signspace *spc, uint32_t len)
+{
+ assert(len <= SIGNSPACE_FREE(spc));
+ smp_append_sign(&spc->ctx, SIGNSPACE_FRONT(spc), len);
+}
+
+/*--------------------------------------------------------------------
+ * Reset a signature space to empty, prepare for appending.
+ */
+
+void
+smp_reset_signspace(struct smp_signspace *spc)
+{
+ smp_reset_sign(&spc->ctx);
+}
+
+/*--------------------------------------------------------------------
+ * Create a new signature space and force the signature to backing store.
+ */
+
+static void
+smp_new_signspace(const struct smp_sc *sc, struct smp_signspace *spc,
+ uint64_t off, uint64_t size, const char *id)
+{
+ smp_new_sign(sc, &spc->ctx, off, id);
+ spc->start = SIGN_DATA(&spc->ctx);
+ spc->size = size - SMP_SIGN_SPACE;
+}
+
+/*--------------------------------------------------------------------
* Initialize a Silo with a valid but empty structure.
*
* XXX: more intelligent sizing of things.
@@ -220,10 +278,14 @@ smp_newsilo(struct smp_sc *sc)
si->stuff[SMP_END_STUFF] = si->mediasize;
assert(si->stuff[SMP_SPC_STUFF] < si->stuff[SMP_END_STUFF]);
- smp_new_sign(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF], "BAN 1");
- smp_new_sign(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF], "BAN 2");
- smp_new_sign(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF], "SEG 1");
- smp_new_sign(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF], "SEG 2");
+ smp_new_signspace(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF],
+ smp_stuff_len(sc, SMP_BAN1_STUFF), "BAN 1");
+ smp_new_signspace(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF],
+ smp_stuff_len(sc, SMP_BAN2_STUFF), "BAN 2");
+ smp_new_signspace(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF],
+ smp_stuff_len(sc, SMP_SEG1_STUFF), "SEG 1");
+ smp_new_signspace(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF],
+ smp_stuff_len(sc, SMP_SEG2_STUFF), "SEG 2");
smp_append_sign(&sc->idn, si, sizeof *si);
smp_sync_sign(&sc->idn);
@@ -282,20 +344,24 @@ smp_valid_silo(struct smp_sc *sc)
assert(smp_stuff_len(sc, SMP_BAN1_STUFF) ==
smp_stuff_len(sc, SMP_BAN2_STUFF));
- smp_def_sign(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF], "BAN 1");
- smp_def_sign(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF], "BAN 2");
- smp_def_sign(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF], "SEG 1");
- smp_def_sign(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF], "SEG 2");
+ smp_def_signspace(sc, &sc->ban1, si->stuff[SMP_BAN1_STUFF],
+ smp_stuff_len(sc, SMP_BAN1_STUFF), "BAN 1");
+ smp_def_signspace(sc, &sc->ban2, si->stuff[SMP_BAN2_STUFF],
+ smp_stuff_len(sc, SMP_BAN2_STUFF), "BAN 2");
+ smp_def_signspace(sc, &sc->seg1, si->stuff[SMP_SEG1_STUFF],
+ smp_stuff_len(sc, SMP_SEG1_STUFF), "SEG 1");
+ smp_def_signspace(sc, &sc->seg2, si->stuff[SMP_SEG2_STUFF],
+ smp_stuff_len(sc, SMP_SEG2_STUFF), "SEG 2");
/* We must have one valid BAN table */
- i = smp_chk_sign(&sc->ban1);
- j = smp_chk_sign(&sc->ban2);
+ i = smp_chk_signspace(&sc->ban1);
+ j = smp_chk_signspace(&sc->ban2);
if (i && j)
return (100 + i * 10 + j);
/* We must have one valid SEG table */
- i = smp_chk_sign(&sc->seg1);
- j = smp_chk_sign(&sc->seg2);
+ i = smp_chk_signspace(&sc->seg1);
+ j = smp_chk_signspace(&sc->seg2);
if (i && j)
return (200 + i * 10 + j);
return (0);
--
1.7.9.5
More information about the varnish-dev
mailing list