Since the beginning of the year 2026, we have been receiving bug reports generated by LLMs. It has never been as bad as with curl last year though. It also started later than curl and with better quality of the reports than what Daniel Stenberg describes. We are not totally overwhelmed by the reports, yet they are still consuming a significant amount of our time every other day.
Security Reports from LLMs
We have been triaging and resolving these reports responsibly, assessing the actual impact and attack surface of each one, and fixing them whenever reasonable. Every single one of them got a proper review, and to be honest, almost all of them are actually bugs, in some sense.
Some of the LLM reports were really laughable. You may crash BIRD’s config parser by a string of thousands of characters long. Severity high, because it crashes. But who would ever do that? You could also make BIRD read some bad memory if you send a precisely crafted flowspec payload. Severity high, but it needs modified equipment and an established BGP session with a feature almost never exposed to untrusted peers.
Yet, these reports were straightforward. These were indeed some low hanging fruit, easy to pick, easy to prove that it’s indeed a bug, relatively easy to fix. Flowspec was a little bit more complicated, but still straightforward.
AS Path Matching: RCE
There was one particularly gnarly report, about the AS Path matching operation in filters. That is a very old feature, present in the original BIRD 1.0.0, and rewritten by Ondřej Zajíček in 2009. This implementation contains a preprocessing step where the incoming AS Path is parsed into an array allocated on stack, and then the matching is done on that array. The array was hardcoded to be 2049 items long, and there is no check whether the path is adequately short.
Yet, it is not so easy to make the path so long. Obviously, one may locally make the path almost as long as they want, the real limit would be probably 1071640567 autonomous system numbers, so that the encoded path itself fits into 4 GB of RAM. Yet, every modification to the path requires reallocation, and therefore creating such a path from scratch would consume (temporarily) about 2 EB of RAM.
While this is a plausible way, as creating a path with 2048 items would consume just about 8 MB of RAM, it still needs a user to do stupid things. And if the user does this, they may as well simply announce bad routes.
You obviously ask, and what about BGP? The default maximum size of a BGP message is 4096 bytes, which fits just about 1000 items if you tried really hard, or about 2000 items if you pretend that you don’t understand 4-byte ASNs at all. But you may switch on the extended messages feature which allows messages as big as 64 kB. That fits even longer paths, it would create a stack overflow and possibly remote code execution. That’s CRITICAL!
Not so fast. There are two (or three) kinds of BGP sessions. Internal and external, and interior between confederation members.
On external sessions, extended messages are very rare. Also, because of various routing junk, one of the first things one does, is to drop routes with way too long AS Path, and while I’ve seen various cutoff values in my life, they were always far lower than 1000.
On interior sessions, the combination of extended messages and some filtering is plausible the most, while on internal sessions, it’s very rare to run filters there. But both interior and internal peers are generally trusted.
Last but not least, one has to actually use the path matching operation, which is itself quite uncommon. Please send us an e-mail if you are actually using it in a serious way, we are genuinely curious how this feature is deployed out there in the wilderness.
We triaged this bug as serious in the impact, but with a negligible attack surface. We replied to this reporter that we’ll look into it when there is some time, and continued preparing the release of BIRD 2.19.0 and 3.3.0 with EVPN/VXLAN support and automatic BGP based on router advertisements.
We also informed our customers that there are some findings of this kind, in the middle of May 2026.
The Crash in ROA Automated Route Reloader in BIRD 3
One month back, at the beginning of April 2026, a crash dump landed in our mailbox, sent by one of the customers of BIRD Support, reporting an assert firing at nest/proto.c:704. On first sight this was a hard bug to reproduce, some weird inconsistency in rare cases, happening randomly. Probably some improbable race condition.
We were working on that, slowly and precisely analyzing the culprit code, and because this customer has very large setups, it always takes time to get oriented in the crash dump. All regular analyses pointed to nowhere.
The crashing check is a consistency check of automated route reload which is triggered on ROA update. All updates are collected in a trie, and the update then reloads only these routes which may have been affected by the changed ROAs. That trie lifetime needs to be tracked, and this crashing counter is counting the number of tries pending.
There was no obvious problem. The active_count variable simply tracks the number of active reload requests at that specific channel-roa subscription.
We also had their log file on hand, which was also quite large. Only after several days of entertaining various hypotheses, we found out that for all reported cases, there was an instance further in the past when the affected peer had been down for a little while and then back up. That triggered the graceful restart feature.
By some coincidence, in all these cases this flap happened exactly when BIRD got new ROAs and triggered the automated route reload.
Well, there was a culprit, but how exactly did this work? It took yet another day to realize that several layers below, if the BGP session is in the exactly right state, the whole reload request is ignored and never cleaned up. Later, when the same peer shuts down for longer, the assertion triggers.
During this, an LLM was used for analyzing pieces of code for suspicious behavior, with mixed results at best.
Only after uncovering the whole sequence, it became obvious that this is an actual problem.
Graceful restart is by default available, and if the other side performs it, BIRD obeys.
Checking ROA on BGP import is the exact thing everybody should do.
A sloppy router occasionally dropping its connection is a common occurence.
You may reliably kill almost any BIRD 3 which is peering with you, if you purposefully kill your own session at the right time, with plausible deniability.
We should have debugged this earlier. This is a real threat. At the end of May, we wrote another e-mail to our customers, this time in a tone way more serious than before.
No LLM found this.
Coordinated Disclosure
The reporter of that AS Path bug reached to us again and insistedly requested coordinated disclosure. After we told them that the report is still in the queue, they apparently lost their patience and disclosed their finding without even bothering with telling us that they did it.
Only after somebody shared this to a Telegram group, and later somebody else reposted that report to bird-users, we got informed about that. CVE is pending.
We produced a one-line trivial patch for the AS Path matching code. Then we spent half a day updating our test suite, double-checking that indeed it is possible to crash and the fix is clean.
We also scanned relevant fora and replied to some concerned messages, to reassure people that we do indeed know about that, we do plan to fix the issue, and we simply have bigger fish to fry.
More bugs in BIRD 3: Fixed
Then we returned to fixing the graceful restart crash. We made such a brutal test setup so that it triggered five more bugs all around BIRD 3, just as a collateral to reproducing the actual fatal crash. We kept fixing these for another week.
We have just released BIRD 3.3.1, 3.2.2, 3.1.7 LTS, 2.19.1, 2.18.2 and 2.17.5 LTS, containing all these fixes, also the flowspec fix, and a little bit more. We still have several outstanding bugs; you may expect another patch release quite soon, but we didn’t want to wait any longer with the graceful restart DoS.
How to continue?
We are still quite lucky. We are not flooded by reports, just swamped. Yet, it doesn’t scale. The receiving side needs years of experience to actually be able to properly triage the reports, and the sender has no idea how much time and effort must go into that.
We are seriously thinking about deploying an LLM to do all the reviewing for us. In the end, reviews are the most annoying part of software development. Included in these reports, we are already getting patches anyway. It would be the easiest way forward, untying our hands. But somebody would still have to review the LLM reviews. Or do we want to relinquish our control over what we merge and why?
It’s unclear whether our user base actually appreciates all the manual labor in BIRD maintenance. Do we even need humans to maintain open-source software? Do we even need consistent upstreams repositories? What if the future is not in running git clone https://gitlab.nic.cz/labs/bird but instead in asking an LLM “get me a routing stack”, which would then get generated on the fly?
There are lots of questions. Until they get resolved in favor of LLMs, if you wish us to continue maintaining BIRD to the highest possible standard which we’re capable of, please consider getting BIRD Support or buying some BIRD merch.
And in all cases, please upgrade your BIRD. Now.