8000 gh-128605: Add branch protections for x86_64 in asm_trampoline.S by stratakis · Pull Request #128606 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-128605: Add branch protections for x86_64 in asm_trampoline.S #128606

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 3, 2025

Conversation

stratakis
Copy link
Contributor
@stratakis stratakis commented Jan 8, 2025

@stratakis
Copy link
Contributor Author

cc @fweimer-rh

@stratakis
Copy link
Contributor Author

In the current implementation the cf-protection test for x86_64 passes but not the branch-protection test for aarch64.

@fweimer-rh
Copy link

You should add PAC support at the same time, using hint 25 (paciasp, replaces bti c) and hint 29 (autiasp). These instructions are in the NOP space, but some CPUs have trouble executing them. This applies to bit c as well. So it's best to make this conditional on compiler flags, by checking the __ARM_FEATURE_BTI_DEFAULT preprocessor macro. Then you can change the flag at the end of the note from 1 to 3, and this should make annocheck happy.

@stratakis
Copy link
Contributor Author

Rebased. The conditionals are a bit of a mess right now so I'll do some macros later on.

However annobin still reports:

Hardened: libpython3.12.so.1.0: FAIL: dynamic-tags test because the BTI_PLT flag is missing from the dynamic tags
Hardened: libpython3.12.so.1.0: FAIL: property-note test because properly formatted .note.gnu.property not found (it is needed for branch protection support)

Btw the arm blog proposes a different styled note than what the annobin docs mention: https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/p2-enabling-pac-and-bti-on-aarch64

Also regarding x86_64. Shouldn't the note be conditionalized in the case CET is active?

@stratakis
Copy link
Contributor Author

cc'ing also @pablogsal as the original author of the file.

@pablogsal pablogsal added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Jan 13, 2025
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @pablogsal for commit 549b894 🤖

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Jan 13, 2025
Copy link
Member
@pablogsal pablogsal left a comment

Choose a reason for hiding this comment

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

This will break the DWARF mode as the debug information we are adding matches exactly with the current assembly instructions and positions:

/* Emit DWARF EH CIE. */
DWRF_SECTION(CIE, DWRF_U32(0); /* Offset to CIE itself. */
DWRF_U8(DWRF_CIE_VERSION);
DWRF_STR("zR"); /* Augmentation. */
DWRF_UV(1); /* Code alignment factor. */
DWRF_SV(-(int64_t)sizeof(uintptr_t)); /* Data alignment factor. */
DWRF_U8(DWRF_REG_RA); /* Return address register. */
DWRF_UV(1);
DWRF_U8(DWRF_EH_PE_pcrel | DWRF_EH_PE_sdata4); /* Augmentation data. */
DWRF_U8(DWRF_CFA_def_cfa); DWRF_UV(DWRF_REG_SP); DWRF_UV(sizeof(uintptr_t));
DWRF_U8(DWRF_CFA_offset|DWRF_REG_RA); DWRF_UV(1);
DWRF_ALIGNNOP(sizeof(uintptr_t));
)
ctx->eh_frame_p = p;
/* Emit DWARF EH FDE. */
DWRF_SECTION(FDE, DWRF_U32((uint32_t)(p - framep)); /* Offset to CIE. */
DWRF_U32(-0x30); /* Machine code offset relative to .text. */
DWRF_U32(ctx->code_size); /* Machine code length. */
DWRF_U8(0); /* Augmentation data. */
/* Registers saved in CFRAME. */
#ifdef __x86_64__
DWRF_U8(DWRF_CFA_advance_loc | 4);
DWRF_U8(DWRF_CFA_def_cfa_offset); DWRF_UV(16);
DWRF_U8(DWRF_CFA_advance_loc | 6);
DWRF_U8(DWRF_CFA_def_cfa_offset); DWRF_UV(8);
/* Extra registers saved for JIT-compiled code. */
#elif defined(__aarch64__) && defined(__AARCH64EL__) && !defined(__ILP32__)
DWRF_U8(DWRF_CFA_advance_loc | 1);
DWRF_U8(DWRF_CFA_def_cfa_offset); DWRF_UV(16);
DWRF_U8(DWRF_CFA_offset | 29); DWRF_UV(2);
DWRF_U8(DWRF_CFA_offset | 30); DWRF_UV(1);
DWRF_U8(DWRF_CFA_advance_loc | 3);
DWRF_U8(DWRF_CFA_offset | -(64 - 29));
DWRF_U8(DWRF_CFA_offset | -(64 - 30));
DWRF_U8(DWRF_CFA_def_cfa_offset);
DWRF_UV(0);

I am also not sure why this is needed other than make the annocheck tool happy so I am not sure we want to add this extra complexity.

@bedevere-app
Copy link
bedevere-app bot commented Jan 13, 2025

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@stratakis
Copy link
Contributor Author

I am also not sure why this is needed other than make the annocheck tool happy so I am not sure we want to add this extra complexity.

The justification for this change is provided at the linked issue.

@pablogsal
Copy link
Member
pablogsal commented Jan 13, 2025

I am also not sure why this is needed other than make the annocheck tool happy so I am not sure we want to add this extra complexity.

The justification for this change is provided at the linked issue.

I don't think that justification is enough. The only thing the issue mentioned is that we are not using a feature and that the annocheck is unhappy. Could you ellaborate what are the consequences of not adding these instructions?

In any case, we need to check if the DWARF needs to be updated to account for the new instructions and if GDB can still unwind across them.

@stratakis
Copy link
Contributor Author

I don't think that justification is enough. The only thing the issue mentioned is that we are not using a feature and that the annocheck is unhappy. Could you ellaborate what are the consequences of not adding these instructions?

Of course. Both ubuntu and Fedora (and by extension RHEL) and I assume other distros, enable by default the -fcf-protection flag for x86_64 and -mbranch-protection=standard for aarch64. When these flags are applied, the compiler places those instructions at the appropriate places when the CPU supports them and a NOP when it doesn't.

Both are implemented to mitigate return-oriented programming (ROP) and Call or Jump Oriented Programming (COP/JOP) attacks.

Minimum supported CPU models are Intel's Tiger lake, AMD's Zen 3, Arm 8.3 (PAC) and Arm 8.5 (BTI).

With pure C code everything is fine by just using the compiler 8000 flag(s), however when an assembly file is added to the mix the instructions need to be added manually.

This feature is an all-or-nothing for the hardware functionality to work. All object files are checked for the note and if it's missing on any one, the linker does not place the note to the final executable and the hardening feature is disabled in the hardware. That essentially means that for Python 3.12+ these flags have no effect anymore.

@stratakis stratakis force-pushed the branch_protection branch 2 times, most recently from a7408db to 6d2d4f7 Compare January 14, 2025 02:39
@pablogsal
Copy link
Member

Ok makes sense. Thanks a lot for the extra context.

We need to complement the DWARF information to ensure that the Perf JIT integration still works and we need to ensure gdb can still unwind through the trampolines when this information is active.

@brandtbucher
Copy link
Member

This feature is an all-or-nothing for the hardware functionality to work. All object files are checked for the note and if it's missing on any one, the linker does not place the note to the final executable and the hardening feature is disabled in the hardware. That essentially means that for Python 3.12+ these flags have no effect anymore.

Are JIT compilers expected to implement this as well? Or no, since they aren't statically present in the executable?

@pablogsal
Copy link
Member
pablogsal commented Jan 14, 2025

This feature is an all-or-nothing for the hardware functionality to work. All object files are checked for the note and if it's missing on any one, the linker does not place the note to the final executable and the hardening feature is disabled in the hardware. That essentially means that for Python 3.12+ these flags have no effect anymore.

Are JIT compilers expected to implement this as well? Or no, since they aren't statically present in the executable?

Technically this code is also not present in the executable: we copy it from memory but the region itself where we copy it from is never executed. So if the answer is "no" then we shouldn't need this either

@stratakis
Copy link
Contributor Author

Ok makes sense. Thanks a lot for the extra context.

We need to complement the DWARF information to ensure that the Perf JIT integration still works and we need to ensure gdb can still unwind through the trampolines when this information is active.

Providing also a more practical reproducer.

On Python 3.11 on x86_64:

$ ./configure && make -j10 CFLAGS=-fcf-protection
$ readelf -n python

Properties: x86 feature: IBT, SHSTK

Both of those flags indicate that CET protection is enabled. In Python 3.12+ they are not present.

Of course when building with --enable-shared libpython needs to be inspected instead.

I'll familiarize myself with the debug information and try to figure it out.

@stratakis
Copy link
Contributor Author

This feature is an all-or-nothing for the hardware functionality to work. All object files are checked for the note and if it's missing on any one, the linker does not place the note to the final executable and the hardening feature is disabled in the hardware. That essentially means that for Python 3.12+ these flags have no effect anymore.

Are JIT compilers expected to implement this as well? Or no, since they aren't statically present in the executable?

The answer here would be possibly yes, assembly instructions emitted by JITs should implement that, however I am not familiar myself with JITs in general or the way CPython implements it to provide a definite answer. As JIT is still being developed I'd treat this as an afterthought and revisit it in the future.

@fweimer-rh
Copy link

Ok makes sense. Thanks a lot for the extra context.

We need to complement the DWARF information to ensure that the Perf JIT integration still works and we need to ensure gdb can still unwind through the trampolines when this information is active.

@pablogsal As the DWARF needs to be updated anyway, it may make sense to add the missing frame pointer to the x86-64 assembler (if Python's policy is to have frame pointers). Or is the goal to elide the calling frame from profiling backtraces? If the latter, there should really be a comment to this effect.

@fweimer-rh
Copy link

Are JIT compilers expected to implement this as well? Or no, since they aren't statically present in the executable?

@brandtbucher For JIT compilers to keep working unchanged, they need to be marked as incompatible for now. On x86-64, SHSTK is generally automatically compatible with JIT compilation unless stack unwinding code is generated. However, x86-64 IBT requires marker instructions at the target of indirect branches. On AArch64, BTI is similar (marker instructions), but PAC is not process-switched on Linux: it's determined at boot whether it is turned on or not. The presence of the extra instructions merely ensures that the JIT code does not contain any easy-to-use JOP/ROP gadgets.

Whether any of this matters is of course debatable, assuming that Python does not write-protect any of its bytecode in the process image.

@pablogsal
Copy link
Member

Ok makes sense. Thanks a lot for the extra context.

We need to complement the DWARF information to ensure that the Perf JIT integration still works and we need to ensure gdb can still unwind through the trampolines when this information is active.

@pablogsal As the DWARF needs to be updated anyway, it may make sense to add the missing frame pointer to the x86-64 assembler (if Python's policy is to have frame pointers). Or is the goal to elide the calling frame from profiling backtraces? If the latter, there should really be a comment to this effect.

One of the problems is that if you add the frame pointer to the x86-64 assembler gdb cannot unwind through this when Python is compiled without frame pointers. The current version allows unwinding with and without frame pointers.

@brandtbucher
Copy link
Member

@brandtbucher For JIT compilers to keep working unchanged, they need to be marked as incompatible for now. On x86-64, SHSTK is generally automatically compatible with JIT compilation unless stack unwinding code is generated. However, x86-64 IBT requires marker instructions at the target of indirect branches. On AArch64, BTI is similar (marker instructions), but PAC is not process-switched on Linux: it's determined at boot whether it is turned on or not. The presence of the extra instructions merely ensures that the JIT code does not contain any easy-to-use JOP/ROP gadgets.

Whether any of this matters is of course debatable, assuming that Python does not write-protect any of its bytecode in the process image.

I'm afraid this is a bit too jargon-heavy for me to follow without doing a bunch of self-guided research on the topic.

What does it mean for the JIT code to be "marked incompatible"? I take it that if the process/kernel has these hardware features enabled, JIT code that doesn't use it will probably crash? What's the typical performance overhead of enabling this, and who exactly is using it (Ubuntu and Fedora were mentioned above... is it all users of these distros who would be unable to use our JIT)?

@miss-islington-app
Copy link

Thanks @stratakis for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.12, 3.13, 3.14.
🐍🍒⛏🤖

@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot AMD64 Debian root 3.x (tier-1) has failed when building commit 485b499.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/345/builds/11525) and take a look at the build logs.
  4. Check if the failure is related to this commit (485b499) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/#/builders/345/builds/11525

Failed tests:

  • test.test_concurrent_futures.test_process_pool
  • test_cmd
  • test_difflib
  • test_buffer
  • test_zipapp
  • test_peg_generator
  • test_ucn
  • test_optparse
  • test_codecencodings_kr
  • test_statistics

Failed subtests:

  • test_html_diff - test.test_difflib.TestSFpatches.test_html_diff
  • test_ternary_operator - test.test_peg_generator.test_c_parser.TestCParser.test_ternary_operator
  • test_memoryview_cast_invalid - test.test_buffer.TestBufferProtocol.test_memoryview_cast_invalid
  • test_map_exception - test.test_concurrent_futures.test_process_pool.ProcessPoolForkserverProcessPoolExecutorTest.test_map_exception

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/test_peg_generator/test_c_parser.py", line 413, in test_ternary_operator
    self.run_test(grammar_source, test_source)
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/test_peg_generator/test_c_parser.py", line 136, in run_test
    assert_python_ok(
    ~~~~~~~~~~~~~~~~^
        "-c",
        ^^^^^
        TEST_TEMPLATE.format(extension_path=self.tmp_path, test_source=test_source),
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/support/script_helper.py", line 182, in assert_python_ok
    return _assert_python(True, *args, **env_vars)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/support/script_helper.py", line 167, in _assert_python
    res.fail(cmd_line)
    ~~~~~~~~^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/support/script_helper.py", line 80, in fail
    raise AssertionError(f"Process return code is {exitcode}\n"
    ...<10 lines>...
                         f"---")
AssertionError: Process return code is -6 (SIGABRT)
command line: ['/root/buildarea/3.x.angelico-debian-amd64/build/python', '-X', 'faulthandler', '-I', '-c', '\ntmp_dir = \'/root/buildarea/3.x.angelico-debian-amd64/build/build/test_python_1500507æ/tmpf33ta7nm\'\n\nimport ast\nimport traceback\nimport sys\nimport unittest\n\nfrom test import test_tools\nwith test_tools.imports_under_tool("peg_generator"):\n    from pegen.ast_dump import ast_dump\n\nsys.path.insert(0, tmp_dir)\nimport parse\n\nclass Tests(unittest.TestCase):\n\n    def check_input_strings_for_grammar(\n        self,\n        valid_cases = (),\n        invalid_cases = (),\n    ):\n        if valid_cases:\n            for case in valid_cases:\n                parse.parse_string(case, mode=0)\n\n        if invalid_cases:\n            for case in invalid_cases:\n                with self.assertRaises(SyntaxError):\n                    parse.parse_string(case, mode=0)\n\n    def verify_ast_generation(self, stmt):\n        expected_ast = ast.parse(stmt)\n        actual_ast = parse.parse_string(stmt, mode=1)\n        self.assertEqual(ast_dump(expected_ast), ast_dump(actual_ast))\n\n    def test_parse(self):\n        \n        stmt = "[i for i in a if b]"\n        self.verify_ast_generation(stmt)\n\n\nunittest.main()\n']


Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/runpy.py", line 198, in _run_module_as_main
    return _run_code(code, main_globals, None,
                     "__main__", mod_spec)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/runpy.py", line 88, in _run_code
    exec(code, run_globals)
    ~~~~^^^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/libregrtest/worker.py", line 6, in <module>
    from test.support import os_helper, Py_DEBUG
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/support/__init__.py", line 6, in <module>
    import annotationlib
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/annotationlib.py", line 22, in <module>
    class Format(enum.IntEnum):
    ...<3 lines>...
        STRING = 4
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/annotationlib.py", line 22, in Format
    class Format(enum.IntEnum):
    
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/enum.py", line 350, in __setitem__
    if self._cls_name is not None and _is_private(self._cls_name, key):
                                      ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
TypeError: 'str' object is not callable


Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/test_concurrent_futures/util.py", line 54, in setUp
    self.manager = self.get_context().Manager()
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/context.py", line 57, in Manager
    m.start()
    ~~~~~~~^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/managers.py", line 570, in start
    self._address = reader.recv()
                    ~~~~~~~~~~~^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/connection.py", line 256, in recv
    buf = self._recv_bytes()
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/connection.py", line 447, in _recv_bytes
    buf = self._recv(4)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/connection.py", line 416, in _recv
    raise EOFError
EOFError


Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/test_difflib.py", line 236, in test_html_diff
    k.make_table(f3.splitlines(True),t3.splitlines(True)),
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/difflib.py", line 2017, in make_table
    fromlist,tolist,flaglist = self._collect_lines(diffs)
                               ~~~~~~~~~~~~~~~~~~~^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/difflib.py", line 1885, in _collect_lines
    for fromdata,todata,flag in diffs:
                                ^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/difflib.py", line 1852, in _line_wrapper
    for fromdata,todata,flag in diffs:
                                ^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/difflib.py", line 1568, in _mdiff
    yield from line_pair_iterator
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/difflib.py", line 1552, in _line_pair_iterator
    from_line, to_line, found_diff = next(line_iterator)
                                     ~~~~^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/difflib.py", line 1466, in _line_iterator
    lines.append(next(diff_lines_iterator, 'X'))
                 ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/difflib.py", line 872, in compare
    yield from g
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/difflib.py", line 960, in _fancy_replace
    for tag, ai1, ai2, bj1, bj2 in cruncher.get_opcodes():
                                   ~~~~~~~~~~~~~~~~~~~~^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/difflib.py", line 525, in get_opcodes
    for ai, bj, size in self.get_matching_blocks():
                        ~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/difflib.py", line 489, in get_matching_blocks
    self.matching_blocks = list(map(Match._make, non_adjacent))
                           ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/collections/__init__.py", line 456, in _make
    if _len(result) != num_fields:
       ~~~~^^^^^^^^
TypeError: object of type 'type' has no len()


Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/test_buffer.py", line 2604, in test_memoryview_cast_invalid
    for dfmt, _, _ in iter_format(1):
                      ~~~~~~~~~~~^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/test_buffer.py", line 233, in iter_format
    for t in iter_mode(nitems, testobj):
             ~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/test_buffer.py", line 228, in iter_mode
    yield randitems(n, obj, mode, char)
          ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/test_buffer.py", line 219, in randitems
    items = gen_items(n, fmt, obj)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/test_buffer.py", line 194, in gen_items
    lst[i] = gen_item(fmt, obj)
             ~~~~~~~~^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/test_buffer.py", line 185, in gen_item
    x.append(randrange_fmt(mode, c, obj))
             ~~~~~~~~~~~~~^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/test_buffer.py", line 167, in randrange_fmt
    x = randrange(*fmtdict[mode][char])
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/random.py", line 321, in randrange
    return istart + self._randbelow(width)
                    ~~~~~~~~~~~~~~~^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/random.py", line 249, in _randbelow_with_getrandbits
    r = self.getrandbits(k)  # 0 <= r < 2**k
TypeError: 'Random' object cannot be interpreted as an integer

@ambv ambv added needs backport to 3.12 only security fixes needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes and removed needs backport to 3.12 only security fixes needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes labels Jun 3, 2025
@miss-islington-app
Copy link

Thanks @stratakis for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.12.
🐍🍒⛏🤖

@miss-islington-app
Copy link

Thanks @stratakis for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.14.
🐍🍒⛏🤖

@miss-islington-app
Copy link

Thanks @stratakis for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13.
🐍🍒⛏🤖

@miss-islington-app
Copy link

Sorry, @stratakis and @vstinner, I could not cleanly backport this to 3.12 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 485b499610eefe362faf171f258b3a3588378ff1 3.12

@miss-islington-app
Copy link

Sorry, @stratakis and @vstinner, I could not cleanly backport this to 3.14 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 485b499610eefe362faf171f258b3a3588378ff1 3.14

@miss-islington-app
Copy link

Sorry, @stratakis and @vstinner, I could not cleanly backport this to 3.13 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 485b499610eefe362faf171f258b3a3588378ff1 3.13

@vstinner
Copy link
Member
vstinner commented Jun 3, 2025

@stratakis: Do you want to try to backport manually this change to the 3.14 branch?

stratakis added a commit to stratakis/cpython that referenced this pull request Jun 3, 2025
python#128606)

Apply Intel Control-flow Technology for x86-64 on asm_trampoline.S.

Required for mitigation against return-oriented programming (ROP)
and Call or Jump Oriented Programming (COP/JOP) attacks.

Manual application is required for the assembly files.

See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html
stratakis added a commit to stratakis/cpython that referenced this pull request Jun 3, 2025
…poline.S (python#128606)

Apply Intel Control-flow Technology for x86-64 on asm_trampoline.S.

Required for mitigation against return-oriented programming (ROP)
and Call or Jump Oriented Programming (COP/JOP) attacks.

Manual application is required for the assembly files.

See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html
@bedevere-app
Copy link
bedevere-app bot commented Jun 3, 2025

GH-135077 is a backport of this pull request to the 3.14 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.14 bugs and security fixes label Jun 3, 2025
vstinner pushed a commit that referenced this pull request Jun 3, 2025
….S (#128606) (#135077)

Apply Intel Control-flow Technology for x86-64 on asm_trampoline.S.

Required for mitigation against return-oriented programming (ROP)
and Call or Jump Oriented Programming (COP/JOP) attacks.

Manual application is required for the assembly files.

See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Jun 3, 2025
…poline.S (pythonGH-128606) (pythonGH-135077)

Apply Intel Control-flow Technology for x86-64 on asm_trampoline.S.

Required for mitigation against return-oriented programming (ROP)
and Call or Jump Oriented Programming (COP/JOP) attacks.

Manual application is required for the assembly files.

See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html
(cherry picked from commit 899cca6)

Co-authored-by: stratakis <cstratak@redhat.com>
@vstinner
Copy link
Member
vstinner commented Jun 3, 2025

Merged, thank you.

vstinner pushed a commit that referenced this pull request Jun 3, 2025
….S (GH-128606) (GH-135077) (#135083)

[3.14] gh-128605: Add branch protections for x86_64 in asm_trampoline.S (GH-128606) (GH-135077)

Apply Intel Control-flow Technology for x86-64 on asm_trampoline.S.

Required for mitigation against return-oriented programming (ROP)
and Call or Jump Oriented Programming (COP/JOP) attacks.

Manual application is required for the assembly files.

See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html
(cherry picked from commit 899cca6)

Co-authored-by: stratakis <cstratak@redhat.com>
stratakis added a commit to stratakis/cpython that referenced this pull request Jun 3, 2025
…poline.S (python#128606)

Apply Intel Control-flow Technology for x86-64 on asm_trampoline.S.

Required for mitigation against return-oriented programming (ROP)
and Call or Jump Oriented Programming (COP/JOP) attacks.

Manual application is required for the assembly files.

See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html
@bedevere-app
Copy link
bedevere-app bot commented Jun 3, 2025

GH-135094 is a backport of this pull request to the 3.12 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.12 only security fixes label Jun 3, 2025
stratakis added a commit to stratakis/cpython that referenced this pull request Jun 3, 2025
Required for mitigation against return-oriented programming (ROP) and Call or Jump Oriented Programming (COP/JOP) attacks

Proposed upstream: python#128606

See also: https://sourceware.org/annobin/annobin.html/Test-cf-protection.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants
0