Background:
I am investigating an issue with the logging in my app. The app receives some string from the server, which we log with function similar to NSLog. The format we call that function is:
MyLog(@"%@", message);
In one case, message contains text "Save 38% now". At this point the app crashes.
The issue:
While looking into it I was able to pinpoint the issue. The full code is below.
#define FOO(FORMAT, ...) (\
{\
char *str;\
str = [[NSString stringWithFormat:FORMAT, ##VA_ARGS] UTF8String];\
str;\
}\
)\
#import "MyClass.h"
@implementation MyClass
(instancetype)init
{
self = [super init];
if (self) {
char *foo = FOO(@"%@", @"Save 38% now");
printf(foo);
}
return self;
}
@end
Instantiate class anywhere,
MyClass *my = [[MyClass alloc] init];
, and the app will crash upon printf(foo); with the message:
%n used in a non-immutable format string
Basically, the string "% n", with a space between "%" and "n" is threated as "%n", which is considered a vulnerability since latest OS releases.
Discussion:
I am still trying to proof my thoughts and find a way to solve the issue.
I believe, the code responsible for the crash is this: https://opensource.apple.com/source/Libc/Libc-1244.30.3/stdio/FreeBSD/vfprintf.c
I cannot understand why space between two characters does not make any difference for the code.
So far, it looks like a bug.
Solution:
n/a
Post
Replies
Boosts
Views
Activity
I am trying to reproduce the crash reported by our CI.
The app uses [NEHotspotConfigurationManager getConfiguredSSIDsWithCompletionHandler:] API to manage SSID configurations and it works fine on device and does not cause any issues when I try to reproduce it in Sim locally.
However, the crash report says that the crash does occur from time to time.
Below is the snipped of the crash report:
...
Code Type:						 X86-64 (Native)
Parent Process:				launchd_sim [52571]
Responsible:					 SimulatorTrampoline [52274]
OS Version:						Mac OS X 10.15.5 (19F101)
System Integrity Protection: disabled
Crashed Thread:				0	Dispatch queue: com.apple.main-thread
Exception Type:				EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:			 KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Note:				EXC_CORPSE_NOTIFY
Termination Signal:		Segmentation fault: 11
Termination Reason:		Namespace SIGNAL, Code 0xb
Terminating Process:	 exc handler [52945]
Application Specific Information:
CoreSimulator 704.12.2 - Device: iPhone 8 (5758E665-FD34-4B76-8846-B8C3551B3E14) - Runtime: iOS 13.6 (17G64) - DeviceType: iPhone 8
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0	 libxpc.dylib									 0x00000001182e8156 xpc_get_type + 72
1	 libxpc.dylib									 0x00000001182edf01 xpc_connection_send_message + 21
2	 com.apple.NetworkExtension		 0x00000001131af9d1 -[NEHelper connection] + 313
3	 com.apple.NetworkExtension		 0x00000001131afcf6 -[NEHelper sendRequest:responseHandler:] + 76
4	 com.apple.NetworkExtension		 0x00000001131b2674 -[NEHotspotConfigurationHelper sendRequest:requestType:resultHandler:] + 242
5	 com.apple.NetworkExtension		 0x00000001131b9c0c -[NEHotspotConfigurationManager getConfiguredSSIDsWithCompletionHandler:] + 163
...
I'm thinking maybe it is an Entitlement issue, since the API usage requires special entitlement. Does XPC call stack suggest this?
In general, this API does not make much sense for the Sim, so I'm thinking about mocking it for that particular case under the conditions
#if targetEnvironment(simulator)
#else
#endif
But, I still want to figure out the cause.
I've been trying to provide NSOutlineView with custom disclosure button.
Here is a simple NSButton subclass for that purpose:
Swift
final class AltDisclosureButton: NSButton {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
setButtonType(.toggle)
isBordered = false
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Then, in my NSOutlineView subclass, I do this:
Swift
override func makeView(withIdentifier identifier: NSUserInterfaceItemIdentifier, owner: Any?) - NSView? {
var view = super.makeView(withIdentifier: identifier, owner: owner)
if identifier == NSOutlineView.showHideButtonIdentifier, let button = view as? NSButton {
let customButton = AltDisclosureButton(frame: .zero)
customButton.target = button.target
customButton.action = button.action
customButton.identifier = identifier
let image = NSImage(systemSymbolName: "chevron.right.circle.fill", accessibilityDescription: "disclosure_indicator_button")!
customButton.image = image
let altImage = NSImage(systemSymbolName: "chevron.down.circle.fill", accessibilityDescription: "disclosure_indicator_button_down")!
customButton.alternateImage = altImage
customButton.symbolConfiguration = NSImage.SymbolConfiguration(pointSize: 16, weight: .medium)
customButton.contentTintColor = NSColor.controlAccentColor
view = customButton
}
return view
}
It basically sets two SF Symbols images to image and alternateImage respectively.
My problem is that there are only three NSButton.ButtonType values that work with button auto-rotate: .toggle, .switch, .radio, but none of them respect the contentTintColor -- the buttons are always gray.