Skip to content

Add kernelCTF CVE-2025-39964_lts_cos_mitigation#265

Open
st424204 wants to merge 10 commits intogoogle:masterfrom
star-sg:CVE-2025-39964_lts_cos_mitigation_fixed
Open

Add kernelCTF CVE-2025-39964_lts_cos_mitigation#265
st424204 wants to merge 10 commits intogoogle:masterfrom
star-sg:CVE-2025-39964_lts_cos_mitigation_fixed

Conversation

@st424204
Copy link
Contributor

No description provided.

@st424204 st424204 force-pushed the CVE-2025-39964_lts_cos_mitigation_fixed branch from f6f4806 to 2aa25ad Compare October 14, 2025 05:21
@st424204 st424204 force-pushed the CVE-2025-39964_lts_cos_mitigation_fixed branch from 2aa25ad to 6b5e504 Compare October 14, 2025 05:37
@koczkatamas koczkatamas added the kCTF: vuln OK The submission exploits the claims vulnerability (passed manual verification) label Oct 15, 2025
@koczkatamas
Copy link
Collaborator

koczkatamas commented Oct 15, 2025

I verified the exploit, the writeup was good enough, but mapping the steps to the exploit code was not trivial to me, to see where the different steps happening:

  1. the loop with 0x7b + the sendmsg and send calls are executing 125 times which matches with MAX_SGL_ENTS - 1 as MAX_SGL_ENTS is ((4096 - sizeof(struct af_alg_tsgl)) / sizeof(struct scatterlist) - 1) so (4096-24)/32-1 = 126.

  2. send(opfd, buf, 0x200, MSG_MORE); is probably

Let say we send len below the PAGE_SIZE, so ctx->merge will set to 1, then this thread will finish.

  1. send(opfd, (void *)0xfff000, 0x400, MSG_MORE); is probably

Now sgl->cur is MAX_SGL_ENTS, it will alloc another sgl at af_alg_alloc_tsgl [3], so we have last sgl that have sgl->cur = 0. In this state, we passed invalid user space addr. So code will fail in this line

Next time try to include in the exploit which call does which steps, otherwise we may stop verification and ask you for changes first which will make the payout process slower.

@koczkatamas koczkatamas added the recheck Triggers kernelCTF PR verification again label Jan 15, 2026
Copy link
Collaborator

@koczkatamas koczkatamas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments along the line, please explain the exploit in more detail, I stopped reviewing because it was hard to follow what's going on exactly.

