5 ms·
> Running a native binary doesn't give it access to anything inherently While this is true from a certain perspective, machine code creates a system which must
by James_K 3y ago
> Running a native binary doesn't give it access to anything inherently
While this is true from a certain perspective, machine code creates a system which must grand access to many things to become usable. A shared file system is a good example of this. Some software could easily echo a line into you .profile that tries to launch a key-logger, and this works in many cases. The expectation of software existing as opaque files creates a huge amount of work for the OS in verifying the exact behaviour of the software as it runs (and in ways which can often be circumvented), rather than a source-based approach in which malware is never allowed to touch the processor.
> I'm typing this on a nice comfy GNU/Linux box where the only blobs are some firmware
So you suffer the worst of both worlds then. You've had to download and compile the source yourself, but as the software is designed around being distributed as blobs, so you enjoy none of the benefits that might come from source distribution.
- gggmaster 3y agoIt's better than an OS that you have no control from top to bottom. But sure, it isn't ideal.
- avianlyric 3y ago> The expectation of software existing as opaque files creates a huge amount of work for the OS in verifying the exact behaviour of the software as it runs That’s not really how the software/OS relationship works. By default OS’s run software in very unprivileged CPU security contexts, where they can’t really do anything beyond but operate on memory the OS allocated to the software, with CPU instructions can’t talk directly to other hardware, or read/write memory beyond the bounds the OS specified. To do literally anything else, like open a file, write to a file, talk to a network interface, talk directly to other hardware connected to the CPU. The software needs to use a syscall, and effectively ask the OS to perform the operation on its behalf. Every single dangerous operation you can perform is guarded by the OS, the OS doesn’t validate anything, it simply decides to perform the operations requested, or it decides not to perform those operations. The only reason why software expects so much unfettered access to a system is simply because OS have historical not limited what software was allowed to do, OS’s simply performed whatever operation was requested of them without question. It only in the last 20 years or so that security became a concern, and it occurred to us that allowing software to just do whatever it wants is probably a bad idea. But the genie is out of the bottle, and it’s proving hard to put it back in. So retroactive work to limit what software can do by default, without simply breaking everything, is slow and difficult. If you ever want to understand why you can do somethings on MacOS, but not iOS, then this is a pretty good place to start (if we ignore Apple’s brand and commercial reasons for a moment). iOS only ever supported tightly sandboxed apps, that had to play nice with a draconian permissions system, where as MacOS is more standard OS, that was originally developed in the age before security was really a concern. So it’s easy to enforce tight sandboxing on iOS, where software has always had to deal with it, but hard on MacOS, where for the majority of MacOS history, sandboxing simply didn’t exist. > rather than a source-based approach in which malware is never allowed to touch the processor. That’s a nice idea, but doesn’t really hold up to scrutiny. You need to look at the ever increasing number of supply chain attacks to realise that simply being open source does little to ensure malware doesn’t make it onto your machine. And that before we get into issues like heart bleed, where the OSS software on your machine may contain bugs or errors that allow remote parties to gain access to privileged data or credentials, via OSS software that isn’t malware, it just got bugs in it. At the end of the day, it doesn’t really matter what magical security boundaries you develop, someone will find a way around it. Which is why defence in depth is such an important principle. Simply relying on the idea that Open Source means no malware is foolish. You need proper OS defences regardless.
- James_K 3y agoI know all that. The process you describe is the OS verifying the behaviour of software as it runs. >That’s a nice idea, but doesn’t really hold up to scrutiny It does actually. The kind of attack you describe only works because software exists in non-source based systems. If you were going to run a Haskell function, and you were told that I was going to modify its body in some way, there is no way I can insert malware into it because you cannot reach out of the context of the function and mess with the operating system. Software is composed of functions, which naturally run in a fully containerised state and only become dangerous when the OS adds an additional layer of computer-wide state.
- avianlyric 3y ago> Software is composed of functions, which naturally run in a fully containerised state That’s simply not true. It’s a convenient fiction that modern programming languages provide, but they only provide it by virtue of not providing API to access external state, and even that isn’t true. Most programming languages do let you access state beyond a functions stack, in the simplest form by allowing your function to interact with data stored on a heap. There’s absolutely nothing about software that inherently results in “functions, which naturally run in a fully containerised state”. Functions are just a useful abstraction, in the same way an OS’s APIs are also just useful abstraction. There’s absolutely nothing that makes function scopes inherently more secure than OS APIs. Arguably function scopes are vastly less secure than OS APIs, there’s a good reason why stack overflows are one of the most common forms of Remote Code Execution exploits.
- James_K 3y ago> Functions are just a useful abstraction Yes. Containers are also just a useful abstraction. And both of them are contained, unless you add something that exposes their environment.
- avianlyric 3y agoThat is kind of my point. To claim that functions are somehow more secure than containers, or just standard process isolation (which is basically all container are), is just silly. Functions are no more inherently secure than containers. Both abstraction are contained, until something exposes the external environment to them, both of them can be configured to simply not do that.
- Veserv 3y agoMachine code does not require granting anything. The presence of a shared filesystem is a artifact of the OS, not any sort of inherent requirement. The actual effect of machine code being opaque is actually "beneficial" to security as only very coarse protection boundaries are even expressible. You must coarsely separate your code to get protection which comes at a potential cost of performance. The advantage of non-machine code is that you can express very fine protection boundaries which reduces the performance cost of protection, but at the cost of more complex analysis. Ensuring protection boundaries in the presence of coarsely separated code is strictly easier. You have strictly less ways to escape. Any coarsely separated code can be trivially transplanted onto a system enabling finer protection since they can just not use the finer protection. By the same logic, any protection boundary that can not protect coarsely separated code has no hope of enforcing protection on finer separations. That the kernel designers of Linux, Windows, iOS, etc. can not even ensure protection in general when the systems are coarsely separated means they certainly can not be trusted to ensure protection in general when things are more finely separated. If they could, fixing their existing coarse protection boundary would be a trivial consequence. About the only theoretical reason why this might not apply to eBPF is that it is not "general" in that many programs are not expressible, but that is not sound, positive evidence of suitability where as the historical track record of protection in all commercial operating systems is abysmal to say the least. Claims of finally achieving security (on a strictly harder variant of the problem) are extraordinary claims and extraordinary claims demand extraordinary evidence.
- James_K 3y ago> Machine code does not require granting anything It requires that you actually run software on your CPU before you can tell if it's malicious or not, by which point it is often too late to do anything about it. Almost all malware that exists does so thanks to this fact.
- Veserv 3y agoMachine code running in unprivileged mode with no shared memory and where syscalls auto-fail can do nothing malicious. Such a system is even more locked down than a Java program (when it does not also rely on hardware isolation) with no access to the filesystem class. To break the JVM protection boundary and access the filesystem only requires finding a JVM runtime breach or a vulnerable library to access the otherwise inaccessible filesystem class. To break the hardware isolation requires finding a hardware bug in the protection boundary which is vastly less common to the point where I am not even sure there has even been a hardware cross-privilege data integrity bug in over a decade. The examples you keep providing are not apples-to-apples as you keep comparing locked down source level programs against ensembles of machine code programs plus unrestricted access to a insecure operating system runtime. Every error you highlight in the machine-code system is actually a operating system/runtime problem, not a problem with machine code as a software delivery mechanism.
- deleted 3y ago[deleted]
- cookiengineer 3y agoWhat else do you suggest then? Is there even hardware available that implements a high-level VM programming language as an abstraction layer (instead of e.g. the x86 instruction set)?
- James_K 3y agoAn program sits on top of hardware and can act as a go-between. Think of the web browser, or the JVM. Both insanely popular by virtue of providing the basic features I describe, and also evidence that they needn't even be integrated to the operating system. Something of this nature that also provides the basics of an interactive desktop.
- yjftsjthsd-h 3y ago> While this is true from a certain perspective, machine code creates a system which must grand access to many things to become usable. A shared file system is a good example of this. Some software could easily echo a line into you .profile that tries to launch a key-logger, and this works in many cases. That's common, but it's certainly not a requirement to run native code. For example, we've done a pretty good job at retroactively fixing that while preserving backwards compatibility with containers (I can, and have run normal official Firefox binaries inside a docker container with zero access to my real home directory) or sandboxes like flatpak (bubblewrap). If you want to run real native binaries but don't have to preserve backwards compatibility, then it gets easy; genode ( https://genode.org/ https://genode.org/ ) does a lovely job of truly practicing only giving programs what access you want to give them. > The expectation of software existing as opaque files creates a huge amount of work for the OS in verifying the exact behaviour of the software as it runs (and in ways which can often be circumvented), rather than a source-based approach in which malware is never allowed to touch the processor. I think you're overoptimistic regarding what you can do with the source code short of manual (human) auditing. I mean, sure there are things you can scan for to try and catch bad behavior, but in the case of actual malice I wouldn't trust automatic code analysis to protect me. >> I'm typing this on a nice comfy GNU/Linux box where the only blobs are some firmware > So you suffer the worst of both worlds then. You've had to download and compile the source yourself, but as the software is designed around being distributed as blobs, so you enjoy none of the benefits that might come from source distribution. I have no idea why you think either of those things? Depending on the distro I certainly can compile from source on my own box (ex. Gentoo, NixOS), but I can also use precompiled binaries (ex. Debian, NixOS) while still having it be trivial to go find the exact source that went in to the binary package I downloaded (this has gotten even stronger with Reproducibility efforts meaning that I can even verify the exact source and build config that created a specific binary). The actual application software and OS are available as Open Source code that can be audited, with binaries available as a convenience, and the only remaining blobs (unwelcome but impractical to fix so far) are firmware blobs with relatively constrained roles (and on machines with an IOMMU we can even enforce what access they have, which is a nice mitigation).
- James_K 3y ago