Humbled to share I will be keynoting at LangSec 2025.
I am thankful for such a unique honor, at one of the most prestigious security venues in the world.
11th LangSec IEEE Security & Privacy workshop is happy to announce its preliminary program: https://t.co/uoG2gzXy3Y Abstracts are posted at https://t.co/ePBp8SZqui Join us on May 15 in San Francisco!
We’re opening the Exodus research vault.
Over the coming weeks, we’ll publish technical writeups highlighting vulnerability research, exploit development, and deep reverse engineering from our team.
First up: Michele Campa’s Adobe Acrobat Reader Escript.api use-after-free RCE.
https://t.co/iycMuZQLix
#VulnerabilityResearch #ExploitDevelopment #ReverseEngineering #OffensiveSecurity #CyberSecurity
found a verifier/interpreter mismatch in the Linux BPF subsystem (CVE-2026-31525, CVSS 7.8). arbitrary kernel read/write; become root, escape containers, disable SELinux, read TLS keys out of other processes' memory.
anyway, it starts with the math bars, the absolute value.
computers store negative numbers in two's complement. the smallest 32-bit signed integer is -2,147,483,648, and the largest positive is +2,147,483,647. there is no +2,147,483,648, since it simply does not fit. so when you call abs(-2,147,483,648), the C specification thinks about it for a moment, says "undefined," and leaves the room. on x86 and arm64, what you actually get back is -2,147,483,648. you asked for the absolute value of a negative number, you got back the same negative number. thank you computer :D
the BPF interpreter implements signed 32-bit division (BPF_ALU | BPF_DIV/MOD, off == 1, added in ec0e2da95f72) by decomposing it into unsigned division: take abs() of both operands, divide via do_div(), reapply the sign. the handler in ___bpf_prog_run (kernel/bpf/core.c):
AX = abs((s32)DST);
AX = do_div(AX, abs((s32)SRC));
and look, the kernel even documents this. include/linux/math.h: "the return value is undefined when the input is the minimum value of the type." when DST = 0x80000000 (S32_MIN), abs() tries to negate it. -(-2,147,483,648) overflows s32, the C spec calls it undefined behavior, and the CPU hands back 0x80000000 unchanged. still negative. abs() had one job.
this s32 then gets assigned into AX, a u64 BPF register. s32 → u64 sign-extends: 0x80000000 becomes 0xFFFFFFFF80000000. that's 18,446,744,071,562,067,968. you wanted 2,147,483,648, you got 18.4 quintillion; a rounding error of about 18.4 quintillion. do_div() is a 64-by-32-bit unsigned division macro and it operates on this full u64 numerator. the quotient is off by a factor of 2³². the smod path has the same problem since do_div() modifies the dividend in place and returns the remainder, both wrong. 8 call sites across sdiv32/smod32 src/imm handlers, all quietly producing nonsense whenever S32_MIN shows up.
the BPF verifier is the safety system that statically analyzes every BPF program before allowing it to run. it exists specifically to guarantee that nothing bad can happen. scalar32_min_max_sdiv() in kernel/bpf/verifier.c tracks value ranges through abstract interpretation. it handles signed division correctly, including S32_MIN. computes tight, mathematically correct bounds. the interpreter, as we've established, computes whatever it feels like. so the verifier thinks register R0 is in range X. the interpreter puts value Y in R0. the safety system and the execution engine disagree about what a program does. in BPF security research, this is where you set down your coffee.
concretely: load S32_MIN into R1, load 2 into R2, execute SDIV32 R1 R2. verifier determines R1 ∈ [-1,073,741,824, -1,073,741,824]. interpreter computes do_div(0xFFFFFFFF80000000, 2) = 0x7FFFFFFFC0000000, reapplies the sign, produces a completely unrelated value. use R1 as an index into a BPF map. verifier approves the access, bounds check passes against its calculated range. interpreter uses the actual value. out-of-bounds read/write on a kernel data structure. on every Linux machine running the BPF interpreter.
the root cause of all of this: the absolute value function doesn't handle one number. one specific number, out of 4.2 billion possible inputs, and it's the one that gives you kernel read/write. the fix is:
c
static u32 abs_s32(s32 x)
{
return x >= 0 ? (u32)x : -(u32)x;
}
cast to u32 before negating. -(u32)0x80000000 = 0x80000000 unsigned. correct absolute value, no overflow, no undefined behavior. the kind of function you'd assume already exists somewhere in 30 million lines of kernel code. it did not. I got to write it. :D
I reported this, wrote the patch, got it through 5 revisions of review. acked by Yonghong Song and Mykyta Yatsenko. now patched in stable 6.6, 6.12, 6.18, 6.19. if you haven't updated your kernel: maybe do that.
Papers and slides from the 12th IEEE Language-theoretic Security & Privacy workshop are posted at the workshop web site, https://t.co/FIvlIxulWu
We hope to post videos within the next few weeks.
We live in interesting times.
Last month Linux patched a core uaf in the epoll subsystem, we rarely see these kind of bugs.
As i like these kind of bugs, i wrote a few words about it here: https://t.co/XIiPU7LSSN
Sergey Bratus @sergeybratus is kicking off the @IEEESSP workshops by remembering our friend and fellow hacker FX of Phenoelit @41414141, one of the leaders of #langsec
@pulsoid@offensive_con@Binary_Gecko Hi Cristofaro,
I don't think you've seen it yet, but I wrote a post on my blog about your excellent presentation at H2HC 2024.
Security Conferences in 2024
https://t.co/0UjFDPsoXd
@andersonc0d3@offensive_con@Binary_Gecko Dear Anderson,
No, indeed, I was not aware. Thank you so much!
It's been an interesting read and I am happy the topic has been resonating with both of us and I thank you for letting me know. 🙏
Happy to talk about it anytime :)
Back from an amazing @offensive_con 2026!
It's been an honor to be on stage and present our Google WiFi Pro/QSEE research.
Thanks everyone at @Binary_Gecko for making it awesome.
We let Claude reproduce our EM fault injection attack on Google's TV Streamer 4K — from restricted adb shell to root — using only our presentation slides and the tool manuals as input.
Time to root in <15 minutes. 🤯
Full write-up 👇
https://t.co/Wgl3EjiGF9
One EM glitch forces setresuid to hand the shell user root on Google's TV Streamer 4K.
Full breakdown from our @hardwear_io Amsterdam talk last year: https://t.co/GFzvbVwd5o
We've seen numerous examples where LLMs are doing the heavy lifting for software vulnerability research. Not too many examples (yet) for hardware vulnerabilities.
For our latest blog post we gave @claudeai full control over our hardware glitching setup: https://t.co/7cJ50Et8Pl
@mrgretzky@0xocdsec@offensive_con I am sorry to hear Kuba!
I would have loved to meet again. Always a great pleasure.
But, indeed, I hope we get an opportunity soon :)
We are honored to be at OffensiveCon2026.
We will share how we got EL3 code exec on Google WiFi Pro.
The exploitation techniques we used are generic and applicable to a wide variety of TrustZone-based TEEs out there.
See you in Berlin!
Twelfth LangSec IEEE Security & Privacy workshop announces its preliminary agenda https://t.co/f6hqs9e3hw . Join us on May 21 for two keynotes on formal methods reaching broad industry practice, a panel on AI & LangSec, and talks. Work-in-progress reports and more TBA soon.
I’m #hiring an individual contributor for a fully remote, global role at the intersection of vulnerability research, exploit development, and ML/AI — with a focus on fine-tuning open-weight #LLMs. 🧠
I’m not looking for an “LLM whisperer” or an “LLM pilot.” 🚫
I’m looking for someone who deeply understands post-training, data, evaluation, and how to make models reliable in real-world environments. 🔐
The application link is in the first comment. 🌍
#Hiring #LLM #AI #ML #FineTuning #CyberSecurity #llmwhisperer #llmpilot
I have a job opening on my team. If you're interested in incident response & software security across a wide range of industries (Laptops, Auto, Mobile, Datacenter) while working with very talented people please apply. DMs are open for questions*.
https://t.co/a7qmDyaZIO