Skip to content

Conversation

pvts-mat
Copy link
Contributor

@pvts-mat pvts-mat commented Sep 18, 2025

[LTS 8.6]
CVE-2022-25265
VULN-3787

Problem

The problem associated with CVE-2022-25265 doesn't seem to be presented clearly, or at least it's not clear how the clearly presented behavior is a problem, let alone how the solution for it should look like.

The CVE.org and NIST say

In the Linux kernel through 5.16.10, certain binary files may have the exec-all attribute if they were built in approximately 2003 (e.g., with GCC 3.2.2 and Linux kernel 2.4.20). This can cause execution of bytes located in supposedly non-executable regions of a file.

The "references" list contains a github project https://github.com/x0reaxeax/exec-prot-bypass with a POC and a link to the kernel commit 1c33bb0. What's important, this commit is not a bugfix, and neither a bug source. In fact, it doesn't seem related to the problem at all, being probably just the latest revision of the arch/x86/include/asm/elf.h file at the time of linking it by the POC author.

The POC on github is a C program, which, when compiled in a specific environment (ancient versions of gcc and kernel) is able to, when run on a current kernel, execute its own data block, which in principle should not be possible.

The cited header fragment documents kernel's behavior when dealing with an ELF file without a PT_GNU_STACK segment:

/*
* An executable for which elf_read_implies_exec() returns TRUE will
* have the READ_IMPLIES_EXEC personality flag set automatically.
*
* The decision process for determining the results are:
*
* CPU: | lacks NX* | has NX, ia32 | has NX, x86_64 |
* ELF: | | | |
* ---------------------|------------|------------------|----------------|
* missing PT_GNU_STACK | exec-all | exec-all | exec-none |
* PT_GNU_STACK == RWX | exec-stack | exec-stack | exec-stack |
* PT_GNU_STACK == RW | exec-none | exec-none | exec-none |
*
* exec-all : all PROT_READ user mappings are executable, except when
* backed by files on a noexec-filesystem.
* exec-none : only PROT_EXEC user mappings are executable.
* exec-stack: only the stack and PROT_EXEC user mappings are executable.
*
* *this column has no architectural effect: NX markings are ignored by
* hardware, but may have behavioral effects when "wants X" collides with
* "cannot be X" constraints in memory permission flags, as in
* https://lkml.kernel.org/r/[email protected]
*
*/

The POC targets the exec-all cases (first row, first and second column), as mentioned in the README:

As it turns out, binary files built on either systems lacking NX or IA32 systems with NX, which do NOT contain the PT_GNU_STACK header will be marked with exec-all.
This allows for complete RWX to/from everywhere in the binary.

As such the POC simply showcases a feature introduced at the very beginning of repository in 1da177e

/*
* An executable for which elf_read_implies_exec() returns TRUE will
* have the READ_IMPLIES_EXEC personality flag set automatically.
*/
#define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X)

documented in 9d9e435 and explained in 1223061:

x86/elf: Split READ_IMPLIES_EXEC from executable PT_GNU_STACK

The READ_IMPLIES_EXEC workaround was designed for old toolchains that
lacked the ELF PT_GNU_STACK marking under the assumption that toolchains
that couldn't specify executable permission flags for the stack may not
know how to do it correctly for any memory region.

This logic is sensible for having ancient binaries coexist in a system
with possibly NX memory, but was implemented in a way that equated having
a PT_GNU_STACK marked executable as being as "broken" as lacking the
PT_GNU_STACK marking entirely. Things like unmarked assembly and stack
trampolines may cause PT_GNU_STACK to need an executable bit, but they
do not imply all mappings must be executable.

This confusion has led to situations where modern programs with explicitly
marked executable stacks are forced into the READ_IMPLIES_EXEC state when
no such thing is needed. (And leads to unexpected failures when mmap()ing
regions of device driver memory that wish to disallow VM_EXEC[1].)

In looking for other reasons for the READ_IMPLIES_EXEC behavior, Jann
Horn noted that glibc thread stacks have always been marked RWX (until
2003 when they started tracking the PT_GNU_STACK flag instead[2]). And
musl doesn't support executable stacks at all[3]. As such, no breakage
for multithreaded applications is expected from this change.

[1] https://lkml.kernel.org/r/[email protected]
[2] https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=54ee14b3882
[3] https://lkml.kernel.org/r/[email protected]

It's not clear whether it's even a vulnerability, and in case it is, it's not clear whether solving it is the reponsibility of the kernel providers (changing the permissions policy for ELFs without PT_GNU_STACK?) or the providers of binaries in the repositories of a distribution (simply making sure they aren't compiled with ancient tools which they certainly aren't anyway?). In case of the former the official "fix" doesn't exist, so it would have to be handcrafted.

For reference:

  • Debian's security response:

    Not considered a security flaw. If desired because no need for backward compatibility
    can be mitigated through a LSM.

  • Ubuntu's security response:

    this is in place so that ancient binaries will continue to work; if an attacker can link a modern binary to allow this, they could just create and execute a binary. need to validate that we don’t ever ship binaries without GNU_PT_STACK

  • Suse's security response:

    verified that this does not affect any of the binaries we build currently. I think it is safe to close as invalid.

    this seems to be really a non-issue…

    while we are not blocking this binaries, we do not have any and if someone can inject binaries he can just inject a normal one.

Considering all of the above the proposed solution is to mark CVE-2022-25265 for LTS 8.6 Rocky version as "won't fix".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant