Skip to content

Commit 2655291

Browse files
bzbarsky-applepull[bot]
authored andcommitted
Make errorToCHIPErrorCode safer to use. (#18707)
The old setup was creating CHIP_ERROR instances pointing to filenames with non-static lifetime, which could cause use-after-free. Removes the workaround chip-tool-darwin had for the broken behavior.
1 parent 3b9656c commit 2655291

File tree

2 files changed

+33
-30
lines changed

2 files changed

+33
-30
lines changed

examples/chip-tool-darwin/commands/common/CHIPCommandBridge.h

-11
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,7 @@ class CHIPCommandBridge : public Command
4444

4545
void SetCommandExitStatus(CHIP_ERROR status)
4646
{
47-
#if CHIP_CONFIG_ERROR_SOURCE
48-
// If there is a filename in the status makes a copy of the filename as the pointer may be released
49-
// when the autorelease pool is drained.
50-
strncpy(mCommandExitStatusFilename, status.GetFile(), sizeof(mCommandExitStatusFilename));
51-
mCommandExitStatusFilename[sizeof(mCommandExitStatusFilename) - 1] = '\0';
52-
mCommandExitStatus = chip::ChipError(status.AsInteger(), mCommandExitStatusFilename, status.GetLine());
53-
#else
5447
mCommandExitStatus = status;
55-
#endif // CHIP_CONFIG_ERROR_SOURCE
5648
ShutdownCommissioner();
5749
StopWaiting();
5850
}
@@ -90,9 +82,6 @@ class CHIPCommandBridge : public Command
9082
CHIP_ERROR ShutdownCommissioner();
9183
uint16_t CurrentCommissionerIndex();
9284

93-
#if CHIP_CONFIG_ERROR_SOURCE
94-
char mCommandExitStatusFilename[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE];
95-
#endif // CHIP_CONFIG_ERROR_SOURCE
9685
CHIP_ERROR mCommandExitStatus = CHIP_ERROR_INTERNAL;
9786

9887
CHIP_ERROR StartWaiting(chip::System::Clock::Timeout seconds);

src/darwin/Framework/CHIP/CHIPError.mm

+33-19
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@
2828

2929
NSString * const MatterInteractionErrorDomain = @"MatterInteractionErrorDomain";
3030

31+
// Class for holding on to a CHIP_ERROR that we can use as the value
32+
// in a dictionary.
33+
@interface CHIPErrorHolder : NSObject
34+
@property (nonatomic, readonly) CHIP_ERROR error;
35+
36+
- (instancetype)init NS_UNAVAILABLE;
37+
+ (instancetype)new NS_UNAVAILABLE;
38+
39+
- (instancetype)initWithError:(CHIP_ERROR)error;
40+
@end
41+
3142
@implementation CHIPError
3243

3344
+ (NSError *)errorForCHIPErrorCode:(CHIP_ERROR)errorCode
@@ -75,15 +86,7 @@ + (NSError *)errorForCHIPErrorCode:(CHIP_ERROR)errorCode
7586
}];
7687
}
7788

78-
#if CHIP_CONFIG_ERROR_SOURCE
79-
if (errorCode.GetFile()) {
80-
userInfo[@"errorFile"] = [NSString stringWithUTF8String:errorCode.GetFile()];
81-
}
82-
83-
if (errorCode.GetLine()) {
84-
userInfo[@"errorLine"] = @(errorCode.GetLine());
85-
}
86-
#endif // CHIP_CONFIG_ERROR_SOURCE
89+
userInfo[@"underlyingError"] = [[CHIPErrorHolder alloc] initWithError:errorCode];
8790

8891
return [NSError errorWithDomain:CHIPErrorDomain code:code userInfo:userInfo];
8992
;
@@ -226,6 +229,13 @@ + (CHIP_ERROR)errorToCHIPErrorCode:(NSError * _Nullable)error
226229
return CHIP_ERROR_INTERNAL;
227230
}
228231

232+
if (error.userInfo != nil) {
233+
id underlyingError = error.userInfo[@"underlyingError"];
234+
if (underlyingError != nil && [underlyingError isKindOfClass:[CHIPErrorHolder class]]) {
235+
return ((CHIPErrorHolder *) underlyingError).error;
236+
}
237+
}
238+
229239
chip::ChipError::StorageType code;
230240
switch (error.code) {
231241
case CHIPErrorCodeInvalidStringLength:
@@ -261,17 +271,21 @@ + (CHIP_ERROR)errorToCHIPErrorCode:(NSError * _Nullable)error
261271
}
262272
}
263273

264-
const char * file = nullptr;
265-
unsigned int line = 0;
266-
if (error.userInfo != nil) {
267-
if (error.userInfo[@"errorFile"] != nil) {
268-
file = [error.userInfo[@"errorFile"] cStringUsingEncoding:NSUTF8StringEncoding];
269-
}
270-
if (error.userInfo[@"errorLine"] != nil) {
271-
line = [error.userInfo[@"errorLine"] unsignedIntValue];
272-
}
274+
return chip::ChipError(code);
275+
}
276+
277+
@end
278+
279+
@implementation CHIPErrorHolder
280+
281+
- (instancetype)initWithError:(CHIP_ERROR)error
282+
{
283+
if (!(self = [super init])) {
284+
return nil;
273285
}
274-
return chip::ChipError(code, file, line);
286+
287+
_error = error;
288+
return self;
275289
}
276290

277291
@end

0 commit comments

Comments
 (0)