Posted by segfaultbuserr 1 day ago
'Classic' non-AI fuzzers like AFL are still insanely useful and powerful, as are static analysis tools.
LLMs make all of these much, much easier to use. The other night, before I went to bed I told Kimi to go and fuzz filesystem code in the latest Linux kernel. I woke up to 26 crashes with reproducers and fixes. I'm still busy reviewing and upstreaming them. (Some have already landed.)
I've also tried DeepSeek and now Mimo. DeepSeek was really quite useful before the price increase, because I didn't care too much about burning a lot of tokens. But it was less useful since, especially since my timezone here in Singapore is the same as in China, so my waking and working hours have a lot of overlap with their peak pricing. However, it's gotten a bit cheaper effectively, because their new flash model is supposedly as good as the old pro model.
Which cheap models are you using (especially those that refuse less)?
So far I've only really used Mimo to drive Sashiko, which is a kernel review tool. I haven't used it for actually writing code.
Kimi is pretty decent overall. But I haven't given it really hard work. Running a fuzzer is pretty simple, and so's the other stuff I asked it so far.
I want to cry.
But yeah, you can't trust user inputs!
Do you have links to some of these?
In mainline:
ext4, xattr cache: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin...
ocfs2, cluster accounting: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin...
Taken into Jan Kara's filesystem tree this week, all isofs:
An out-of-bounds read in the multi-extent directory walk: https://lore.kernel.org/all/20260923153220.777907-1-matthias...
A hang in a fix Jan had just written, which he is folding into it: https://lore.kernel.org/all/20260923153134.771632-1-matthias...
A bug Jan fixed himself after my report: https://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-f...
Sashiko, the LLM patch reviewer that now comments on kernel mailing lists, merged a fix of mine: https://github.com/sashiko-dev/sashiko/pull/556 (a patch that contained one of its prompt placeholders as text had it replaced).
Not accepted yet, but I think interesting:
libata, reviewed by the maintainer but not applied yet: a faulty ATAPI device could make the kernel write past its sense buffer. https://lore.kernel.org/all/20260922182655.2423663-1-matthia...
e2fsck, the repair tool, could deadlock on some corrupt images and hang forever. Reviewed by Darrick Wong. https://lore.kernel.org/all/20260922110435.1528332-1-matthia...
ntfs: a crafted image makes mount hang forever, because the mount waits on a lock its own read already holds. One of the maintainers asked for a wider fix, which I am testing. https://lore.kernel.org/all/20260922153931.1976405-1-matthia...
Sashiko was reviewing ext4 patches against a tree from 2020: https://github.com/sashiko-dev/sashiko/issues/559, fix in https://github.com/sashiko-dev/sashiko/pull/560, plus a one-line MAINTAINERS patch naming the ext4 branch, which Jan acked: https://lore.kernel.org/all/20260923101749.3505886-1-matthia...
Not posted yet, still being reviewed on my side:
ntfs: writing to a compressed file on a volume whose free space is fragmented silently overwrote clusters belonging to other files. write() reported success; the damage only showed after a remount.
ntfs: reads of a damaged file could return zeros for data that is on disk, and writes to it could be dropped.
Sashiko: on its Claude, Vertex and Gemini backends, a connection that drops mid-response is treated as a permanent error rather than retried.
The rest, mostly more ntfs, are still in review or on my desk. Not all of these came from that first night; the ext4 and ocfs2 ones are older.
I also have a lot of bcachefs contributions, but that's because I'm actively using that filesystem on my desktop; instead of a pure fuzzing run.
Fuzzers execute, which has different failure modes that having an LLM do informal reasoning on the code. (I haven't played enough with static analysis to say anything insightful about how they compare with LLM.)
The Linux kernel is a really big piece of software. Using a fuzzer to point you at an interesting (and potentially dodgy) piece of code is a good start. Often once you found the first problem, you or your LLM can read around and find more problems.
Club live lost msft millions of dollars by itself.
Hard to detect at n=1, yes. But larger scale - are you assuming that no Accounting or Sales managers are watching the returns ratios, nobody in Shipping is minding carrier delivery failure metrics, and nobody in Returns is raising alarms about the bricks they're receiving?
Leveraging user data to get malicious behavior is the basis of interpreter eval injection (php, js, perl, shell calls, SQL ...). These attacks are like 50 years old. What do I miss?
In this context, practical data-only attacks as reported by this paper are the holy grail in this field.
As an outsider critic, you may say it's a side-effect of C/C++. If you use dynamic programming languages, this issue doesn't exist in your universe because there's no fundamental difference between code and data. But in another parallel universe of systems programming, it's a huge subject. Both the Morris worm and the publication of the article Smashing the Stack for Fun and Profit in Phrack were regarded by many as the milestones of hacker culture and canonical models of hacking, all the exploitation and mitigation studies that followed it were partially motivated by new hackers who wanted to "advance the field of hacking", so any advancement would be considered significant by a hacker. This is Hacker News, and I thought most people would understand this background. But apparently many developers are application-focused nowadays and hack in different universes, and it's not the case.
An example I’ve seen somewhere is if a buffer overflow lets you change the value of another variable, but not directly control the instruction pointer. The exploit developer then has to figure out a way to turn their very constrained primitive into something useful, versus having access to a more powerful and generic primitive (stack return pointer, write-what-where, etc).
The example in the post is, basically, command injection, but it requires you to manipulate the app-specific state into a vulnerable state.
I feel this checklist of shell-tools [0] is relevant, although the focus is more on how setuid is dangerous because you might not know the fancier arguments someone could supply.
> GTFOBins is a curated list of Unix-like executables that can be used to bypass local security restrictions in misconfigured systems.
I thought the whole point of fuzzing was an example of finding data-only attacks.
A data-only attack would be an attack that reuses the original logic by only corrupting data inputs (such as a flag or a file path), without overwriting code or overriding the logic. W^X, stack canary, or CFI won't work in these cases since no code is tampered by the attacker. In almost ever talk about compiler mitigations, you always hear a passing-by mention of data-only attacks - before the speaker immediately dismisses them as an academic curiosity when the software industry is still facing a flood of stack smashing and ROP attacks.
Add assertions to your code. Voila, your run-of-the-mill fuzzer can now hunt for arbitrary problems with your program by turning them into crashes.
When fuzzing C programs, I usually also add undefined-behaviour sanitizers and friends, in the mode where they crash when you run into the kinds of UB they can detect.
So I think adding assertion is definitely a way to discover data-only attacks in fuzzing, or even as a partial mitigation of these attacks. It's just stack canary for variables and strings (but as the paper authors said, complete mitigation can be impractical).
If "the server has a memory safety bug that allows a malicious client to overflow some buffer and overwrite, for instance, the contents of the cgi_bin_path variable", then why is this a data-only attack? Instill need to overflow a buffer the "traditional" way.
The attacker controls what's executed, and stitches side-effects together to achieve the desired attack. This also starts with "data" but ends with "instructions of the attacker's choosing doing what the attacker wants".
In a data-flow attack (which _still_ has some characteristics of the former), the attacker does _not_ have the ability to pick-and-choose what gets executed, even in the final stages of their attack. They _still_ need to overflow the buffer, and put some other data in some other registers, but their attack _never_ gets to the point where they pick the next instruction.
Likely, at the end of the exploit, arbitrary code execution or privilege escalation has been unlocked. But the exploit chain itself doesn't go through a stage of arbitrary execution (either through ROP, or executable stack). That's how I like to distinguish anyway.
Can’t we just use prim and proper terms like provenance
The word itself is getting on for a thousand years old, originally solely in the sense of colour dyes, similar to “stain”, but over time this was adopted to be “to corrupt” in a more figurative sense, I suspect the same root for taint and stain, with taint more indisputable and harder to remove perhaps.
Seems appropriate to use in computing.
Total 944
Table 2: Confirmed exploits for nginx.Next, I believe they found 944 available "data-only gadgets" usable by a pre-existing memory corruption bug. You still need to find a memory corruption bug first to use them, in the same sense that you need to hunt for ROP gadgets to get arbitrary code execution on a W^X system.
The quality of research (and by extent HN submissions) has really plummeted since LLMs have become marginally useful
(BC and AC are obviously Before and After ChatGPT.)