10 ms·
Why I’m not enabling Bitcode
- mikeash 11y agoThe security implications of new compiler optimizations potentially eliminating security-essential code really interest me. As do the plain old reliability implications of hitting new compiler bugs. It's going to be really really really Fun with a capital PH when Apple enables some new optimization that contains a subtle bug, and recompiles everybody's apps, and us third parties are left holding the bag trying to figure out why our apps are crashing with no visibility whatsoever into the process.
- ris 11y agoHow is this significantly different from shipping java/dalvik/whatever bytecode?
- notacoward 11y agoThe real issue is who gets to sign the code. Formerly, you could sign the code yourself, so the cryptographic "chain of custody" between you and your users would be preserved. Now, since Apple generates the code that users see, you can't check and sign it. Apple can sign it, somebody who has compromised Apple's infrastructure can sign it, but you can't (unless you're the one who compromised their infrastructure). So, basically, this is a giant MITM just waiting to be exploited.
- dmishe 11y agoThat's not new though, Apple is the one signing the apps on the store from its launch.
- notacoward 11y agoTrue, but what is now a mutable choice becomes less so when the technology involved doesn't support any other option. Their approach also precludes a second signature embedded and checked within the app itself, independent of the app-store signature.
- NateLawson 11y agoApple already re-signs all apps sent through the App Store. That plus Fairplay encryption makes it unnecessarily difficult for end recipients to verify the chain of custody for the code. I don't quite get why Xcode couldn't generate both the LLVM bitcode + the fat binary for all architectures, along with any flags. Then Apple could regenerate the same binary (to verify the two match) but use the bitcode for their program analysis tools. Then, the developer's signature could be left intact on the binary and Apple would add an additional signature over the whole thing that indicated it was approved for distribution via the App Store.
- eridius 11y agoBecause Apple explicitly wants to be able to regenerate binaries from the bitcode, which means that any locally-generated binary is meaningless. The claimed reason for this is to take advantage of new optimizations added to LLVM (which is a perfectly sensible thing to take advantage of), but probably the more useful reason is to take advantage of new microarchitectures that Apple introduces in new devices.
- NateLawson 11y agoYes, this is the real thing that should be debated -- where does the developer's responsibility end and the App Store's begin? If I created an app, both distributed internally (say, to my corporate users) and via the App Store, but the App Store version has a bug because they're using a different ARM backend than my Xcode, that will be a real pain to debug.
- vbezhenar 11y agoTranslating bitcode to binary must be done by open-source tool (llvm?) and bitcode must be available for end-user. Then end-user can download bitcode, download llvm, translate bitcode and compare it to the binary he got from AppStore. But it unlikely to happen, because this feature would be hard to sell.
- teacup50 11y agojava/dalvik/whatever bytecode is simple, has a clear formal specification, and is not vulnerable to the same scale of "undefined behavior" traps that you'll find in C/C++ and LLVM IR.
- mikeash 11y agoIt's not significantly different, although iOS hasn't had bytecode before. One thing that is different is that there's no transparency into the process. If your Java code is crashing, you can look at the code the JIT is generating. If your Java code is only crashing on certain hardware or OS revisions or whatever, you can see what's different about the JIT in those circumstances and at least make an attempt to investigate. With Apple's system, you have no idea what compiler version they're running, when they make changes, what machine code your users end up running, etc.
- notacoward 11y agoEven more fun when Apple recompiles the apps so that new users get one behavior but people who had already downloaded the supposedly-same app get quite another behavior. This takes all of the existing problems with non-reproducible builds and makes them worse.
- tedunangst 11y agoHere's something to ponder: security implications of new CPU micro architecture even running the exact same code. From generation to generation, various x86 instructions have varied in latency. Register renaming gets better. Incorrect hazards get eliminated. No reason to believe it can't happen to arm. There's no guarantee an ARMv99 will run even identical code at a rate directly proportional to an ARMv7.
- mikeash 11y agoYou're absolutely right, of course. Anything that depends on machine instructions taking a certain amount of time (that aren't guaranteed by the spec, e.g. I believe Intel's AES instructions are guaranteed not to have data-dependent timings) is potentially screwed on newer hardware. Bitcode does add potentially new and exciting failure modes, though, since you might start failing even in the absence of new hardware, and you might encounter problems other than timing (e.g. failing to zero out sensitive data because dead store elimination got smarter, or buggier).
- api 11y agoHe's right, but he's almost too right: absolutely everything he says is a problem with bitcode applies to normal app store distribution and all other centralized cloud-powered OSes and apps. Therefore I don't see this as a good argument against bitcode -- not using bitcode does not prevent anything he says from occurring since anything that can be done to bitcode can be done to machine code. (1) Apple has the signing master keys for app store certificates. It would be easy for them to binary-patch your app with anything they want, generate their own signing certificate in your name, and re-sign the app as they push it out to users. Since app store transactions are on a per-customer basis this could be done only for some customers -- such as only residents of a certain country, people whose names are on a list, etc. It's very unlikely that anyone would notice. (2) It would also be easy for an attacker to do this if they compromised Apple's core infrastructure as described in this article. Then they could generate signing certs in other developers' names and trojanize apps in exactly the same way. A "doomsday hack" that trojanized all Apple devices in the world within hours is not impossible. If they all started, say, DDOSing core BGP and DNS systems at the same time, such an attack could take down the entire Internet. (3) Apple, since they control the platform and can remotely patch it at any time, needn't bother with trojanizing apps. They could simply trojanize the OS kernel or user-space OS components and accomplish anything a trojanized app accomplishes. The same also applies, by the way, to Windows and also to Linux if you trust remote code repositories and do not compile everything yourself from verified known-safe source code. It also applies to from-source-compiled OSes and distributions if you did not painstakingly check every line of code yourself. Google the "underhanded C contest." If you run code that is not yours, you are trusting someone else. It's a subset of a larger principle: civilization implies trust. Without trust you cannot have specialization of labor, commerce, or law. Without those there could be no advanced technology or infrastructure, so none of this would matter. To use an Apple device is to trust Apple, at least insofar as that device and any data you keep on it goes. To use Ubuntu and its repositories implies the same level of trust in Canonical, etc. The privacy problems of the digital age are not entirely technical in nature and do not have entirely technical solutions. They can only really be solved legislatively and socially.
- SomeCallMeTim 11y ago>The same also applies, by the way, to Windows and also to Linux if you trust remote code repositories Curiously, Google/Android has developers sign the app, and that exact signed package is what's distributed, so at least the app developer can verify that the distributed app is identical to the one shipped to the store. On the other hand, Amazon/Android signs apps with their own keys, so they suffer from the same issue as Apple.
- nekitamo 11y agoThere are intellectual property concerns. You are now giving Apple your LLVM IR along with the program symbols. What happens if you have sensitive code in your application that you don't want Apple reverse engineering and having access to? LLVM bitcode also limits the kind of tamper resistance and obfuscation you can put into your apps. Fairplay offers almost no security if your attacker has a jailbroken device. He can simply dump the decrypted app from memory and reverse enegineer it. If you care about protecting your secrets, or preventing your app from being pirated and redistributed on Chinese app stores, you could at least apply fairly sophisticated obfuscation & integrity checks to the app binary. With LLVM bitcode that all becomes much harder, and applying integrity checks to the app becomes impossible. Also, Apple doesn't really need the LLVM bitcode of the app to carry out app thinning. All they really need to do is extract the proper architecture from a FAT binary, and send that to the user's device, instead of the entire FAT binary. It makes me wonder what will they even be using the LLVM bitcode for? Will it become a requirement for all apps submitted to the app store sometime in the future? If so, why?
- tptacek 11y agoThere is nothing that the LLVM ARM backend is going to emit that Apple, or most security consultancies, can't trivially reverse engineer.
- nekitamo 11y agoReverse engineering machine code is not trivial if it is obfuscated, has its symbols stripped, and has its ObjectiveC metadata obfuscated/encrypted. LLVM bitcode is much easier to reverse engineer than machine code, and you will be handing Apple all your symbols and metadata as well.
- dymk 11y agoSymbols are obfuscated or removed entirely if you choose to build without them; you don't have to hand Apple your .dSYM if you don't want. I'm not sure what other metadata you're referring to.
- tptacek 11y agoan adversary could find a vulnerability in the LLVM backend to obtain remote code execution on Apple’s Bitcode compilation infrastructure to inject a compiler trojan that would affect every single app on the App Store that was submitted with Bitcode I'm not clear on how Bitcode changes this, apart from expanding the already huge attack surface of the app store. Code execution inside app store servers is already game over for end-user privacy, isn't it? The bit about how Bitcode makes backdoor injection harder is also very hand-wavy, since backdoor injection into fully compiled binaries is a teenaged pastime going back to the late 1980s. About the most you can say here is that Bitcode makes a trivial task trivial-er. The concern about introducing side-channels into crypto apps seems legitimate (though: if you believe this is a real issue, and I do too, you're also saying "I will never trust Javascript cryptography"). I wouldn't want Signal submitting Bitcode.
- munin 11y ago> The concern about introducing side-channels into crypto apps seems legitimate If you're relying on compiler optimization levels to enforce stuff about crypto, you're gonna have a bad time. What happens when compiler behavior changes from minor revision to minor revision? Are you going to stare at the assembly code to make sure that something you did that was fair game for the optimizer to play with changed, or are you going to write your code so that it does the same thing no matter a (relatively correct) compiler and optimizer? If your code had UB in it, you're already hosed and it's a matter of when. Fix that. There are primitives like RtlSecureZeroMemory to deal with the intersection of cryptography/security and compiler optimizations. We've mapped this terrain.
- tptacek 11y agoYes: if you care about side channels, you are going to evaluate the assembly code your compiler generates.
- munin 11y agoThat works once. Are you going to do it every time you compile? I guess the side channel crew can be appeased in the llvm bitcode view of the world - write your side channel resistant stuff in inline assembler. The bitcode optimizer can't touch it then. (edit-apple probably keeps you from doing this though)
- nfg 11y agoSomething we're a little worried about (shipping middleware for games on iOS) is the potential difficulty of debugging client issues when we don't (I assume?) have native binary identical libs.
- devit 11y agoI don't think there any additional security issues regarding Apple altering the binaries. iOS devices are already running a closed source proprietary OS, which can easily set an hardware breakpoint in a binary and then do anything that could be done by modifying the binary itself without leaving traces anywhere (other than timing and cache effects). Apple even designs and manufactures the CPU so they could even modify the CPU to detect instruction patterns and siphon off private keys without any detectable timing or cache effects at all. Of course, that doesn't mean that it's all fine, but rather that the system is already completely broken to begin with in this respect.
- sneak 11y agoYeah, this is important. As much as I'd like to be upset about the lack of binary verifiability throughout the chain, as the article even points out, without jailbreaking it is already impossible. We have no idea what code Apple is telling our devices to run, regardless of the form in which it is submitted to the App Store. It's a bummer, but rms was right all along.
- azinman2 11y agoDoes anyone know more, or have a link to more info, about the problems with dSYM and bitcode?
- draw_down 11y agoObviously you're welcome to do what you like. But it seems how these things go with Apple is: they introduce it, and it's optional, then they build on it some (still optional), then they say "using this is a really good idea", then they say "a year from now you have to use this". And maybe not a year. So you're free to exercise your choice... for a while.
- rsl7 11y agoSometimes there is a secret master plan behind these actions, sometimes they're doing what makes the most sense. I can see how bitcode might make a lot of sense from a centralized distribution standpoint, and it may work for certain types of apps. But you still may prefer to test and experiment with the actual code that will be distributed to your customers. Seems like a reasonable requirement. Apple ought to have an extraordinarily good and transparent reason to require centralized compilation in the future.
- MichaelGG 11y agoNot only that, but when people's excuses for not shipping it are "Bitcode's gonna get the AppStore hacked and my apps backdoored"... they'll be more inclined to realise they know better than most of their app developers.
- coldtea 11y agoAny example of some other thing that went that way? And no, the transition to 64 bit or Swift are not that.
- draw_down 11y agoJava-Objc bridge, requiring Xcode (people used to use Metrowerks and other tools). I don't do this for my day job so there are probably lots of others... something around ARC maybe?
- coldtea 11y agoOK, I though you meant some kind of evil plan, lockdown etc impossed to people by Apple progressively. That's why I said we should exclude ARC and transition to Swift. I meant in general that we shouldn't count "migration to newer technologies/frameworks" as such a thing. If you meant, Apple imposing newer stuff to developers, then yes Apple does that. Though, I'd say most of that is for the platform's good. Even stuff like deprecating Java -- it never got popular for OS X apps as Apple intented, the situation with SUN had changed, and keeping it going forward would be dead weight. And Metrowerks might be good for early '00s, but not going forward with iOS, and multiple languages, and Storyboards, and all those things.
- teambob 11y agoAside from the security - Apple made much of write once run anywhere being a terrible idea (e.g. Java, Flash and iOS/Android frameworks) yet now it is a fabulous idea that Apple just thought of