Skip to content

Unaligned memory access in _write_short_int #20473

@onitake

Description

@onitake

Bug Report

librt is currently not usable on architectures that require strict memory alignment (notably: sparc64), because the helper macros _READ and _WRITE in librt_internal.c completely ignore the natural alignment of the input type.

On architectures that have more lenient alignment rules, or where an OS-level fallback is available, unaligned memory access may also incur a performance penalty. It's usually better to let the compiler know about it and optimize accordingly.

This was discovered during automatic unit testing on the Debian packaging infrastructure, and has been present in librt since at least version 0.3: https://buildd.debian.org/status/logs.php?pkg=python-librt&arch=sparc64

I suggest replacing the custom helpers with calls to memcpy, which avoids unaligned access when needed. A small runtime performance impact may be possible, but compilers will normally fully optimize the function call away and replace it with direct load/store instructions.

To Reproduce

  1. Build the native Python libraries on a system with strict memory alignment
  2. Run the librt smoke tests: python3.14 -m pytest smoke_tests.py

Expected Behavior

The tests execute without error.

Actual Behavior

Python crashes with a bus error.

See https://buildd.debian.org/status/fetch.php?pkg=python-librt&arch=sparc64&ver=0.7.3-1&stamp=1765104691&raw=0 for example output, near the end of the log.

An abridged gdb stack trace is attached further below.

Your Environment

  • Mypy version used: Current master branch
  • Mypy command-line flags: N/A, see above
  • Mypy configuration options from mypy.ini (and other config files): From mypy source tree
  • Python version used: 3.13 and 3.14

gdb stack trace on sparc64:

(gdb) run -m pytest smoke_tests.py
Starting program: /usr/bin/python3.14 -m pytest smoke_tests.py
...
Program received signal SIGBUS, Bus error.
0xfffff8010700acd0 in _write_short_int (data=<WriteBuffer at remote 0xfffff801062c8f00>, real_value=3000) at ./librt_internal.c:469
(gdb) bt
#0  0xfffff8010700acd0 in _write_short_int (data=<WriteBuffer at remote 0xfffff801062c8f00>, real_value=3000) at ./librt_internal.c:469
#1  write_str_internal (data=<WriteBuffer at remote 0xfffff801062c8f00>,
    value='barbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarb') at ./librt_internal.c:494
#2  0xfffff8010700af1c in write_str (self=<module at remote 0xfffff8010629b420>, args=0x7feffffbbc8, nargs=2, kwnames=0x0) at ./librt_internal.c:522
#3  0x00000000001f48e4 in cfunction_vectorcall_FASTCALL_KEYWORDS (func=<built-in method write_str of module object at remote 0xfffff8010629b420>, args=0x7feffffbbc8,
    nargsf=9223372036854775810, kwnames=0x0) at ../Objects/methodobject.c:465

At this point, data->ptr points to an address that is not divisible by two, but the _WRITE macro tries to write a 16-bit value to it. This leads to a misaligned memory access and the program crashes with a SIGBUS.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions