Skip to content

Add kernelCTF CVE-2025-39964_lts_cos_mitigation#265

Open
st424204 wants to merge 13 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 13 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.

Copy link
Contributor

Choose a reason for hiding this comment

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

explained in recent changes

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

explained in recent changes

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)

Copy link
Contributor

Choose a reason for hiding this comment

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

explained in recent changes

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

removed

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).

Copy link
Contributor

Choose a reason for hiding this comment

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

explained in recent changes

@@ -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
Contributor

Choose a reason for hiding this comment

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

removed

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

removed

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

explained in recent changes

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

updated


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.

Copy link
Contributor

Choose a reason for hiding this comment

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

removed

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

updated

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

fixed

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

fixed

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

fixed


// 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.

Copy link
Contributor

Choose a reason for hiding this comment

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

fixed

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

done

@st424204 st424204 force-pushed the CVE-2025-39964_lts_cos_mitigation_fixed branch from 8ea1847 to 2592f76 Compare February 25, 2026 08:12
d4em0n and others added 5 commits February 25, 2026 17:09
- Add KERNEL_TEXT_BASE macro (0xffffffff81000000UL) and use it in all
  CORE_PATTERN_*_OFFSET definitions instead of the raw literal
- Add SCAN_END_ADDR (0x500000000000ULL) and MAP_CHUNK_SIZE (0x80000000ULL)
  macros; replace all raw values in allocate_map() and the binary search
- Add PAGE_SIZE / PAGE_MASK macros; use in adjust_offset calculation and
  the page-aligned delta expression (~0xfff -> ~PAGE_MASK)
- Replace 6 duplicate system("cat /flag") calls with a for loop
- Rename job() -> spray_send_thread(), do_spray() -> spray_unix_sockets()
  for descriptiveness; apply consistently to all three targets
- Fix remaining raw 0x100 -> THREAD_NUM in Step 4 release loop
- Use MITIGATION_PHYSMAP_EXTRA_OFFSET macro (already defined) instead of
  the raw (0x100000000ULL >> 6) literal in mitigation-v4-6.6
- Add explanatory comment on global buf (intentionally shared across threads)
- Fix "Exploit chain (LTS 6.12.44)" header in COS and mitigation files
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