« first day (4258 days earlier)      last day (44 days later) » 

12:03 AM
@forest So how much does that improve the security of userns?
Depends on what modules are already loaded.
It improves it a fair bit, but unpriv userns is still shit.
I assume there is plenty of attack surface still exposed that normally isn't?
Yup. All turning off module autoloading does is make it so that attack surface area that's present in some obscure kernel module isn't always exploitable.
Q: What is the proper way to exit the current process from a kernel module?

forestI'm writing a livepatch module to hook a function and replace it with one that causes the process to terminate. I can't call abort() because that calls BUG() and my kernel will panic on oops. What is the correct way to terminate a process in a module, given that do_exit() is no longer exported?

(If anyone can help)
Trying to mitigate CVE-2022-2590 with livepatch but I can't just hook the vulnerable function and make it return an error or it could result in the calling function triggering BUG(), so I've got to make it kill the process by force.
But do_exit() stopped being exported since 2021. And I haven't done any real kernel hacking in years.
Erm, I'm retarded. It actually does work.
12:36 AM
I wonder what real kernel hacking is by your standards...
Something more serious than trivial kernel modules and the occasional addition of simple interfaces.
The fruits of my pointless labor:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/livepatch.h>

static int livepatch_ni_syscall(void)
	return -ENOSYS;

static void livepatch_exit_process(void)

static struct klp_func funcs[] = {
		.old_name = "io_uring_setup",
		.new_func = livepatch_ni_syscall,
	}, {
		.old_name = "posix_cpu_timer_create",
		.new_func = livepatch_ni_syscall,
	}, {
		.old_name = "shmem_mfill_atomic_pte",
		.new_func = livepatch_exit_process,
Mitigates CVE-2022-2585, CVE-2022-2590, and CVE-2022-29582 for those too lazy to apply patches and upgrade.
Had to use do_exit() when hooking shmem_mfill_atomic_pte() because of elixir.bootlin.com/linux/latest/source/mm/shmem.c#L2341
if (!shmem_inode_acct_block(inode, 1)) {
	 * We may have got a page, returned -ENOENT triggering a retry,
	 * and now we find ourselves with -ENOMEM. Release the page, to
	 * avoid a BUG_ON in our caller.
	if (unlikely(*pagep)) {
		*pagep = NULL;
	return -ENOMEM;
Otherwise I'd just force it to return -ENOSYS, but I have kernel.panic_on_oops=1 so having the caller BUG_ON() would suck.
So... I'm just having it kill the process.
(This is yet another reason why distros should unset CONFIG_USERFAULTFD)
3 hours later…
3:37 AM
@nobody I second that thought
10 hours later…
1:18 PM
I've started a personal project of reversing Vanguard anti-cheat which I started ages ago but never finished. And fuck me... This is so obfuscated.
@forest It's on my list to read!! <3
@J-- Interesting. So how far have you gotten yet?
@nobody Not too far. I've got two approaches and I'm yet to work out which one is actually going to be better.
Are you making progress though?
The first approach is emulation, the benefit of this is that with enough effort we can emulate the entire driver and build a rudimentary debugger around that. The downside to this is most anti-cheats use lots of anti-emulation tactics.
The second approach is to use a lifter to try and unpack the virtualised sections of the assembly.
@J-- the name vaguely rings a bell
1:28 PM
I've made some progress with emulation, yes. I'm currently dealing with a nice null pointer dereference which is of course crashing my emulator.
that's riot's isn't it?
@JourneymanGeek Yes.
@J-- Nice
ah, good, my brain isn't completely swiss cheese
I think that the second approach is going to be better in the sense that I'll probably get the virtualised functions quicker.
1:29 PM
@JourneymanGeek then which cheese is it?
The problem with doing that is I'll have no progress made on emulation which means absolutely zero dynamic analysis.
So there's swings and roundabouts, I guess. But this isn't something I'm expect to solve in a month or not even in a few months.
@nobody well, I suspect its.. de brie
Lifting is... Something I know much less about. So the rest of today is going to be learning lifting, I think.
rather soft, and mushy
@JourneymanGeek Well, now I see where zombies came from
Just folks who liked cheese...
1:31 PM
On the bright side
@J-- what's a lifter?
I handed in my notice and my last day's the end of the month
@nobody So basically, modern anti-cheats use virtualisation based obfuscation.
so I'll get some decent sleep, and time to upskill while I look for another job
The general idea is that we take assembly instructions and compile them again with the virtualisation obfuscation compiler.
This produces an obfuscated version of the original assembly instructions and those sections are then inside the binary. The only way to dissassemble them then is to do the reverse of the virtualisation compiler.
The idea behind lifting is to take the virtualised instructions (obfuscated instructions) and lift them into an intermediate representation format. The reason this is useful is because the logic and semantics stay mostly the same through obfuscation.
So by lifting we can then reconstruct them back into "normal" assembly.
1:35 PM
@J-- Lol lost track of this here. What does the virtualisation obfuscation compiler do? Create object code for the VM that the driver implements?
@nobody Sorry, I skipped on some details for the sake of simplicty.
The easiest way to think about it is that the virtualiser recompiles the code to some format only itself understands. When the handler function runs, it passes that obfuscated code to the virtualiser whose job it is to reinterpret that into "normal" instructions. Effectively, it becomes the virtualisers job to execute the original code.
The whole point of this process is to make the code extremely hard to reverse if you open it in IDA because all of the virtualised handler functions are... Virtualised. Completely obfuscated and can only be de-obfuscated by the virtualiser.
@J-- Ok, got that
Again, it is a bit more complicated than that but I think that explains the high-level principle.
So lifter is basically a bit akin to a disassembler for the obfuscated assembly?
Yeah, sort of.
The whole idea is that logically the code still needs to make sense. So if we lift it to some IR, i.e, logic and semantics only. We can put that back into assembly.
1:40 PM
So where do you get the lifter from? Write it yourself?
Oh no, I am no where near smart enough for that :rofl:
At the moment I am looking into a project called VTIL. But there's a bunch of lifters these days. LLVM-IR is another good one.
Wait, wouldn't you need a separate lifter for every flavor/version of the obfuscation? Or is the obfuscation used by the vanguard so well known that there already are lifters available for it?
Good question.
It isn't like you need to start over for every obfuscation out there. But yes, you will need to make changes according to the architecture of the obfuscation you're looking at.
The whole point of something like VTIL is to provide a framework around lifting to avoid the exact problem you describe as much as you possibly can.
And this is where it gets a bit complicated. Basically, you're right in assuming that there is no single tool you can just download and lift on every obfuscator out there.
There's way more work to it.
I see
6 hours later…
7:24 PM
What's with @UndercoverDog suggesting lots of minor and incomplete edits to old, unanswered posts?
2 hours later…
9:09 PM
@J-- Seems you've gotten really good at RE. Nice job!
That's something I really need to pick up myself. As is, I think you know a lot more about RE than I do. :P
9:21 PM
@J-- Do you have any exploit RE experience?
If I have find kernel oops from an interesting exploit in the wild, you want me to send you a copy of the kdump?

« first day (4258 days earlier)      last day (44 days later) »