Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

ioctl_tiocsctty passes the address of a zero instead of the documented 0 argument

Open Beginner friendly
#1,703 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 3 days

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
68/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
linux, rust

Research direction

The bug is in src/process/ioctl.rs: the documented call is at line 13, and the argument adapter at lines 45-47 passes the address of a stack-local 0u32 instead of the value 0. Start by reading that adapter and the ioctl_tiocsctty doc comment, then run the strace repro from the issue to confirm the bad argument. Done means the adapter passes the literal 0, the comment cites ioctl_tty(2), and the strace output shows TIOCSCTTY, 0.

Written by the indexing model from the issue text.

Description

rustix::process::ioctl_tiocsctty is documented as performing ioctl(fd, TIOCSCTTY, 0):

https://github.com/bytecodealliance/rustix/blob/1e2954a46ecffa6b30426ad7b1833b226530dcf4/src/process/ioctl.rs#L13

but the argument adapter passes the address of a stack-local 0u32:

https://github.com/bytecodealliance/rustix/blob/1e2954a46ecffa6b30426ad7b1833b226530dcf4/src/process/ioctl.rs#L45-L47

Linux from 2.6.12 requires the third arg to be exactly 1 for the option to steal the terminal, and only uses that arg anyway when CAP_SYS_ADMIN. On BSDs the arg is ignored. The Linux manpage says to use 0 otherwise; the comment in the code has tty_ioctl(4) but that's since been renamed to ioctl_tty(2) and TIOCSCTTY(2const) has the detail:

Make the given terminal the controlling terminal of the
calling process.  The calling process must be a session
leader and not have a controlling terminal already.  For
this case, arg should be specified as zero.

If this terminal is already the controlling terminal of a
different session group, then the ioctl fails with EPERM,
unless the caller has the CAP_SYS_ADMIN capability and arg
equals 1, in which case the terminal is stolen, and all
processes that had it as controlling terminal lose it.

From kernel source:

static int tiocsctty(struct tty_struct *tty,
                     struct file *file, int arg)
{
    // ...
    if (tty->ctrl.session) {
        if (arg == 1 && capable(CAP_SYS_ADMIN)) {
            session_clear_tty(tty->ctrl.session);
        } else {
            ret = -EPERM;
            goto unlock;
        }
    }
    // ...
}

This isn't unsafe exactly, but it's still confusing. Also, it might be worth exposing the steal variant.

Tiny repro:

#!/usr/bin/env -S cargo +nightly -Zscript
---cargo
package.edition = "2024"
dependencies.rustix = { version = "1.1.5", features = ["process"] }
---
fn main() {
    let _ = rustix::process::ioctl_tiocsctty(std::io::stdin());
}

With strace:

$ ./repro.rs >/dev/null # compile
$ sudo strace -e ioctl ~/.cargo/build/*/*/target/debug/repro # run with CAP_SYS_ADMIN
ioctl(0, TIOCSCTTY, -527932840)         = -1 ENOTTY (Inappropriate ioctl for device)

The return may vary and isn't relevant: -527932840 is an address and is neither 0 nor 1, the two permitted values. A silver lining is that it's also impossible for arg to be 1 under the current code, so it's technically harmless.

Dominant language
Rust
Stars
2.1k
Forks
308
PR merge metrics
No merged PRs in 30d

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from bytecodealliance/rustix

All issues in bytecodealliance/rustix

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.