Skip to content

Fix syscall_info #2653

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

cbarrete
Copy link

What does this PR do

It fixes ptrace::syscall_info, which is currently broken (at least on Linux 6.12.31).

See the commit message for more details.

Reproduction

The following program panics when built against master and behaves correctly (i.e. it does not panic and prints valid syscall info) when built against this branch:

fn main() {
    let pid = unsafe { nix::unistd::fork().unwrap() };

    match pid {
        nix::unistd::ForkResult::Child => {
            nix::sys::ptrace::traceme().unwrap();
            nix::sys::signal::raise(nix::sys::signal::Signal::SIGCONT).unwrap();
            println!("I'm issuing a syscall!");
        }
        nix::unistd::ForkResult::Parent { child } => {
            nix::sys::wait::waitpid(Some(child), None).unwrap();
            nix::sys::ptrace::setoptions(child, nix::sys::ptrace::Options::PTRACE_O_TRACESYSGOOD)
                .unwrap();

            nix::sys::ptrace::syscall(child, None).unwrap();
            nix::sys::wait::waitpid(Some(child), None).unwrap();
            let syscall_info = nix::sys::ptrace::syscall_info(child).unwrap();
            println!("{syscall_info:?}");
            assert!(syscall_info.op == libc::PTRACE_SYSCALL_INFO_ENTRY);

            nix::sys::ptrace::syscall(child, None).unwrap();
            nix::sys::wait::waitpid(Some(child), None).unwrap();
            let syscall_info = nix::sys::ptrace::syscall_info(child).unwrap();
            println!("{syscall_info:?}");
            assert!(syscall_info.op == libc::PTRACE_SYSCALL_INFO_EXIT);
        }
    }
}

Checklist:

  • I have read CONTRIBUTING.md
  • I have written necessary tests and rustdoc comments
  • A change log has been added if this PR modifies nix's API

@cbarrete cbarrete force-pushed the fix-ptrace-syscall-info branch from b931d13 to 9076df2 Compare July 26, 2025 04:51
According to the man page:

> The addr argument contains the size of the buffer pointed to by the
> data argument (i.e., sizeof(struct ptrace_syscall_info)).

We were setting the data argument, so this syscall was returning
garbage. This is easily reproduced and verified by looking at the `op`
value, which should range from 0 to 3. The PR associated with this
commit contains a sample program to demonstrate this.

The fix is done in the `ptrace_get_data` helper to avoid duplicating its
implementation just for `syscall_info`.

Of all the other callers, all but one are documented as ignoring `addr`.
The other one (`PTRACE_GETREGS`) is documented as ignoring `addr`
_except on SPARC systems_, on which `addr` and `data` are reversed.
However, this is already not respected by `nix`, so this changes is not
disruptive in this regard.

There should be no performance concerns as we are replacing one constant
with another.
@cbarrete cbarrete force-pushed the fix-ptrace-syscall-info branch from 9076df2 to 499f154 Compare July 26, 2025 05:13
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 this pull request may close these issues.

1 participant