If your language is capable of expressing "this part of the code can't access the network", in a general way such that networking is not some special snowflake that's baked in, then you've created an effects system which is likely to be useful in many, many other contexts for other things you want to assert without having them supported in the OS. (For example, "is this code async", or "does this code print anything", or "does this code have any side effects", or "does this code throw", or "does this code allocate".)
That's an interesting idea. Although denying network to log4j wouldn't have stopped this I think, as it was the JNDI code that made the network calls, not log4j directly.
That would be difficult to do within an application. If your app needs network access, but logging performed by the app should not, how could the OS help there?
The usual ways to do that are to open a connection to the things you need at startup, and then drop your privileges, set ulimits or whatever. Or you don't have network access at all, but pipe your logs to a local process that does.
Alternatively the application can be made to have some OS-specific rules to e.g. generate iptables rules on Linux, so it can contacts its logger, but not anything else.
All of those are probably anathema to the typical Java programmer though, as they require crossing the boundary from JVM into OS configuration.
I don't think Java apps can drop privileges like that, but yes, that would prevent unexpected bits of code from acquiring a network connection. I suspect only the most secure code bases would bother though, and most things would still be affected even if it were possible in Java.
And how do you do that, without operating system support? I mean, you can't of course limit that based on the code, in the JVM there is only a single address space, thus every method or class can be instantiated from anywhere in the code (despite public/private/etc. that are only for programmer convenience, they are easily circumvented with reflection, they don't provide any security at all).
You can imagine doing something like adding some bytecode instructions that if encountered by the JVM block the network access to every other request done in the call stack after that instruction. Something that reduces efficiency drastically and still can easily be circumvented if you don't implement different address spaces for different parts of the code (something that only the OS can do).
> I mean, you can't of course limit that based on the code, in the JVM there is only a single address space
You can in principle, just look at the Joe-E language.
The article is likely talking about revisions to existing VM designs though, because capabilities are a fundamental, architectural decision that underlie the runtime.
If you're asking how th jvm might do it, I can assure you I do not know. If the question is "can this be a language feature" then I say, surely it can be.
A language that supports static analysis and can disallow dynamic dispatch would do the trick, no?
There are ways to call a function that cannot be caught by static analysis: basically you just need a way to jump to an arbitrary address of memory where a particular function is stored. If we exclude languages that by design sandbox the code (for example JavaScript, and most of the time it isn't enough because engines are bugged and thus browsers also use facilities of the operating system to sandbox the entire engine itself) no other programming language can do that.
Most logging libraries are facades over a concrete implementation. And there exist adapters for those that aren't. One could easily provide one that pipes the log stream to a child process that drops privileges and is restricted down by the OS. This will probably entail a performance penalty, but it could be worth it. It would be nice to have such a capability in-process though.
Programming language can know more about the program's (intended) state at any given time. The OS can/should frequently be involved, but even then you're frequently doing something like pledge() from the program to let the OS know when/how to restrict you. Doing it totally externally, like SELinux does, is valuable but coarser-grained.
Pledge and SELinux are the same level of graininess but pledge’s sauce is that the app has a channel to ask the OS for process restrictions where SELinux has to be applied in advance.
I think it's reasonable to describe one as more coarse gained when it simply doesn't have enough information to be as precise as the other method. Yes, they work at the same layer and can do vaguely the same things, but s targeting makes a huge difference.
Yes, and you can even have a single process with threads in multiple namespaces. But it still doesn’t solve the problem unless you magik passing all log messages to a dedicated pool of threads just for logging.
The process is simply the wrong layer for this boundary, it’s too coarse and trying to hack your way into telling the OS about the parts of your program. OS security treats processes are black boxes, just like hypervisor security treats vms like black boxes. Trying to force it will be extremely clunky.
The Linux kernel developers don't recommend using namespaces for security, but only for access control (the two are not the same!) because it's a relatively recent concept and the syscall interfaces and semantics are huge and subtle. Dedicated user accounts together with firewall rules are a better idea IMHO.