Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(proxy-wasm) strengthen host functions context checks #444

Merged
merged 2 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ members = [
"t/lib/proxy-wasm-tests/rust-sdk-ver-zero-one",
"t/lib/proxy-wasm-tests/benchmarks",
"t/lib/proxy-wasm-tests/instance-lifecycle",
"t/lib/proxy-wasm-tests/context-checks",
]
exclude = [
"lib/ngx-wasm-rs",
Expand Down
33 changes: 16 additions & 17 deletions src/common/proxy_wasm/ngx_proxy_wasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ action2rc(ngx_proxy_wasm_ctx_t *pwctx,
case NGX_HTTP_REWRITE_PHASE:
case NGX_HTTP_ACCESS_PHASE:
case NGX_HTTP_CONTENT_PHASE:
case NGX_WASM_BACKGROUND_PHASE:
ngx_log_debug6(NGX_LOG_DEBUG_WASM, pwctx->log, 0,
"proxy_wasm pausing in \"%V\" phase "
"(filter: %l/%l, step: %d, action: %d, "
Expand Down Expand Up @@ -683,6 +684,7 @@ ngx_proxy_wasm_run_step(ngx_proxy_wasm_exec_t *pwexec,
ngx_int_t rc;
ngx_proxy_wasm_err_e ecode;
ngx_proxy_wasm_action_e action = NGX_PROXY_WASM_ACTION_CONTINUE;
ngx_proxy_wasm_exec_t *out;
ngx_proxy_wasm_ctx_t *pwctx = pwexec->parent;
ngx_proxy_wasm_filter_t *filter = pwexec->filter;
#if (NGX_DEBUG)
Expand All @@ -700,10 +702,12 @@ ngx_proxy_wasm_run_step(ngx_proxy_wasm_exec_t *pwexec,
if (pwexec->ictx == NULL || pwexec->ictx->instance->trapped) {
#endif
ecode = ngx_proxy_wasm_create_context(filter, pwctx, pwexec->id,
pwexec, NULL);
pwexec, &out);
if (ecode != NGX_PROXY_WASM_ERR_NONE) {
return ecode;
}

pwexec = out;
#if 1
}
#endif
Expand Down Expand Up @@ -842,6 +846,9 @@ get_instance(ngx_proxy_wasm_filter_t *filter,

dd("get instance in store: %p", store);

/* store initialized */
ngx_wasm_assert(store->pool);

for (q = ngx_queue_head(&store->busy);
q != ngx_queue_sentinel(&store->busy);
q = ngx_queue_next(q))
Expand Down Expand Up @@ -988,9 +995,6 @@ ngx_proxy_wasm_create_context(ngx_proxy_wasm_filter_t *filter,
ictx = in->ictx;

} else {
/* store initialized */
ngx_wasm_assert(store->pool);

ictx = get_instance(filter, store, log);
if (ictx == NULL) {
goto error;
Expand Down Expand Up @@ -1187,10 +1191,15 @@ ngx_proxy_wasm_create_context(ngx_proxy_wasm_filter_t *filter,

pwexec->started = 1;
}
}

if (out) {
*out = pwexec;
if (out) {
*out = pwexec;
}

} else {
if (out) {
*out = rexec;
}
}

return NGX_PROXY_WASM_ERR_NONE;
Expand Down Expand Up @@ -1245,19 +1254,9 @@ ngx_proxy_wasm_on_done(ngx_proxy_wasm_exec_t *pwexec)
pwexec->index + 1, pwexec->parent->nfilters);

#if 0
/**
* Currently, dispatches are synchronous hence will always
* have been executed when on_done is invoked.
*/
#ifdef NGX_WASM_HTTP
call = pwexec->call;
if (call) {
ngx_log_debug3(NGX_LOG_DEBUG_WASM, pwexec->log, 0,
"proxy_wasm \"%V\" filter (%l/%l) "
"cancelling HTTP dispatch",
pwexec->filter->name, pwexec->index + 1,
pwexec->parent->nfilters);

ngx_http_proxy_wasm_dispatch_destroy(call);

pwexec->call = NULL;
Expand Down
150 changes: 128 additions & 22 deletions src/common/proxy_wasm/ngx_proxy_wasm_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,42 @@ static ngx_int_t ngx_proxy_wasm_hfuncs_no_http(ngx_wavm_instance_t *instance,

static ngx_chain_t *
ngx_proxy_wasm_get_buffer_helper(ngx_wavm_instance_t *instance,
ngx_proxy_wasm_buffer_type_e buf_type, unsigned *none)
ngx_proxy_wasm_buffer_type_e buf_type, unsigned *none, char **trapmsg)
{
#ifdef NGX_WASM_HTTP
ngx_chain_t *cl;
ngx_http_wasm_req_ctx_t *rctx;
ngx_http_request_t *r;
ngx_proxy_wasm_ctx_t *pwctx;
ngx_proxy_wasm_exec_t *pwexec;

rctx = ngx_http_proxy_wasm_get_rctx(instance);
r = rctx->r;
pwexec = ngx_proxy_wasm_instance2pwexec(instance);
pwctx = pwexec->parent;
#endif

switch (buf_type) {

#ifdef NGX_WASM_HTTP
case NGX_PROXY_WASM_BUFFER_HTTP_REQUEST_BODY:

/* check context */

switch (pwctx->step) {
case NGX_PROXY_WASM_STEP_REQ_HEADERS:
case NGX_PROXY_WASM_STEP_REQ_BODY:
case NGX_PROXY_WASM_STEP_LOG:
break;
default:
*trapmsg = "can only get request body during "
"\"on_request_body\", \"on_log\"";
return NULL;
}

/* get */

rctx = ngx_http_proxy_wasm_get_rctx(instance);
r = rctx->r;

if (r->request_body == NULL
|| r->request_body->bufs == NULL)
{
Expand All @@ -61,6 +82,22 @@ ngx_proxy_wasm_get_buffer_helper(ngx_wavm_instance_t *instance,
return r->request_body->bufs;

case NGX_PROXY_WASM_BUFFER_HTTP_RESPONSE_BODY:

/* check context */

switch (pwctx->step) {
case NGX_PROXY_WASM_STEP_RESP_BODY:
break;
default:
*trapmsg = "can only get response body during "
"\"on_response_body\"";
return NULL;
}

/* get */

rctx = ngx_http_proxy_wasm_get_rctx(instance);

cl = rctx->resp_chunk;
if (cl == NULL) {
/* no body */
Expand All @@ -74,9 +111,21 @@ ngx_proxy_wasm_get_buffer_helper(ngx_wavm_instance_t *instance,
{
ngx_wasm_http_reader_ctx_t *reader;
ngx_http_proxy_wasm_dispatch_t *call;
ngx_proxy_wasm_exec_t *pwexec;

pwexec = ngx_proxy_wasm_instance2pwexec(instance);
/* check context */

switch (pwctx->step) {
case NGX_PROXY_WASM_STEP_DISPATCH_RESPONSE:
case NGX_PROXY_WASM_STEP_LOG:
break;
default:
*trapmsg = "can only get dispatch response body during "
"\"on_http_dispatch_response\"";
return NULL;
}

/* get */

call = pwexec->call;
if (call == NULL) {
return NULL;
Expand Down Expand Up @@ -207,11 +256,10 @@ ngx_proxy_wasm_hfuncs_set_tick_period(ngx_wavm_instance_t *instance,
ngx_event_t *ev;
ngx_proxy_wasm_exec_t *rexec = ngx_proxy_wasm_instance2pwexec(instance);

ngx_wasm_assert(rexec->root_id == NGX_PROXY_WASM_ROOT_CTX_ID);

if (rexec->root_id != NGX_PROXY_WASM_ROOT_CTX_ID) {
/* ignore */
return ngx_proxy_wasm_result_ok(rets);
return ngx_proxy_wasm_result_trap(rexec,
"can only set tick_period in "
"root context", rets, NGX_WAVM_OK);
}

if (ngx_exiting) {
Expand Down Expand Up @@ -254,6 +302,7 @@ ngx_proxy_wasm_hfuncs_get_buffer(ngx_wavm_instance_t *instance,
{
size_t offset, max_len, len, chunk_len;
unsigned none = 0;
char *trapmsg = NULL;
u_char *start = NULL;
ngx_chain_t *cl = NULL;
ngx_buf_t *buf;
Expand Down Expand Up @@ -282,8 +331,14 @@ ngx_proxy_wasm_hfuncs_get_buffer(ngx_wavm_instance_t *instance,
break;

default:
cl = ngx_proxy_wasm_get_buffer_helper(instance, buf_type, &none);
cl = ngx_proxy_wasm_get_buffer_helper(instance, buf_type, &none,
&trapmsg);
if (cl == NULL) {
if (trapmsg) {
return ngx_proxy_wasm_result_trap(pwexec, trapmsg,
rets, NGX_WAVM_BAD_USAGE);
}

if (none) {
return ngx_proxy_wasm_result_notfound(rets);
}
Expand All @@ -304,7 +359,7 @@ ngx_proxy_wasm_hfuncs_get_buffer(ngx_wavm_instance_t *instance,

if (!len) {
/* eof */
return ngx_proxy_wasm_result_notfound(rets);
return ngx_proxy_wasm_result_ok(rets);
}

p = ngx_proxy_wasm_alloc(pwexec, len);
Expand Down Expand Up @@ -376,9 +431,10 @@ ngx_proxy_wasm_hfuncs_set_buffer(ngx_wavm_instance_t *instance,
ngx_wavm_ptr_t *buf_data;
ngx_http_wasm_req_ctx_t *rctx;
ngx_proxy_wasm_exec_t *pwexec;
ngx_proxy_wasm_ctx_t *pwctx;

rctx = ngx_http_proxy_wasm_get_rctx(instance);
pwexec = ngx_proxy_wasm_instance2pwexec(instance);
pwctx = pwexec->parent;

offset = args[1].of.i32;
max = args[2].of.i32;
Expand All @@ -400,35 +456,64 @@ ngx_proxy_wasm_hfuncs_set_buffer(ngx_wavm_instance_t *instance,

#ifdef NGX_WASM_HTTP
case NGX_PROXY_WASM_BUFFER_HTTP_REQUEST_BODY:

/* check context */

switch (pwctx->step) {
case NGX_PROXY_WASM_STEP_REQ_HEADERS:
case NGX_PROXY_WASM_STEP_REQ_BODY:
break;
default:
return ngx_proxy_wasm_result_trap(pwexec,
"can only set request body "
"during \"on_request_body\"",
rets, NGX_WAVM_BAD_USAGE);
}

/* set */

rctx = ngx_http_proxy_wasm_get_rctx(instance);

ngx_wasm_assert(rctx);

if (offset == 0 && max == 0 && buf_len > 0) {
rc = ngx_http_wasm_prepend_req_body(rctx, &s);

} else {
rc = ngx_http_wasm_set_req_body(rctx, &s, offset, max);
}

if (rc == NGX_ABORT) {
ngx_wasm_assert(rc != NGX_ABORT);
break;

case NGX_PROXY_WASM_BUFFER_HTTP_RESPONSE_BODY:

/* check context */

switch (pwctx->step) {
case NGX_PROXY_WASM_STEP_RESP_BODY:
break;
default:
return ngx_proxy_wasm_result_trap(pwexec,
"cannot set request body",
"can only set response body "
"during \"on_response_body\"",
rets, NGX_WAVM_BAD_USAGE);
}

break;
/* set */

rctx = ngx_http_proxy_wasm_get_rctx(instance);

ngx_wasm_assert(rctx);

case NGX_PROXY_WASM_BUFFER_HTTP_RESPONSE_BODY:
if (offset == 0 && max == 0 && buf_len > 0) {
rc = ngx_http_wasm_prepend_resp_body(rctx, &s);

} else {
rc = ngx_http_wasm_set_resp_body(rctx, &s, offset, max);
}

if (rc == NGX_ABORT) {
return ngx_proxy_wasm_result_trap(pwexec,
"cannot set response body",
rets, NGX_WAVM_BAD_USAGE);
}

ngx_wasm_assert(rc != NGX_ABORT);
break;
#endif

Expand Down Expand Up @@ -972,12 +1057,33 @@ ngx_proxy_wasm_hfuncs_dispatch_http_call(ngx_wavm_instance_t *instance,
uint32_t *callout_id, timeout;
ngx_str_t host, body;
ngx_proxy_wasm_marshalled_map_t headers, trailers;
ngx_proxy_wasm_ctx_t *pwctx;
ngx_proxy_wasm_exec_t *pwexec;
ngx_http_wasm_req_ctx_t *rctx;
ngx_http_proxy_wasm_dispatch_t *call = NULL;

pwexec = ngx_proxy_wasm_instance2pwexec(instance);
rctx = ngx_http_proxy_wasm_get_rctx(instance);
pwctx = pwexec->parent;

/* check context */

switch (pwctx->step) {
case NGX_PROXY_WASM_STEP_REQ_HEADERS:
case NGX_PROXY_WASM_STEP_REQ_BODY:
case NGX_PROXY_WASM_STEP_TICK:
case NGX_PROXY_WASM_STEP_DISPATCH_RESPONSE:
break;
default:
return ngx_proxy_wasm_result_trap(pwexec,
"can only send HTTP dispatch "
"during "
"\"on_request_headers\", "
"\"on_request_body\", "
"\"on_dispatch_response\", "
"\"on_tick\"",
rets, NGX_WAVM_BAD_USAGE);
}

host.len = args[1].of.i32;
host.data = NGX_WAVM_HOST_LIFT_SLICE(instance, args[0].of.i32, host.len);
Expand Down
Loading
Loading