The /dev/pwncollege device runs whatever shellcode you write to it in ring 0. Send shellcode that calls commit_creds(prepare_kernel_cred(&init_task)) to turn your process into root, then return to userland and read the flag.
Historically the one-liner was commit_creds(prepare_kernel_cred(NULL)) (often written prepare_kernel_cred(0)). Since Linux 6.2 prepare_kernel_cred() no longer defaults to init_cred on a NULL arg, so that path stopped granting root. Pass a real template like &init_task instead.
This is ret2usr: the kernel executes your code straight out of a user page. Save your user cs, ss, rsp, and rflags first so you can swapgs/iretq cleanly back after escalating.
ret2usr was the kernel privilege escalation technique until SMEP (Supervisor Mode Execution Prevention) landed in Ivy Bridge / Linux 3.0, which faults the CPU the moment ring 0 tries to execute a user page.
SMEP is on. The CPU now faults when ring 0 tries to execute a user page, so ret2usr is dead. But SMAP is off, so the kernel can read user memory. You can place your chain on a user page and pivot the stack there, or ride the overflow itself.
The classic SMEP bypass was a ROP to native_write_cr4 to clear CR4 bit 20. Since Linux 5.3 the SMEP and SMAP bits in CR4 are pinned. native_write_cr4 silently ORs them back in, so the CR4-flip trick is dead.
Same bug, same kernel ROP, new KASLR problem. But the module gives you one kernel text leak through ioctl, and that is all you get. Use it to recover the kernel base, rebase your gadgets and symbols.
/proc/kallsyms and dmesg are locked down, so the leak from the device is the only one you get.
KASLR randomizes the kernel image by a single slide picked at boot, so one leaked text pointer deanonymizes all of it. It landed in Linux 3.14 and is why modern kernel exploits usually start by finding one good kernel address before they do anything else.