Commit 840aa8e5 authored by Devon H. O'Dell's avatar Devon H. O'Dell Committed by Lasse Karstensen

WS: Fix off-by-one in WS_Reset

WS_Assert allows the workspace to be full in its check that `ws->f <= ws->e`.
WS_Reset does not honor this; if a snapshot was taken of a full workspace, and
that snapshot is reverted with WS_Reset, we panic.

This issue was identified by Jozef Hatala <jozef@fastly.com>
parent 826cee31
......@@ -116,7 +116,7 @@ WS_Reset(struct ws *ws, char *p)
ws->f = ws->s;
else {
assert(p >= ws->s);
assert(p < ws->e);
assert(p <= ws->e);
ws->f = p;
}
ws_ClearOverflow(ws);
......
varnishtest "Test WS_Reset off-by-one when workspace is full"
server s1 {
rxreq
txresp
} -start
varnish v1 -vcl+backend {
import ${vmod_debug};
import ${vmod_std};
sub vcl_recv {
set req.http.ws-free = debug.workspace_free(session);
debug.workspace_allocate(session, std.integer(req.http.ws-free, 0));
debug.workspace_snap(session);
debug.workspace_reset(session);
}
} -start
client c1 {
txreq -url /foo
rxresp
expect resp.status == 200
} -run
......@@ -139,6 +139,14 @@ $Function INT workspace_free(ENUM { client, backend, session, thread })
Find how much unallocated space there is left in a workspace.
$Function VOID workspace_snap(ENUM { client, backend, session, thread})
Snapshot the named workspace. Only one snapshot may be active at a time.
$Function VOID workspace_reset(ENUM { client, backend, session, thread })
Reset to the previous snapshot of a workspace, taken from debug.workspace_snap.
$Function VOID vcl_release_delay(DURATION)
Hold a reference to the VCL when it goes cold for the given delay.
......@@ -419,6 +419,31 @@ vmod_workspace_overflowed(VRT_CTX, VCL_ENUM which)
return (WS_Overflowed(ws));
}
static char *debug_ws_snap;
void
vmod_workspace_snap(VRT_CTX, VCL_ENUM which)
{
struct ws *ws;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
ws = wsfind(ctx, which);
WS_Assert(ws);
debug_ws_snap = WS_Snapshot(ws);
}
void
vmod_workspace_reset(VRT_CTX, VCL_ENUM which)
{
struct ws *ws;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
ws = wsfind(ctx, which);
WS_Assert(ws);
WS_Reset(ws, debug_ws_snap);
}
void
vmod_workspace_overflow(VRT_CTX, VCL_ENUM which)
{
......
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