[!WARNING] These rules apply from 2026-09-04, you can find the previous version of the rules on Github.
kernelCTF is a part of the Google VRP and is focused on making exploiting Linux kernel vulnerabilities harder by inviting security researchers to demonstrate their exploitation techniques on 0-day vulnerabilities.
We are asking researchers to publish their submissions, helping the community to learn from each other’s techniques.
hardened-v1-7.x)The target is Linux 7.2-rc5 (x86_64) based on the COS kernel config with additional hardenings and a reduced attack surface.
kCFI + IBTSLAB_VIRTUAL=yKMALLOC_PARTITION_TYPED=ySLAB_MERGE_DEFAULT=nCONFIG_IO_URING=nCONFIG_USER_NS=nCONFIG_TLS=nCONFIG_CRYPTO_USER_API_AEAD=nCONFIG_BPF_UNPRIV_DEFAULT_OFF=yCONFIG_AF_UNIX_OOB=n--vuln-trigger flag on LTS 6.12, the exploit must crash the system (a full LPE chain is not required on LTS).We have retired separate target tiers and bonus categories in favor of a single static reward per eligible exploit.
Only one submission is eligible per kernel version. The 7.2 version will generally remain fixed due to the SLAB_VIRTUAL porting requirement. However, we will update the LTS version (used for vulnerability freshness testing) when we release new slots, upgrading the LTS kernel version every 2-4 weeks on average.
On weeks when a slot is released, the submission window will open on Monday at 12:00 UTC and close on Friday at 12:00 UTC, at which point the winning submission will be selected.
Submissions are evaluated on both speed and reliability over 20 exploit runs. The server extracts the pre-compiled exploit binary from your .tar.gz archive and executes it (without recompilation), awarding a final score based on the following formula:
You can connect to the target with socat - ssl:kernelctf.vrp.ctfcompetition.com:1337,cafile=server_cert.pem
server_cert.pem:
-----BEGIN CERTIFICATE-----
MIIBazCCAR2gAwIBAgIUSXiRksvnzRI2WYqh7nDZVoZydOIwBQYDK2VwMCsxKTAn
BgNVBAMMIGtlcm5lbGN0Zi52cnAuY3RmY29tcGV0aXRpb24uY29tMB4XDTIzMDYw
ODIyNDA0MFoXDTMzMDYwNTIyNDA0MFowKzEpMCcGA1UEAwwga2VybmVsY3RmLnZy
cC5jdGZjb21wZXRpdGlvbi5jb20wKjAFBgMrZXADIQCTg2ayrs3BsxUocgbd1eWj
WWVzQQmORR5LT3unlZCzFaNTMFEwHQYDVR0OBBYEFCSsjYgVH8funXWPApo32zpS
NhPgMB8GA1UdIwQYMBaAFCSsjYgVH8funXWPApo32zpSNhPgMA8GA1UdEwEB/wQF
MAMBAf8wBQYDK2VwA0EAxJ+NlnvVYZKj/ctSIzcuPm7+4SlziIHDRW43SrLks15v
KQVTtek3sAifw5NuaXWZrGrX7JAqNqci3QPCMHFEDA==
-----END CERTIFICATE-----
You can use a maximum of two connections per IPv4 address and the connection will be closed after 30 minutes.
The source code running on the server is available on our Github.
Only the first submission for a vulnerability is eligible for a reward.
This means: if a vulnerability is exploited on the target by Researcher A, it can no longer be exploited on the target (even if the LTS kernel version is updated).
If a patch commit fixes multiple vulnerabilities (e.g. by backporting a new version of a component to the stable tree), we assume the root cause is the same and we consider further submissions as duplicates.
If the same vulnerability is fixed in multiple patch commits (e.g. in commit A in the mainline tree and separately in commit B in the stable tree), then we still consider it as the same vulnerability, thus making further submissions duplicates.
If you are unsure about eligibility, contact us on the #kernelctf Discord channel before making the submission.
Note: Minor details of the submission process may change from time to time, please make sure you check this page again for updates when you make a new submission.
Before you start the submission process, please make sure that the submission window is currently open (Monday 12:00 UTC to Friday 12:00 UTC on slot release weeks) and that you are submitting for the active target version by checking the public spreadsheet or the evaluation server.
Submissions can only target 0-day vulnerabilities.
We consider a bug 0-day if at the time of the submission:
There is no patch commit in the mainline tree, and
The vulnerability is not disclosed in any form (e.g. there is no Syzkaller report about the bug)
A submission will not be eligible if the vulnerability details were reported somewhere (e.g. Pwn2Own) other than security@kernel.org.
The submission process has two stages to make sure the vulnerability details are not shared with us before the patch is released:
Compress the compiled exploit binary, its source code, and all the build files as a .tar.gz file.
Save this exact file, you will need to send us this later.
Note: The evaluation system will extract the exploit binary from the archive and run it without recompilation.
Try to keep this file to the minimum necessary, leave out large files like e.g. vmlinux, bzImage as they can be downloaded separately if needed.
Upload the compressed file to the evaluation system, which will provide a flag upon successful exploitation.
Submit the flag on this form with the additional details requested.
Check the public spreadsheet after submitting the form and confirm that your submission was added and your score is correct.
Wait until Friday at 12:00 UTC and verify that your submission won the current slot. If there are multiple submissions for the same slot, another submission with a higher score may take the slot. If your submission does not win, you must wait for a new, empty slot to be released (start from Step 1).
Report the vulnerability to security@kernel.org within 7 days of winning the slot.
If you are not the author of the patch that fixes the bug, make sure that you are credited in the Reported-By tag of the patch that fixes the bug.
Do not include the Reported-By tag if you both discovered the flaw and authored the patch.
Use the same email address in the Reported-By tag as you use for the form submission or in the “Email address used in Reported-By tag” field of the form.
If there is no Reported-By tag on a patch commit, then a 0-day submission is eligible only if this is the first 0-day submission for that patch commit (based on the first stage submission date).
If it is unclear who reported the bug, then the reward can be split (multiple reporters), reduced, or invalidated at our discretion.
Wait for the patch to land in a release candidate on the mainline tree (and be tagged in Git) or be committed to a stable tree, whichever happens first.
Modify the form within 7 days by following the previously saved link and fill out the extra vulnerability details.
Send us your exploit within 90 days with the description of the exploitation technique via a PR to the security-research repo (see required structure below). This is a mandatory step for us to start verification of the vulnerability.
Once the PR’s GitHub Actions (GHA) checks pass and we confirm the submission exploits the claimed vulnerability, you receive the first half of the reward. After a manual review and the PR is merged, the second half is issued.
Submitting reports via bughunters.google.com prior to PR submission is no longer required; an issue will automatically be created on the portal for winning entries.
However, to collect your payout reward:
You have to publish your exploit within 90 days of submitting the patch commit via the Google Form to be eligible for a reward.
We only process submissions after the exploit becomes public. We can only issue the first half of the reward once the PR passes the automated checks and the initial review confirms that the submission exploits the claimed vulnerability. Following an in-depth review and successful quality checks, the PR will be merged, and the second half of the reward will be issued.
If you want to delay the publication (within the 90 days window), you could do that, but you would get the money later (we want to encourage you to publish the exploit details sooner than later).
The above is about the exploit itself, not the vulnerability. We automatically share some limited vulnerability details of the submissions on our public submission spreadsheet, as a CVE, once you submit the extra vulnerability details via the form in Stage 2.
The submission should be put into the pocs/linux/kernelctf/<cve>_<targets>/ folder within the security-research repo, where:
cve is the CVE number of the vulnerability in the format CVE-yyyy-NNNNN
<targets> is the list of targets separated by underscore (_)
hardened-v1-7.xIf there is a conflicting submission directory name, then append _2 (or _3, etc.) after the directory name.
For example: pocs/linux/kernelctf/CVE-2023-1872_hardened-v1-7.x/.
The structure of this submission folder should be:
original.tar.gz
metadata.json
docs/vulnerability.md
docs/exploit.md
exploit/hardened-v1-7.x/
exploit.c
exploit
Makefile
exploit) to compile exploit.c into exploit and target (run) to run the exploit on the live instance (which steals the flag).You can add additional files (e.g. images for writeup or supporting libraries for the exploit). The exploit can be split into multiple files, although we prefer if it is kept as a single .c file.
If possible please include the following information in the vulnerability details:
Commit which introduced the vulnerability
Commit which fixed the vulnerability
Affected kernel versions
Affected component, subsystem
Cause (UAF, BoF, race condition, double free, refcount overflow, etc)
Ensure that exploit code follows kernelCTF code style guide.
Make sure that the exploit is properly commented and the accompanying exploit.md includes all the details, making it easy to understand what the exploit does.
Give a step-by-step overview of the exploitation process. When describing the following activities, include them as a separate step:
Triggering a vulnerability.
Converting one attack primitive into another.
Spraying or grooming the heap.
Executing cross-cache attack.
Leaking information (e.g. heap pointer, kASLR base address).
Overwriting kernel memory.
Getting RIP control.
Executing interesting post-RIP approaches.
Doing a major step towards a successful exploitation which is not listed above.
In the steps, include the affected objects (e.g. struct file), their role (e.g. vulnerable object, victim object), and their respective caches (e.g. kmalloc-1k) and the used field members of the object (e.g. getting RIP control via file->ops->ioctl, overwriting msg_msg->security).
We expect the following parts to be properly documented:
rop[0] = base + 0x123456; explain that 0x123456 is resolved to e.g. call_usermodehelper_exec.data[0x8] = base + 0x123456; -> data variable contains a fake struct file, the field at 0x8 offset is a f_inode pointer which is set to ...Namespaces usage and why are they required.
Separation between code parts which are needed to trigger the vulnerability and parts which are part of the exploitation process (spraying, heap grooming, cross-cache, converting one primitive to another).
sleep) used for a specific side-effect which is not trivial see.If possible, also include how stable your exploit is (e.g. it worked 90% of the time during your testing).
Your exploit must support the --vuln-trigger argument, which triggers the underlying vulnerability to crash the system (ideally under KASAN) on other versions without requiring a full LPE chain. To stay within vuln-verify workflow time limits, this mode should skip non-essential steps such as KASLR prefetching.
We announce program changes through #kernelctf-announcements Discord channel. All major changes are going to be announced 2 weeks in advance before they take an effect. This document will be updated to reflect current set of kernelCTF rules.
If you have any questions regarding kernelCTF, check the FAQ page and feel free to ask on the #kernelctf Discord channel.
If you are submitting a non-kernel vulnerability affecting our kCTF VRP cluster, please submit the vulnerability to our kCTF VRP.
kernelCTF is part of Google VRP, so its rules including but not limited to these Legal points apply.
You should understand that we can cancel the program at any time and the decision as to whether or not to pay a reward and how much has to be entirely at our discretion.