Additionally, test privs on all esi levels

parent babe8a39
......@@ -4,3 +4,9 @@ sub vcl_recv {
sub vcl_deliver {
pesi_debug.check_privs();
}
sub vcl_synth {
# return(fail) implies a rollback - PRIVs lost
if (resp.status != 503 || resp.reason != "VCL failed") {
pesi_debug.check_privs();
}
}
......@@ -2,18 +2,18 @@
#include <string.h> // INIT_OBJ
#include <cache/cache.h>
#include <vmb.h>
#include "vcc_pesi_debug_if.h"
#define A(x) assert(x)
/*
* locking: because we require the PRIV_TOP to be created exactly once and
* varnish-cache takes care of serializing access to the PRIV_TOP tree itself,
* we do not need to lock here.
*
* BUT: For any real-world vmod for which a PRIV_TOP max only be created at esi
* level > 0, a static mutex is required for access to the priv_top priv (a lock
* _in_ the priv is not sufficient because also access to the private pointer
* can race)
* see below for how to lock properly for PRIV_TOPs created at lower levels
*/
struct pedbg_top {
......@@ -30,6 +30,75 @@ struct pedbg_task {
const struct req *req;
};
/*
* dynamic PRIV_TOP for each esi level
*/
struct pedbg_level {
unsigned magic;
#define PEDBG_LEVEL_MAGIC 0x220c28ff
unsigned level;
const struct pedbg_level *up;
};
/* used as uintptr for pedbg_level */
#define MAX_LEVELS 255
static const char level_id[MAX_LEVELS] = { 'L' };
static void
pedbg_level(VRT_CTX, struct req *topreq, unsigned esi_level)
{
struct sess *sp;
struct vmod_priv *p;
const struct vmod_priv *pup;
struct pedbg_level *level = NULL;
const struct pedbg_level *up = NULL;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
assert(esi_level < MAX_LEVELS);
sp = ctx->sp;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
p = VRT_priv_top(ctx, &level_id[esi_level]);
while (p->priv == NULL) {
if (esi_level > 0) {
pup = VRT_priv_top(ctx, &level_id[esi_level - 1]);
CAST_OBJ_NOTNULL(up, pup->priv, PEDBG_LEVEL_MAGIC);
}
Lck_Lock(&sp->mtx);
if (p->priv != NULL) {
// raced
Lck_Unlock(&sp->mtx);
break;
}
level = WS_Alloc(topreq->ws, sizeof *level);
AN(level);
INIT_OBJ(level, PEDBG_LEVEL_MAGIC);
level->level = esi_level;
level->up = up;
p->priv = level;
Lck_Unlock(&sp->mtx);
}
if (level == NULL) {
/* write barrier is implicit in mutex */
VRMB();
CAST_OBJ_NOTNULL(level, p->priv, PEDBG_LEVEL_MAGIC);
}
A(level->level == esi_level);
up = level->up;
while (up) {
CHECK_OBJ_NOTNULL(up, PEDBG_LEVEL_MAGIC);
A(up->level == --esi_level);
up = up->up;
}
AZ(esi_level);
}
/* ============================================================
*/
#define PEDBG_SETUP(ctx, ptop, ptask, r, tr) \
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); \
AN(ptop); \
......@@ -77,10 +146,9 @@ pedbg_register_privs(VRT_CTX,
task->req = req;
priv_task->priv = task;
pedbg_check_privs(ctx, priv_top, priv_task);
pedbg_level(ctx, topreq, req->esi_level);
}
#define A(x) assert(x)
VCL_VOID
pedbg_check_privs(VRT_CTX,
struct vmod_priv *priv_top, struct vmod_priv *priv_task)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment