Ch21.1: The App Sandbox Problem

中文(简体)

1. The Promise and the Trap

"Write once, run everywhere" is the oldest promise in cross-platform development. UWP promised it for Windows Phone, Surface RT, HoloLens and Xbox. HarmonyOS's "all-scenario" story promises the same for phones, tablets, watches, TVs and cars. Both are universal only inside one vendor's ecosystem. UWP is dead, WinUI3 is half-dead, and the reason is not technical: no developer can afford to write only for one ecosystem, and no user owns only one ecosystem.

The app sandbox is how the platform turns that ecosystem into a chokepoint. It is sold as security, and it does provide isolation, but it also decides what can run, what can access storage, what can be installed, and what can be updated. When the sandbox is designed around the vendor's language and the vendor's store, "cross-platform" becomes "write the app again for every vendor".

2. Five Costs of the App Sandbox

The argument is not that sandboxes are useless. It is that they are not free, and the bill is paid in portability. The concrete costs:

  1. No sharing. A sandbox breaks the shared-library model. In the Snap package, Firefox startup can take around twenty seconds because the runtime and its dependencies are no longer shared the way a system package shares them. Each app carries more of its own runtime, binaries grow, and cross-app access to common resources becomes an integration project.
  2. Driver and hardware access. Flatpak-style sandboxes regularly hit driver problems. A sandbox that cannot see the device cannot use it, and the missing functionality is not a bug the app can fix from inside.
  3. The security illusion. The sandbox isolates user space, not the kernel. If the kernel is compromised, the sandbox is a fence around a room whose floor is gone. Isolation is still worth having; it is not the absolute guarantee the marketing implies.
  4. Development cost. Existing apps must be rewritten, and so must their dependencies. The interesting part is why: mainstream languages were not designed for this environment. fopen and fstream open a file — where? Third-party libraries assume a current directory, a console, environment variables and a process that starts at main. In a sandbox, nobody knows how the app was launched or which paths it is allowed to touch.
  5. Vendor monopoly. Mobile is an Android/iOS duopoly. Windows Phone and UWP are the counterexample: a third ecosystem failed even with a major vendor behind it. Even on Android, tools such as gcc and clang are structurally incompatible with the sandbox, because a compiler is a process that reads and writes arbitrary files and launches other processes.

3. C++ Is the Portable Core

It is tempting to explain C++'s popularity with performance. Performance is part of it, but the more important reason is portability. The standard architecture of a serious cross-platform app is a portable core plus a platform-specific UI:

Spotify, QQ and WeChat are the obvious examples: their core engines are C++, with platform-specific shells around them. The core is the asset that took years to build; the UI is the part that is expected to be replaced.

Spotify is a specific and useful case. It uses assembly in the DRM and streaming path so that playback can begin immediately. That "instant streaming" is a competitive advantage, not a nice-to-have, and it is exactly the kind of code that cannot be reimplemented in a managed language for one phone platform. When Windows Phone 7 restricted third-party apps to managed code and did not allow native C++, Spotify's WP7 app ran native under a Microsoft exception, and Spotify complained directly to Microsoft. The argument was blunt: we are not going to rewrite Spotify's core engine just to support your phones. That pressure is part of why Windows Phone 8 reversed the policy and added full C and C++ support.

The same reasoning makes Android's "don't use the NDK" advice wrong for cross-platform products. That advice is written for a single-platform app: use the platform language unless you have a measured performance reason. But for a product that already has a portable core, the native core is the rule and the platform UI is the exception. Moving the core into Kotlin or Swift is not a simplification; it is a second implementation, with a second set of bugs, that has to be kept in sync forever.

This is why the app sandbox is a portability tax. It attacks the one layer that was portable. A sandbox that forces the core into the platform language, or behind platform-specific storage and process APIs, takes the asset and makes it platform-specific again.

4. The Category the Standard Does Not Have

Chapter 20 gave the standard's two categories: a freestanding implementation may execute without an operating system; a hosted implementation supports all the facilities described in the document. There is no third category. In particular, the standard never defines a restricted environment.

Android is the test case. It has an operating system, a scheduler, a filesystem and a network stack, so it is hosted by the definition. Yet most of the hosted facilities that touch the outside world do not behave the way a desktop program expects. The functions exist; the authority does not.

That distinction matters because "hosted" is about API availability, not universal reach. A sandboxed process can call fopen. Whether the call succeeds is a permission decision, not a conformance issue. The standard says the function exists; it does not say the program can open any particular path.

Concretely:

And this is not a C++ problem. No mainstream language's standard I/O library is built around capabilities. Java's File and Path, C#'s File and Directory, Python's open and pathlib, Ruby's File, Go's os.Open, Rust's std::fs and Swift's FileManager all assume a path, a current directory and ambient authority. The runtime sandboxes that did exist were removed: Java's SecurityManager is deprecated and permanently disabled, .NET Code Access Security is gone, Ruby's $SAFE was removed in Ruby 3.0, and Python's rexec and Bastion are long gone. Sandboxing moved to the operating system; the I/O API never moved with it.

5. The Walled Garden and the Duopoly

Definition. A walled-garden operating system is one that forbids running binaries directly. Everything is an app; apps are installed from a store; each app runs in a sandbox with a permission list. The vendor decides what can run, what can be installed, and what can access the device.

Walled gardens: Android, iOS, iPadOS, ChromeOS, Windows 11 S mode and the UWP platform.

Not walled gardens: GNU/Linux, Windows, macOS, FreeBSD, SerenityOS.

Once it is defined that way, the problems are structural rather than incidental:

UWP is the failure that proves the point. Microsoft wanted Apple's tax model and tried to force a walled garden through Windows Phone and Windows RT. UWP's permission model was coarse, and its managed-first design made C++ a second-class citizen; Windows Phone 7 did not allow native C++ at all. Most apps had a C/C++/assembly cross-platform logic layer with a thin platform API on top (JNI on Android, for example). UWP forced managed code and restricted the filesystem so aggressively that there was no file manager, and many apps could not be ported at all. Windows Phone users could not change the browser, so there was no Chromium, so YouTube could not even ship a PWA. Microsoft abandoned UWP and returned to PWA and Win32. The joke is exact: a $1,000 premium Lumia ran Windows and could not run a Windows .exe at all, because the walled garden had no Win32 subsystem. A $39.99 Android phone bought at Walmart for an elderly relative can install clang, point it at Microsoft's own Windows sysroot headers and libraries, build a PE, and run it natively under Wine. The expensive phone was Windows and could not run Windows programs; the cheap phone is not Windows and can. Microsoft wanted the app-store monopoly more than it wanted Windows Phone to be Windows. The Windows kernel could not run a Windows .exe; Android could. Of course Windows Phone failed. What a joke.

The duopoly is the same structure at market scale. Android and iOS control the store, the payment rail, the review process and the APIs, and often the browser engine. Apple's WebKit requirement is the clearest example: every browser on iOS had to use WebKit, which limits what the web can do on the platform that sells itself as the most privacy-conscious. The EU's Digital Markets Act and Japan's rules have forced openings, but the structure is still the structure.

There is also a less comfortable point. A vendor that complains about the store tax while refusing to ship a PWA is part of the problem. The article's example is WeChat: it complains about Apple's cut, but it does not offer a PWA, and its mobile web experience is deliberately worse than the app. Baidu Tieba is the performance version of the same argument: the Java/Kotlin app is slower than its own mobile web page, while the web page is crippled to push the APK. If a vendor will not do PWA, it has no standing to complain about the tax.

The sandbox is not neutral security infrastructure. It is the boundary where the platform decides which code is allowed to exist. A cross-platform framework that runs only inside one vendor's sandbox is not cross-platform. It is a first-party framework with a universal-looking name.

6. The Right to Repair Is the Same Fight

The app sandbox is the software half of a larger argument about ownership. The hardware half is the right to repair. Samuel Greengard's CACM article "Fighting for the Right to Repair" (5 September 2025) makes the connection explicit: embedded software now runs phones, appliances, cars, medical devices and military equipment, and that software makes it easy for manufacturers and rights holders to block repairs and control the aftermarket.

"In almost every instance, embedded software makes it easier to block repairs and control the aftermarket. This includes locking devices and controlling who can fix them, charging higher prices for replacement parts and labor, and threatening to void warranties if someone opens a device or tampers with a system."
— Samuel Greengard, Fighting for the Right to Repair, CACM, 5 September 2025

The mechanisms are not subtle:

That is the same move as the app sandbox, one layer down. The sandbox says the vendor decides which code may run; the repair lock says the vendor decides who may fix the machine and which parts may be installed. Both turn a purchase into a license. John Deere's position in the American tractor fight was the purest version: farmers do not own the tractor, they have a "license to operate" it. Apple's parts pairing is the phone version: a replacement screen or battery can be rejected or flagged as an "unidentified part" because its serial number was not blessed by the vendor.

The right-to-repair movement asks for the obvious remedy: owners and independent repair shops should get the same parts, tools, documentation, diagnostics and software access as authorized service providers, on fair terms. Manufacturers answer with safety, security and intellectual property. Some of those concerns are real; none of them requires a monopoly on repair. A device that can only be serviced by its maker is not a product with a warranty, it is a subscription with a piece of hardware attached.

The legal fight is real and unfinished. New York's Digital Fair Repair Act, Minnesota's and California's laws, Oregon's ban on parts pairing and the EU's ecodesign rules are progress, but manufacturers lobby, litigate and redesign around them. Digital locks and DRM make circumvention illegal under laws such as DMCA §1201 even when the purpose is repair, and end-user license agreements claim the software is licensed rather than sold. The result is that the owner has the bill but not the control.

The cost is not abstract: e-waste

The environmental case is the same argument with bodies attached. The CBS report below cites the UN estimate that about 50 million tons of electronic waste are produced every year, most of which is not formally recycled. A large share is shipped to the global South, where workers burn cables, acid-wash circuit boards and pick through debris for copper, gold and rare earths. The tragic costs of e-waste (CBS Sunday Morning, 26 November 2023) follows that trade.

