I do wonder if this is the case for many people. It seems verifier is a bit unpredictable and makes eBPF programming quite painful.
I do wonder if this is the case for many people. It seems verifier is a bit unpredictable and makes eBPF programming quite painful.
The bpftools maintainers tell you to learn the bytecode format when you ask them what the errors mean, because they expect you to understand what the verifier means when it tells you "unknown scalar" on every single goddamn line of code.
Something like "ebpf coding rules, what to use and what not" would be very helpful.
All ebpf examples that are older than say, 3 months, already don't work anymore. Not even the official ones from the XDP tutorial project (and the libxdp maintainers because the kinda are splitting off a lot of headers into a separate xdp library as it seems).
Most userspace code still relies on the 5 years old bpf-helpers.h, which meanwhile is not supported anymore because it doesn't use the __helper methods from the kernel (they also refactored the kernel in the meantime, and force you to use e.g. __u128 instead of native data types).
Oh boi, did I underestimate what "bytecode vm" means when kernel developers talk about it.
Also, always use llvm, and remember to build two bpf files for each endianness, and use -g for debug symbols. Otherwise you will try to find out what the bpftool errors mean for days, because of shitty mailing list answers.
Or do you mean something else?
But in this case I think they mean on the same machine. "In production" would be more accurate than "in a cloud environment". And yeah I wouldn't load custom kernel modules in production just to do observability.
Unsolvable problem: reject any loop that is provably infinite.
Solvable problem: reject any loop that isn't provably finite.
The trade off is that there will always be some loops that in fact always do terminate, but that the verifier can't prove do.
while (condition) { … }
Do: #define MAX 1000 for n = 0; n < MAX; n++ { if !condition break; … }
Unroll all loops, don’t allow any backward jumps and limit to (say) 1m instructions.
while(condition)[1000 label]{…}
What could possibly go wrong.
Way better than running a denial of service attack on your own systems or those of your customer's.
That certainly depends on what eBPF is used for. If your load balancer errors out at [greatest number of connections envisioned] and an adversary manages to establish [greatest number of connections envisioned] then the result is a denial of service.
Not every operator is confident in making code changes in 3rd party software or might even be allowed to make such changes. Increasing resources o.t.o.h., e.g. adding RAM, is rarely banned. I sure would want a system to make best use of available resources.
If the code is intended to use as a library or the binary distributed to third parties one will have to handle it differently. For libraries taking a parameter indicating the maximum expected is common, for example. See e.g. man 3 read.