Open
Description
Subject of the issue
use-after-free error in Wire library.
The relevant methods are Wire.begin
:
Arduino_Apollo3/libraries/Wire/src/Wire.cpp
Lines 14 to 19 in 4e24a02
and Wire.end
:
Arduino_Apollo3/libraries/Wire/src/Wire.cpp
Lines 31 to 40 in 4e24a02
With the sequence:
Wire.begin();
Wire.end();
Wire.begin();
//I2C Activity
After the call to Wire.end, master is pointing to the location of the deleted mbed::I2C
object.
Your workbench
- RedBoard-Artemis-ATP
- Sparkfun Arduino_Apollo3 2.2.0, Arduino 1.8.13
- TMP117 connected via QWIIC connector.
- Powered via the USB-C plug.
Steps to reproduce
Example Code
#include "Wire.h"
arduino::MbedI2C *myWire;
void setup() {
Serial.begin(115200);
Serial.println("Wire Use-After-Free");
Wire.end();
myWire = new arduino::MbedI2C(40, 39);
}
void loop() {
Serial.println("Loop");
myWire->begin();
Serial.println("Begin succeeded!");
Serial.println("Starting I2C transmission");
myWire->beginTransmission(0x48); //TMP117
myWire->endTransmission();
Serial.println("I2C transmission succeeded!");
myWire->end();
}
Example Code Output
Wire Use-After-Free
Loop
Begin succeeded!
Starting I2C transmission
I2C transmission succeeded!
Loop
Begin succeeded!
Starting I2C transmission
++ MbedOS Fault Handler ++
FaultType: HardFault
Context:
R0: 1000A750
R1: 90
R2: 1000A584
R3: A3009150
R4: 1000A750
R5: 0
R6: 0
R7: 0
R8: 0
R9: 0
R10: 0
R11: 0
R12: 23949
SP : 10006E48
LR : 10F2D
PC : A3009150
xPSR : 0
PSP : 10006DE0
MSP : 1005FF70
CPUID: 410FC241
HFSR : 40000000
MMFSR: 1
BFSR : 0
UFSR : 0
DFSR : 0
AFSR : 0
Mode : Thread
Priv : Privileged
Stack: PSP
-- MbedOS Fault Handler --
++ MbedOS Error Info ++
Error Status: 0x80FF013D Code: 317 Module: 255
Error Message: Fault exception
Location: 0xA3009150
Error Value: 0x10005E30
Current Thread: main Id: 0x10004248 Entry: 0x22C75 StackSize: 0x1000 StackMem: 0x10005E90 SP: 0x10006E48
For more info, visit: https://mbed.com/s/error?error=0x80FF013D&tgt=SFE_ARTEMIS_ATP
-- MbedOS Error Info --
Trace of I2C Output
First I2C transmission definitely worked:
Possible solution
This code would stop the use-after-free. Maybe more is needed.
void arduino::MbedI2C::end() {
if (master != NULL) {
delete master;
master = NULL;
}
#ifdef DEVICE_I2CSLAVE
if (slave != NULL) {
delete slave;
slave = NULL;
}
#endif
}