Make sure you follow the style guide: https://google.github.io/security-research/kernelctf/style_guide

};
```

If sgl is at address 0, sgl->sg[-1] will be at -8 (24-32), so we can use previous chunk's content to control `page_link`, but `offset` and `length` is not controllable.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explain this part (everything from here until the end of the writeup) in more depth, it's hard to follow that's going on exactly.

xcnt++;
oracle = *(size_t *)&payload[0xff8];
char *start = (void *)(0ULL);
// test guess is first/second half
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explain the whole logic better behind the binary search, what's going on exactly, how the oracle works, etc.

read(cfd[1], buf, 1);
}

*(size_t *)&payload[0xff8] += (((core_pattern & ~0xfff) - (leak_offset & ~0xfff)) >> 6);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's at offset 0xff8? (-8)

else
stext = bypass_kaslr(0);
core_pattern = 0xffffffff8420dde0;
core_pattern = 0xffffffff8420e260;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unnecessary lines.

char *start = (void *)0x100000000ULL;
while (1)
{
start = SYSCHK(mmap(start, 0x80000000ULL, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON | MAP_FIXED, -1, 0));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explain more about this allocation (why chose the size 0x80000000ULL, etc).

@@ -0,0 +1,8 @@
#LTS/COS
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need these RUN files? It seems core_pattern is also specified in the source code as well.

Copy link
Collaborator

@koczkatamas koczkatamas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've asked our friendly AI to review your exploits based on our style guide and here are its recommendations to guide your fixing.

We manually checked the findings, but it can still contain mistakes, please double-check it and feel free to push back if you think it's wrong.

Please take a look below.

#endif

pthread_t tid[0x100];
pthread_t tid2[0x100];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused array tid2 clutters the global scope.

Recommendation: Remove the unused array declaration.

AI-suggested fix (do not apply blindly, but can be helpful for inspiration): remove the line.

Read more about this violation in the 'Unused code' section of the style guide.

This comment is AI-generated. Although it was manually checked, it can still contain mistakes, please double-check it and feel free to push back if you think it's wrong.

pthread_t tid[0x100];
pthread_t tid2[0x100];

char buf[0x10000];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a global variable for a generic temporary buffer instead of localized buffers.

Recommendation: Move the buffer to the local scope of the functions that require it.

AI-suggested fix (do not apply blindly, but can be helpful for inspiration):

char buf[0x10000]; // moved inside main2 or job function

Read more about this violation in the 'Usage of global variables instead of local ones' section of the style guide.

This comment is AI-generated. Although it was manually checked, it can still contain mistakes, please double-check it and feel free to push back if you think it's wrong.

char vec[0x100000];

int cfd[2];
int sfd[0x200][2];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mismatch between the allocated array size (0x200) and actual usage (0x100).

Recommendation: Change the allocation size to match the exact number of threads used.

AI-suggested fix (do not apply blindly, but can be helpful for inspiration):

int sfd[THREAD_NUM][2];

Read more about this violation in the 'Match iteration count for allocation, creation and usage' section of the style guide.

This comment is AI-generated. Although it was manually checked, it can still contain mistakes, please double-check it and feel free to push back if you think it's wrong.


int cfd[2];
int sfd[0x200][2];
int sfd2[0x200][2];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused array sfd2 is present in the code.

Recommendation: Remove the unused array declaration.

AI-suggested fix (do not apply blindly, but can be helpful for inspiration): remove the line.

Read more about this violation in the 'Unused code' section of the style guide.

This comment is AI-generated. Although it was manually checked, it can still contain mistakes, please double-check it and feel free to push back if you think it's wrong.

char payload[0x1000];
int opfd;

#define LEN 0x1000 / 8 * 0x1000
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generic macro name used for a length constant.

Recommendation: Rename it to something more descriptive like MMAP_REGION_LEN.

AI-suggested fix (do not apply blindly, but can be helpful for inspiration):

#define MMAP_REGION_LEN (0x1000 / 8 * 0x1000)

Read more about this violation in the 'Naming conventions' section of the style guide.

This comment is AI-generated. Although it was manually checked, it can still contain mistakes, please double-check it and feel free to push back if you think it's wrong.

Comment on lines +275 to +280
system("cat /flag");
system("cat /flag");
system("cat /flag");
system("cat /flag");
system("cat /flag");
system("cat /flag");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repeating lines of modification or execution requires explanation to prove it is not a typo and to document its purpose.

Recommendation: Either wrap the code in a loop or leave a comment explicitly stating the reason for executing it six times.

AI-suggested fix (do not apply blindly, but can be helpful for inspiration):

// Repeatedly execute cat /flag to ensure success before panic for (int i = 0; i < 6; i++) { system("cat /flag"); }

Read more about this violation in the 'Explain duplicated lines' section of the style guide.

This comment is AI-generated. Although it was manually checked, it can still contain mistakes, please double-check it and feel free to push back if you think it's wrong.

wait(NULL);
}
}
int main2()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exploit staging functions must be named descriptively to inform the reader about the steps taking place.

Recommendation: Rename the function to something descriptive like execute_cross_cache_exploit.

AI-suggested fix (do not apply blindly, but can be helpful for inspiration):

int execute_cross_cache_exploit()

Read more about this violation in the 'Naming conventions' section of the style guide.

This comment is AI-generated. Although it was manually checked, it can still contain mistakes, please double-check it and feel free to push back if you think it's wrong.

printf("init %ld\n", n);
// PAUSE;

for (int i = 0; i < 0x7b; i++)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Numeric constants determining counts and iteration constraints must be named and/or commented.

Recommendation: Define a macro or provide a comment explaining what the limit 0x7b achieves.

Read more about this violation in the 'Name and/or comment numeric constants' section of the style guide.

This comment is AI-generated. Although it was manually checked, it can still contain mistakes, please double-check it and feel free to push back if you think it's wrong.


// PAUSE;

sleep(1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every sleep() call must feature a comment explaining what background kernel task it waits for.

Recommendation: Add a descriptive sleep comment explaining the delay trigger.

AI-suggested fix (do not apply blindly, but can be helpful for inspiration):

// @sleep(desc="Wait for network operation to complete handling before advancing") sleep(1);

Read more about this violation in the 'Sleeping & waiting' section of the style guide.

This comment is AI-generated. Although it was manually checked, it can still contain mistakes, please double-check it and feel free to push back if you think it's wrong.

read(sfd[i][0], buf, 0x1000);
read(cfd[1], buf, 1);
}
*(size_t *)&payload[0xff8] -= (0x500000000000ULL >> 6);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applying complex arithmetic using hardcoded sizes and magic offsets into raw buffers is strictly discouraged.

Recommendation: Use a struct layout or defined macros for offsets and size constants.

AI-suggested fix (do not apply blindly, but can be helpful for inspiration):

#define MAGIC_GUESS_ADJUST 0x500000000000ULL #define PAYLOAD_OVERLAP_OFFS 0xff8 *(size_t *)&payload[PAYLOAD_OVERLAP_OFFS] -= (MAGIC_GUESS_ADJUST >> 6);

Read more about this violation in the 'Sprayed and leaked structures' section of the style guide.

This comment is AI-generated. Although it was manually checked, it can still contain mistakes, please double-check it and feel free to push back if you think it's wrong.

@st424204 st424204 force-pushed the CVE-2025-39964_lts_cos_mitigation_fixed branch from 8ea1847 to 2592f76 Compare February 25, 2026 08:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kCTF: vuln OK The submission exploits the claims vulnerability (passed manual verification) recheck Triggers kernelCTF PR verification again

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants