An iOS zero-click radio proximity exploit odyssey
googleprojectzero.blogspot.com
googleprojectzero.blogspot.com
> Using two MacOS laptops and enabling AirDrop on both of them I used a kernel debugger to edit the SyncTree TLV sent by one of the laptops, which caused the other one to kernel panic due to an out-of-bounds memmove.
How did this even pass the _smell_ test? How did it get through code reviews and auditing? You're allocating from an untrusted source. It's like memory management 101. I mean, my goodness, it's from a wireless source, at that.
† In this specific scenario, namely the list of `IO80211AWDLPeer`s.
Ensuring an oft-loaded structure always fits inside a single cache line (instead of splaying across ~1.9 cache lines on average) is good not only for fitting lots of those structures into your L1 but for not blowing out cache bandwidth (read _and_ write, if you're modifying them).
(someone please correct me if I'm wrong)
There is also the claim that linked lists are better in certain types of performance sensitive code because you can sometimes avoid allocating. I don't fully understand the logic there myself but I trust that there are cases where this is true.
A linked list also avoids copying the entire array when you need to insert more elements than you have allocated space for.
This is false. Big O notation says it should be true, you'll get marked wrong if you say arrays are faster in your algorithms & data structures final, but when you're running on actual hardware the array is faster at all sizes of n and as n becomes larger so does the gap in performance.
Here is a talk[0] by Bjarne Stroustrop (Creator of C++) that even includes imaginary graphs demonstrating this phenomenon. If you want a visual for what the missing graph was supposed to look like, here's a similar one.[1]
Here's another video[2] by Scott Meyers (Author of Effective C++) that goes into more detail about why this happens.
[0]: https://www.youtube.com/watch?v=YQs6IC-vgmo [1]: https://airspeedvelocity.files.wordpress.com/2015/08/pasted_... [2]: https://www.youtube.com/watch?v=WDIkqP4JbkE
While the array change does need on average 50k items to be shuffled up to make room or close the gap, modern caches are very good at that.
If the array is sorted it can be binary searched to get to the change point, which improves its performance even more, linked lists can’t do that.
Interesting.
And if you not doing ordered insertion you wouldn't have to move the data in the array anyway, you would keep track of the size and jump to the end, so not sure I understand the binary search comment.
The next question is at what level of growth the waste of empty space in the array becomes too much. Some kind of data structure (tree/linked list) with largish (whatever size applicable for modern cpu) as probably mentioned in other comments does seem the most versatile approach while keeping the performance. Or perhaps the handling of that data structure might overwhelm the array advantage?
> And if you not doing ordered insertion you wouldn't have to move the data in the array anyway, you would keep track of the size and jump to the end, so not sure I understand the binary search comment.
It just means that if I want to view the nth element of an array, that's a constant time operation. I just take the pointer and add n times the size of the elements.
But for a linked list if I want to view the nth element of the list, I have to view the (n-1)th element first, all the way back until the first element I have a reference to.
> The next question is at what level of growth the waste of empty space in the array becomes too much.
Everything I've tried and everything I've seen from people testing on real hardware is that the gap in performance widens with larger values of n.
You might expect different performance as the system runs out of memory. But arrays have a size of n * element size, and linked lists have a size of n * (pointer(s) + element size), so the linked list would hit memory limitations more quickly regardless.
But yes the size advantage is very reduced for most use cases. What would you imagine the cases where LinkedList is still a valid data structure?
True. Then it comes down to the size of your data vs the size of your pointers.
> What would you imagine the cases where LinkedList is still a valid data structure?
Compared to an array? When the array doesn't have the behavior that you need.
For instance, if you need to keep a stable reference to a particular element in a list, even while that list is being inserted into, then an array is not going to cut it. The linked list handles this case with ease.
That's not to say you can't write a wrapper for the array that does the right thing, probably for cheaper. But out of the box the linked list can do things that the array cannot and if you rely on them, then use the right tool for the job.
If you're not, then why is all of that data packed together? Is there an alternate layout you could use instead where you iterate over the exact values you need? If performance is important to you in that context it might be worth it.
One case where I don't know what to think: the implications of memmoving the subarray on NUMA cache invalidation in an extremely multithreaded application.
The tradeoff in moving memory at the end of the array vs scanning to the point of linked list insertion could be different on some existing and some hypothetical systems where these concepts may be relevant. For example, storage write cycle minimization could be a priority in rare cases.
That said this is an excellent point about the majority of use cases. I hadn't considered the dominance of the time it takes to locate the element to modify. I've never had a reason to benchmark a linked list since even a basic idea of the effect of cache/prefetch precludes its use in every use case I've actually come across.
Probably useful for CS education to start comparing linked lists to bubble sort. There's always a better algorithm, but here's a simple one to learn so you understand how to compare data structure performance.
You could, in principle, allocate your linked list out of contiguous memory in such a way that sequentially reading the list doesn't cause so many page accesses. That would itself be a complicated data structure to maintain, so simply using a linear array is often the right tradeoff.
In practice, I would let benchmarks decide the array size. Modern CPUs are surprisingly good at prefetching even linked lists, and x86 works weird out-of-order magic and speculation while waiting for memory. My rules of two thumbs were 1) where performance really matters, don't trust your intuition, program and benchmark alternative implementations 2) don't trust microbenchmarks, e.g. total icache pressure changes whether inlining is good or not.
Here is an article about them in Modula-2, to use a language of similar age as C.
GP comment was curious about why they've only heard about "linked lists" in a language, C, which like Modula-2 does not use them as the basic standard library collections type. When you have to implement linked lists yourself if you want to use them, you're always going to refer to them by implementation detail. In the vast majority of cases where they're used, though, it's as the fundamental standard library collection, and in that case they're usually just called Lists without telling the caller about their implementation.
(This idiom is true to the point that the Python implementers feel the need to point out that CPython uses arrays to implement the list type, as they feel that this would be unexpected to users of other languages that call their basic collections type a "list".)
> The data structure holding the peers is in fact much more complex than a linked list, it's more like a priority queue with some interesting behaviours when the queue is modified and a distinct lack of safe unlinking and the like.
I amended my post for clarification, I'm sure Apple uses linked lists all the time :)
Because attackers only have to find one place that was unlucky in implementation, and hence defenders are burdened with eliminting every last one of them.
This is why implementing your network protocols in unsafe languages is bad. Testing can just find some bugs, not ensure absence of bugs.
https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=rust
Now I know it's deeply comforting to think if you just had "safety" you could write all the code you want with abandon and the computer would tell you if you did it wrong, but this is a sophomoric attitude that you will either abandon when you have the right experiences, or you will go into management where the abject truth in this statement will be used to keep programmer salaries in the gutter, and piss-poor managers in a job. Meanwhile, these "safe" languages will give you nothing but shadows you'll mistake for your own limitations.
My suggestion is just learn how to write secure code in C. It's an unknown-unknown for you at the moment, so you're going to have to learn how to tackle that sort of thing, but the good news is that (with the right strategy) many unknown-unknowns can be attacked using the same tricks. That means if you do learn how to write secure code in C, then the skills you develop will be transferable to other languages and other domains, and if you still like management, those skills will even be useful there.
That is a good suggestion to an individual developer. What is your suggestion to a lead developer of a big organisation? Let’s say to the CTO of Apple.
You can see at that level of abstraction the “make sure every one of your developers know how to write secure code in C and they never slip up” manifestly doesnt work.
You can fault individuals for bugs up to a certain point, but if we want to make secure systems we have to change how we are making them. To make the whole process resistant to oopsies.
You don't need "every one of your developers" to write C neither.
When a company puts security first, they can get results. Unfortunately, security doesn't really sell software like features do, so a true hardened-by-default mindset is impossible in practice. Hence, we need better tools and processes to build features, as you say.
Apple employees would have access to these symbols and much more debugging info that the OP poster "got lucky due to an accidental share", so the process would be a lot easier for them.
EDIT: also, required reading on how vulnerabilities are discovered, important types of bugs, is not unreasonable, nor a long read.
He can pay for my advice if he really wants to hear it, but this isn't really about programming at this point because we're talking about business goals which can have all sorts of priorities besides making quality software.
Do we want software quality? Then we want better programmers.
> if we want to make secure systems we have to change how we are making them.
On this we agree, but thicker training wheels just gets more people on bikes; It doesn't make the roads any safer.
Of course after we do eliminate these low hanging fruit, we will be left with a pie of the remaining classes of vulnerabilities that looks different, it's like Amdahls law. But that's no excuse to skip past "step 1".
Sure they can, it just requires discipline. Most of djb's code (in C) has a lower defect count than most other implementations you'll find in any language, and the mistakes he does make are in relaxing his discipline when thinking it doesn't matter (because of privilege isolation -- something he later admitted was a mistake[1] -- or because nobody puts that much memory in a machine, because times change!).
[1]: https://cr.yp.to/qmail/qmailsec-20071101.pdf
> But that's no excuse to skip past "step 1".
Zeno would like a word. I'm arguing a different metaphor, not "try harder".
If it is true that programs get too big to maintain the level of discipline the language requires, and regardless of the language you're going to be confronted with defects, then the solution (in my mind) is smaller programs because only the small program has a chance of being correct in the first place.
This not good advice. We've been battling with this issue for decades, and it's clearly not going away by trying to be more careful.
The reason for that is because large projects can’t have only one developer. As soon as you have multiple developers you have a problem. What happens when two developers begin working on the same base commit. Developer A makes a change to remove a contractual behavior that is not relied upon. Developer B makes a change that relies on this contractual behavior. Both changes are correct on their own, could very well pass code review simultaneously, and then both merge without conflicts. And then your last life line is whatever guarantees you have via static analysis, etc. (notably, this could still fail in a memory safe language if there aren’t any safe guards for this particular logic bug. Nothing is a panacea. Having more tools to write safer code, though, can at least help prevent some of these cases.)
That’s assuming everyone is perfect and has unlimited time to write perfectly sound code always. And it still fails.
You point to Rust but nobody said it had to be Rust. Still, just because Rust is not a panacea does not mean it has no value. On the contrary, while there has been decades to hone practices for secure C, Rust is a relative newcomer and obviously shows a ton of promise. It and other new memory safe languages are very likely to take a bite out of C usages where security is important. You can embrace this or deny it... but if you think it’s not happening, you should definitely take a look at the writing on the wall, because it’s certainly there. On the other hand, there are also other approaches. I believe seL4 is doing C code with proofs of correct operation. (Admittedly, I do not fully understand what guarantees this gives you and how, but it sounds promising based on descriptions. There could still be bugs in the proofs, but it certainly raises the bar.)
Why not?
Doctors got better with more training and better strategies towards medicine, and that's a game where a single mistake really is "end game".
You bring up a great point, though. Historically, C is often not trusted for software where people’s lives are on the line. Thus bringing up doctors is a great example of how building a better programmer is not good enough. There’s an entire class of “safety critical” programming practices and standards and it was common to prefer a language like Ada that made more bugs and logic errors into compiler errors.
Apologies for missing your point. I thought you meant by this:
> The reason for that is because large projects can’t have only one developer.
... that you meant we would have to change more things in our business and software cultures rather than just making programmers smart (something I could agree with), not that you believed this was some kind of truism.
I don’t believe this is true. Why are you convinced it is impossible to do “big” things without big teams of idiots?
> Historically, C is often not trusted for software where people’s lives are on the line. Thus bringing up doctors is a great example of how building a better programmer is not good enough.
I don’t see how one of these things has to do with the other. Can you explain the link?
Almost all of those are due to code in unsafe blocks. In other words, not safe rust.
A few are cryptographic errors. No argument there, Rust won't save you from that.
FWIW Rust does badly need a standardized unsafe-block auditing mechanism. Like "show me all the unsafe blocks in my code or any of the libraries it uses, except the standard library". If that list is too long to read, that's a bug in your project.
The readme is quite good.
I guess all that's left is the socialogical aspect: packages' "geiger" status ought to be treated as being as important as their dependencies. In other words, lib.rs/docs.rs/crates.io ought to display these data in all the sorts of places where they list the dependencies of a package.
It would also be great if this tool were made a standard part of cargo. I think it's important enough to deserve that status.
I could see there being all kinds of scans of dependencies, like enforcing test coverage, builds and tests passing on certain platforms (risc-v, wasi, etc).
Anything that tracks dependencies ought to be tracking transitive unsafeness.
That's the mindset shift the Rust world needs. Otherwise we're going to keep getting these (in some sense valid) complaints about how Rust isn't memory-safe because it has unsafe-blocks.
My personal hope is that lib.rs and docs.rs replace crates.io and that safety, code coverage, perf and other dimensions of quality are prominently displayed and queryable. Crates.io as it is now has outlived its usefulness.
I believe you and I agree on this issue completely.
I've been looking for a good project to get my feet wet in rust and your idea sounds like a perfect one, but a quick Google search makes it seem like a solved problem. I'd like to understand what's still left that I might add.
Thanks!!
https://www.reddit.com/r/rust/comments/8ssjv2/cargogeiger_ye...
The whole point of safe systems language is not to write 100% code free of exploits, rather to minimize it as much as possible.
Naturally there are still possible exploits, however the attack surface is much smaller when memory corruption, UB (> 200 documented use cases), implicit conversions and unchecked overflows aren't part of every translation unit.
Decades of evidence demonstrate that this cannot be done. Even world experts introduce vulns. Writing secure code in languages with tons of guardrails is hard. Writing and evolving secure C is impossible at almost any scale.
This is why researchers like the OP exist. They find exploits and report them to the manufacturer (hopefully) before they can be used. The fact that this is an effective way of protecting us is also why major software companies offer bug/exploit bounties to researchers.
To demand that all possible exploits of this nature never find their way into production builds is to demand perfection from humans. There is too much to know and think about, and definitely too many unknowns about the future, to make such a fantasy possible while still meeting release deadlines. We software developers often have a hard enough time just meeting feature and documentation deadlines, and adding more people just makes organizing your efforts more complex and difficult which then requires even more people until you reach the point that the scope of organizing your development teams is financially impossible.
Short of rewriting the whole of iOS in a memory safe language I'm not sure how they could even solve this problem. Assigning a researcher to search for 6 months only to find one bug is financially prohibitive.
> One of the most time-consuming tasks of this whole project was the painstaking process of reverse engineering the types and meanings of a huge number of the fields in these objects. Each IO80211AWDLPeer object is almost 6KB; that's a lot of potential fields. Having structure layout information would probably have saved months.
> Six years ago I had hoped Project Zero would be able to get legitimate access to data sources like this. Six years later and I am still spending months reversing structure layouts and naming variables.
I believe they're about to do this: https://www.theverge.com/2019/8/8/20756629/apple-iphone-secu...
No sources or structure layout or symbols, so you're still stuck waddling through megabytes of compiled code to reverse-engineer everything from scratch.
It's Apple drumming up absolutely nothing, and from my point of view it's mostly a PR stunt.
Well, I don't think it's quite "nothing". Newer phones don't have access to checkm8, and getting a private jailbreak or exploit working can be non-trivial. And in some cases, researchers may need to avoid reporting that exploit to Apple in order to keep using it.
It's a good step. It's just not sufficient, especially given all the other restrictions.
And this will continue to happen until Apple just starts selling the damn things to anyone who wants them, instead of trying to gatekeep them to people who are playing by their ridiculous security disclosure rules.
Sure, some crazy people who aren't security researchers will probably buy them too and use them as daily drivers (I'd probably be one of them). So what? I don't understand why Apple feels the need to hold this stuff so close to their chest. Everyone in this scenario knows exactly what they're buying.
Oh, that's a shame. The slide in the referenced tweet says, "advanced debug capabilities", so I'd assumed that's what it meant. I wonder what else that could mean?
https://twitter.com/benhawkes/status/1286021329246801921
> It looks like we won't be able to use the Apple "Security Research Device" due to the vulnerability disclosure restrictions, which seem specifically designed to exclude Project Zero and other researchers who use a 90 day policy.
For some reason this ridiculous restriction reminds me when Apple sued Samsung because their phones had round corners.
Rounded corners are the after-the-strategic-decision legal justification.
This is no longer possible on any phone, tablet, or computer Apple sells: all require online activation with device-specific info. There is no way to put the device back into a known state offline or without Apple having an opportunity to tamper with it (or be forced to tamper with it).
It is still possible on all of their computers, just not their phones or tablets. Intel Macs (which are still being sold in large numbers) can always be wiped and restored from USB without an internet connection, and Apple Silicon Macs can do it if you set the boot-loader to "Reduced Security" mode.
I would love to be wrong about this.
This is the case even if you have a full offline boot/restore USB.
I have a post coming out today about just this, and how it renders all current macs unsuitable for long term offline/airgap applications.
No need to dig so much if you just want to fix the problem.
But he wanted to prove something. That is a different thing.
By 'wanting to prove something', he showed the shortcomings of multiple security mitigations, all defeated by simple bugs.
By 'wanting to prove something', he also discovered two other exploitable 0days, that wouldn't have been discovered otherwise. Those 0days were likely already in the hands of bad actors, too.
Finally, the reason he even discovered the original bug is because Apple accidentally once or twice forgot to strip function names from a binary. If this didn't happen, that bug very likely would still be out there in the wild.
I'm not sure you understand how security research works.
But, if you actually stop and think about it for a moment... isn't this situation completely bizarre? Apple Silicon Macs explicitly support booting alternate OSs, because Apple went out of their way to add a `permissive-security` option to the boot-loader. They know Linux is important—the initial Apple Silicon reveal included a Linux VM demonstration—and now a well-known and talented developer is planning to do a native Linux port, at no cost to Apple, and we all fully expect that Apple won't make any documentation available or answer any questions? And, we're probably right?
The more I consider it, the more crazy it all seems. Why is Apple so private about the internals of their products? It won't affect marketing—normal consumers don't care—and I can't think of a plausible scenario where this type of information could help a competitor.
Is Apple using source code stolen from Oracle? Are they scared someone will discover an internal library written in COBOL and make fun of them? Are they worried their documentation could revive Steve Jobs as a vengeful ghost? I just don't get it.
Even when it doesn't rely on anything Apple-specific, it can be unclear how to build it.
I noticed that if I ctrl-z dc, then resume it, it silently exits. I grabbed the source to see if I could build it, and then perhaps debug this.
The source is part of bc. When you extract it there is a directory containing a bc dir, a patches dir, a bc sources tarball, and a Makefile. The bc directory is the contents of the tarball with the patches from the patches directory applied.
Optimistically typing "make" does not work. It runs configure somewhere (in the bc directory, I think), decides that gcc is /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc, and decides that this cannot create executables and exits.
Maybe just going into the bc directory and running configure and make there will do the trick? ./configure works and builds a makefile. Trying to compile with that gets fatal errors, apparently due to missing <string.h> in some C files.
OK, I don't actually care about bc, so how about just trying to build dc, which lives in a subdirectory under the bc directory.
That gets a fatal error due to a conflict between "#define ptrdiff_t size_t" in the config.h that configure made, and "typedef __darwin_size_t size_t" from somewhere. Based on the comments in config.h, apparently it should only be defining that if it is not defined by the system. Commenting it out in config.h and trying again...and all the compiling steps for dc actually finish!
Alas...it then fails because it needs ../lib/libbc.a, which presumably would have been built before building dc if the bc build had worked.
Maybe if I go to ../lib and type make? Nope. In fact, the errors are identical to when I typed make for bc, because it turns out that making libbc.a is the first thing the bc make tries to do.
Tossing in "#include <string.h>" in lib/getopt.c and lib/number.c makes everything build, finally giving me a locally built dc.
Is it too much to ask that when I download the source from Apple to their version of a simple command line knows-nothing-about-MacOS utility like this, I should just be able to type "make" somewhere and have it build? Or at least have a README in the tarball that tells me what I need to do?
$ CC="clang -Wno-implicit-function-declaration" ./configure
$ makeBecause they don't care. The extent they care is directly linked to the amount of money they will make from caring. They won't sell more macs if macs can run Linux better; but they will sell more Apple Music subscriptions if macs keep running macOS.
> They know Linux is important
No, they know Linux is a pain in the ass. The bootloader option assuages the executives' conscience enough to be able to talk to a journalist and keep a straight face when asked about "openness" or being "hacker-friendly", stuff those 1980s-style Linux hobbyists keep talking about and nobody else gives a shit about.
Apple makes money by selling iDevices to consumers and selling Macs to enough developers to build apps for iDevices. Everything else is a bonus, and not worth spending much time on. They do the minimum and leave it as that. There is no inconsistency or secret motive. They just don't care. When they cared, in the early '00s, they did a bit more; now they do less. The attitude is the same.
For now. They haven't made any "I have to buy this right fucking now!" worthy revolutionary improvements in the iDevices lineup recently, the Western market for smartphones is near saturation - and with Corona tanking the US economy for wide masses, people don't have the hundreds of dollars just lying around to shell off for the latest iteration.
I believe that both the last (horribly expensive at that, and still people kept buying it) Mac Pro and the new M1 lineup is a sign that Apple wants to shift back attention to the non-mobile sector - because the competition there is asleep on the wheels. Everyone uses Intel who has managed to fuck up its lineup for many years now, Microsoft has thoroughly pissed off the privacy-conscious folks with Win10 and (judging by a random walk through a Mediamarkt) build quality in Windows laptops still hovers barely above "acceptable" - cheap plastics, tiny touchpads and abysmal screens are the norm, whereas Apple is only robust aluminium cases, giant touchpads and crystal clear, bright screens.
What I'm really excited for is when Apple decides to put an Mx chip into an iMac, paired with a decent AMD GPU. The thermals and energy profile should be allowing a lot more leeway for resource usage than a Macbook...
The type of person who buys an Apple Silicon Mac to run Linux is not going to buy an Apple Silicon Mac to run macOS. However...
> They won't sell more macs if macs can run Linux better.
They would sell some more Macs. Possibly hundreds of thousands more. A drop in the bucket for Apple, but still money—and all they have to do to get it is answer some questions.
I certainly understand the frustration for legitimate researchers, and there's plenty to be said about having the source code available to make auditing easier but in itself it seems that making a black hat take 6 months instead of 1 to create an exploit raise the skill/patience level needed and busy them for while where they are not working on the next exploit.
Because it makes it easier for attackers to find vulns. That's why they do it. The high payouts on these platforms are evidence that it isn't as simplistic as "only defenders would look at this why won't they release it!?"
Wordpress is a mess, but being OSS does not inherently make something less secure.
Do you have a source for this?
Also a good idea to DDG Phineas Phisher. You should turn up an interesting read on pastebin iirc.
Edit: found it on exploit-db
There are of corse Yacy and other more independent options, but they aren't ready for most people.
https://www.spiegel.de/international/world/catalog-reveals-n...
https://www.haaretz.com/middle-east-news/.premium-with-israe...
https://podcasts.apple.com/us/podcast/darknet-diaries/id1296...
I believe they described their toolbox as metasploit on steroids. Some other episodes of darknet diaries also interview former and current government hackers.
The average small business loan is more than that at $633,000 [1]. Hell, a single McDonalds restaurant [2] costs more than that to setup. In fact, it is not even out of the reach of vast numbers of individuals. Using the net worth percentiles in the US [3], $500,000 is only the 80th percentile of household net worth. That means in the US alone, which has 129 million households, there are literally 25.8 million households with the resources to bankroll such an effort (assuming they were willing to liquidate their net worth). You need to increase the cost by 1,000x to 10,000x before you get a point where it is out of reach for anybody except for large governments and you need to increase the cost by 100,000x to 1,000,000x before it actually becomes infeasible for any government to bankroll such attacks.
tl;dr It is way worse than you say. Every government can fund such an effort. Every Fortune 500 company can fund such an effort. Every multinational can fund such an effort. Probably ~50% of small businesses can fund such an effort. ~20% of people in the US can fund such an effort. The costs of these attacks aren't rookie numbers, they are baby numbers.
[1] https://www.fundera.com/business-loans/guides/average-small-...
[2] https://www.mcdonalds.com/us/en-us/about-us/franchising/new-...
[3] https://dqydj.com/average-median-top-net-worth-percentiles/
There are also paranoid people in positions of power, and bureaucracies that can justify spying on employees. One of the interesting things about this lockdown was finding out that many companies put spyware on their employee-issued computers to monitor their usage.
Note that memory safe languages won't solve security. They only eliminate a class of security bugs, which would be amazing progress, but not all of them.
(yes I know I'm talking about macOS but the vulnerability was found in iOS, but there's a lot of shared code between them, especially on levels this low)
Yes, same old buffer C/C++ overflow problem. We have mainstream alternatives now. C#. Go. Rust. It's time to move on.
Thankfully, Apple is starting to hire Rust developers as well as AWS.
The tide is changing, one day we will see some Rust code in iOS/macOS so that these issues are a thing of the past.
It seems much more likely that they will use Swift in some form.
There is reason to believe they will adapt it.
That being said, ARC is probably easier to get to work well in-kernel vs. tracing garbage collection. There's a performance cost to all of those reference count updates, but at least the variance is extremely low.
> Swift is a successor to both the C and Objective-C languages.
https://developer.apple.com/swift
> Swift is intended as a replacement for C-based languages (C, C++, and Objective-C).
There are people that believe systems programming languages in an OS kernel is doable with some form of GC, and then there those that will never change their mind.
https://www.f-secure.com/en/consulting/foundry/usb-armory
https://blog.arduino.cc/2019/08/23/tinygo-on-arduino/
https://github.com/mit-pdos/biscuit
https://github.com/ycoroneos/G.E.R.T
By the way, NeXTSTEP drivers were written in Objective-C, and the new userspace framework, DriverKit, is an homage to the NeXTSTEP driver API.
https://www.nextop.de/NeXTstep_3.3_Developer_Documentation/O...
That being said, ARC may faire much better than a tracing GC, particularly in latency variance, throughput variance, and mean heap usage.
Though, I think we're best off moving off of hypervisors and onto 4th generation microkernels with isolation similar to AIX LPARs / Solaris Containers. After all, a hypervisor is essentially a microkernel that's forced to use hardware traps/faults plus hardware emulation for its syscall interface (plus upcalls for performance, which use a calling convention much closer to traditional syscalls). There are stability, security, and performance advantages to throwing out all of that hardware emulation code, moving everything to upcalls, and getting rid of the second (guest OS) kernel running between the application and the hardware. If you push most of the system functionality out of kernel space, then rewriting some of the less performance-critical components in a language with ARC or tracing GC starts to make more sense.
Biscuit was a research project whose goal was to get the thesis done, when the thesis was done, no more effort was spent.
Bing was powered by Midori for the Asian countries for part of its life, and Joe Duffy has stated in the RustConf keynote that Windows Dev team was a reason why Midori faced so much internal resistance, even when they were proven wrong.
Before Google was willing to put the money into JavaScript many would assert that JavaScript would be worthless to anything besides form validation and DHTML.
Mainframes to this day still make use of their own systems programming languages, way safer than C, and you don't see people crying that their kernels are too slow.
In fact, Unisys uses this fact to sell ClearPath MCP to customers that value security above anything else, Fort Knox style.
Burroughs MCP was written in essentially an extended Algol 60 dialect. Algol 60 only had very limited heap allocation for dynamic arrays, no GC, and I haven't read any indications that Burroughs added GC to their extended dialects.
Multics was written in a PL/I dialect, without tracing GC. Likewise, IBM OS/360 and descendants are written in the PL/S dialect of PL/I, and I haven't seen any indication it has tracing GC.
With tracing GC, you have a trade-off between the peak amount of unclaimed garbage and the GC overhead. ARC should have lower variance in both latency and heap usage, which I presume is the reason Apple moved the whole Objective-C and Swift ecosystem to ARC and deprecated the Objective-C tracing GC.
I used to be a True Believer(tm) in the JVM and other managed runtimes. I was one of 5 developers of the most popular Java desktop application in the mid 2000s. Then I moved to Google and started developing web search infrastructure. I was at Google when V8 was created, and I put a lot of effort into running all of the JavaScript that the indexing system found, across the entire visible web. For things at massive scale, spending millions of dollars per year just in electricity bills, it's extremely tough to beat highly tuned C++. Yes, it's a lot of effort. Yes, I hope safer languages like Rust replace C++ and static analysis tools continue to improve.
I still kind of want to be a managed runtime true believer again, but it's tough to go back after believing for so many years that managed runtimes were going to match expertly hand-optimized C++ in latency- and throughput-critical applications "any day now".
Fortunately there are enough true believers to keep them in business.
By the way, apparently it is time for Google to improve their gRPC C++ implementation.
https://devblogs.microsoft.com/aspnet/grpc-performance-impro...
As for the mainframe languages, yes they don't have a GC, but they have the right defaults regarding bounds checking, implicit conversions, explicit unsafe code.
Regarding managed runtimes, versus C++, languages like C#, D, Modula-3, Swift have the features to write C++ like code when needed, the main problem is that many don't bother to learn the language features available to them.
At Microsoft stories about hard core C++ devs having to be proven wrong with C# running in front of them is relatively known, Joe Duffy has shared a couple of such stories.
His experience in Singularity and Midori is also what made him bet on Go for Pulumi.
There's so much low-hanging fruit to pick in that code and switching to Rust is like saying that we should go to Mars to pick fruit instead.
To me it's that this extremely trivial bug (the heap overflow, let's ignore the rest for now) passed through code review, security review, security audits, fuzzing... Or that Apple didn't have these in place at all. Not sure which option is worse.
Safe languages are the only way forward to drastically reduce the problem. It can’t be guaranteed to be eliminated 100% obviously because there are still escape hatches available, but it will be significantly improved because you can limit the surface area where such bugs can live.
If it's taken someone a whole fortnight to write it, you should expect to spend at least half a day reviewing it, IMO.
To me, this strongly suggests that the problem is in fact memory-unsafe languages, and not general engineering practices.
Apple, by the way, has all the things you're talking about in place, and in spades.
You can improve the tools, or you can improve the human, and nobody has managed to improve the human despite decades of trying.
In practice, the best case and average case rarely line up.
Languages don't introduce bugs by themselves. Engineers produced those bugs.
I always thought that bugs are the programmers' fault, and not to blame the language. It's like blaming the English language because it allows you to misuse it and manufacture very offensive racial slurs, or to be rude and cruel, and thus we should replace it with another language that doesn't allow to exploit these weaknesses. We won't be able to express ourselves with beautifully (low-level) crafted poems anymore, but that's the price to pay.
In Hungarian we don't have this problem at all, there's no concept of gender specific pronouns.
The basic trick for backwards compatibility is that all arrays have sizes, but you get to specify the expression which represents the size and associate it with the array. So you don't need array descriptors and can keep many existing representations.
Also, if you have slices, you rarely need pointer arithmetic. Slices are pointer arithmetic with sane semantics.
I'm tired of seeing decade after decade of C/C++ buffer overflows. It speaks badly of software engineering as a profession.
[1] http://www.animats.com/papers/languages/safearraysforc43.pdf
> Gets added to Visual C/C++, LLVM, and Gnu C as an extention.
And had to do a double-take because I thought you were talking about gets(3)…
But yeah, it only works if you use those types.
There are other divisions pushing for .NET and Rust systems code in Windows, but the political wars between WinDev and DevTools are quite well known, e.g. Longhorn (in .NET) vs WinRT (same thing just in COM).
So much that many of the System C# features are now in .NET 5 and other ones will eventually land on .NET 6.
Also on another front Apple seems to have already enabled device drivers in user space: https://developer.apple.com/system-extensions/
But you definitely cannot build a performant and robust kernel from scrtach with these languages.
I think this is irrelevant (and less importantly, false). Its's fine to use eg se4l as a foundation, or as a incremental step even just have a safety focused driver runtime inside the kernel proper.
https://www.wildernesslabs.co/
https://en.m.wikipedia.org/wiki/Singularity_(operating_syste...
I agree rust is probably better suited. Or Apple could make their own memory safe language. They’re clearly capable.
I just wonder, for example, how a capable hardware abstraction layer would work in C#, interrupt handling, CPU and IO scheduling, etc.
Go: GC again, so no go.
Rust: most sane of the examples you've given.
Apple has already started migrating to Swift which is a memory safe language.
However the real reasons Rust and Go aren't feasible is that they're both essentially all-or-nothing, and neither offers even the most basic semblance of ABI compatibility. Their only nod to ABI stability is "use FFI to C" which means your APIs remain unsafe, and doesn't work for non-C languages without all your system APIs having other languages layered on top.
Swift at least lets you replace individual objc classes one at a time, and is ABI stable, but has no C++ interaction.
XNU also has ABI stability requirements which rules out rust.
If they haven't kept up with the changes in their current language, what makes one think that they would "move on" to the alternatives, two of which aren't even alternatives?
Before they switch to Rust it would be much faster and more efficient to use smart pointers, std::array, std::vector and stop using memcpy.
Naturally when one writes C in C++ it doesn't help.
I'm reminded of ye olde Gumstix BlueSniper rifle. Back in the early 2000's there were a series of exploits against bluetooth stacks. The standard response by the industry was that they attacks weren't practically exploitable due to the low power of typical bluetooth devices.
The BlueSniper was a cantenna + gumstix SBC specifically constructed for the purpose of demonstrating the low cost of the threat.
Apple sits on this giant stack of unused money [1]. Why don’t they get the best security researchers in the world, pay each of them north of $1M / year in salary and create the ultimate red team where their only task is to try to hack Apple devices.
If they get a team of 1000(!) people, each with $1M(!) in salary that would be less than 0.5%(!) of their revenue in 2019 [2].
Wouldn’t that be worth it?
[1] https://fortune.com/2018/01/18/apple-overseas-cash-repatriat...
[2] https://www.statista.com/statistics/265125/total-net-sales-o...
What an Apple P0 buys Apple might just be a bunch of favorable nerd press cycles. But that's not a problem Apple really has.
I am, however, convinced that with the right resource commitment, you could scale up a world-class research capability --- to potentially arbitrary levels --- without headhunting existing researchers, which is where I see the bottleneck right now.
Or, I mean, Apple could just rewrite their OS infrastructure in a memory-safe language. If I had the two options, I would put all my chips on the language change.
(I think P0 is extremely cool and valuable to Google in a bunch of ways and would be thrilled to see more major vendors try to replicate it, even I doubt they'll be successful).
And they are also moving all kernel extensions to user space anyway.
The reason why Apple in 20 years turned from being 90 days away from bankruptcy to a revolutionary machine and most valuable 2+ trillion dollar company in the world is not because of HW ops or anything else, it's because of people.
While we know Steve Jobs had "issues with people", he also clearly stated:
> My model for business is The Beatles. They were four guys who kept each other kind of negative tendencies in check. They balanced each other and the total was greater than the sum of the parts. That's how I see business: great things in business are never done by one person, they're done by a team of people.
It takes a lot of people effort, talent and operations to achieve what Apple has achieved. So I think saying Apple is mediocre at people ops is unfair.
There's also the highly secretive internal Apple University for employees - https://www.nytimes.com/2014/08/11/technology/-inside-apples...
I am just surprised because there are so many problems in tech where throwing money at it is not going to improve things.
However in this case, shouldn’t they be able to attract the best in the world just by turning the money gauge up?
If you are one of the most highly specialised vulnerability researchers in the world, would you seriously reject a $10m / year offer from Apple where you’d be able to spend all your time doing what you love with the only condition being that you report findings to Apple?
My theory is: people that are quite tech savvy (like the HN crowd) would look at such an effort quite favourably and these folks are often micro-influencers when it comes to buying decisions of their direct peers.
Just an anecdote, but my entire family uses Apple devices, because I am the go-to computer guy in that circle and I advised them to buy Apple. The company that I co-founded used Apple hardware and so on.
Maybe that is just wishful thinking and it is hard to quantify, but I’d like to believe that increasing your reputation with developers (who in itself are a niche) helps you grow revenue in the long-term nevertheless.
Google is the one paying all those researchers at Project Zero, Apple doesn't seem to have that kind of security group, and yet you still buy/recommend Apple instead of Android.
I am sure it can move some people, but the reality is that this kind of effort is so down the list of priorities when buying for most people that it is certainly not worth $1B per year.
Do you have any reason to think that Apple could stiff people that submit vulnerabilities to them?
My understanding of game theory says that Apple’s incentives are to try to act with integrity and to pay their bounties. There may be corner cases where confusion reigns, and where Apple mistake someone for a fraud, but I would presume they need to be very rare – otherwise Apple’s reputation as a buyer would suffer and people would sell to other buyers who cared for their reputation better (and every vulnerability sold to a third party has a high expected cost to Apple. Edit: on second thoughts maybe the cost to Apple is fairly low - certainly the maximum bounty size says that).
Edit: I agree that Apple stating a maximum payout is hardly helpful. I presume third party buyers indicate a minimum value they will pay depending on the value of the vulnerability to them. There is a market here, and it isn’t clear that Apple is willing to pay market prices, perhaps because too many people/teams give their vulnerabilities to Apple for $0 (e.g. projectzero!)
In what other industries is that the case?
It would be far more beneficial for them to just use the tried-and-true techniques that have already been deployed for decades in high-reliability/high-security systems. In the event that such things are too onerous, they could run development methodology tests to remove the elements that provide the least security ROI to produce lesser, but still good, systems at a reduced cost. This would be far more likely to produce a good outcome than taking the standard high development velocity commercial methodology that has failed to produce meaningful security despite decades of attempts and enhancing it to be a high security process. At least in the former you can be reasonably confident you get good security, though possibly at a higher cost than desired. In the latter, although the cost may be less, the security is a complete unknown since you are using a new process invented by people who have never used, let alone made, a high security process before and it is a class of strategy that has literally never succeeded over multiple decades of attempts. Not to say it could not happen, it took hundreds or possibly even thousands of years of failed attempts before heaver-than-air flight was cracked, but they would probably be better served just using the existing techniques that are known to solve the problem.
This finding is not about this single bug, it's just that someone bothered to scrape the surface.
(Note that 99% of the effort went into crafting the demo exploit once the vulnerability was found, which is basically wasted effort in the context of eliminating vulnerabilities - the vulnerability finding was easy)
Apparently Apple failed in their hiring process to get those mythical developers that never write such kind of errors in production C or C++ code. /s
Wow, so Apple was ahead of Amazon's Sidewalk with AWDL. Can you disable this?
> All iOS devices are constantly receiving and processing BLE advertisement frames like this. In the case of these AirDrop advertisements, when the device is in the default "Contacts Only" mode, sharingd (which parses BLE advertisements) checks whether this unsalted, truncated hash matches the truncated hashes of any emails or phone numbers in the device's address book.
Then follows the section on brute-forcing 2 bytes (only) of a SHA256 hash.
Spray noise on channels 6 and 44?
If you turn AirDrop/Bluetooth off, you may well disable this.
On my phone:
- If you disable Bluetooth in the notification tray, then it goes to Bluetooth "Not Connected", but not Off. - If you disable Bluetooth in settings, AirDrop automatically goes into "Receiving Off". - If you then enable AirDrop, it'll automatically turn Bluetooth on.
So I don't think it's true that you can't disable it - unless the UI is misleading about Off.
Not exactly. The wording in the article implies that AWDL forms some kind of multi-hop network topology, but it doesn’t - it just enables nearby devices to communicate with each other directly at Wi-Fi speeds without the burden of pairing (like Wi-Fi Direct) or being associated with the same Wi-Fi network.
This is used not just in AirDrop but also in the Multipeer Connectivity Framework, AirPlay 2 and the Continuity framework. The standard discovery mechanism for these services is mDNS over AWDL, so for a device to browse for or advertise these services, it needs to be aware of other nearby AWDL neighbours first. (For example, you can browse for and discover other nearby AirDrop devices even if you don’t allow incoming AirDrop enabled yourself.)
It’s also worth noting that Apple devices very strictly do not send or receive AWDL traffic when they are locked/asleep, and will often even stop listening on the AWDL social channels when there are no services being advertised or in use.
And then just, well, practice. A lot of practice. Mostly driven by curiosity about how things work - bugs will then just start to pop up and you are free to investigate whatever piques your interest. The more likely you are to just open up a debugger when a piece of software annoys you and try to binary patch it, the closer you are to being a security researcher :).
There's not much books/courses on this, low-level hacking is something that you kind of just learn as you go. But, for instance, if you never touched gdb/lldb, or never looked at assembly code, or never wrote C - you should investigate that first as base skills.
Checkout https://ctftime.org/ for a list of ctfs. There are also intro ctfs like https://picoctf.org/
Do play CTFs. Just pick the fun challenges. pwnable.kr used to have some good stuff if you want to level up.
You can also do the challenges using IDA/Ghidra instead of looking at the source for a proper challenge and I recommend doing this initially for each challenge.
Think about it, an ocean of electrons in the copper WiFi antenna bump along with a certain guiding EM wave and in so doing, they inadvertently cause the information moving electrons in the silicon crystal to disconnect from the electrons being pushed out of the Li-ion battery.
This amplitude fluctuation in principal could have been broadcast by motions of stars in the universe, as astronomy does peer into the deep with these frequencies [0].
In the future, one could imagine a bad actor with control over a global network of low orbit satellites spewing out this code for decades preventing the such devices from being turned on long enough to receive updates, deactivating billions of dollars of human capital.
[0]: http://www.astrosurf.com/luxorion/radioastro-frequencieslist...
[1] https://github.com/apple/llvm-project/blob/73ea7cb9eba3196ae...
> Vulnerability discovery remains a fairly linear function of time invested. Defeating mitigations remains a matter of building a sufficiently powerful weird machine. Concretely, Pointer Authentication Codes (PAC) meant I could no longer take the popular direct shortcut to a very powerful weird machine via trivial program counter control and ROP or JOP. Instead I built a remote arbitrary memory read and write primitive which in practise is just as powerful and something which the current implementation of PAC, which focuses almost exclusively on restricting control-flow, wasn't designed to mitigate.
Signed pointers are just a mitigation. With enough time to find other primitives/constructs (from less severe but more common bugs) you will work around them.
I wonder if the daily HN article about Apple failing to be secure is a result of 1 OS, 1 phone. Where as no one is going to put the effort to find an exploit on a phone with 1% market share.
Similar question for desktops.
The main difference between the two I have seen is ios users get an update that fixes the issue often after their device has stopped getting feature updates while many android users are on kernels that haven't received an update in the last few years.
It was fantastic; I got a whole year of not being able to see work emails after I went home, and then they let us opt out of the invasive MDM software that they wanted to put on Android phones to let them access corporate email. All for a bug that my phone wasn't even vulnerable to.
By the time I left, I had gone 4 years without ever responding to unexpected evening emails. And now that I know it's possible, I'm never going back! :)
Although none of those are recent like daily security flaws we see on HN.
And a second: https://googleprojectzero.blogspot.com/2020/09/attacking-qua...
Holy shit.