China is the case that made the trade visible. Guiyu in Guangdong and Taizhou in Zhejiang became enormous informal recycling towns. The work was done in backyards and on riverbanks: open burning of insulation, acid baths for gold, manual dismantling of CRTs. Researchers reported lead poisoning in children and dioxin contamination; a 2013 study estimated that residents faced a significantly higher cancer risk from inhalation, and birth-outcome studies found more stillbirths and low birth weights. Entire communities paid for the cheap electronics of the rich world with their health.

China eventually banned the import of foreign e-waste, first with the 2017 "National Sword" policy and then with a full ban on solid-waste imports by 2021. The trade did not disappear. It moved: to Malaysia, Thailand, Vietnam and Indonesia, and to West Africa, especially Agbogbloshie in Accra, Ghana. The same burning and acid leaching followed the waste. Studies of mothers living near e-waste sites in Ghana have found PCBs and flame retardants in breast milk, and dioxins at extreme levels in eggs laid nearby. The contamination is not a local nuisance; it enters the food chain and the next generation.

This is why repair is an environmental policy, not only a property right. A device that can be repaired stays in use; a device that is glued shut, serial-locked and abandoned by its software becomes waste. The app sandbox contributes to that: when the store drops an app, the OS stops updating, or the vendor refuses to activate a replacement part, a working machine is turned into e-waste. The cheapest way to reduce e-waste is to stop designing it.

This is why the PWA argument is not just about convenience. A repairable device is one you can open, understand and fix; an open web app is one you can inspect, host, modify and install without a gatekeeper. The walled garden is the same claim at both layers: the vendor owns the machine after you buy it, and the vendor owns the software after you install it. If you cannot repair the device, you do not own it. If you cannot run the software you choose, you do not own it either.

Support the groups that fight this

Three organizations are doing the technical and political work that this chapter depends on. Support them, and use their material when you talk to regulators:

Go further: buy devices you can unlock

Advocacy changes the law; buying changes the market. The most effective vote you cast is the device you buy next. Prefer hardware that lets you unlock the bootloader, install another operating system, and keep the device alive after the vendor stops shipping updates. A phone that can run postmarketOS or GrapheneOS in 2030 is a phone that did not become e-waste in 2027.

A practical checklist:

Good starting points are devices from Fairphone, Purism (Librem 5), Pine64 (PinePhone), and a carrier-unlocked Pixel running GrapheneOS. A used ThinkPad with coreboot is a better long-term purchase than a sealed laptop with a firmware password. These are examples, not endorsements; the checklist matters more than the brand.

This is where the license matters. GPLv2 required TiVo to publish the source of the Linux kernel it used, but it did not require TiVo to let anyone run a modified kernel on the box. The signature check in the bootloader made the source useless for modification. GPLv3 fixed that with the anti-tivoization clause: for a "User Product", the distributor must provide "Installation Information" — the methods, procedures, authorization keys and other information needed to install and execute modified versions. That is exactly the legal machinery behind bootloader unlocking and long-lived devices.

The clause is not a universal unlock law. It applies to GPLv3-covered code in consumer products, not to a proprietary bootloader, and the Linux kernel is still GPLv2-only. That is why the practical rule is both legal and technical: prefer boot firmware that is free software and comes with an installation path, and prefer hardware whose bootloader can actually be unlocked. A GPLv3 notice on a device whose bootloader is permanently locked is a press release, not a repair path.

These fights are the same fight at different layers. OWA fights the browser and app-store gatekeeper; Keep Android Open fights the operating-system gatekeeper; Rossmann and the Repair Preservation Group fight the repair and parts gatekeeper. All three are the right to repair applied to software and hardware: the owner decides what runs, who may fix it, and how long it lives. A PWA is the practical way to exercise that right without asking permission.

7. The Pivot

If the goal is genuinely to run the same app on phones, tablets, desktops, TVs, cars and headsets, there is already a platform that is on all of them and does not require a vendor's permission: the web. A Progressive Web App is a website with a manifest and a service worker. It is installable, it works offline, it runs in its own window, and it is distributed by URL instead of by store review.

The useful way to say it is: a PWA is UWP minus the W. It keeps the universal app model and removes the requirement that the universe be one vendor's.

The usual objections are weaker than they sound. "The web is slow" — WebAssembly is fast, and Android's Java/Kotlin is not native either. "Safari and Firefox are bad" — that is an argument for better browsers, not against the web. "Outlook and Teams are bad PWAs" — those are WebView wrappers, not real PWAs. "The web cannot do X" — Project Fugu exists precisely to close the gap, and the gap is shrinking.

The rest of this chapter is the constructive part. 21.2 builds the shell. 21.3 puts the C++ core into it with WebAssembly. 21.4 publishes it without a gatekeeper.

The background argument is developed at length in three articles: why UWP and vendor "all-scenario" schemes are a false proposition, what a walled garden is, and why the app sandbox is inferior to a Progressive Web App. The CACM article in section 6 is the journalistic counterpart.