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:
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.
Instantiate class anywhere,
, and the app will crash upon printf(foo); with the message:
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
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:
Code Block C 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.
Code Block C #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,
Code Block MyClass *my = [[MyClass alloc] init];
, and the app will crash upon printf(foo); with the message:
Code Block %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
Regardless of the space issue you highlighted, the code you posted doesn’t make sense. Specifically, this line:
should be this:
Without that, any percents in foo will be interpreted as introducing a conversion specifier and that’s not what you want.
If you want this sort of code to work as written, you’d need code to escape the percents. Or switch to fwrite.
Beyond that, your FOO macro’s use of UTF8String is worrying. UTF8String is declared using NS_RETURNS_INNER_POINTER, which maps to objc_returns_inner_pointer. Technically this is supposed to work because the Clang docs (1) say “the last use of the returned pointer … in the calling function” — note that it’s “calling function”, not “enclosing scope” — but I’d be inclined to be a bit conservative here.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
(1) releases.llvm.org/9.0.0/tools/clang/docs/AutomaticReferenceCounting.html#interior-pointers
Code Block printf(foo);
should be this:
Code Block printf("%s", foo);
Without that, any percents in foo will be interpreted as introducing a conversion specifier and that’s not what you want.
If you want this sort of code to work as written, you’d need code to escape the percents. Or switch to fwrite.
Beyond that, your FOO macro’s use of UTF8String is worrying. UTF8String is declared using NS_RETURNS_INNER_POINTER, which maps to objc_returns_inner_pointer. Technically this is supposed to work because the Clang docs (1) say “the last use of the returned pointer … in the calling function” — note that it’s “calling function”, not “enclosing scope” — but I’d be inclined to be a bit conservative here.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
(1) releases.llvm.org/9.0.0/tools/clang/docs/AutomaticReferenceCounting.html#interior-pointers