Skip to content
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

incorrect type passed to variadic function in set_timerslack #2497

Closed
plugwash opened this issue Sep 10, 2024 · 1 comment · Fixed by #2505
Closed

incorrect type passed to variadic function in set_timerslack #2497

plugwash opened this issue Sep 10, 2024 · 1 comment · Fixed by #2505
Assignees

Comments

@plugwash
Copy link

On debian CI, we noticed that test_prctl was failing on armel and armhf.

https://ci.debian.net/packages/r/rust-nix/testing/armel/51179683/

 95s ---- test_prctl::test_get_set_timerslack stdout ----
 95s thread 'test_prctl::test_get_set_timerslack' panicked at test/sys/test_prctl.rs:97:9:
 95s assertion `left == right` failed
 95s   left: 60000
 95s  right: 18446744073551668736
 95s stack backtrace:
 95s    0: rust_begin_unwind
 95s              at /usr/src/rustc-1.79.0/library/std/src/panicking.rs:652:5
 95s    1: core::panicking::panic_fmt
 95s              at /usr/src/rustc-1.79.0/library/core/src/panicking.rs:72:14
 95s    2: core::panicking::assert_failed_inner
 95s    3: core::panicking::assert_failed
 95s              at /usr/src/rustc-1.79.0/library/core/src/panicking.rs:364:5
 95s    4: test_prctl::test_prctl::test_get_set_timerslack
 95s              at ./test/sys/test_prctl.rs:97:9
 95s    5: test_prctl::test_prctl::test_get_set_timerslack::{{closure}}
 95s              at ./test/sys/test_prctl.rs:91:33
 95s    6: core::ops::function::FnOnce::call_once
 95s              at /usr/src/rustc-1.79.0/library/core/src/ops/function.rs:250:5
 95s    7: core::ops::function::FnOnce::call_once
 95s              at /usr/src/rustc-1.79.0/library/core/src/ops/function.rs:250:5
 95s note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

After much head scratching, and chasing up false leads, I found the issue was an incorrect type passed to a variadic function.

Specifically set_timerslack passes the ns value to libc::prctl as a u64, but according to the man page it is supposed to be passed as an unsigned long (c_ulong in rust terms).

https://man7.org/linux/man-pages/man2/PR_SET_TIMERSLACK.2const.html

Whether this error actually causes a failure depends on the architecture and ABI. The error is benign on 64-bit architectures because unsigned long is the same as u64 there. It's also benign on i386 because i386 passes parameters on the stack, is little endian and has a "max alignment" of 4, so the lower 32-bits of the value end up in the right place.

However, it is not benign on arm eabi. arm eabi has a max alignment of 8 and applies that max alignment even when passing parameters in registers. So two 32-bit integer parameters is passed as.

r0 - first parameter
r1 - second parameter

However, a 32-bit first parameter followed by a 64-bit integer second parameter are passed as.

r0 - first parameter
r1 - unused due to alignment rules
r2 - low word of second parameter
r3 - high word of second parameter

I patched this in Debian simply by adding a typecast, it may be neater to instead change the signature of the function but that would be a breaking API change.

Patch is available at https://salsa.debian.org/rust-team/debcargo-conf/-/blob/1d998d491b5cc8f459aaef48931db6c759d031f4/src/nix/debian/patches/fix-incorrect-type-in-set-timerslack.patch

@SteveLauC SteveLauC self-assigned this Sep 13, 2024
@SteveLauC
Copy link
Member

Hi, thanks for the detailed issue report and for digging into the underlying root cause!

but that would be a breaking API change.

No need to worry, breaking changes are fine as the next release will be a major release:)

Let me give this issue a fix.

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

Successfully merging a pull request may close this issue.

2 participants