-
Notifications
You must be signed in to change notification settings - Fork 6k
Disable ptrace on arm64e running iOS 14.2 and greater #22377
Conversation
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat. Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
Let's hold off actually merging this until we know more about what devices still need tracing, but I wanted a PR ready to go. |
int major_version = 0; | ||
char minor_letter = 'Z'; | ||
|
||
for (size_t index = 0; index < osversion_size; index++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This parsing felt like an interview question (atoi
!), happy to try something more idiomatic if ya'll can think of a better way to do it. I started with an istringstream
but it actually wound up being identical logic so it didn't seem worth the extra object.
return false; | ||
} | ||
|
||
// Check for iOS 14.2 and higher. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
up to you but it feels like we're building in a lot of platform specific knowledge at this point. How about just letting this file statically take a SetOSVersionMayNeedTracingCheck injection or something and FlutterEngine can just set it to https://developer.apple.com/documentation/foundation/nsprocessinfo/1414876-isoperatingsystematleastversion? Could save us some work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this were all in obj-c++ world then I wouldn't have bothered with all these syctl checks. But it would need to be injected from:
Line 333 in e78e405
const bool tracing_result = EnableTracingIfNecessary(settings_); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's what I meant injecting it statically (since all these stuff is static anyway). Since the engine calls first, we know it would be set before dart calls it again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't love that the lower level code would require a static variable to be set before it can be called, without enforcing that ordering itself. Seems like an easy opportunity for bugs if this ever gets refactored. Will defer to @chinmaygarde's opinion here.
If we decide to keep this kern.osversion
parsing I'll add a unit test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love the initiative in doing this in C, but let's make this an ObjC++ TU and use NSOperatingSystemVersion
instead. You can remove the TRACING_CHECKS_NECESSARY
macro and add a stub C++ file for non-Darwin platforms.
|
||
// Tracing is necessary unless the device is arm64e (A12 chip or higher). | ||
if (cputype != CPU_TYPE_ARM64 || cpusubtype != CPU_SUBTYPE_ARM64E) { | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ultra-nit: there's a triple negation at this point :) false to != arm64 to unnecessary. Can we simplify slightly?
@@ -27,6 +27,7 @@ | |||
#include <sys/sysctl.h> | |||
#include <sys/types.h> | |||
|
|||
#include <mach/machine.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be conditionally imported and used? @chinmaygarde might have a better idea of whether this is available on all our target platforms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine. TRACING_CHECKS_NECESSARY
is unset on all other platforms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Construction issues aside, this must not land as you'd still to check if the entitlement is present at the specific iOS version. Apps without the entitlement in debug will still crash. I'd also rather link to Apple's documentation instead of relying on speculation right now.
@@ -27,6 +27,7 @@ | |||
#include <sys/sysctl.h> | |||
#include <sys/types.h> | |||
|
|||
#include <mach/machine.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine. TRACING_CHECKS_NECESSARY
is unset on all other platforms.
cpu_type_t cputype = 0; | ||
size_t cputype_size = sizeof(cpu_type_t); | ||
if (::sysctlbyname("hw.cputype", &cputype, &cputype_size, nullptr, 0) < 0) { | ||
FML_LOG(ERROR) << "Could not execute sysctl() to get CPU type: " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and elsewhere: Early return in case of error.
return false; | ||
} | ||
|
||
// Check for iOS 14.2 and higher. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love the initiative in doing this in C, but let's make this an ObjC++ TU and use NSOperatingSystemVersion
instead. You can remove the TRACING_CHECKS_NECESSARY
macro and add a stub C++ file for non-Darwin platforms.
|
||
// Check for iOS 14.2 and higher. | ||
size_t osversion_size; | ||
::sysctlbyname("kern.osversion", NULL, &osversion_size, NULL, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unchecked error code. Though, I'd suggest using the ObjC++ variant instead.
@jmagman Any updates? Have you tried this without the entitlement in the plist? |
I haven't created the ObjC++ variant yet. On this PR it's working on an (arm64e) iPad Pro by launching without the debugger attached and running the app. And on an (arm64) iPhone 6s it's showing the warning screen.
Which entitlement?
Yeah all I have is speculation about the A12 and higher chips. |
@zanderso Would you like me to keep working on this so users can launch apps from the home screen on new devices? Or should I abandon? |
I think we should probably abandon until we can get some more solid info about the devices where this is supported. |
Description
The ptrace trick may not be necessary on iOS 14.2 (beta release candidate) which seems to have added JIT compilation support. This means Flutter debug apps aren't sigkilled when launched without an attached debugger.
There's speculation that this is only true on A12 (and presumably later A-) chips. With
#define TRACING_CHECKS_NECESSARY 0
a debug app launched from the home screen on my A12 iPad Pro, but on @xster's A9 iPhone 6s it still crashed.engine/runtime/ptrace_check.h
Lines 13 to 15 in f0fb74b
The outstanding theory is JIT may only be working on arm64e devices running iOS 14.2.
Related Issues
Fixes flutter/flutter#69984
Testing
I have no idea how to test this any more than the rest of this
ptrace
file without adding some wrappers aroundsysctlbyname
. Unfortunately I don't think we have any arm64e devicelab test devices, either.