Hacker News new | ask | show | jobs
by Shrezzing 770 days ago
This is almost certainly intentional, and is very similar to the way web browsers mitigate the Spectre vulnerability[1]. Your processor (almost certainly) does some branch prediction to improve efficiency. If an application developer reliably knows the exact time, they can craft an application which jumps to another application's execution path, granting them complete access to its internal workings.

To mitigate this threat, javascript engine developers simply added a random fuzzy delay to all of the precision timing techniques. Swift's large volume of calls to unrequired methods is, almost certainly, Apple's implementation of this mitigation.

[1] https://en.wikipedia.org/wiki/Spectre_(security_vulnerabilit...

7 comments

This is not true in the slightest, and I feel that you might be misunderstanding how these attacks work. Spectre does not allow you to control execution of another process. It does not touch any architecturally visible state; it works via side channels. This means all it can do is leak information. The mitigation for Spectre in the browser adds a fuzzy delay (which is not considered to be very strong, fwiw). Just making a slower timer does not actually mitigate anything. And if you look at the code (it's all open source!) you can see that none of it deals with this mitigation, it's all just normal stuff that adds overhead. These attacks are powerful but they are not magic where knowing the exact time gives you voodoo access to everything.
Nothing prevents applications from just calling the underlying methods mentioned in the article, so that can’t be it. The author even benchmarked these!
Nothing? FTA: “The downside to calling mach_absolute_time directly, though, is that it’s on Apple’s “naughty” list – apparently it’s been abused for device fingerprinting, so Apple require you to beg for special permission if you want to use it”
All the other methods "above" mach_absolute_time are still allowed though, including clock_gettime_nsec_np that's only ~2x slower than mach_absolute_time. While the Swift clock is ~40x slower than mach_absolute_time. I don't see how intentional slowdown for fingerprinting protection can be the cause.
Someone took inspiration from FizzBuzzEnterpriseEdition[1] and made their integer query API future proof.

[1] https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...

All of the new privacy declarations are silly, but this one is especially ridiculous.

I'm pretty sure I can trigger a hit to the naughty API just by updating a @Published var in an ObservedObject. For those unfamiliar with SwiftUI, this is the most basic way to tell the system that your model data has changed and thus it needs to re-render the view. Pretty much every non-trivial SwiftUI app will need to do this.

but date and clock_gettime are still accessible and not much more overhead than the Mach API call. Additionally as I mention in another comment, this would have to be about Meltdown, not Spectre, and Meltdown is mitigated in the kernel through other techniques without sacrificing timers.
It isn't difficult to be granted this permission. All an app needs to do is supply a reason defined in https://developer.apple.com/documentation/bundleresources/pr... as to why it's being used in the app's bundled PrivacyInfo.xcprivacy file, which could be disingenuous.
It may not be difficult, but it's an additional layer of requirement. Defense in depth baby!
In addition, if you get caught lying about this, your app may be nuked and your developer account terminated. May not be a big hurdle, but definitely can hurt if you have many users.
This would have to be for Meltdown not Spectre. Spectre is in process and meltdown is cross-process. In process would be pointless for a language like swift.

And it’s a weird mitigation because Meltdown afaik has been mitigated on other OSes without banning high res timers.

The nail in the coffin is that it’s unlikely about security is Date and clock_get_time are accessible and an order of magnitude faster.

This seems a more likely scenario of poorly profiled abstraction layers adding features without measuring the performance.

If this was intentional, shouldn't it also affect `mach_absolute_time` which is used by the standard libraries of most languages and accessible to Swift?

Also note you can get precise JavaScript measurements (and threading, eg. using pthreads and Emscripten) by adding some headers: https://developer.mozilla.org/en-US/docs/Web/API/Window/cros...

> Also note you can get precise JavaScript measurements (and threading) by adding some headers

Though you can access these techniques now, in the weeks after Spectre attacks were discovered, the browsers all consolidated on "make timing less accurate across the board" as an immediate-term fix[1]. All browsers now give automatic access to imprecise timing by default, but have some technique to opt-in for near-precise timing.

Similarly, Swift has SuspendingClock and ContinuousClock, which you can use without informing Apple. Meanwhile mach_absolute_time & similarly precise timing methods require developers to disclose the reasons for its use before Apple will approve your app on the store[2].

[1] https://blog.mozilla.org/security/2018/01/03/mitigations-lan...

[2] https://developer.apple.com/documentation/kernel/1462446-mac...

That makes a lot of sense, thank you!
No it doesn’t. Higher performance APIs like Date and clock_gettime are still available and not specially privileged and 40x faster. This looks pretty clearly like a bug.

Spectre mitigations also are really silly here because as a swift app you already have full access to all in-process memory. It would have to be about meltdown but meltdown is prevented through other techniques.

Have to protect those pesky application developers from knowing the time so they can write correct software.

It makes sense for a web browser. Not for something like Swift.

No, this is pretty clearly just a bug / poor design. Mistakes happen.
Probably but I'm just responding to GP who implied that Apple, in all its infinite wisdom, did this on purpose.
Literally one page into the article there is the full stack trace that makes abundantly clear there is no such thing going on, they just added a bunch of overhead.

That's despite OSX having a vDSO style mechanism for it: https://github.com/opensource-apple/xnu/blob/master/libsysca...

No, that is nonsense.

A competent organization would not make the function call take longer by a random amount of time. You would just do it normally then add the random fudge factor to the normal result. That is not only more efficient, it also allows more fine-tuned control, the randomization is much more stable, and it is just plain easier to implement.

Though I guess I should not put it past them to do something incompetent given that they either implemented their native clocks poorly as the article says, or they incompetently implemented a Spectre mitigation as you theorize.