Implemented an OOM-aware decode path for PEL/PROGRAM-DAG and plumbed it through the core entrypoints so OOM is treated as out‑of‑model (returns false) while invalid bytes still map to INVALID_PROGRAM.

This commit is contained in:
Carl Niklas Rydberg 2025-12-22 00:36:10 +01:00
parent 503ad05061
commit 3333b577ff
4 changed files with 82 additions and 42 deletions

View file

@ -11,11 +11,22 @@ extern "C" {
enum { PEL_ENC_PROGRAM_DAG_V1 = 0x0101u }; enum { PEL_ENC_PROGRAM_DAG_V1 = 0x0101u };
enum { AMDUAT_PEL_ENC_PROGRAM_DAG_V1 = PEL_ENC_PROGRAM_DAG_V1 }; enum { AMDUAT_PEL_ENC_PROGRAM_DAG_V1 = PEL_ENC_PROGRAM_DAG_V1 };
typedef enum {
AMDUAT_PEL_PROGRAM_DAG_DECODE_OK = 0,
AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID = 1,
AMDUAT_PEL_PROGRAM_DAG_DECODE_OOM = 2
} amduat_pel_program_dag_decode_status_t;
/* Caller owns any heap allocations returned in out_bytes/out_program. */ /* Caller owns any heap allocations returned in out_bytes/out_program. */
bool amduat_enc_pel_program_dag_encode_v1( bool amduat_enc_pel_program_dag_encode_v1(
const amduat_pel_program_t *program, const amduat_pel_program_t *program,
amduat_octets_t *out_bytes); amduat_octets_t *out_bytes);
amduat_pel_program_dag_decode_status_t
amduat_enc_pel_program_dag_decode_v1_ex(
amduat_octets_t bytes,
amduat_pel_program_t *out_program);
bool amduat_enc_pel_program_dag_decode_v1( bool amduat_enc_pel_program_dag_decode_v1(
amduat_octets_t bytes, amduat_octets_t bytes,
amduat_pel_program_t *out_program); amduat_pel_program_t *out_program);

View file

@ -473,7 +473,8 @@ bool amduat_enc_pel_program_dag_encode_v1(
return true; return true;
} }
bool amduat_enc_pel_program_dag_decode_v1( amduat_pel_program_dag_decode_status_t
amduat_enc_pel_program_dag_decode_v1_ex(
amduat_octets_t bytes, amduat_octets_t bytes,
amduat_pel_program_t *out_program) { amduat_pel_program_t *out_program) {
amduat_cursor_t cur; amduat_cursor_t cur;
@ -483,11 +484,11 @@ bool amduat_enc_pel_program_dag_decode_v1(
size_t i; size_t i;
if (out_program == NULL) { if (out_program == NULL) {
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
if (bytes.len != 0 && bytes.data == NULL) { if (bytes.len != 0 && bytes.data == NULL) {
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
memset(out_program, 0, sizeof(*out_program)); memset(out_program, 0, sizeof(*out_program));
@ -497,23 +498,23 @@ bool amduat_enc_pel_program_dag_decode_v1(
cur.offset = 0; cur.offset = 0;
if (!amduat_read_u16(&cur, &version)) { if (!amduat_read_u16(&cur, &version)) {
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
if (version != 1) { if (version != 1) {
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
if (!amduat_read_u32(&cur, &node_count)) { if (!amduat_read_u32(&cur, &node_count)) {
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
if (node_count != 0) { if (node_count != 0) {
if (node_count > SIZE_MAX / sizeof(amduat_pel_node_t)) { if (node_count > SIZE_MAX / sizeof(amduat_pel_node_t)) {
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
out_program->nodes = (amduat_pel_node_t *)calloc( out_program->nodes = (amduat_pel_node_t *)calloc(
node_count, sizeof(amduat_pel_node_t)); node_count, sizeof(amduat_pel_node_t));
if (out_program->nodes == NULL) { if (out_program->nodes == NULL) {
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_OOM;
} }
} }
out_program->nodes_len = node_count; out_program->nodes_len = node_count;
@ -527,42 +528,42 @@ bool amduat_enc_pel_program_dag_decode_v1(
if (!amduat_read_u32(&cur, &node->id)) { if (!amduat_read_u32(&cur, &node->id)) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
if (!amduat_read_u32(&cur, &name_len)) { if (!amduat_read_u32(&cur, &name_len)) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
if (cur.len - cur.offset < name_len) { if (cur.len - cur.offset < name_len) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
if (name_len != 0) { if (name_len != 0) {
uint8_t *name = (uint8_t *)malloc(name_len); uint8_t *name = (uint8_t *)malloc(name_len);
if (name == NULL) { if (name == NULL) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_OOM;
} }
memcpy(name, cur.data + cur.offset, name_len); memcpy(name, cur.data + cur.offset, name_len);
node->op.name = amduat_octets(name, name_len); node->op.name = amduat_octets(name, name_len);
if (!amduat_utf8_is_valid(node->op.name)) { if (!amduat_utf8_is_valid(node->op.name)) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
} }
cur.offset += name_len; cur.offset += name_len;
if (!amduat_read_u32(&cur, &node->op.version)) { if (!amduat_read_u32(&cur, &node->op.version)) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
if (!amduat_read_u32(&cur, &input_count)) { if (!amduat_read_u32(&cur, &input_count)) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
if (input_count > SIZE_MAX / sizeof(amduat_pel_dag_input_t)) { if (input_count > SIZE_MAX / sizeof(amduat_pel_dag_input_t)) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
node->inputs_len = input_count; node->inputs_len = input_count;
if (input_count != 0) { if (input_count != 0) {
@ -570,7 +571,7 @@ bool amduat_enc_pel_program_dag_decode_v1(
input_count, sizeof(amduat_pel_dag_input_t)); input_count, sizeof(amduat_pel_dag_input_t));
if (node->inputs == NULL) { if (node->inputs == NULL) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_OOM;
} }
} }
@ -579,13 +580,13 @@ bool amduat_enc_pel_program_dag_decode_v1(
amduat_pel_dag_input_t *input = &node->inputs[j]; amduat_pel_dag_input_t *input = &node->inputs[j];
if (!amduat_read_u8(&cur, &kind)) { if (!amduat_read_u8(&cur, &kind)) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
if (kind == AMDUAT_PEL_DAG_INPUT_EXTERNAL) { if (kind == AMDUAT_PEL_DAG_INPUT_EXTERNAL) {
uint32_t input_index; uint32_t input_index;
if (!amduat_read_u32(&cur, &input_index)) { if (!amduat_read_u32(&cur, &input_index)) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
input->kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL; input->kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL;
input->value.external.input_index = input_index; input->value.external.input_index = input_index;
@ -595,30 +596,30 @@ bool amduat_enc_pel_program_dag_decode_v1(
if (!amduat_read_u32(&cur, &node_id) || if (!amduat_read_u32(&cur, &node_id) ||
!amduat_read_u32(&cur, &output_index)) { !amduat_read_u32(&cur, &output_index)) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
input->kind = AMDUAT_PEL_DAG_INPUT_NODE; input->kind = AMDUAT_PEL_DAG_INPUT_NODE;
input->value.node.node_id = node_id; input->value.node.node_id = node_id;
input->value.node.output_index = output_index; input->value.node.output_index = output_index;
} else { } else {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
} }
if (!amduat_read_u32(&cur, &params_len)) { if (!amduat_read_u32(&cur, &params_len)) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
if (cur.len - cur.offset < params_len) { if (cur.len - cur.offset < params_len) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
if (params_len != 0) { if (params_len != 0) {
uint8_t *params = (uint8_t *)malloc(params_len); uint8_t *params = (uint8_t *)malloc(params_len);
if (params == NULL) { if (params == NULL) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_OOM;
} }
memcpy(params, cur.data + cur.offset, params_len); memcpy(params, cur.data + cur.offset, params_len);
node->params = amduat_octets(params, params_len); node->params = amduat_octets(params, params_len);
@ -628,20 +629,20 @@ bool amduat_enc_pel_program_dag_decode_v1(
if (!amduat_read_u32(&cur, &root_count)) { if (!amduat_read_u32(&cur, &root_count)) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
out_program->roots_len = root_count; out_program->roots_len = root_count;
if (root_count != 0) { if (root_count != 0) {
if (root_count > SIZE_MAX / sizeof(amduat_pel_root_ref_t)) { if (root_count > SIZE_MAX / sizeof(amduat_pel_root_ref_t)) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
out_program->roots = out_program->roots =
(amduat_pel_root_ref_t *)calloc(root_count, (amduat_pel_root_ref_t *)calloc(root_count,
sizeof(amduat_pel_root_ref_t)); sizeof(amduat_pel_root_ref_t));
if (out_program->roots == NULL) { if (out_program->roots == NULL) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_OOM;
} }
} }
@ -651,7 +652,7 @@ bool amduat_enc_pel_program_dag_decode_v1(
if (!amduat_read_u32(&cur, &node_id) || if (!amduat_read_u32(&cur, &node_id) ||
!amduat_read_u32(&cur, &output_index)) { !amduat_read_u32(&cur, &output_index)) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
out_program->roots[i].node_id = node_id; out_program->roots[i].node_id = node_id;
out_program->roots[i].output_index = output_index; out_program->roots[i].output_index = output_index;
@ -659,8 +660,15 @@ bool amduat_enc_pel_program_dag_decode_v1(
if (cur.offset != cur.len) { if (cur.offset != cur.len) {
amduat_enc_pel_program_dag_free(out_program); amduat_enc_pel_program_dag_free(out_program);
return false; return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
} }
return true; return AMDUAT_PEL_PROGRAM_DAG_DECODE_OK;
}
bool amduat_enc_pel_program_dag_decode_v1(
amduat_octets_t bytes,
amduat_pel_program_t *out_program) {
return amduat_enc_pel_program_dag_decode_v1_ex(bytes, out_program) ==
AMDUAT_PEL_PROGRAM_DAG_DECODE_OK;
} }

View file

@ -55,6 +55,7 @@ bool amduat_pel_exec_program_bytes(amduat_octets_t program_bytes,
size_t *out_outputs_len, size_t *out_outputs_len,
amduat_pel_execution_result_value_t *out_result) { amduat_pel_execution_result_value_t *out_result) {
amduat_pel_program_t program; amduat_pel_program_t program;
amduat_pel_program_dag_decode_status_t decode_status;
bool ok; bool ok;
if (out_outputs == NULL || out_outputs_len == NULL || out_result == NULL) { if (out_outputs == NULL || out_outputs_len == NULL || out_result == NULL) {
@ -76,7 +77,12 @@ bool amduat_pel_exec_program_bytes(amduat_octets_t program_bytes,
memset(out_result, 0, sizeof(*out_result)); memset(out_result, 0, sizeof(*out_result));
memset(&program, 0, sizeof(program)); memset(&program, 0, sizeof(program));
if (!amduat_enc_pel_program_dag_decode_v1(program_bytes, &program)) { decode_status = amduat_enc_pel_program_dag_decode_v1_ex(program_bytes,
&program);
if (decode_status == AMDUAT_PEL_PROGRAM_DAG_DECODE_OOM) {
return false;
}
if (decode_status != AMDUAT_PEL_PROGRAM_DAG_DECODE_OK) {
out_result->pel1_version = 1; out_result->pel1_version = 1;
out_result->status = AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM; out_result->status = AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM;
out_result->scheme_ref = amduat_pel_program_dag_scheme_ref(); out_result->scheme_ref = amduat_pel_program_dag_scheme_ref();

View file

@ -404,18 +404,12 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
amduat_init_core_result(&core_result, scheme_ref, amduat_init_core_result(&core_result, scheme_ref,
AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM, AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2); AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2);
} else if (!amduat_enc_pel_program_dag_decode_v1(program_artifact.bytes,
&program)) {
amduat_init_core_result(&core_result, scheme_ref,
AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2);
} else { } else {
program_decoded = true; amduat_pel_program_dag_decode_status_t decode_status =
if (!amduat_pel_program_dag_exec_trace( amduat_enc_pel_program_dag_decode_v1_ex(program_artifact.bytes,
&program, input_artifacts, input_refs_len, &outputs, &outputs_len, &program);
&core_result, &trace_eval)) { if (decode_status == AMDUAT_PEL_PROGRAM_DAG_DECODE_OOM) {
amduat_artifact_free(&program_artifact); amduat_artifact_free(&program_artifact);
amduat_enc_pel_program_dag_free(&program);
for (i = 0; i < input_refs_len; ++i) { for (i = 0; i < input_refs_len; ++i) {
amduat_artifact_free(&input_artifacts[i]); amduat_artifact_free(&input_artifacts[i]);
} }
@ -423,9 +417,30 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
if (has_params_artifact) { if (has_params_artifact) {
amduat_artifact_free(&params_artifact); amduat_artifact_free(&params_artifact);
} }
amduat_pel_program_dag_free_outputs(outputs, outputs_len);
return false; return false;
} }
if (decode_status != AMDUAT_PEL_PROGRAM_DAG_DECODE_OK) {
amduat_init_core_result(&core_result, scheme_ref,
AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2);
} else {
program_decoded = true;
if (!amduat_pel_program_dag_exec_trace(
&program, input_artifacts, input_refs_len, &outputs, &outputs_len,
&core_result, &trace_eval)) {
amduat_artifact_free(&program_artifact);
amduat_enc_pel_program_dag_free(&program);
for (i = 0; i < input_refs_len; ++i) {
amduat_artifact_free(&input_artifacts[i]);
}
free(input_artifacts);
if (has_params_artifact) {
amduat_artifact_free(&params_artifact);
}
amduat_pel_program_dag_free_outputs(outputs, outputs_len);
return false;
}
}
} }
amduat_artifact_free(&program_artifact); amduat_artifact_free(&program_artifact);