gvisor icon indicating copy to clipboard operation
gvisor copied to clipboard

ttyname: Inappropriate ioctl for device

Open dseomn opened this issue 8 months ago • 4 comments

Description

If I call ttyname(0) in C, it gives an Inappropriate ioctl for device error.

Steps to reproduce

If I compile this code to a.out:

#include <stdio.h>
#include <unistd.h>

int main() {
  char *name = ttyname(0);
  if (!name) {
    perror("ttyname");
    return 1;
  }
  printf("ttyname = %s\n", name);
  return 0;
}

With runsc, it fails:

$ podman run --rm -ti -v $PWD/a.out:/a.out:ro --runtime=runsc --runtime-flag=ignore-cgroups --runtime-flag=network=none debian:testing /a.out
ttyname: Inappropriate ioctl for device

With runc, it works:

$ podman run --rm -ti -v $PWD/a.out:/a.out:ro --runtime=runc debian:testing /a.out
ttyname = /dev/pts/0

Note that in both cases, I gave it the -t flag.

runsc version

runsc version 0.0~20240729.0
spec: 1.2.0

docker version (if using docker)

$ podman version
Client:       Podman Engine
Version:      5.4.0
API Version:  5.4.0
Go Version:   go1.24.0
Built:        Sun Feb 16 08:51:11 2025
OS/Arch:      linux/amd64

uname

Linux solaria 6.12.12-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.12-1 (2025-02-02) x86_64 GNU/Linux

kubectl (if using Kubernetes)


repo state (if built from source)

No response

runsc debug logs (if available)


dseomn avatar Mar 25 '25 04:03 dseomn

Interesting find!

This is a tricky one because when you pass -t into podman (or Docker), gvisor will "donate" the terminal FD from the host into the sandbox. The donated terminal FD does not have a corresponding file in /dev filesystem inside the sandbox.

I believe this is the error we are hitting: https://elixir.bootlin.com/glibc/glibc-2.41.9000/source/sysdeps/posix/ttyname_r.c#L89-L91

I'll have to think about how to handle this. Maybe we could populate something in /dev/ for the donated terminal FD.

Also, if you run a program that creates an in-sandbox PTY (like tmux), and run your repro inside that, it does work:

$ docker run --runtime=runsc  -it --rm ubuntu
root@babd2660deaa:/# apt update && apt install tmux
root@babd2660deaa:/# tmux
# now inside tmux
root@babd2660deaa:/# ./a.out 
ttyname = /dev/pts/1

nlacasse avatar Mar 25 '25 05:03 nlacasse

I believe this is the error we are hitting: https://elixir.bootlin.com/glibc/glibc-2.41.9000/source/sysdeps/posix/ttyname_r.c#L89-L91

That doesn't involve ioctl, so I think it's somewhere else? I was looking at https://elixir.bootlin.com/glibc/glibc-2.41.9000/source/sysdeps/unix/sysv/linux/ptsname.c#L54 yesterday, but I'm not sure if or how that's called from ttyname.

dseomn avatar Mar 25 '25 17:03 dseomn

I was able to reproduce the tty name part of https://github.com/tmux/tmux/issues/4421 outside of gvisor, so this ioctl error isn't actually relevant to any apps I'm using in gvisor anymore, as far as I know.

dseomn avatar Mar 27 '25 21:03 dseomn

I believe this is the error we are hitting: https://elixir.bootlin.com/glibc/glibc-2.41.9000/source/sysdeps/posix/ttyname_r.c#L89-L91

That doesn't involve ioctl, so I think it's somewhere else? I was looking at https://elixir.bootlin.com/glibc/glibc-2.41.9000/source/sysdeps/unix/sysv/linux/ptsname.c#L54 yesterday, but I'm not sure if or how that's called from ttyname.

The code I linked returns ENOTTY which is often stringified as "inappropriate ioctl for device", so it can occur even when there's no actual ioctl being made.

I looked at the strace logs from your repro, and all of the ioctl calls are handled correctly (none return errors).

nlacasse avatar Mar 27 '25 22:03 nlacasse