[!WARNING] These rules apply from 2026-04-30, 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 and 1-day vulnerabilities.
We are asking researchers to publish their submissions, helping the community to learn from each other’s techniques.
A submission can contain any number of the following 2 parts:
This instance uses the latest LTS with COS kernel config and unpriviledged user namespaces turned off since July 1st, 2025. Besides that, io_uring and nftables are also disabled. Only the first submission is eligible per LTS kernel version, but we are upgrading the kernel version every 2-4 weeks on average.
Base reward: $71,337
Stability bonus (+$10,000)
Criteria: 90% of runs successfully steal the flag.
More precisely, the exploit_repro Github Action reports Reliability: 90% or better in the Reproduction summary (after a sane amount of re-runs if needed)
We don’t support providing a KASLR base address anymore ("requires_separate_kaslr_leak": true in the metadata.json file), using this option makes the submission ineligible.
0-day bonus (+$20,000)
Every three months, we reward the submission - or submissions - that demonstrate the most novel exploitation techniques, at our discretion.
The submission should include a description of the techniques (docs/novel-techniques.md) and show why it is novel.
Novel techniques can be submitted at any time exploiting any available environment, even if the vulnerability was already exploited in that environment.
A technique can only be sent once.
You can connect to the targets 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 maximum 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 (per target).
This means: if a vulnerability is exploited on the latest LTS by Researcher A (but not on the other targets), then it can still be exploited on other targets (e.g. by Researcher B or later by Researcher A), but can no longer be exploited on the latest LTS (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 (for the same target) 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 (for the same target) duplicates.
The “novel techniques” category is an exception from these rules, as in that category we are rewarding the technique, so you can target already exploited vulnerabilities.
Minimum 10% stability (if not specified otherwise) is required for all targets. Stability is measured by the exploit_repro Github Action which should report Reliability: 10% or better in the Reproduction summary (after a sane amount of re-runs if needed).
The exploit needs to run within 5 minutes, otherwise it will be counted as a failed run when we measure stability.
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 target’s slot you are planning to exploit is not taken by looking at the public spreadsheet. The server also tries to warn you about this by putting “Slot is taken by expNNN” next to the target.
Submissions can target 0-day and 1-day bugs.
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)
If the submission targets a bug which is not patched yet (0-day or 1-day without a patch), then the submission process has one additional initial stage.
The purpose of this additional stage is to make sure the vulnerability details are not shared with us before the patch is released but to still provide a 7-days long “protection window” for 0-day vulnerability founders in case some else makes a 1-day submission for the same vulnerability before the 0-day founder.
In this stage:
Exploit the bug and capture the flag from the target environment (the flag is a proof of successful exploitation).
Compress the exploit and its source code as a .tar.gz file and calculate its SHA256 checksum.
Save this exact file, you will need to send us this later.
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.
Submit the flag and the hash via this form with the additional details requested.
Check the public spreadsheet that you actually took a free slot and your submission is not a dupe (if there is a race for a slot, it is possible that someone else was faster than you and took the slot). If your submission was dupe, you have to wait for new, empty slot to be released.
Report the vulnerability to security@kernel.org within 7 days of the first form submission.
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 0-day bonus can be split (multiple reporters), reduced, invalidated or the 0-day submission protection can be lost 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 details as described below in the 1-day section.
A submission will not be eligible as a 0-day submission if the vulnerability details were reported somewhere (e.g. Pwn2Own) other than security@kernel.org.
Exploit the bug and capture the flag from the target environment (the flag is a proof of successful exploitation).
Submit the requested vulnerability details via this form (without including additional details on the exploitation technique for now).
Check the public spreadsheet that you actually took a free slot and your submission is not a dupe (if there is a race for a slot, it is possible that someone else was faster than you and took the slot). If your submission was dupe, you have to wait for new, empty slot to be released.
Send us the description of the vulnerability via bughunters.google.com (please follow the process described below).
Wait for the kernel CNA to publish the CVE or publish the vulnerability details yourself on oss-sec.
Send us your exploit within 90 days of Step 1 with the description of the exploitation technique via a PR to the security-research repo (see required structure below). This is 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. Note that these payouts exclude the potential novelty bonus, which is awarded separately every three months.
Sign in (this helps us identify you and send you a reward)
Put a summary of the vulnerability in the report description field – please mention “kernelCTF”, the submission ID (“expNN”) listed on the public spreadsheet, the affected targets, the affected subsystem, the cause and type of vulnerability (e.g. kernelCTF expNNN: Refcount issue leading to UAF in <subsystem> affecting LTS 6.12)
Enter Linux Kernel into the affected product / website field, select the My product is not listed in the product list checkbox.
Enter kernel.org into the URL field.
Describe the vulnerability in detail (see the Documentation requirements section):
Do not include the exploitation details here.
Put “kernelCTF” and the submission ID here again (e.g. “kernelCTF exp45”).
Make sure that the patch commit, CVE (optionally, if it is already known) and the exact target(s) (e.g. lts-6.12.36) are included.
You can reuse the contents of your vulnerability.md if it already exists (see the “Exploit PR file structure” section).
You can just enter “unprivileged user can get root” into the attack scenario (bottom) field.
If you’d like to attach images or a PoC (triggering the vulnerability without actually exploiting it), you can attach them as a tar.gz file here.
Select Privilege Escalation as the Vulnerability Type
Select Yes, this vulnerability is public or known to third parties (as the patch is already out).
You can optionally donate twice the reward to charity if you select “Donate to charity and double my reward.”
Submit your report.
We highly recommend to change your payment provider to BugCrowd for a better payment process. You can read here how.
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.
The novelty bonus is awarded separately once per quarter; if yours is chosen, the bonus will be issued after the quarterly review.
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, and as soon as you submit the vulnerability details via the form.
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 (_)
ltsIf there is a conflicting submission (e.g. you are only submitting a novel technique), then append _2 (or _3, etc.) after the directory name.
For example: pocs/linux/kernelctf/CVE-2023-1872_lts/.
The structure of this submission folder should be:
original.tar.gz
metadata.json
docs/vulnerability.md
docs/exploit.md
docs/novel-techniques.md
exploit/lts-6.x.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.
kernelCTF submissions from 2025-10-23 have to use the kernelXDK (Kernel eXploit Development Kit, read more here: xdk.dev) in the Github PR.
This requirement only affects submissions whose “Flag submission time” column on the public spreadsheet contains a date newer than 2025-10-23T00:00:00Z. Older submissions don’t have to use the kernelXDK even if the PR is submitted after 2025-10-23.
The exploit used on our server to capture the flag does not have to use the kernelXDK.
kernelXDK is a toolset which aims to help in creating “universal” exploits that can be easily ported between various kernel versions. In its current form, it decouples target-specific information (symbol offsets, ROP gadgets, structure, field information) from the exploit itself, thereby can make (some) exploits target-independent. This approach allows us to easily introduce new targets for kernelCTF without the need to manually port existing exploits to new targets.
We ask you to compile our libxdk library into your exploit and if a feature which you use in your exploit also exists in the latest libxdk release, then you have to use it.
For example: if your exploit uses ROP, then use libxdk to generate the stack pivot and ROP chain (the libxdk will detect the kernelCTF target the exploit runs on and generate the right primitives for that). Similarly for example you should not hardcode symbol and structure offsets into your exploit but use the library’s functions like GetSymbolOffset to get the right offset. If your exploit does not use ROP (e.g. it’s data-only), then of course you don’t have to rewrite your exploit to use ROP.
To help understand the difference between a traditional exploit and a kernelXDK-based one, take a look at the how-to guide and this guide on how sample, traditional exploit was ported to one which uses libxdk library. Other converted samples can be found in the libxdk’s source code.
The reproduction environment on Github has the kernelXDK pre-installed, you just have to compile your exploit as C++ and with the library linked (-lkernelXDK).
If you are exploiting multiple targets where the exploits are identical, feel free to just symlink the exploit folders (e.g. ln -s exploit/lts-6.1.36 exploit/<other_target>) instead of submitting the same files multiple times.
If you have any questions regarding the usage of kernelXDK, use the #kernelxdk Discord channel. You can report bugs on Github.
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; passing this flag should trigger the vulnerability on a KASAN build. To ensure the submission runs within the vuln-verify workflow time limits, this mode should also skip unnecessary steps, such as KASLR prefetch.
We announce program changes through #kernelctf-announcements Discord channel. All major changes are going to be announced 1 month 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.