oem: meta: Add decode_oem_meta_file_io_write_req()
Add decode_oem_meta_file_io_write_req function.
Deprecate decode_oem_meta_file_io_req function.
The difference between functions decode_oem_meta_file_io_req and
decode_oem_meta_file_io_write_req:
- decode_oem_meta_file_io_write_req:
- return 0 on success and return a negative errno value on failure.
- input parameters is structure.
- add req_length parameter to check whether the total length of
the request is buffer overflow.
- decode_oem_meta_file_io_req:
- return PLDM_SUCCESS on success and return another PLDM completion
code on failure.
- input parameters is passing individual pointers.
Change-Id: Iae3c7f24128bc25c5af6951f34fdc6d8a7b90381
Signed-off-by: Delphine CC Chiu <Delphine_CC_Chiu@wiwynn.com>
Signed-off-by: Lora Lin <lora.lin.wiwynn@gmail.com>
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1a4f18d..ae80421 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,23 @@
## [Unreleased]
+### Added
+
+1. oem: meta: Add decode_oem_meta_file_io_write_req()
+
+### Deprecated
+
+1. oem: meta: Deprecate `decode_oem_meta_file_io_req()`
+
+ Users should switch to `decode_oem_meta_file_io_write_req()`. Modify this
+ function to make it safer.
+
+ Modification:
+
+ - The meaning of the returned result.
+ - Change parameters from individual pointers to a struct.
+ - Check the length provided in the message won't exceed the buffer.
+
### Removed
1. Deprecated functions with the `_check` suffix
diff --git a/include/libpldm/oem/meta/file_io.h b/include/libpldm/oem/meta/file_io.h
index 32a7109..e30ab47 100644
--- a/include/libpldm/oem/meta/file_io.h
+++ b/include/libpldm/oem/meta/file_io.h
@@ -2,6 +2,8 @@
#ifndef LIBPLDM_OEM_META_FILE_IO_H
#define LIBPLDM_OEM_META_FILE_IO_H
+#include <libpldm/compiler.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -13,18 +15,42 @@
/** @brief PLDM Commands in OEM META type
*/
-enum pldm_oem_meta_fileio_commands {
- PLDM_OEM_META_FILEIO_CMD_WRITE_FILE = 0x2,
- PLDM_OEM_META_FILEIO_CMD_READ_FILE = 0x3,
+enum pldm_oem_meta_file_io_commands {
+ PLDM_OEM_META_FILE_IO_CMD_WRITE_FILE = 0x2,
+ PLDM_OEM_META_FILE_IO_CMD_READ_FILE = 0x3,
};
-struct pldm_oem_meta_write_file_req {
- uint8_t file_handle;
+struct pldm_oem_meta_file_io_write_req {
+ uint8_t handle;
uint32_t length;
- uint8_t file_data[1];
+#ifndef __cplusplus
+ uint8_t data[] LIBPLDM_CC_COUNTED_BY(length);
+#endif
};
+#define PLDM_OEM_META_FILE_IO_WRITE_REQ_MIN_LENGTH 5u
-/** @brief Decode OEM meta file io req
+/** @brief Obtain the pointer to the data array of a write request
+ *
+ * @param[in] req - The pointer to the write request struct
+ *
+ * @return The write request data pointer.
+ */
+void *pldm_oem_meta_file_io_write_req_data(
+ struct pldm_oem_meta_file_io_write_req *req);
+
+/** @brief Decode OEM meta write file io req
+ *
+ * @param[in] msg - Pointer to PLDM request message
+ * @param[in] payload_length - Length of request payload
+ * @param[out] req - Pointer to the structure to store the decoded response data
+ * @param[in] req_length - Length of request structure
+ * @return 0 on success, negative errno value on failure
+ */
+int decode_oem_meta_file_io_write_req(
+ const struct pldm_msg *msg, size_t payload_length,
+ struct pldm_oem_meta_file_io_write_req *req, size_t req_length);
+
+/** @brief Deprecated decoder for OEM meta write file io req
*
* @param[in] msg - Pointer to PLDM request message
* @param[in] payload_length - Length of request payload
diff --git a/src/api.h b/src/api.h
index 3f1fed0..f99f3ed 100644
--- a/src/api.h
+++ b/src/api.h
@@ -32,6 +32,10 @@
case -ENOMSG:
rc = PLDM_ERROR_INVALID_PLDM_TYPE;
break;
+ case -EBADMSG:
+ case -EOVERFLOW:
+ rc = PLDM_ERROR_INVALID_LENGTH;
+ break;
default:
assert(false);
rc = PLDM_ERROR;
diff --git a/src/oem/meta/file_io.c b/src/oem/meta/file_io.c
index 9df6263..ce7d9e3 100644
--- a/src/oem/meta/file_io.c
+++ b/src/oem/meta/file_io.c
@@ -1,41 +1,91 @@
/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
#include <libpldm/oem/meta/file_io.h>
#include <endian.h>
+#include <stdlib.h>
#include <string.h>
#include <stdio.h>
-#include "msgbuf.h"
-#define PLDM_OEM_META_DECODE_WRITE_FILE_IO_MIN_SIZE 6
-LIBPLDM_ABI_STABLE
-int decode_oem_meta_file_io_req(const struct pldm_msg *msg,
- size_t payload_length, uint8_t *file_handle,
- uint32_t *length, uint8_t *data)
+#include "api.h"
+#include "msgbuf.h"
+#include "dsp/base.h"
+
+LIBPLDM_ABI_TESTING
+void *pldm_oem_meta_file_io_write_req_data(
+ struct pldm_oem_meta_file_io_write_req *req)
+{
+ return req->data;
+}
+
+LIBPLDM_ABI_TESTING
+int decode_oem_meta_file_io_write_req(
+ const struct pldm_msg *msg, size_t payload_length,
+ struct pldm_oem_meta_file_io_write_req *req, size_t req_length)
{
struct pldm_msgbuf _buf;
struct pldm_msgbuf *buf = &_buf;
int rc;
- if (msg == NULL || file_handle == NULL || length == NULL ||
- data == NULL) {
- return PLDM_ERROR_INVALID_DATA;
+ if (msg == NULL || req == NULL) {
+ return -EINVAL;
}
- rc = pldm_msgbuf_init_cc(buf,
- PLDM_OEM_META_DECODE_WRITE_FILE_IO_MIN_SIZE,
- msg->payload, payload_length);
+ if (req_length < sizeof(*req)) {
+ return -EINVAL;
+ }
+
+ rc = pldm_msgbuf_init_errno(buf,
+ PLDM_OEM_META_FILE_IO_WRITE_REQ_MIN_LENGTH,
+ msg->payload, payload_length);
if (rc) {
return rc;
}
- pldm_msgbuf_extract_p(buf, file_handle);
- pldm_msgbuf_extract_p(buf, length);
+ pldm_msgbuf_extract(buf, req->handle);
+ rc = pldm_msgbuf_extract(buf, req->length);
+ if (rc) {
+ return rc;
+ }
- /* NOTE: Memory safety failure */
- rc = pldm_msgbuf_extract_array_uint8(buf, (size_t)(*length), data,
- UINT32_MAX);
+ rc = pldm_msgbuf_extract_array(buf, req->length, req->data,
+ req_length - sizeof(*req));
if (rc) {
return rc;
}
return pldm_msgbuf_destroy_consumed(buf);
}
+
+LIBPLDM_ABI_DEPRECATED
+int decode_oem_meta_file_io_req(const struct pldm_msg *msg,
+ size_t payload_length, uint8_t *file_handle,
+ uint32_t *length, uint8_t *data)
+{
+ struct pldm_oem_meta_file_io_write_req *request_msg;
+ size_t request_msg_len;
+ int rc;
+
+ if (msg == NULL || file_handle == NULL || length == NULL ||
+ data == NULL) {
+ return pldm_xlate_errno(-EINVAL);
+ }
+
+ request_msg_len = sizeof(*request_msg) + payload_length;
+ request_msg = malloc(request_msg_len);
+
+ rc = decode_oem_meta_file_io_write_req(msg, payload_length, request_msg,
+ request_msg_len);
+ if (rc < 0) {
+ free(request_msg);
+ return pldm_xlate_errno(rc);
+ }
+
+ *file_handle = request_msg->handle;
+ *length = request_msg->length;
+
+ /* NOTE: Unsafe, memory safety is not possible due to API constraints. */
+ memcpy(data, request_msg->data, request_msg->length);
+
+ free(request_msg);
+
+ return 0;
+}