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 { 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. */
bool amduat_enc_pel_program_dag_encode_v1(
const amduat_pel_program_t *program,
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(
amduat_octets_t bytes,
amduat_pel_program_t *out_program);

View file

@ -473,7 +473,8 @@ bool amduat_enc_pel_program_dag_encode_v1(
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_pel_program_t *out_program) {
amduat_cursor_t cur;
@ -483,11 +484,11 @@ bool amduat_enc_pel_program_dag_decode_v1(
size_t i;
if (out_program == NULL) {
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
if (bytes.len != 0 && bytes.data == NULL) {
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
memset(out_program, 0, sizeof(*out_program));
@ -497,23 +498,23 @@ bool amduat_enc_pel_program_dag_decode_v1(
cur.offset = 0;
if (!amduat_read_u16(&cur, &version)) {
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
if (version != 1) {
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
if (!amduat_read_u32(&cur, &node_count)) {
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
if (node_count != 0) {
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(
node_count, sizeof(amduat_pel_node_t));
if (out_program->nodes == NULL) {
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_OOM;
}
}
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)) {
amduat_enc_pel_program_dag_free(out_program);
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
if (!amduat_read_u32(&cur, &name_len)) {
amduat_enc_pel_program_dag_free(out_program);
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
if (cur.len - cur.offset < name_len) {
amduat_enc_pel_program_dag_free(out_program);
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
if (name_len != 0) {
uint8_t *name = (uint8_t *)malloc(name_len);
if (name == NULL) {
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);
node->op.name = amduat_octets(name, name_len);
if (!amduat_utf8_is_valid(node->op.name)) {
amduat_enc_pel_program_dag_free(out_program);
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
}
cur.offset += name_len;
if (!amduat_read_u32(&cur, &node->op.version)) {
amduat_enc_pel_program_dag_free(out_program);
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
if (!amduat_read_u32(&cur, &input_count)) {
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)) {
amduat_enc_pel_program_dag_free(out_program);
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
node->inputs_len = input_count;
if (input_count != 0) {
@ -570,7 +571,7 @@ bool amduat_enc_pel_program_dag_decode_v1(
input_count, sizeof(amduat_pel_dag_input_t));
if (node->inputs == NULL) {
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];
if (!amduat_read_u8(&cur, &kind)) {
amduat_enc_pel_program_dag_free(out_program);
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
if (kind == AMDUAT_PEL_DAG_INPUT_EXTERNAL) {
uint32_t input_index;
if (!amduat_read_u32(&cur, &input_index)) {
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->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) ||
!amduat_read_u32(&cur, &output_index)) {
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->value.node.node_id = node_id;
input->value.node.output_index = output_index;
} else {
amduat_enc_pel_program_dag_free(out_program);
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
}
if (!amduat_read_u32(&cur, &params_len)) {
amduat_enc_pel_program_dag_free(out_program);
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
if (cur.len - cur.offset < params_len) {
amduat_enc_pel_program_dag_free(out_program);
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
if (params_len != 0) {
uint8_t *params = (uint8_t *)malloc(params_len);
if (params == NULL) {
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);
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)) {
amduat_enc_pel_program_dag_free(out_program);
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
out_program->roots_len = root_count;
if (root_count != 0) {
if (root_count > SIZE_MAX / sizeof(amduat_pel_root_ref_t)) {
amduat_enc_pel_program_dag_free(out_program);
return false;
return AMDUAT_PEL_PROGRAM_DAG_DECODE_INVALID;
}
out_program->roots =
(amduat_pel_root_ref_t *)calloc(root_count,
sizeof(amduat_pel_root_ref_t));
if (out_program->roots == NULL) {
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) ||
!amduat_read_u32(&cur, &output_index)) {
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].output_index = output_index;
@ -659,8 +660,15 @@ bool amduat_enc_pel_program_dag_decode_v1(
if (cur.offset != cur.len) {
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,
amduat_pel_execution_result_value_t *out_result) {
amduat_pel_program_t program;
amduat_pel_program_dag_decode_status_t decode_status;
bool ok;
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(&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->status = AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM;
out_result->scheme_ref = amduat_pel_program_dag_scheme_ref();

View file

@ -404,8 +404,22 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
amduat_init_core_result(&core_result, scheme_ref,
AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2);
} else if (!amduat_enc_pel_program_dag_decode_v1(program_artifact.bytes,
&program)) {
} else {
amduat_pel_program_dag_decode_status_t decode_status =
amduat_enc_pel_program_dag_decode_v1_ex(program_artifact.bytes,
&program);
if (decode_status == AMDUAT_PEL_PROGRAM_DAG_DECODE_OOM) {
amduat_artifact_free(&program_artifact);
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);
}
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);
@ -427,6 +441,7 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
return false;
}
}
}
amduat_artifact_free(&program_artifact);