msgbuf: Rework error handling to improve soundness
Design the implementation to uphold the invariant that a non-negative
remaining value implies the cursor pointer is valid, and that under
other conditions error values must be observed by the msgbuf user. The
former is tested with assertions in the implementation. The latter is
enforced by construction.
With this change, all msgbuf instances for which
pldm_msgbuf_init_errno() succeeds must be either completed or discarded
by calls to the pldm_msgbuf_complete*() or pldm_msgbuf_discard() APIs
respectively.
We then build on the properties that:
- pldm_msgbuf_init_errno() is marked with the warn_unused_result
function attribute
- pldm_msgbuf_init_errno() returns errors for invalid buffer
configurations
- The complete and discard APIs are marked with the warn_unused_result
function attribute
- The complete APIs test for negative remaining values and return an
error if encountered.
- The discard API propagates the provided error code
Together these provide the foundation to ensure that buffer access
errors are (eventually) detected.
A msgbuf object is always in one of the uninitialized, valid, invalid,
or completed states. The states are defined as follows:
- Uninitialized: Undefined values for remaining and cursor
- Valid: cursor points to a valid object, remaining is both non-negative
and describes a range contained within the object pointed to
by cursor
- Invalid: The value of remaining is negative. The value of cursor is
unspecified.
- Completed: the value of remaining is INTMAX_MIN and cursor is NULL
msgbuf instances must always be in the completed state by the time
their storage is reclaimed. To enforce this, PLDM_MSGBUF_DEFINE_P()
is introduced both to simplify definition of related variables, and
to exploit the compiler's 'cleanup' attribute. The cleanup function
associated with the msgbuf object asserts that the referenced object is
in the completed state.
From there, update the implementations of the msgbuf APIs such that
exceeding implementation type limits forces the msgbuf object to the
invalid state (in addition to returning an error value) to relieve the
caller from testing the result of all API invocations.
Change-Id: I4d78ddc5f567d4148f2f6d8f3e7570e97c316bbb
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
diff --git a/src/dsp/platform.c b/src/dsp/platform.c
index b37de42..0d5d917 100644
--- a/src/dsp/platform.c
+++ b/src/dsp/platform.c
@@ -265,8 +265,7 @@
uint8_t *comp_effecter_count,
set_effecter_state_field *field)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
int i;
@@ -287,10 +286,13 @@
}
pldm_msgbuf_extract_p(buf, effecter_id);
- pldm_msgbuf_extract_p(buf, comp_effecter_count);
+ rc = pldm_msgbuf_extract_p(buf, comp_effecter_count);
+ if (rc) {
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
+ }
if (*comp_effecter_count > 8) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
for (i = 0; i < *comp_effecter_count; i++) {
@@ -312,8 +314,7 @@
uint8_t *transfer_op_flag, uint16_t *request_cnt,
uint16_t *record_chg_num)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || record_hndl == NULL || data_transfer_hndl == NULL ||
@@ -447,8 +448,7 @@
uint32_t *repository_size, uint32_t *largest_record_size,
uint8_t *data_transfer_handle_timeout)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || completion_code == NULL ||
@@ -466,32 +466,35 @@
return pldm_xlate_errno(rc);
}
- pldm_msgbuf_extract_p(buf, completion_code);
+ rc = pldm_msgbuf_extract_p(buf, completion_code);
+ if (rc) {
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
+ }
if (PLDM_SUCCESS != *completion_code) {
return PLDM_SUCCESS;
}
rc = pldm_msgbuf_extract_p(buf, repository_state);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (*repository_state > PLDM_FAILED) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
/* NOTE: Memory safety */
rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE, update_time,
PLDM_TIMESTAMP104_SIZE);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
/* NOTE: Memory safety */
rc = pldm_msgbuf_extract_array(buf, PLDM_TIMESTAMP104_SIZE,
oem_update_time, PLDM_TIMESTAMP104_SIZE);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
pldm_msgbuf_extract_p(buf, record_count);
@@ -512,8 +515,7 @@
const struct pldm_msg *msg, size_t payload_length,
struct pldm_pdr_repository_info_resp *resp)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || resp == NULL) {
@@ -535,7 +537,7 @@
rc = pldm_msgbuf_extract(buf, resp->completion_code);
if (rc) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
pldm_msgbuf_extract(buf, resp->repository_state);
@@ -544,14 +546,14 @@
resp->update_time,
sizeof(resp->update_time));
if (rc) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
rc = pldm_msgbuf_extract_array(buf, sizeof(resp->oem_update_time),
resp->oem_update_time,
sizeof(resp->oem_update_time));
if (rc) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
pldm_msgbuf_extract(buf, resp->record_count);
@@ -606,8 +608,7 @@
uint8_t *record_data, size_t record_data_length,
uint8_t *transfer_crc)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || completion_code == NULL ||
@@ -624,11 +625,11 @@
rc = pldm_msgbuf_extract_p(buf, completion_code);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (PLDM_SUCCESS != *completion_code) {
- return PLDM_SUCCESS;
+ return pldm_msgbuf_complete(buf);
}
pldm_msgbuf_extract_p(buf, next_record_hndl);
@@ -636,18 +637,19 @@
pldm_msgbuf_extract_p(buf, transfer_flag);
rc = pldm_msgbuf_extract_p(buf, resp_cnt);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (*resp_cnt > 0 && record_data != NULL) {
if (record_data_length < *resp_cnt) {
- return PLDM_ERROR_INVALID_LENGTH;
+ return pldm_msgbuf_discard(buf,
+ PLDM_ERROR_INVALID_LENGTH);
}
/* NOTE: Memory safety */
rc = pldm_msgbuf_extract_array(buf, *resp_cnt, record_data,
*resp_cnt);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
}
@@ -668,8 +670,7 @@
struct pldm_get_pdr_resp *resp, size_t resp_len,
uint8_t *transfer_crc)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || resp == NULL || transfer_crc == NULL) {
@@ -694,19 +695,19 @@
rc = pldm_msgbuf_extract(buf, resp->transfer_flag);
if (rc) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
rc = pldm_msgbuf_extract(buf, resp->response_count);
if (rc) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
rc = pldm_msgbuf_extract_array(
buf, resp->response_count, resp->record_data,
resp_len - (sizeof(*resp) - sizeof(resp->record_data)));
if (rc) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
if (resp->transfer_flag == PLDM_END) {
@@ -723,8 +724,7 @@
uint8_t *effecter_data_size,
uint8_t effecter_value[4])
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || effecter_id == NULL || effecter_data_size == NULL ||
@@ -742,11 +742,11 @@
pldm_msgbuf_extract_p(buf, effecter_id);
rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
if (rc) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
@@ -948,8 +948,7 @@
uint8_t *comp_sensor_count,
get_sensor_state_field *field)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
uint8_t i;
int rc;
@@ -967,20 +966,20 @@
rc = pldm_msgbuf_extract_p(buf, completion_code);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (PLDM_SUCCESS != *completion_code) {
- return PLDM_SUCCESS;
+ return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
}
rc = pldm_msgbuf_extract_p(buf, comp_sensor_count);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (*comp_sensor_count < 0x1 || *comp_sensor_count > 0x8) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
for (i = 0; i < *comp_sensor_count; i++) {
@@ -1005,8 +1004,7 @@
bitfield8_t *sensor_rearm,
uint8_t *reserved)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || sensor_id == NULL || sensor_rearm == NULL) {
@@ -1075,8 +1073,7 @@
uint8_t *event_class,
size_t *event_data_offset)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || format_version == NULL || tid == NULL ||
@@ -1130,8 +1127,7 @@
uint8_t *format_version, uint8_t *transfer_operation_flag,
uint32_t *data_transfer_handle, uint16_t *event_id_to_acknowledge)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || format_version == NULL ||
@@ -1150,22 +1146,22 @@
pldm_msgbuf_extract_p(buf, format_version);
rc = pldm_msgbuf_extract_p(buf, transfer_operation_flag);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (*transfer_operation_flag > PLDM_ACKNOWLEDGEMENT_ONLY) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
pldm_msgbuf_extract_p(buf, data_transfer_handle);
rc = pldm_msgbuf_extract_p(buf, event_id_to_acknowledge);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
rc = pldm_platform_poll_for_platform_event_message_validate(
*transfer_operation_flag, *event_id_to_acknowledge);
if (rc < 0) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
rc = pldm_msgbuf_complete(buf);
@@ -1217,8 +1213,7 @@
uint8_t *event_data, uint32_t checksum, struct pldm_msg *msg,
size_t payload_length)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (!msg) {
@@ -1247,13 +1242,14 @@
pldm_msgbuf_insert(buf, tid);
rc = pldm_msgbuf_insert(buf, event_id);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (event_id == 0xffff || event_id == 0x0000) {
if (PLDM_POLL_FOR_PLATFORM_EVENT_MESSAGE_MIN_RESP_BYTES !=
payload_length) {
- return PLDM_ERROR_INVALID_LENGTH;
+ return pldm_msgbuf_discard(buf,
+ PLDM_ERROR_INVALID_LENGTH);
}
rc = pldm_msgbuf_complete(buf);
@@ -1265,7 +1261,7 @@
}
if ((event_data == NULL) && (event_data_size > 0)) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
pldm_msgbuf_insert(buf, next_data_transfer_handle);
@@ -1273,14 +1269,14 @@
pldm_msgbuf_insert(buf, event_class);
rc = pldm_msgbuf_insert(buf, event_data_size);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if ((event_data_size > 0) && event_data) {
rc = pldm_msgbuf_insert_array(buf, event_data_size, event_data,
event_data_size);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
}
@@ -1357,8 +1353,7 @@
uint8_t *completion_code,
uint8_t *platform_event_status)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || completion_code == NULL ||
@@ -1374,20 +1369,20 @@
rc = pldm_msgbuf_extract_p(buf, completion_code);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (PLDM_SUCCESS != *completion_code) {
- return PLDM_SUCCESS;
+ return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
}
rc = pldm_msgbuf_extract_p(buf, platform_event_status);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (*platform_event_status > PLDM_EVENT_LOGGING_REJECTED) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
rc = pldm_msgbuf_complete(buf);
@@ -1428,8 +1423,7 @@
uint8_t *completion_code,
uint16_t *terminus_max_buffer_size)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || completion_code == NULL ||
@@ -1446,11 +1440,11 @@
rc = pldm_msgbuf_extract_p(buf, completion_code);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (PLDM_SUCCESS != *completion_code) {
- return PLDM_SUCCESS;
+ return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
}
pldm_msgbuf_extract_p(buf, terminus_max_buffer_size);
@@ -1504,8 +1498,7 @@
uint8_t *event_class,
uint8_t event_class_count)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int i;
int rc;
@@ -1524,27 +1517,27 @@
rc = pldm_msgbuf_extract_p(buf, completion_code);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (PLDM_SUCCESS != *completion_code) {
- return PLDM_SUCCESS;
+ return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
}
rc = pldm_msgbuf_extract_p(buf, synchrony_config);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (*synchrony_config > PLDM_MESSAGE_TYPE_ASYNCHRONOUS_WITH_HEARTBEAT) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
pldm_msgbuf_extract_p(buf, &synchrony_config_support->byte);
rc = pldm_msgbuf_extract_p(buf, number_event_class_returned);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (*number_event_class_returned == 0) {
@@ -1557,7 +1550,7 @@
}
if (event_class_count < *number_event_class_returned) {
- return PLDM_ERROR_INVALID_LENGTH;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_LENGTH);
}
for (i = 0; i < *number_event_class_returned; i++) {
@@ -1578,8 +1571,7 @@
uint8_t *sensor_event_class_type,
size_t *event_class_data_offset)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (event_data == NULL || sensor_id == NULL ||
@@ -1595,7 +1587,7 @@
}
if (event_data_length < PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES) {
- return PLDM_ERROR_INVALID_LENGTH;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_LENGTH);
}
size_t event_class_data_length =
@@ -1604,28 +1596,31 @@
pldm_msgbuf_extract_p(buf, sensor_id);
rc = pldm_msgbuf_extract_p(buf, sensor_event_class_type);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (*sensor_event_class_type == PLDM_SENSOR_OP_STATE) {
if (event_class_data_length !=
PLDM_SENSOR_EVENT_SENSOR_OP_STATE_DATA_LENGTH) {
- return PLDM_ERROR_INVALID_LENGTH;
+ return pldm_msgbuf_discard(buf,
+ PLDM_ERROR_INVALID_LENGTH);
}
} else if (*sensor_event_class_type == PLDM_STATE_SENSOR_STATE) {
if (event_class_data_length !=
PLDM_SENSOR_EVENT_STATE_SENSOR_STATE_DATA_LENGTH) {
- return PLDM_ERROR_INVALID_LENGTH;
+ return pldm_msgbuf_discard(buf,
+ PLDM_ERROR_INVALID_LENGTH);
}
} else if (*sensor_event_class_type == PLDM_NUMERIC_SENSOR_STATE) {
if (event_class_data_length <
PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MIN_DATA_LENGTH ||
event_class_data_length >
PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_MAX_DATA_LENGTH) {
- return PLDM_ERROR_INVALID_LENGTH;
+ return pldm_msgbuf_discard(buf,
+ PLDM_ERROR_INVALID_LENGTH);
}
} else {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
*event_class_data_offset =
@@ -1643,8 +1638,7 @@
int decode_sensor_op_data(const uint8_t *sensor_data, size_t sensor_data_length,
uint8_t *present_op_state, uint8_t *previous_op_state)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (sensor_data == NULL || present_op_state == NULL ||
@@ -1676,8 +1670,7 @@
uint8_t *event_state,
uint8_t *previous_event_state)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (sensor_data == NULL || sensor_offset == NULL ||
@@ -1711,8 +1704,7 @@
uint8_t *sensor_data_size,
uint32_t *present_reading)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (sensor_data == NULL || sensor_data_size == NULL ||
@@ -1737,7 +1729,7 @@
pldm_msgbuf_extract_p(buf, previous_event_state);
rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
/*
@@ -1789,7 +1781,7 @@
break;
}
default:
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
rc = pldm_msgbuf_complete_consumed(buf);
@@ -1805,10 +1797,13 @@
const void *pdr_data, size_t pdr_data_length,
struct pldm_numeric_sensor_value_pdr *pdr_value)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
+ if (!pdr_data || !pdr_value) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
rc = pldm_msgbuf_init_errno(buf, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
pdr_data, pdr_data_length);
if (rc) {
@@ -1819,7 +1814,7 @@
buf, &pdr_value->hdr, PLDM_PDR_NUMERIC_SENSOR_PDR_MIN_LENGTH,
pdr_data_length);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
pldm_msgbuf_extract(buf, pdr_value->terminus_handle);
@@ -1842,10 +1837,10 @@
rc = pldm_msgbuf_extract(buf, pdr_value->sensor_data_size);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (pdr_value->sensor_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
pldm_msgbuf_extract(buf, pdr_value->resolution);
@@ -1867,10 +1862,10 @@
rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
@@ -2014,8 +2009,7 @@
size_t payload_length,
uint16_t *effecter_id)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || effecter_id == NULL) {
@@ -2048,8 +2042,7 @@
uint8_t *pending_value,
uint8_t *present_value)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || effecter_data_size == NULL ||
@@ -2067,29 +2060,29 @@
rc = pldm_msgbuf_extract_p(buf, completion_code);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (PLDM_SUCCESS != *completion_code) {
- return PLDM_SUCCESS;
+ return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
}
rc = pldm_msgbuf_extract_p(buf, effecter_data_size);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (*effecter_data_size > PLDM_EFFECTER_DATA_SIZE_SINT32) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
rc = pldm_msgbuf_extract_p(buf, effecter_oper_state);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (*effecter_oper_state > EFFECTER_OPER_STATE_INTEST) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
pldm_msgbuf_extract_effecter_value(buf, *effecter_data_size,
@@ -2176,8 +2169,7 @@
uint8_t *number_of_change_records,
size_t *change_record_data_offset)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (event_data == NULL || event_data_format == NULL ||
@@ -2212,8 +2204,7 @@
const void *event_data, size_t event_data_length,
struct pldm_message_poll_event *poll_event)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (!event_data || !poll_event) {
@@ -2229,11 +2220,11 @@
pldm_msgbuf_extract(buf, poll_event->format_version);
rc = pldm_msgbuf_extract(buf, poll_event->event_id);
if (rc) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
if (poll_event->event_id == 0x0000 || poll_event->event_id == 0xffff) {
- return -EPROTO;
+ return pldm_msgbuf_discard(buf, -EPROTO);
}
pldm_msgbuf_extract(buf, poll_event->data_transfer_handle);
@@ -2246,8 +2237,7 @@
const struct pldm_message_poll_event *poll_event, void *event_data,
size_t event_data_length)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (poll_event == NULL || event_data == NULL) {
@@ -2276,8 +2266,7 @@
uint8_t *event_data_operation, uint8_t *number_of_change_entries,
size_t *change_entry_data_offset)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (change_record_data == NULL || event_data_operation == NULL ||
@@ -2344,8 +2333,7 @@
uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
uint8_t *present_reading)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || completion_code == NULL ||
@@ -2364,20 +2352,20 @@
rc = pldm_msgbuf_extract_p(buf, completion_code);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (PLDM_SUCCESS != *completion_code) {
- return PLDM_SUCCESS;
+ return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
}
rc = pldm_msgbuf_extract_p(buf, sensor_data_size);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (*sensor_data_size > PLDM_SENSOR_DATA_SIZE_SINT32) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
pldm_msgbuf_extract_p(buf, sensor_operational_state);
@@ -2473,8 +2461,7 @@
size_t payload_length, uint16_t *sensor_id,
uint8_t *rearm_event_state)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || sensor_id == NULL || rearm_event_state == NULL) {
@@ -2548,8 +2535,7 @@
size_t payload_length,
uint8_t *completion_code)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || completion_code == NULL) {
@@ -2581,8 +2567,7 @@
uint16_t *heartbeat_timer)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || event_message_global_enable == NULL ||
@@ -2599,7 +2584,7 @@
pldm_msgbuf_extract_p(buf, event_message_global_enable);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
pldm_msgbuf_extract_p(buf, transport_protocol_type);
@@ -2657,8 +2642,7 @@
struct pldm_msg *msg,
size_t payload_length)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL) {
@@ -2710,8 +2694,7 @@
uint8_t *event_class, uint32_t *event_data_size, void **event_data,
uint32_t *event_data_integrity_checksum)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || completion_code == NULL || tid == NULL ||
@@ -2731,34 +2714,34 @@
rc = pldm_msgbuf_extract_p(buf, completion_code);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (PLDM_SUCCESS != *completion_code) {
- return *completion_code;
+ return pldm_msgbuf_discard(buf, *completion_code);
}
pldm_msgbuf_extract_p(buf, tid);
rc = pldm_msgbuf_extract_p(buf, event_id);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if ((*event_id == 0) || (*event_id == 0xffff)) {
- return PLDM_SUCCESS;
+ return pldm_msgbuf_discard(buf, PLDM_SUCCESS);
}
pldm_msgbuf_extract_p(buf, next_data_transfer_handle);
rc = pldm_msgbuf_extract_p(buf, transfer_flag);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
pldm_msgbuf_extract_p(buf, event_class);
rc = pldm_msgbuf_extract_p(buf, event_data_size);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (*event_data_size > payload_length) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
if (*event_data_size > 0) {
@@ -2783,8 +2766,7 @@
const void *pdr_data, size_t pdr_data_length,
struct pldm_numeric_effecter_value_pdr *pdr_value)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
struct pldm_value_pdr_hdr hdr;
int rc;
@@ -2828,10 +2810,10 @@
rc = pldm_msgbuf_extract(buf, pdr_value->effecter_data_size);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (pdr_value->effecter_data_size > PLDM_SENSOR_DATA_SIZE_MAX) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
pldm_msgbuf_extract(buf, pdr_value->resolution);
@@ -2848,10 +2830,10 @@
rc = pldm_msgbuf_extract(buf, pdr_value->range_field_format);
if (rc) {
- return pldm_xlate_errno(rc);
+ return pldm_xlate_errno(pldm_msgbuf_discard(buf, rc));
}
if (pdr_value->range_field_format > PLDM_RANGE_FIELD_FORMAT_MAX) {
- return PLDM_ERROR_INVALID_DATA;
+ return pldm_msgbuf_discard(buf, PLDM_ERROR_INVALID_DATA);
}
pldm_msgbuf_extract(buf, pdr_value->range_field_support.byte);
@@ -2880,8 +2862,7 @@
struct pldm_msg *msg,
size_t payload_length)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL) {
@@ -2916,8 +2897,7 @@
size_t payload_length,
uint16_t *effecter_id)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (msg == NULL || effecter_id == NULL) {
@@ -2941,8 +2921,7 @@
const struct pldm_msg *msg, size_t payload_length,
struct pldm_get_state_effecter_states_resp *resp)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
get_effecter_state_field *field;
int rc;
int i;
@@ -2960,23 +2939,23 @@
rc = pldm_msgbuf_extract(buf, resp->completion_code);
if (rc) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
if (PLDM_SUCCESS != resp->completion_code) {
- return 0;
+ return pldm_msgbuf_complete(buf);
}
rc = pldm_msgbuf_extract(buf, resp->comp_effecter_count);
if (rc) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
uint8_t comp_effecter_count = resp->comp_effecter_count;
if (comp_effecter_count < PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MIN ||
comp_effecter_count > PLDM_GET_EFFECTER_STATE_FIELD_COUNT_MAX) {
- return -EBADMSG;
+ return pldm_msgbuf_discard(buf, -EBADMSG);
}
for (i = 0, field = resp->field; i < comp_effecter_count;
@@ -2994,8 +2973,7 @@
uint8_t instance_id, struct pldm_get_state_effecter_states_resp *resp,
struct pldm_msg *msg, size_t payload_length)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
get_effecter_state_field *field;
int rc;
int i;
@@ -3047,12 +3025,9 @@
const void *data, size_t data_length,
struct pldm_entity_auxiliary_names_pdr *pdr, size_t pdr_length)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
- struct pldm_msgbuf _src;
- struct pldm_msgbuf *src = &_src;
- struct pldm_msgbuf _dst;
- struct pldm_msgbuf *dst = &_dst;
+ PLDM_MSGBUF_DEFINE_P(buf);
+ PLDM_MSGBUF_DEFINE_P(src);
+ PLDM_MSGBUF_DEFINE_P(dst);
size_t names_len = 0;
void *names = NULL;
int rc;
@@ -3085,7 +3060,7 @@
buf, &pdr->hdr, PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH,
data_length);
if (rc) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
pldm_msgbuf_extract(buf, pdr->container.entity_type);
@@ -3094,7 +3069,7 @@
pldm_msgbuf_extract(buf, pdr->shared_name_count);
rc = pldm_msgbuf_extract(buf, pdr->name_string_count);
if (rc < 0) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
rc = pldm_msgbuf_span_remaining(buf, &names, &names_len);
@@ -3103,6 +3078,11 @@
}
assert(names);
+ rc = pldm_msgbuf_complete_consumed(buf);
+ if (rc) {
+ return rc;
+ }
+
pdr->auxiliary_name_data_size = pdr_length - sizeof(*pdr);
rc = pldm_msgbuf_init_errno(dst, pdr->auxiliary_name_data_size,
@@ -3121,51 +3101,54 @@
/* Initialise for the first pass to extract the UTF16-BE name strings */
rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
if (rc < 0) {
- return rc;
+ goto cleanup_msgbuf_dst;
}
for (i = 0; i < pdr->name_string_count; i++) {
pldm_msgbuf_span_string_ascii(src, NULL, NULL);
rc = pldm_msgbuf_copy_string_utf16(dst, src);
if (rc) {
- return rc;
+ goto cleanup_msgbuf_src;
}
}
rc = pldm_msgbuf_complete_consumed(src);
if (rc < 0) {
- return rc;
+ goto cleanup_msgbuf_dst;
}
/* Reinitialise for the second pass to extract the ASCII tag strings */
rc = pldm_msgbuf_init_errno(src, names_len, names, names_len);
if (rc < 0) {
- return rc;
+ goto cleanup_msgbuf_dst;
}
for (i = 0; i < pdr->name_string_count; i++) {
rc = pldm_msgbuf_copy_string_ascii(dst, src);
if (rc) {
- return rc;
+ goto cleanup_msgbuf_src;
}
pldm_msgbuf_span_string_utf16(src, NULL, NULL);
}
- if ((rc = pldm_msgbuf_complete(dst)) ||
- (rc = pldm_msgbuf_complete(src)) ||
- (rc = pldm_msgbuf_complete(buf))) {
- return rc;
+ rc = pldm_msgbuf_complete(src);
+ if (rc) {
+ goto cleanup_msgbuf_dst;
}
- return 0;
+ return pldm_msgbuf_complete(dst);
+
+cleanup_msgbuf_src:
+ rc = pldm_msgbuf_discard(src, rc);
+cleanup_msgbuf_dst:
+ return pldm_msgbuf_discard(dst, rc);
}
LIBPLDM_ABI_STABLE
int decode_pldm_entity_auxiliary_names_pdr_index(
struct pldm_entity_auxiliary_names_pdr *pdr)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
int i;
@@ -3227,8 +3210,7 @@
struct pldm_platform_cper_event *cper_event,
size_t cper_event_length)
{
- struct pldm_msgbuf _buf;
- struct pldm_msgbuf *buf = &_buf;
+ PLDM_MSGBUF_DEFINE_P(buf);
int rc;
if (!cper_event || !event_data) {
@@ -3248,29 +3230,29 @@
pldm_msgbuf_extract(buf, cper_event->format_version);
rc = pldm_msgbuf_extract(buf, cper_event->format_type);
if (rc) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
if (cper_event->format_type != PLDM_PLATFORM_CPER_EVENT_WITH_HEADER &&
cper_event->format_type !=
PLDM_PLATFORM_CPER_EVENT_WITHOUT_HEADER) {
- return -EPROTO;
+ return pldm_msgbuf_discard(buf, -EPROTO);
}
rc = pldm_msgbuf_extract(buf, cper_event->event_data_length);
if (rc) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
if (cper_event->event_data_length >
(cper_event_length - sizeof(*cper_event))) {
- return -EOVERFLOW;
+ return pldm_msgbuf_discard(buf, -EOVERFLOW);
}
rc = pldm_msgbuf_extract_array_uint8(
buf, cper_event->event_data_length, cper_event->event_data,
cper_event_length - sizeof(*cper_event));
if (rc) {
- return rc;
+ return pldm_msgbuf_discard(buf, rc);
}
return pldm_msgbuf_complete_consumed(buf);