mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-18 17:13:34 +08:00
smbus: fix invalid memory access in read_word()
read_word() expected 3 bytes (uint16_t + PEC byte), but was passed an address to an uint16_t value. write_word() is changed to be type-safe as well.
This commit is contained in:
@@ -50,23 +50,23 @@ SMBus::SMBus(int bus_num, uint16_t address) :
|
||||
{
|
||||
}
|
||||
|
||||
int SMBus::read_word(const uint8_t cmd_code, void *data)
|
||||
int SMBus::read_word(const uint8_t cmd_code, uint16_t &data)
|
||||
{
|
||||
uint8_t buf[6];
|
||||
// 2 data bytes + pec byte
|
||||
int result = transfer(&cmd_code, 1, (uint8_t *)data, 3);
|
||||
int result = transfer(&cmd_code, 1, buf + 3, 3);
|
||||
|
||||
if (result == PX4_OK) {
|
||||
data = buf[3] | ((uint16_t)buf[4] << 8);
|
||||
// Check PEC.
|
||||
uint8_t addr = get_device_address() << 1;
|
||||
uint8_t full_data_packet[5];
|
||||
full_data_packet[0] = addr | 0x00;
|
||||
full_data_packet[1] = cmd_code;
|
||||
full_data_packet[2] = addr | 0x01;
|
||||
memcpy(&full_data_packet[3], data, 2);
|
||||
buf[0] = addr | 0x00;
|
||||
buf[1] = cmd_code;
|
||||
buf[2] = addr | 0x01;
|
||||
|
||||
uint8_t pec = get_pec(full_data_packet, sizeof(full_data_packet) / sizeof(full_data_packet[0]));
|
||||
uint8_t pec = get_pec(buf, sizeof(buf) - 1);
|
||||
|
||||
if (pec != ((uint8_t *)data)[2]) {
|
||||
if (pec != buf[sizeof(buf) - 1]) {
|
||||
result = -EINVAL;
|
||||
}
|
||||
}
|
||||
@@ -74,14 +74,14 @@ int SMBus::read_word(const uint8_t cmd_code, void *data)
|
||||
return result;
|
||||
}
|
||||
|
||||
int SMBus::write_word(const uint8_t cmd_code, void *data)
|
||||
int SMBus::write_word(const uint8_t cmd_code, uint16_t data)
|
||||
{
|
||||
// 2 data bytes + pec byte
|
||||
uint8_t buf[5] = {};
|
||||
uint8_t buf[5];
|
||||
buf[0] = (get_device_address() << 1) | 0x10;
|
||||
buf[1] = cmd_code;
|
||||
buf[2] = ((uint8_t *)data)[0];
|
||||
buf[3] = ((uint8_t *)data)[1];
|
||||
buf[2] = data & 0xff;
|
||||
buf[3] = (data >> 8) & 0xff;
|
||||
|
||||
buf[4] = get_pec(buf, 4);
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
* @param cmd_code The command code.
|
||||
* @param data The data to be written.
|
||||
* @param length The number of bytes being written.
|
||||
* @return Returns PX4_OK on success, PX4_ERROR on failure.
|
||||
* @return Returns PX4_OK on success, -errno on failure.
|
||||
*/
|
||||
int block_write(const uint8_t cmd_code, void *data, uint8_t byte_count, bool use_pec);
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
* @param cmd_code The command code.
|
||||
* @param data The returned data.
|
||||
* @param length The number of bytes being read
|
||||
* @return Returns PX4_OK on success, PX4_ERROR on failure.
|
||||
* @return Returns PX4_OK on success, -errno on failure.
|
||||
*/
|
||||
int block_read(const uint8_t cmd_code, void *data, const uint8_t length, bool use_pec);
|
||||
|
||||
@@ -72,23 +72,23 @@ public:
|
||||
* @brief Sends a read word command.
|
||||
* @param cmd_code The command code.
|
||||
* @param data The 2 bytes of returned data plus a 1 byte CRC if used.
|
||||
* @return Returns PX4_OK on success, PX4_ERROR on failure.
|
||||
* @return Returns PX4_OK on success, -errno on failure.
|
||||
*/
|
||||
int read_word(const uint8_t cmd_code, void *data);
|
||||
int read_word(const uint8_t cmd_code, uint16_t &data);
|
||||
|
||||
/**
|
||||
* @brief Sends a write word command.
|
||||
* @param cmd_code The command code.
|
||||
* @param data The 2 bytes of data to be transfered.
|
||||
* @return Returns PX4_OK on success, PX4_ERROR on failure.
|
||||
* @return Returns PX4_OK on success, -errno on failure.
|
||||
*/
|
||||
int write_word(const uint8_t cmd_code, void *data);
|
||||
int write_word(const uint8_t cmd_code, uint16_t data);
|
||||
|
||||
/**
|
||||
* @brief Calculates the PEC from the data.
|
||||
* @param buffer The buffer that stores the data to perform the CRC over.
|
||||
* @param length The number of bytes being written.
|
||||
* @return Returns PX4_OK on success, PX4_ERROR on failure.
|
||||
* @return Returns PX4_OK on success, -errno on failure.
|
||||
*/
|
||||
uint8_t get_pec(uint8_t *buffer, uint8_t length);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user