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

[release/4.x] Cherry pick: Extend testing of JS runtime limits, take 2 (#5668) #5770

Merged
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
2 changes: 1 addition & 1 deletion .daily_canary
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-^- ___ ___
(- -) (= =) | Y & +--?
( V ) / . \ | +---=---'
/--x-m- /--n-n---xXx--/--yY------>>>+++<<<
/--x-m- /--n-n---xXx--/--yY------>>>----<<<
63 changes: 40 additions & 23 deletions tests/js-custom-authorization/custom_authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@ def temporary_js_limits(network, primary, **kwargs):
"max_heap_bytes": default_max_heap_size,
"max_stack_bytes": default_max_stack_size,
"max_execution_time_ms": default_max_execution_time,
"return_exception_details": True,
}

temp_kwargs = default_kwargs.copy()
temp_kwargs.update(**kwargs)
LOG.info(f"Setting JS runtime options: {temp_kwargs}")
network.consortium.set_js_runtime_options(
primary,
**temp_kwargs,
Expand All @@ -79,25 +81,33 @@ def temporary_js_limits(network, primary, **kwargs):
def test_stack_size_limit(network, args):
primary, _ = network.find_nodes()

safe_depth = 50
unsafe_depth = 2000
safe_depth = 1
depth = safe_depth
max_depth = 8192

with primary.client() as c:
with primary.client("user0") as c:
r = c.post("/app/recursive", body={"depth": safe_depth})
assert r.status_code == http.HTTPStatus.OK, r.status_code

# Stacks are significantly larger in SGX (and larger still in debug).
# So we need a platform-specific value to fail _this_ test, but still permit governance to pass
msb = 400 * 1024 if args.enclave_platform == "sgx" else 40 * 1024
with temporary_js_limits(network, primary, max_stack_bytes=msb):
r = c.post("/app/recursive", body={"depth": safe_depth})
assert r.status_code == http.HTTPStatus.INTERNAL_SERVER_ERROR, r.status_code
max_stack_bytes = (
512 * 1024
) # Lower than 1024 * 1024 default, but enough to pass a proposal to restore the limit
with temporary_js_limits(network, primary, max_stack_bytes=max_stack_bytes):
while depth <= max_depth:
depth *= 2
r = c.post("/app/recursive", body={"depth": depth})
if r.status_code == http.HTTPStatus.INTERNAL_SERVER_ERROR:
message = r.body.json()["error"]["details"][0]["message"]
assert message == "InternalError: stack overflow", message
LOG.info(
f"Stack overflow at depth={depth} with max_stack_bytes={max_stack_bytes}"
)
break

assert depth < max_depth, f"No stack overflow trigger at max depth {depth}"

r = c.post("/app/recursive", body={"depth": safe_depth})
assert r.status_code == http.HTTPStatus.OK, r.status_code

r = c.post("/app/recursive", body={"depth": unsafe_depth})
assert r.status_code == http.HTTPStatus.INTERNAL_SERVER_ERROR, r.status_code
assert r.status_code == http.HTTPStatus.OK, r

return network

Expand All @@ -109,19 +119,22 @@ def test_heap_size_limit(network, args):
safe_size = 5 * 1024 * 1024
unsafe_size = 500 * 1024 * 1024

with primary.client() as c:
with primary.client("user0") as c:
r = c.post("/app/alloc", body={"size": safe_size})
assert r.status_code == http.HTTPStatus.OK, r.status_code
assert r.status_code == http.HTTPStatus.OK, r

with temporary_js_limits(network, primary, max_heap_bytes=3 * 1024 * 1024):
r = c.post("/app/alloc", body={"size": safe_size})
assert r.status_code == http.HTTPStatus.INTERNAL_SERVER_ERROR, r.status_code
assert r.status_code == http.HTTPStatus.INTERNAL_SERVER_ERROR, r
message = r.body.json()["error"]["details"][0]["message"]
assert message == "InternalError: out of memory", message

r = c.post("/app/alloc", body={"size": safe_size})
assert r.status_code == http.HTTPStatus.OK, r.status_code
assert r.status_code == http.HTTPStatus.OK, r

r = c.post("/app/alloc", body={"size": unsafe_size})
assert r.status_code == http.HTTPStatus.INTERNAL_SERVER_ERROR, r.status_code
message = r.body.json()["error"]["details"][0]["message"]
assert message == "InternalError: out of memory", message

return network

Expand All @@ -133,19 +146,23 @@ def test_execution_time_limit(network, args):
safe_time = 50
unsafe_time = 5000

with primary.client() as c:
with primary.client("user0") as c:
r = c.post("/app/sleep", body={"time": safe_time})
assert r.status_code == http.HTTPStatus.OK, r.status_code
assert r.status_code == http.HTTPStatus.OK, r

with temporary_js_limits(network, primary, max_execution_time_ms=30):
r = c.post("/app/sleep", body={"time": safe_time})
assert r.status_code == http.HTTPStatus.INTERNAL_SERVER_ERROR, r.status_code
assert r.status_code == http.HTTPStatus.INTERNAL_SERVER_ERROR, r
message = r.body.json()["error"]["details"][0]["message"]
assert message == "InternalError: interrupted", message

r = c.post("/app/sleep", body={"time": safe_time})
assert r.status_code == http.HTTPStatus.OK, r.status_code
assert r.status_code == http.HTTPStatus.OK, r

r = c.post("/app/sleep", body={"time": unsafe_time})
assert r.status_code == http.HTTPStatus.INTERNAL_SERVER_ERROR, r.status_code
assert r.status_code == http.HTTPStatus.INTERNAL_SERVER_ERROR, r
message = r.body.json()["error"]["details"][0]["message"]
assert message == "InternalError: interrupted", message

return network

Expand Down
12 changes: 6 additions & 6 deletions tests/js-limits/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"post": {
"js_module": "limits.js",
"js_function": "recursive",
"forwarding_required": "sometimes",
"authn_policies": ["no_auth"],
"forwarding_required": "never",
"authn_policies": ["user_cert"],
"mode": "readonly",
"openapi": {}
}
Expand All @@ -14,8 +14,8 @@
"post": {
"js_module": "limits.js",
"js_function": "alloc",
"forwarding_required": "sometimes",
"authn_policies": ["no_auth"],
"forwarding_required": "never",
"authn_policies": ["user_cert"],
"mode": "readonly",
"openapi": {}
}
Expand All @@ -24,8 +24,8 @@
"post": {
"js_module": "limits.js",
"js_function": "sleep",
"forwarding_required": "sometimes",
"authn_policies": ["no_auth"],
"forwarding_required": "never",
"authn_policies": ["user_cert"],
"mode": "readonly",
"openapi": {}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/js-limits/src/limits.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export function recursive(request) {

function _recursive(depth) {
if (depth > 0) {
_recursive(--depth);
_recursive(depth - 1);
}
}

Expand Down
Loading