Skip to content

bug: slave FD leak in parent process after pty.openpty() #78

Closed

Description

@datasciencemonkey

Problem

After pty.openpty() returns master_fd and slave_fd, the slave FD is passed to Popen for stdin/stdout/stderr but is never closed in the parent process. This causes:

  1. FD leak — one file descriptor leaked per session for the lifetime of that session
  2. EOF not propagated — the kernel won't send EOF to the master side when the child exits, because the parent still holds the slave FD open
  3. Zombie accumulation — combined with the 24-hour session linger, leaked FDs accumulate over time

With a typical 1024 soft FD limit, ~500 accumulated sessions would exhaust file descriptors.

Location

app.py lines 666-692 — no os.close(slave_fd) after the Popen call.

Recommended Fix

One-line fix — add os.close(slave_fd) immediately after the Popen call:

proc = subprocess.Popen(
    ["/bin/bash"],
    stdin=slave_fd, stdout=slave_fd, stderr=slave_fd,
    preexec_fn=os.setsid,
    env=env,
)
os.close(slave_fd)  # Parent doesn't need the slave side; child inherited it

The child process inherits the slave FD through Popen, so closing it in the parent is safe and correct. This is the standard pattern for PTY management (see Python docs for pty.openpty()).

Severity

Medium — causes resource leak over time, but mitigated by Databricks Apps container restarts.

Found during security assessment v2 (2026-03-24).

Activity

  1. added a commit that references this issue on Mar 24, 2026
    d8d908c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions