Skip to content

Segfault on Linux when opening a terminal; stack overflow in pty_utils.isPasswordMode #780

Closed

Description

@jolenta-dev

Full transparency: I do not know much Zig, most of the tracing on this came from AI, but I have reproduced and verified the issue/fix herein by hand.

M-x ghostel segfaults Emacs on first render on Linux (aarch64, glibc 2.42,
Emacs 30.2, ghostel 0.60.0) with both the prebuilt release binary and
with a source build (zig 0.17.0, ReleaseFast), and with emacs -Q -nw. It does
not happen in --batch, or with a Debug build.

Cause: isPasswordMode in src/pty_utils.zig declares var tio: sys.termios. On
Linux, std.posix.system.termios is the kernel struct (36 bytes: 4 flag words,
line, 19 control chars). It then calls glibc's tcgetattr, which writes glibc's
struct termios (60 bytes: NCCS=32 plus speeds). That overflows the stack by 24
bytes on every call. ReleaseFast overwrites the saved return address (gdb showed a
jump to 0x960000000000). A ReleaseSafe build with symbols trips the stack
protector:

  #0 compiler_rt.ssp.__chk_fail
  #1 pty_utils.isPasswordMode
  #2 GhostelTerm.isPasswordMode  (GhostelTerm.zig:335)

PosixPtyProcess.zig is unaffected because it uses the C-imported termios.

I think something like the following should fix this (tested locally, working):

   --- a/src/pty_utils.zig
   +++ b/src/pty_utils.zig
   @@ -34,8 +34,15 @@
        if (sys.errno(fd) != .SUCCESS) return false;
        defer _ = sys.close(fd);

   -    var tio: sys.termios = undefined;
   -    const result = sys.tcgetattr(fd, &tio);
   +    var buf: extern struct {
   +        tio: sys.termios,
   +        _pad: [64]u8 = undefined,
   +    } = undefined;
   +    const result = sys.tcgetattr(fd, &buf.tio);
        if (sys.errno(result) != .SUCCESS) return false;
   -    return tio.lflag.ICANON and !tio.lflag.ECHO;
   +    return buf.tio.lflag.ICANON and !buf.tio.lflag.ECHO;
    }

Activity

  1. self-assigned this
    on Nov 1, 2026
  2. jolenta-dev commented on Nov 1, 2026

    @jolenta-dev
    Author

    @emil-e thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions