The Wayback Machine - https://web.archive.org/web/20201212123910/https://lwn.net/Articles/830154/
User: Password:
|
|
Subscribe / Log in / New account

Lua in the kernel?

Did you know...?

LWN.net is a subscriber-supported publication; we rely on subscribers to keep the entire operation going. Please help out by buying a subscription and keeping LWN on the net.

By Jake Edge
September 9, 2020
Netdev

BPF is, of course, the language used for network (and other) customization in the Linux kernel, but some people have been using the Lua language for the networking side of that equation. Two developers from Ring-0 Networks, Lourival Vieira Neto and Victor Nogueira, came to the virtual Netdev 0x14 to present that work. It consists of a framework to allow the injection of Lua scripts into the running kernel as well as two projects aimed at routers, one of which is deployed on 20 million devices.

Neto introduced the talk by saying that it was also based on work from Ana Lúcia de Moura and Roberto Ierusalimschy of the Pontifical Catholic University of Rio de Janeiro (PUC-Rio), which is the home organization of the Lua language. They have been working on kernel scripting since 2008, Neto said, developing the Lunatik framework for Linux. It allows kernel developers to make their subsystems scriptable with Lua and also allows users to load and run their Lua scripts in the kernel.

Lua and sandboxes

Lua was chosen because it is a small, fast language, he said. It is also widely used as the scripting language in networking tools such as Wireshark, Nmap, and Snort. The talk focused on scripting two networking subsystems in Linux, netfilter using NFLua and the express data path (XDP) subsystem with XDPLua.

[Lourival Vieira Neto]

It is important that any scripting in the kernel not cause it to malfunction. Scripts should not be able to crash the system, run indefinitely, or corrupt other parts of the system. To ensure that, Lunatik uses the Lua virtual machine (VM) facilities for sandboxing the scripts so that they run in a safe execution environment, he said.

Lua scripts cannot address memory directly; they can only access it through Lua data types, such as strings and tables. All of the Lua types are allocated by the VM and garbage collected when they are no longer being used. But that is not enough to restrict scripts from causing harm since they could allocate too many objects and use enough memory to harm the rest of the system. A custom memory allocator is used that will cap the amount of memory available to Lua scripts in order to avoid this problem.

Lua provides "fully isolated execution states", Neto said. Those states are initially created with only the language operators available in them; the developer of the subsystem can then determine which libraries get loaded for additional capabilities given to scripts. Those might be Lua standard libraries or specialized libraries, such as Luadata and LuaRCU; the former provides safe access to data external to the Lua VM, while the latter is a mechanism for sharing data between execution states. Both NFLua and XDPLua use Luadata to access packet data, for example.

Lua provides a single-threaded execution environment without any primitives, such as mutexes, for synchronization. That means the scripts cannot explicitly block the kernel, but they could still run indefinitely. Lua has a facility to interrupt a script after it has run a certain number of instructions, which is used by both NFLua and XDPLua. Multitasking is allowed by Lunatik via multiple execution states in the kernel.

Only network administrators with the CAP_NET_ADMIN capability can load scripts and access the execution states. Netlink sockets are used to transfer data between the kernel and user space; the capability is checked on each access, he said.

NFLua

NFLua is a netfilter extension that targets advanced layer 7 (application layer) filtering using Lua. Iptables rules can be applied at layer 3 (network) and layer 4 (transport) to send packets to NFLua; scripts can then be called to inspect the upper layer. Lua is already widely used by network operators for various tasks, including for security and network monitoring, so Lua is a good fit for this kind of filtering.

NFLua is implemented as a loadable kernel module that contains the Lunatik framework, the Lua interpreter, and whatever libraries are being made available to execution states. Once it is loaded, the nfluactl command can be used to create a Lua state and to load Lua code into it.

He gave an example of a simple filter based on the User-Agent sent with an HTTP request. An iptables rule is used to direct packets to an execution state and a function in that state by name. Packets matching the rule (being sent to port 80) get passed to NFLua, which calls the named function with the packet data. The function looks up the User-Agent from the HTTP request in a table to determine whether to block it or not. The Lua function return value indicates whether netfilter should terminate the connection or allow it to proceed.

XDPLua

At that point, Nogueira took over; he described XDPLua as an extension for XDP that allows using Lua in the data path. It represents the natural evolution of NFLua to process packets before they are handled by the network stack. It creates one Lua execution state per CPU, so it can take advantage of parallelism on modern systems. One of the goals of the project was to add "expressiveness and dynamism" on the data path, so that programmers could create more complex applications to be loaded into the kernel.

XDP uses BPF, so XDPLua has added wrappers for the Lua C API as BPF helpers, allowing BPF programs to call Lua scripts. The XDPLua developers want BPF and Lua to cooperate, "so we can have the best of both of them", Nogueira said. They wanted the performance of BPF while maintaining the expressiveness of Lua.

[Victor Nogueira]

He quickly went through the same example as Neto. The Lua program is loaded into XDPLua, while a BPF program gets loaded into XDP. When a packet arrives at XDP, the BPF program can call the Lua function to determine whether to block or allow the processing of the request; if it is allowed, then the packet will be passed on to the networking stack.

Another example that he showed was processing cookie values, which are being used to distinguish bots from legitimate traffic, before the packet ever reaches the web server. On the first request from a particular client, the web server replies with a cookie value and some JavaScript to attach the cookie value to further requests. Since bots typically won't run the JavaScript, they will not have the proper cookie value.

When a new cookie is generated, the web server will pass its value and the source address to the Lua code, which stores it in a table. The code to actually handle the value is straightforward, simply extracting the cookie value and checking to see that it matches what is in the table. If it is not, the request is dropped before it ever reaches the web server. In addition, the XDP program will add the IP address to its block list so that no further requests will even need to consult the Lua program.

He also outlined an access-control example using server name indication (SNI) in TLS connection requests to restrict which domains can be connected to. This could be used to disallow local users of a network from accessing a forbidden site. Using a simple block list and function in Lua, along with a BPF program to recognize the TLS client hello message and call the Lua function, the SNI data can be checked from XDP.

Benchmarks

In order to gather some numbers, the access-control example was implemented for NFLua, XDPLua, and XDP (in BPF). The BPF version was difficult to write and turned out to be cumbersome to work with, he said, while the same Lua script is shared between NFLua and XDPLua. trafgen was then used to send TLS client hello packets, with SNI values that were in the block list, as quickly as possible. Two things were measured: how many connections per second are dropped on the server (the drop rate) and the CPU usage. It was a fully virtualized environment, both client and server ran on 8-core 3GHz CPUs with 32GB of RAM each; they were connected by a 10Gbps virtio network interface.

NFLua could drop roughly 0.5-million packets per second, while both XDPLua and XDP/BPF could handle around three times that rate (1.5Mpps). In addition, XDPLua and XDP/BPF both used roughly 0.1% of the available CPU, while NFLua used 50%. Nogueira said that NFLua only gets the packets once they have gone through the network stack and it does not take advantage of the multiple cores, which may help explain the 500x difference. It is important to note that having XDP call out to Lua did not have a significant impact in terms of CPU usage, he said.

Neto returned to the video stream to wrap things up before the speakers took questions from attendees; roughly half of the 45-minute slot was devoted to Q&A. He noted that NFLua is used in 20 million home routers and that it is being used by network operators for security and monitoring tasks. The lessons learned from NFLua were incorporated into XDPLua, which is designed from the outset to work cooperatively with BPF, so that developers get the ease of use of Lua combined with the performance of BPF. XDPLua is currently used in Ring-0 Networks firewall products that are deployed as part of the infrastructure at internet point of presence (POP) companies on 10Gbps networks.

One problem area that they have faced is that XDP does not support extensions as loadable kernel modules. Netfilter supports that functionality, which has been beneficial for developing the Lua-based filtering mechanisms. Maintaining out-of-tree bindings in order to support XDPLua has been somewhat difficult.

Instead of using an in-kernel verifier, as BPF does, the Lua environments take a sandboxing approach to protect the kernel. The BPF verifier can be hard to work with, as they found when developing the XDP/BPF version of the access-control benchmark, Neto said. With that, they turned it over to questions.

Questions

Tom Herbert, who was shepherding the Netdev track, noted from the outset that it would be an uphill struggle to try to get this work merged into the mainline. The BPF verifier is part of what allows the kernel developers to be comfortable with XDP, so adding Lua to the kernel will require a similar effort to convince them that Lua is also safe. For example, the kernel cannot crash because Lua has accessed memory inappropriately; what is being done to prevent that? Neto reiterated that Lua does not access kernel memory directly—it has no pointer type. It can allocate memory, but that can be (and is) limited. Furthermore, the number of instructions can be limited, so that infinite loops are not possible.

Neto said that there are various places you can enforce the safety assurances: at compile time, load time, or run time. BPF does load time checks with the verifier, while Lua sandboxes its programs with its VM at run time. There could, of course, be a bug in the VM implementation, but that is also true with the BPF verifier.

Another question that will likely be asked, Herbert said, is why a Lua-to-BPF compiler could not be created; there are already compilers for C and P4, why not do that for Lua? You could perhaps turn Lua syntax into BPF, Neto said, but you cannot write a Lua VM that runs on BPF, so you wouldn't get all of the features that Lua can provide. The verifier purposely limits the BPF that can be run, so you can't write general-purpose code. You might be able to have some elements of Lua, but not the "full package" if you are targeting BPF.

Shrijeet Mukherjee said that having two VMs in the kernel was likely to be problematic; he suggested minimizing the Lua VM component in the kernel and to move as much as possible into user space. The BPF VM has momentum and acceptance; from a community perspective, adding another will be difficult. Neto said that getting the Lua work upstream is not necessarily the path being pursued; if XDP could provide a mechanism to allow dynamic extensions, like netfilter has, that could work as well. Herbert said that will be a hard sell; XDP started with the idea that it would be pluggable, but it is now simply a BPF hook.

Netdev organizer Jamal Hadi Salim said that there is a need for both scripting and compiled code for networking tasks. But there are political and technical hurdles to getting another programming environment added to the kernel. The security concerns are important, but he believes that Lua could meet the requirements, just differently than is done with BPF.

Mukherjee suggested that there might be a way to split things up, such that the in-kernel packet-handling was done in XDP, while the policy handling could be done with Lua in user space; communication could be done through a shared BPF map. Packet handling is really in the kernel's domain, he said, but the policy aspects may not be. But, as Neto pointed out, that will add latency. They have tried that approach in the past, but the performance was such that they moved on to NFLua and then to XDPLua.

But Mukherjee wondered if caching the policy decisions in the kernel could avoid much of the added latency for consulting user space. The "basic stuff" could be handled in the kernel, while the "really complicated" pieces are handled in user space—with the results of the decision somehow cached in the kernel. He was not sure that was a reasonable approach, but there may be a middle ground to be found that would still allow much of what Lua is providing without putting it into the kernel.

An attendee asked about the maturity of XDPLua. Neto said that it is running in production, but it is also still under development. There is no patch ready for upstream submission at this point. There is cleanup work that needs to be done before that can happen. The system used for the benchmarks was overpowered, from a CPU standpoint, for the 10Gbps link speed, so the CPU usage difference between XDP/BPF and XDPLua was not truly shown, an attendee said. Neto agreed that more testing, including using slower virtual CPUs, needs to be done.

They are using the standard Lua, rather than the LuaJIT fork, Neto said, in answer to another question. Investigation of a "typed Lua" for compilation is something on the roadmap. That is the approach that the main Lua project is taking to compete with LuaJIT on performance. The Lunatik developers have avoided using LuaJIT directly because it is based on an older version of the language, but they are interested in pursuing the performance gains that could come with compiled and optimized Lua.

The entrenchment of BPF and its VM make it rather hard to see how Lua could actually be added into the kernel itself. Getting hooks for other pluggable programming environments added to XDP might be a more plausible approach, though Herbert did not seem too optimistic even though he (and others) thought the Lua approach was interesting and potentially useful. But, "it is a moonshot", Herbert said. Whether the XDPLua developers can overcome whatever resistance there will be remains to be seen, but it seems clear that there are at least some who are chafing at the restrictions of the BPF programming environment.


Index entries for this article
KernelNetworking/eXpress Data Path (XDP)
KernelPacket filtering
ConferenceNetdev/2020


(Log in to post comments)

Lua in the kernel?

Posted Sep 9, 2020 17:11 UTC (Wed) by mathstuf (subscriber, #69389) [Link]

This is cool and all, but since different versions of Lua all basically have the Python2/Python3 problem (to a much lesser extent, but enough that I suspect it interferes with kernel ABI policies), what is the plan if/when the next version of Lua comes out and has some incompatibility? Is the kernel stuck with the version of the Lua language when it was first committed to the tree? Are multiple versions of the language/VM going to be supported over time?

Lua in the kernel?

Posted Sep 9, 2020 17:42 UTC (Wed) by smurf (subscriber, #17840) [Link]

You need to take a sensible subset of Lua and stick to it.

The progression of Lua 5.1 to 5.4 with their accompanying incompatibilities is unlikely to affect a kernel-side Lua implementation. You're not going to add introspective object-oriented Lua code or similar complicated structures to the kernel. The idea is to write hooks, traps and/or packet filters in Lua, not drivers. Thus whatever could possibly cause compatibility problems will be missing from the kernel's Lua anyway.

Lua in the kernel?

Posted Sep 9, 2020 19:20 UTC (Wed) by mathstuf (subscriber, #69389) [Link]

5.4 introduced (versus 5.3) consts and destructors (of a flavor), "new semantics for the integer 'for' loop" seems like it could affect kernel-oriented Lua code (and it looks like the kernel wants the new semantics of not wrapping on overflow), and string -> numbers conversions are no longer in the language, but in the stdlib. 5.3 introduced bitwise operators which seem pretty handy (5.2 added them in a library).

These are not object-oriented features, but core semantics to the language itself that seem to not be on the bottom of the list of features I'd expect in these kinds of programs.

> Thus whatever could possibly cause compatibility problems will be missing from the kernel's Lua anyway.

I mean, if it's going to be Lua 5.k, can we just call it that and make the incompatibilities with the other releases of Lua explicit?

Lua in the kernel?

Posted Sep 9, 2020 20:59 UTC (Wed) by meyert (subscriber, #32097) [Link]

The correct thing to do (TM) is of course to include the one and only true universal language into the kernel, i.e. common lisp!
Syntax problems solved!

Lua in the kernel?

Posted Sep 9, 2020 21:36 UTC (Wed) by mpr22 (subscriber, #60784) [Link]

I suppose in the sense that if you force the humans to parse their own programs, machines will have more time to think :)

Lua in the kernel?

Posted Sep 9, 2020 17:32 UTC (Wed) by Cyberax (✭ supporter ✭, #52523) [Link]

Adding LUA (or WebAssembly/JavaScript) has always made more sense to me than reinventing the wheel with ever-more complicated BPF. Virtual machines, JITs and scripting languages are a solved problem, why do it (badly) all over again?

Lua in the kernel?

Posted Sep 9, 2020 22:57 UTC (Wed) by Polynka (subscriber, #129183) [Link]

> Virtual machines, JITs and scripting languages are a solved problem, why do it (badly) all over again?

I guess the problem is the entrenched FLOSS*/*n?x culture, which raises technical limitations of PDP-11 to the rank of “philosophy” (applied of course inconsistently), and seems to prefer homegrown, crappy, hacked-together “solutions” (see “worse is better”) to things that are well-researched and well-designed. Oh, and of course the prevalent technological conservatism – I guess that one of reasons why Linux went with BPF is that it allows for writing the code in the holy C (1972; don’t confuse with HolyC) instead of some of those newfangled things like Lua (1993).

* Or maybe I should just say “open source”, since the biggest proponent of “free software”, Richard Stallman, doesn’t seem to be fan of this approach – I guess that if the website on which we’re commenting was named Hurd Weekly News, we would see articles not about BPF and Lua-which-of-course-will-never-happen, but about GNU Guile integration in the Hurd servers, Scheme and, funnily – Lua and ECMAScript as the planned Guile front-ends.

Lua in the kernel?

Posted Sep 11, 2020 5:28 UTC (Fri) by kmweber (subscriber, #114635) [Link]

> don’t confuse with HolyC

I feel like maybe seven people will understand this reference.

Lua in the kernel?

Posted Sep 11, 2020 11:36 UTC (Fri) by roc (subscriber, #30627) [Link]

<raises hand>

Lua in the kernel?

Posted Sep 11, 2020 14:07 UTC (Fri) by k8to (subscriber, #15413) [Link]

I've installed TempleOS. I didn't use it for anything productive though.

Lua in the kernel?

Posted Sep 15, 2020 19:19 UTC (Tue) by atai (subscriber, #10977) [Link]

RMs never suggested to put guile or any scripting language in the kernel

Lua in the kernel?

Posted Sep 17, 2020 22:54 UTC (Thu) by nix (subscriber, #2304) [Link]

No, but we *did* get a Lispish interpreter in GCC (removed in 2.7, IIRC: I haven't done the archaeology to see if it was ever used for anything) and something kinda like eval in *glibc ld.so*, where you could invoke it as a program (with the usual binary name as the first arg, as per usual for direct ld.so invocations) and then feed it the names of functions with string or numeric arguments or nested function calls (more or less as in C source code) and have them executed via the distinctly nonportable __builtin_apply and __builtin_return builtins.

(The latter awesome and terrible hack was done by Roland McGrath, not RMS, and I do rather wish we lived in a world where it was safe to keep in there. Honestly I think this is even more wonderfully crazy than putting an interpreter in the kernel, all the more so given that it was done in under a hundred lines, not counting the crucial builtins inside GCC.)

Lua in the kernel?

Posted Sep 12, 2020 13:16 UTC (Sat) by karim (subscriber, #114) [Link]

I somewhat agree with this. Note, however, that this approach has already been tried in the past and was nack'ed by Ingo in as far as I can recall: https://github.com/ktap/ktap

I suspect there might be some NIH going on here.

Lua in the kernel?

Posted Sep 12, 2020 14:48 UTC (Sat) by foom (subscriber, #14868) [Link]

Kernel bpf, with the verifier, offers a staticly verified guarantee of normal program completion within a given number of executed instructions, which none of the other options offer.

(But lack of such a static guarantee is also _why_ the other options can be more generally useful than bpf...)

Lua in the kernel?

Posted Sep 17, 2020 16:36 UTC (Thu) by HelloWorld (guest, #56129) [Link]

How does that work? If you can prove for every BPF program that it will terminate, then that implies that BPF is not Turing complete. If it's not Turing complete, then you can't compile Turing-complete languages like C to BPF. But GCC does seem to work on a backend that will emit BPF, so how does that work?

Lua in the kernel?

Posted Sep 17, 2020 17:43 UTC (Thu) by excors (subscriber, #95769) [Link]

In practice C is not Turing complete, because it runs on systems with limited memory and limited time. Outside of theoretical computer science, Turing completeness almost never seems a productive way to think about programming languages. All that matters is whether you can express a useful range of algorithms that run efficiently on your hardware.

BPF can statically guarantee normal completion by forbidding loops, or forbidding loops which are not provably bounded - see https://lwn.net/Articles/794934/ - and avoiding function pointers and recursion etc. C compilers can unroll loops with static bounds, or convert a dynamic bound like "for (i = 0; i < n; ++i) ..." into a static bound like "for (i = 0; i < MAX_N; ++i) if (i < n) ...", and emit errors for code they can't work out how to compile safely. So it only supports a restricted subset of C, but it's a subset that still allows a lot of useful algorithms.

(You could support a much larger subset of C by relaxing the requirement on "normal" completion and making BPF programs abort after a fixed number of instructions, and making sure the kernel safely handles aborted programs. It still wouldn't be Turing complete but it'd be no less expressive than normal C. But at that point you've given up the most distinctive feature of BPF and you probably should have used WASM/etc instead.)

Lua in the kernel?

Posted Sep 17, 2020 21:22 UTC (Thu) by HelloWorld (guest, #56129) [Link]

> In practice C is not Turing complete, because it runs on systems with limited memory and limited time. Outside of theoretical computer science, Turing completeness almost never seems a productive way to think about programming languages.

Yes it's possible in theory solve the halting problem for C programs by running the program in question and waiting until it either terminates or reaches a state that it has been in before, one of which will necessarily happen because of the finite number of states that the machine could possibly be in.
But in practice, this is utterly impractical because the number of possible states, while finite, is far too big. Thinking of C as a turing complete language thus gave the correct answer in practice: it's not possible to determine in general whether a C program will halt. Considering the practical limitation of having finite memory on the other hand gives a positive answer that is complete bogus in practice. You got it *exactly the wrong way around*. Remember that next time you're trying to be a smart-ass.

Turing pseudo-incompleteness

Posted Sep 19, 2020 16:37 UTC (Sat) by smurf (subscriber, #17840) [Link]

Just to put that into perspective. The number of possible states of your computer is 2^2³⁷, if we assume 16 GBytes of RAM. That's a 456562320870-digit number, which I won't paste here for obvious reasons.

The number of distinct states a single computer can ever reach is about 2^(64*8+32+24+30), the exponent consisting of word size, #cores, and the log2 of cycles per seconds, seconds per year, and years until the Earth gets boiled into oblivion by way of the Sun going all red giant on us, respectively.

598 is about 200 million times smaller than 2³⁷.

Lua in the kernel?

Posted Sep 20, 2020 18:52 UTC (Sun) by scientes (guest, #83068) [Link]

LWN didn't use to have so many smart-asses. They use to stick to hacker news. Yet another consequence of the very poor situation in the US and Europe.

Lua in the kernel?

Posted Sep 23, 2020 23:18 UTC (Wed) by flussence (subscriber, #85566) [Link]

We can do better than feeding the troll.

Lua in the kernel?

Posted Sep 17, 2020 23:03 UTC (Thu) by nix (subscriber, #2304) [Link]

> (You could support a much larger subset of C by relaxing the requirement on "normal" completion and making BPF programs abort after a fixed number of instructions, and making sure the kernel safely handles aborted programs. It still wouldn't be Turing complete but it'd be no less expressive than normal C. But at that point you've given up the most distinctive feature of BPF and you probably should have used WASM/etc instead.)

... or, y'know, Lua, which does exactly that.

If "the most distinctive feature of BPF" is a restriction which dramatically limits the usefulness of programs and can provably be lifted without actually preventing the "infloops prohibited" thing that actually matters, while also allowing the verifier to be massively simplified at the huge cost of... an instruction counter, well, I'm not sure this is exactly a major advert for the language. However, the important thing about this feature is what it allows: JIT-compilation into native machine code which needs no interpretation (and obviously without an interpreter, instruction counting becomes impractical). *That* is the benefit of BPF's bounded-loop guarantee.

(I'd be inclined to say that for many use cases, particularly outside the networking layer, particular BPF programs are invoked rarely enough that JIT-compilation is not beneficial: it would seem nice to have a BPF variant which can only be interpreted and which *does* use instruction counting, permitting indirect calls, arbitrary looping, etc: this could then be used for contexts where speed was not crucial and instead you want generality. But that's not what people have done, so...)

Lua in the kernel?

Posted Sep 18, 2020 5:16 UTC (Fri) by foom (subscriber, #14868) [Link]

To me, it seems entirely unclear that this feature of BPF was the right decision. It greatly increases the complexity, and TTBOMK, there exist no C (or C-ish) compilers which can actually generate code for it. (That said, there really is a trade-off -- it's not _obviously_ the wrong decision, either.)

LLVM has a BPF backend, but it basically operates on hope and luck. In general, LLVM cannot promise to generate BPF-that-will-pass-the-verifier. (See, e.g. https://lists.llvm.org/pipermail/cfe-dev/2020-June/065894... for some discussion on this). I don't think BPF-with-verifier really even has a spec that a C compiler _could_ reasonably target! Of course, if you craft your input C code correctly, and the optimizer doesn't do something too tricky, it does often work out in practice. But "Your program will work if you're lucky, but due to normal compiler optimizations, it might get mysteriously rejected instead -- good luck!" is a really unsatisfying system design. I haven't looked into it, but I'm gonna bet the GCC BPF backend has the same properties.

But, I think you're understating the real advantages that the BPF model provides -- KNOWING that the program is guaranteed to complete _normally_ is useful! If you instead simply count the number of executed-instructions, you can ensure that a program won't run forever -- but only by aborting it, dynamically, once you've reached the limit.

Imagine -- you're running a instruction-counting version of BPF (or, say, kernel-Lua), and a BPF program is doing some important packet processing for a router. The current version of the program always executes less than $dynamic_instruction_limit instructions to process any packet, and everything is fine. You then modify the program -- adding just one more trivial "clearly correct" check -- and all of a sudden, you start hitting the limit and abort whenever you get a packet with a certain combination of properties which, put together, now go just over the limit. Of course, it doesn't fail on every packet -- that would be too easy. This sort of surprise could very well cause a serious outage! And it _cannot happen_ with current BPF.

Lua in the kernel?

Posted Sep 18, 2020 13:35 UTC (Fri) by nix (subscriber, #2304) [Link]

> I haven't looked into it, but I'm gonna bet the GCC BPF backend has the same properties.

This is unavoidable given that indirect function calling through function pointers and varargs are part of C, and BPF cannot really support either even in the absence of a verifier, though there is no need for the compiler to actually *crash* or emit invalid code when it sees such things.

In theory you could implement indirect function calls using self-modifying code, implementing function pointers the way x86 compilers of yore implemented INT %reg, but that's gross and self-modifying code isn't a thing in BPF either, thank goodness). This is why xBPF exists, so that these things *can* be implemented, even if not verified: that way they can at least run in the simulator, so the GCC testsuite can stand a hope of passing.

Lua in the kernel?

Posted Sep 18, 2020 15:50 UTC (Fri) by foom (subscriber, #14868) [Link]

I'm afraid you've missed the point. Those issues you raise are trivial -- the compiler can simply prohibit indirect calls and varargs. You don't have a full C implementation, but that's ok. The compiler frontend can even report an error if the programmer attempts to use these features.

The critical problem in correctly compiling BPF is ensuring that loop iteration bounds and pointer accesses can be verified-safe, by the verifier implementation currently in the kernel (which changes, of course). Critically, the compiler optimizations should not turn a "verifiable" program into an "unverifiable" program!

You can write this function in a BPF program:

  int foo(int* o, int v) { return o[v]; }

And, that's fine, despite not being provably safe by itself. However, the function must only be called in a context where the verifier statically knows which object "o" points to, and that the integer "v" is known to be within the bounds of o's object. In order to check this, the verifier does simulated program execution through all possible branches, tracking min/max and known-bits for every value -- even across function calls.

But this tracking cannot be 100% precise, and that imprecision breaks all sorts of normally-correct compiler transforms. One bug report for LLVM is that it optimized code like the following:

int check_range(int v) {
  if (v >= 4 && v <  7) return v;
  return 0;
}

into (approximately -- of course the actual output is BPF-asm, not C):

int check_range(int v) {
  unsigned v_offset = (unsigned)v - 4u;
  if (v_offset < 3u) return v;
  return 0;
}

This seems like a valid optimization...but it completely breaks the BPF kernel verifier. Now, the value which gets a narrowed range "v_offset", rather than "v". Ranges aren't propagated backwards, only forwards, so the narrowed range can't also be applied back to "v".

Thus, the return value of this function has the same value-range as the argument "v", rather than the intersection of the range of the argument "v", and [0, 3). If the caller subsequently calls foo(some_object, check_range(v)), the optimized program will fail to verify. Even though the unoptimized program did verify.

I have my doubts that this problem is even properly solvable in a normal C compilation model.

Lua in the kernel?

Posted Sep 18, 2020 16:48 UTC (Fri) by foom (subscriber, #14868) [Link]

> [0, 3)
Minor correction: this should've been [0, 7).

Lua in the kernel?

Posted Sep 19, 2020 11:48 UTC (Sat) by nix (subscriber, #2304) [Link]

Oh yes, you're quite right: suddenly needing perfectly accurate VRP *and* having to cope with a VRP model (in the kernel) which is, ah, intentionally not as full-blown as a compiler's because nobody wants the verifier to slow down that much is a *big* problem. VRP before now has been the sort of thing where if it goes wrong you get a slightly worse optimization or points-to analysis or something like that. Now, suddenly, it affects correctness! And no C-like compiler I know of is really ready for that. (Obviously Rust has to, and anything else where range analysis of various sorts has semantic impact, but not C. Obviously everyone should be writing their BPF programs in Rust and targetting BPF :) )

Lua in the kernel?

Posted Sep 18, 2020 5:28 UTC (Fri) by foom (subscriber, #14868) [Link]

> and obviously without an interpreter, instruction counting becomes impractical

Not at all impractical. A JIT compiler can generate native code to maintain such a counter easily enough. You only need to update the counter for each basic block (and maybe split excessively-long blocks). The number of instructions in a block is constant, and there's no need to abort _exactly_ at a particular instruction limit, as long as you guarantee to do so within some bound.

You can likely further reduce overhead by only instrumenting just enough to ensure termination. (E.g., maybe you only count backwards branches and calls.)

Lua in the kernel?

Posted Sep 18, 2020 9:42 UTC (Fri) by farnz (subscriber, #17727) [Link]

You can compile a Turing complete language to a non-Turing complete language, by rejecting valid programs.

The halting problem only says that you cannot classify all programs into one of two buckets: "halts" and "never halts"; it does not prevent you from classifying programs into three buckets: "halts", "never halts", and "probably halts, but might not halt". With this extra bucket in hand, you can now only accept programs which are in the "halts" bucket.

The rest is a quality of implementation issue - how do you minimise the number of programs that halt but end up in the"probably halts, but might not halt" bucket?

Lua in the kernel?

Posted Sep 18, 2020 21:41 UTC (Fri) by HelloWorld (guest, #56129) [Link]

> You can compile a Turing complete language to a non-Turing complete language, by rejecting valid programs.

If you reject valid programs, then you're not compiling the Turing-complete language but a non-Turing-complete language that happens to be a subset of the Turing-complete one.

Lua in the kernel?

Posted Sep 19, 2020 13:33 UTC (Sat) by farnz (subscriber, #17727) [Link]

While that's true, it's a statement that only applies in theory - we compile Turing complete languages such as C down to finite state machines like x86-64 and AArch64 all the time, and there's no useful outcome from saying that we don't, in fact, compile C, we compile a non-Turing complete language that happens to be a subset of C.

Lua in the kernel?

Posted Sep 19, 2020 14:10 UTC (Sat) by HelloWorld (guest, #56129) [Link]

I have already addressed this nonsense elsewhere:

https://lwn.net/Comments/831793/

I believe our editor already asked you to stop with the personal insults...

Posted Sep 20, 2020 22:00 UTC (Sun) by sdalley (subscriber, #18550) [Link]

...so you are now in my rather short plonk list. The poor signal-to-noise ratio just isn't worth it.

I believe our editor already asked you to stop with the personal insults...

Posted Sep 21, 2020 5:13 UTC (Mon) by smurf (subscriber, #17840) [Link]

That remark was about the content of your post, not about your person. Thus it was not a personal insult by definition.

Yes, calling a post "nonsense" is harsh. On the other hand, a discussion only works by listening to the other side's arguments, and @farnz plainly didn't do that.

I believe our editor already asked you to stop with the personal insults...

Posted Sep 21, 2020 8:48 UTC (Mon) by farnz (subscriber, #17727) [Link]

Actually, smurf, I believe that HelloWorld is making an argument without a point and refusing to listen to anyone who disagrees with him - this is emphasised by him pointing to a comment he made in another subthread ; Turing-completeness is of limited practical value, as it's an argument from theory. But in practice, we have no Turing machines to run programs on; we always run on finite state machines in as far as our physics goes (we have reason to believe that the distance over which you can communicate is finite, that everything is contained in quantum states, and that the number of quantum states in a finite space is also finite).

If you are going to appeal to Turing-completeness, then you also need to explain why, in this case, the distinction you are drawing is helpful. Otherwise, it's just a claim that the observable universe is a finite space.

As I said in my comment, which HelloWorld has completely and utterly failed to respond to with anything other than an insult, the question is not about Turing completeness - it's about which programs are rejected that could have been accepted. That is an interesting question, and worth considering. Are the programs rejected by compiling C to BPF actually interesting in this context, or are they of no consequence?

I believe our editor already asked you to stop with the personal insults...

Posted Sep 22, 2020 23:31 UTC (Tue) by HelloWorld (guest, #56129) [Link]

> Actually, smurf, I believe that HelloWorld is making an argument without a point and refusing to listen to anyone who disagrees with him - this is emphasised by him pointing to a comment he made in another subthread ; Turing-completeness is of limited practical value, as it's an argument from theory. But in practice, we have no Turing machines to run programs on; we always run on finite state machines

Yes, I pointed to a comment that I made in another subthread. In that thread excors wrote this:
> In practice C is not Turing complete, because it runs on systems with limited memory and limited time.
This is the *exact same point* that you made:
> we compile Turing complete languages such as C down to finite state machines like x86-64 and AArch64

> If you are going to appeal to Turing-completeness, then you also need to explain why, in this case, the distinction you are drawing is helpful.
I already did in my other comment. The point is that while the number of states a computer can be in is finite, it is still so large that there is no *practical* way for arbitrary programs whether they will halt. A computer is thus a good enough approximation of a turing machine *in practice* that results from theoretical compsci do carry over. And the “compiling C to BPF” use case clearly shows this: it can't be done, which is why they can't compile C to BPF but a less general subset of C.

> As I said in my comment, which HelloWorld has completely and utterly failed to respond to
You just didn't understand the response, and that is not a problem on my side.

I believe our editor already asked you to stop with the personal insults...

Posted Sep 23, 2020 2:06 UTC (Wed) by excors (subscriber, #95769) [Link]

Consider these languages:

1) C compiled to verifiable BPF
2) C compiled to a finite x86 machine
3) C compiled to a hypothetical unbounded machine
4) C compiled to verifiable BPF then implemented on a universal Turing machine implemented in Conway's Game of Life implemented on a hypothetical unbounded machine

(By "C" I mean some C-like language that is appropriate for the target architecture, not strictly ISO standard C.)

Theoretical CS says that the halting problem is solvable for 1, 2, and 4, but unsolvable for 3. Only 3 is Turing complete.

In practice, you can only determine whether a program will halt in a reasonable amount of time on 1.

Your original question was about how can GCC compile C to BPF. Obviously GCC can already compile C to x86 (and I assume you're happy to say C-on-x86 really is C). So your question was about the difference between languages 1 and 2, and the difference is not in their Turing completeness, because both are incomplete.

In general, proofs involving Turing machines seem perfectly happy to take a finite algorithm and make it exponentially more expensive, e.g. using unary representation for numbers, because it'll remain finite (which is all they care about). The Game of Life UTM is a reasonable theoretical construction, despite being completely absurd in practice. So the techniques used to examine Turing completeness are very different to the techniques you need to practically determine if a program will halt in reasonable time. When trying to solve almost any practical problem, Turing completeness is an irrelevant distraction, which is why I pushed back against framing the question that way.

I believe our editor already asked you to stop with the personal insults...

Posted Sep 23, 2020 8:52 UTC (Wed) by farnz (subscriber, #17727) [Link]

> > If you are going to appeal to Turing-completeness, then you also need to explain why, in this case, the distinction you are drawing is helpful.
> I already did in my other comment. The point is that while the number of states a computer can be in is finite, it is still so large that there is no *practical* way for arbitrary programs whether they will halt. A computer is thus a good enough approximation of a turing machine *in practice* that results from theoretical compsci do carry over. And the “compiling C to BPF” use case clearly shows this: it can't be done, which is why they can't compile C to BPF but a less general subset of C.

That's still avoiding the key point - the important question is nothing to do with the halting problem, but whether what you can compile from C to BPF (or x86-64, or AArch64) is useful. If the subset of C that compiles to BPF is sufficiently large and expressive, then it doesn't matter that obscure capabilities are missing (e.g. true with AArch64, as the inability to have a single value in memory that needs 2**68 bits to represent it is not an issue). If it's not large enough, then there's a problem - but that requires not an appeal to Turing-completeness, but a pointer to language features that cannot be used in C->BPF compilation, together with an explanation of why those features matter in the real world.

> > As I said in my comment, which HelloWorld has completely and utterly failed to respond to
> You just didn't understand the response, and that is not a problem on my side.

No, that is a problem on your side - you are assuming that if people don't understand what you're saying, it's because they are the issue, and not your explanation. Taken to extremes, this attitude is why the British conquerors thought Africans were stupid - the Africans didn't understand English, and therefore the problem was on their side.

And I would note that this applies both ways round - you've ignored the meat of my disagreement in favour of showing off how clever you are and making statements about theoretical CS that don't apply directly to the real world. Does that imply that you just don't understand CS?

I believe our editor already asked you to stop with the personal insults...

Posted Sep 23, 2020 10:12 UTC (Wed) by HelloWorld (guest, #56129) [Link]

> That's still avoiding the key point - the important question is nothing to do with the halting problem, but whether what you can compile from C to BPF (or x86-64, or AArch64) is useful.

I started this thread, so I get to determine what the question was about. I asked how it's possible to compile C to BPF when that is clearly impossible due to the halting problem (nitpicking about finite memory notwithstanding). And the answer is that they *don't* compile C to BPF but only a subset. Whether that subset is useful or not is completely besides the point.

I believe our editor already asked you to stop with the personal insults...

Posted Sep 23, 2020 10:17 UTC (Wed) by farnz (subscriber, #17727) [Link]

But, by that very statement, compiling C to x86-64 is also impossible, and yet you've said that the subset of C that compiles to x86-64 is fine by you, citing the fact that the limits on what C can be compiled to x86-64 are so large that they are practically not relevant.

I'm asking you why you don't feel the same way about the subset of C that compiles to a practical BPF program - after all, I can just raise the limits on BPF (as we do with x86-64) to get into the same situation where the limits exist but are so huge that they amount to the same limits as x86-64.

I believe our editor already asked you to stop with the personal insults...

Posted Sep 23, 2020 12:05 UTC (Wed) by foom (subscriber, #14868) [Link]

It's different precisely because you *cannot* simply raise the limits to fix the problem. BPF requires the program to be proven to normally terminate on all possible inputs, before the program can be run. This is an entirely different ball game from C or x86-64, which require no such proof.

And -- of course -- most programs which in fact DO always terminate (without raising an exception, and within the proscribed run time bounds) cannot be proven to do so by the BPF verifier, and are therefore incorrectly rejected. This will not change if you increase the limits.

I believe our editor already asked you to stop with the personal insults...

Posted Sep 23, 2020 17:40 UTC (Wed) by farnz (subscriber, #17727) [Link]

Except that BPF has no such requirement - the kernel's eBPF validator will not accept a program that it cannot verify will terminate normally on all possible inputs, but that's a consequence of that restricted execution environment, and not an eBPF requirement.

The same restriction would apply to x86-64 if the execution environment wanted to verify that it terminates on all possible inputs. That does not mean that you can't compile C to eBPF or x86-64 - it just means that in the context of compiling for the kernel eBPF validator (which would be the same for x86-64, or Lua bytecode, or WebAssembly), you can't use constructs that the verifier would reject.

I believe our editor already asked you to stop with the personal insults...

Posted Sep 23, 2020 21:13 UTC (Wed) by foom (subscriber, #14868) [Link]

> Except that BPF has no such requirement

Oh come on, this is a useless nitpick.

There is effectively no use for eBPF, except to feed it to the Linux kernel. And for that purpose it must be verifiable. So, yes, fine -- when I said "BPF requires" I really meant "BPF-with-verifier-as-implemented-by-the-linux-kernel-for-use-from-user-space requires". _That_ is the target we're talking about in this whole thread, not the practically-useless "BPF-without-verifier" target.

I believe our editor already asked you to stop with the personal insults...

Posted Sep 24, 2020 10:23 UTC (Thu) by farnz (subscriber, #17727) [Link]

But that limit can be raised, too - it's an artificial limit the kernel imposes so that it can safely accept user programs that get to hold the CPU. We can change that limit if it's a problem - we can (for example) allow programs that can't be proven to terminate a fixed number of executed instructions after which a default result is produced.

Which puts us right back at the original problem that HelloWorld is continuing to not answer; what practical programs would you like to express in C that cannot be compiled down to eBPF right now, and can we fix that up?

I believe our editor already asked you to stop with the personal insults...

Posted Sep 23, 2020 22:34 UTC (Wed) by HelloWorld (guest, #56129) [Link]

> I'm asking you why you don't feel the same way about the subset of C that compiles to a practical BPF program

Because that C subset is much, much smaller than the C subset that is implemented by common C implementations. It's reasonable to say that C is a good approximation of a Turing machine (from a computability perspective), but the same cannot be said for the C subset that can be compiled to verified BPF.

I believe our editor already asked you to stop with the personal insults...

Posted Sep 24, 2020 10:26 UTC (Thu) by farnz (subscriber, #17727) [Link]

Still no specifics - if there are things you want to express in C that cannot be compiled to eBPF as it stands today, what exactly are they? How difficult is it to change the rules of the verifier such that those things are accepted?

The reason I don't care about x86-64 being more limited than C on a Turing Machine is that there's nothing practical we want to do with C that doesn't also run on x86-64; as far as I can see, the same currently applies with eBPF (in that, while there are things I can't do in C compiled to eBPF, they're also things I don't want to do with an eBPF program anyway).

I believe our editor already asked you to stop with the personal insults...

Posted Sep 24, 2020 12:26 UTC (Thu) by nix (subscriber, #2304) [Link]

Neither loops of runtime-computed length nor indirect function calls through function pointers are exactly unusual, yet neither are verifiable in BPF as it stands, and the latter is not even expressible (which was one of the motivations for xBPF).

Indeed, both are so far from unusual that the BPF verifier itself makes extensive use of both.

I believe our editor already asked you to stop with the personal insults...

Posted Sep 25, 2020 8:01 UTC (Fri) by Wol (subscriber, #4433) [Link]

> Neither loops of runtime-computed length

And yet the original FORTRAN spec didn't permit these either (nor did it deny them). It explicitly permitted storing the loop counter in a read-only register, which imho BPF should certainly permit.

Cheers,
Wol

I believe our editor already asked you to stop with the personal insults...

Posted Sep 23, 2020 19:31 UTC (Wed) by smurf (subscriber, #17840) [Link]

> I asked how it's possible to compile C to BPF when that is clearly impossible due to the halting problem

Well … we're pretty far away from the kind of complexity where the halting problem, in the CS theory sense of that word, would be a meaningful boundary for verifying BPF-or-whatever programs.

There are lots of valid algorithms that can easily be proven to yield a correct result within some small bounded runtime – but which you cannot write in BPF because its set of operations is incomplete and/or because its verifier is too dumb.

This difference matters because a somewhat-extended instruction set plus an improved verification algorithm (with back propagation and a couple of other tricks) might well be able to cope with a large-enough class of BPF programs so that the current problems, esp. with optimizing compilers, can be solved.

This kind of verifier probably is too large and complex to implement inside the kernel, but doing it in userspace and signing the result would work just as well.

I believe our editor already asked you to stop with the personal insults...

Posted Sep 21, 2020 9:16 UTC (Mon) by sdalley (subscriber, #18550) [Link]

"Nonsense" is actually an OK thing to call an argument if it doesn't make any sense. I had just followed HelloWorld's own link to where he accuses subscribers worthy of a good deal more respect than his behaviour deserves, of being smart-arses. I prefer not to waste time with such unpleasantness.

Lua in the kernel?

Posted Sep 9, 2020 17:37 UTC (Wed) by smurf (subscriber, #17840) [Link]

I wonder whether it'd be possible to run a benchmark of something like this test in both userspace interpreted-Lua and LuaJIT, in order to get a handle on the actual performance difference after optimization. Comparing BPF to "plain" Lua is hardly fair, after all, and 500x slowdown somewhat unacceptable.

On the other hand, if nothing else running Lua is easily two orders of magnitude more accessible than BPF, to people who want to actually get things done instead of fighting with a BPF compiler and its limitations. (Been there, done that, thrown in the towel in favor of more satisfactory pursuits.) This alone is a rather powerful argument in favor of adding Lua IMHO.

Lua in the kernel?

Posted Sep 10, 2020 6:24 UTC (Thu) by amarao (guest, #87073) [Link]

500kpps is not kernel scale number. You can have the same performance on the usual proxy servers in userpsace. Lua in the kernel sounds like 'oh, I have a hammer. Isn't it a nice nail shines out there?'. Why in the kernel? Userspace was created for those things, wasn't it?

Lua in the kernel?

Posted Sep 10, 2020 7:30 UTC (Thu) by smurf (subscriber, #17840) [Link]

You can say the same thing about BPF. A BPF interpreter should be about as fast as non-JITted Lua.

Transitioning each and every message to userspace requires a context switch (and/or a cache transfer between CPUs) at minimum. That kills performance.

Lua in the kernel?

Posted Sep 10, 2020 7:30 UTC (Thu) by edeloget (subscriber, #88392) [Link]

Doing it in the kernel means that you still use the kernel network stack. If you plan to do it in user space as afast as possible then you have to extract the network stack (for example using DPDK) which is a burden of its own (but possible: we're doing it ; it's not pretty and we still have rare bugs we do not understand).

(but for the record, I also think this is a hammer-based solution; there is a limit to what the kernel should do "in the name of performance"; does this announce the return of the HTTP server module?)

Lua in the kernel?

Posted Sep 12, 2020 13:11 UTC (Sat) by foom (subscriber, #14868) [Link]

If someone is willing to add Lua, they could also eliminate the artificial restrictions of bpf.

The current state of things is really unfortunate, because you cannot _actually_ compile C to bpf. Well, rather, you can compile, but most nontrivial programs will be rejected by the bpf verifier when you try to load it into the kernel.

The verifier requires that all programs be statically analyzable to determine that the program will terminate, and that it is statically impossible for the program to ever access out of bounds memory. There is, by design, no runtime "failure" -- every bpf program that passes the verifier is guaranteed to terminate with a valid return value from the end of the program.

This is certainly an interesting property! But, this makes bpf very much not a generic architecture, and furthermore, impossible to reliably target with a C compiler. Even if you've carefully written your code to be verifier-safe, normal compiler optimizations may foil the static analysis, and break your program.

Yet, these verifier restrictions are not necessary -- *if* you're willing to admit the possibility of a program which can (safely!) fail to return a result when run.

Supporting Lua necessarily admits such a possibility of failure (e.g. by execution timeout, excessive memory allocation, etc etc). If that's acceptable, the same could surely be allowed for bpf, and result in a more generally usable system.

Lua in the kernel?

Posted Sep 18, 2020 9:29 UTC (Fri) by HelloWorld (guest, #56129) [Link]

The way the BPF verifier ensures termination appears to be rather simplistic. More sophisticated mechanisms do exist, such as these:

http://docs.idris-lang.org/en/latest/tutorial/theorems.ht...
http://ats-lang.sourceforge.net/DOCUMENT/INT2PROGINATS/HT...

However while this does allow for more complex programs, I'm not sure how useful it is in practice at this time. For one, even if you prove that a program will run for a finite amount of time, that amount may well be longer than the age of the universe. These approaches also require additional training and education for programmers to use them effectively.

Lua in the kernel?

Posted Sep 10, 2020 11:55 UTC (Thu) by ibukanov (subscriber, #3942) [Link]

I wonder why Lua with its multiple incompatibilities between releases and not WebAssembly, which is designed to provide tight sandboxes while allowing to use most programming languages these days? Big plus of WebAssembly is that it allows multi threading while tightly controlling memory consumption. Plus pure interpreter is rather small (https://github.com/wasm3/wasm3 claims to fit under 100KB for code and runtime) and compatibility story for WebAssembly is very good.

Lua in the kernel?

Posted Sep 11, 2020 6:46 UTC (Fri) by marcH (subscriber, #57642) [Link]

> I wonder why Lua with its multiple incompatibilities between releases and not WebAssembly,

Probably because WebAssembly is 20+ years younger.

Lua in the kernel?

Posted Sep 11, 2020 18:12 UTC (Fri) by marcH (subscriber, #57642) [Link]

> there are already [BPF] compilers for C and P4,

Any idea which language(s) most BPF code comes from? These two? I felt this is the bit of information really missing from the (excellent) report for a true "Apples to Apples" comparison with Lua. Maybe I'm the only non-BPF expert reading it :-)

> The BPF VM has momentum and acceptance ...

... in the Linux kernel community. This is obviously hard to gauge but I suspect the BPF "momentum" is small compared to Lua's momentum is the larger space of small, embedded VMs. Plus it's not like no LUA user has safety and security concerns.

> Herbert said that will be a hard sell; XDP started with the idea that it would be pluggable, but it is now simply a BPF hook.

It's not clear to me why the _initial idea_ would be a hard sell?

> Netdev organizer Jamal Hadi Salim said that there is a need for both scripting and compiled code for networking task

This sounds like the Lua VM runs much higher level code than the BPF VM but how higher really? Lua is a very simple language and XDPLua and XDP/BPF had the same performance in this (artificial?) example.

This is what I find very impressive about Lua design choices BTW and clearly a big reason for its success: packing in one language all the programming features that are very expressive yet cost very little.

PS: please share a link to the slides; couldn't find them.

Lua in the kernel?

Posted Sep 22, 2020 10:56 UTC (Tue) by pctammela (subscriber, #126687) [Link]

Lua in the kernel?

Posted Sep 12, 2020 16:49 UTC (Sat) by mirabilos (subscriber, #84359) [Link]

Having seen the C side of a part-Lua application, with bad -Wcast-qual, not even “const” clean, etc. I wonder how this is used this much *at all*.

Inspecting SNI… while I *told* people that SNI is a privacy violation and should be *REMOVED*, not furthered, this is beyond what I had foreseen.

GET SNI OFF TLS *NOW!*

It’s nothing more than a bad excuse for not using IPv6 IP-based vhosts, or wildcard or multi-SNA certificates.

Lua in the kernel?

Posted Sep 13, 2020 1:16 UTC (Sun) by foom (subscriber, #14868) [Link]

There is a draft rfc "TLS encrypted client hello" which fixes this privacy issue, finally.

https://tools.ietf.org/html/draft-ietf-tls-esni-07

China is already adjusting their country's firewall to block connections where clients request this extension, of course...

Lua in the kernel?

Posted Sep 13, 2020 3:22 UTC (Sun) by pabs (subscriber, #43278) [Link]

It seems unlikely that obscuring the hostname is really that feasible on the modern web, at least according to the "What can you learn from an IP?" paper from last year. The only solution I can think of is onion routing like Tor.

https://irtf.org/anrw/2019/slides-anrw19-final44.pdf

Lua in the kernel?

Posted Sep 13, 2020 16:19 UTC (Sun) by foom (subscriber, #14868) [Link]

Well, at the least, it can make collecting hostname data not effectively _foolproof_, which is a good thing.

Lua in the kernel?

Posted Sep 18, 2020 22:08 UTC (Fri) by xyzzy (guest, #1984) [Link]

SNI is great for virtual hosting behind a single IPv4 address. My small IT business used it to pack customers into containers on the same server. I'd love a world where all the eyeballs had v6 but that's not the world we're in.

SNI is also great for filtering. We buy filtered internet to reduce the risk of our kids seeing something they shouldn't. I look with horror upon encrypted DNS and encrypted SNI and will block them if I can. If Lua in the kernel lets me built an OpenWRT router with performant content filtering that sounds great to me!

Lua in the kernel?

Posted Sep 19, 2020 0:05 UTC (Sat) by mirabilos (subscriber, #84359) [Link]

Ad 1: as I said, lame excuse. You’d want to be looking at wildcard and multi-sAN certificates instead.

Ad 2: I shudder at the distrust you do towards your kids and the amount of spying instead of doing parenting right. (I’m not the right person to talk about this with though, so I won’t respond to this particular issue.) But even so, I’m asking to *drop* SNI, not to merely encrypt it, and *especially* not to make it mandatory, as those idiots did.

Lua in the kernel?

Posted Sep 21, 2020 19:57 UTC (Mon) by marcH (subscriber, #57642) [Link]

> I’m asking to *drop* SNI,

May I ask _whom_ you're asking that nicely?

> I won’t respond to this particular issue.

I think you already did.

Lua in the kernel?

Posted Oct 12, 2020 9:27 UTC (Mon) by wtarreau (subscriber, #51152) [Link]

We're having Lua in haproxy which has similar constraints as the kernel (limited execution time, shared memory, multi-threaded etc). While the Lua language isn't exactly beautiful (looks more like incremental improvements over something initially much simpler), it's definitely targetted at light embedded environments.

You configure how much memory its stack may use, you also configure the maximum number of instructions it will execute before yielding, and it shows pretty decent performance. Overall there's no way to end up eating all memory or in an infinite loop there. At best a bogus script will keep the CPU at 100% just like a userland program would, but the machine would remain totally responsive.

Personally speaking I don't regret that choice at all for haproxy. Some would have liked more modern or more elegant languages like JS, but these ones are resource hogs that cannot be embedded anywhere on a real-wolrd machine. Lua sits reasonably well at the junction of safe, fast and usable.

Lua in the kernel?

Posted Nov 18, 2020 6:44 UTC (Wed) by SiriusDev.Net (subscriber, #115124) [Link]

I would suggest we just go brave, raise the bar and include Java VM in Kernel. Field tested, industry accepted VM. Byte-code nicely maps to Spark assembly. Also lacks explicit pointers so rock solid safe. Why not?

Idiotic ideas are infinite in numbers so this is why it is pointless to even discuss them.


Copyright © 2020, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds