Skip to content
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

Remove jl_getch() to fix race condition in getpass() #45954

Merged
merged 4 commits into from
Jul 8, 2022

Conversation

staticfloat
Copy link
Member

We accidentally introduced a race condition in getpass() by having
jl_getch() toggle terminal modes for each keystroke. Not only is this
slower and wasteful, it allows the kernel to receive keystrokes within a
TTY in canonical mode (where it replaces certain characters [0]) and
then reads from the kernel buffer in non-canonical mode. This results
in us reading a 0x00 when we expected a 0x04 in certain cases on CI,
which breaks some of our tests.

The fix is to switch the TTY into raw mode once, before we ever print
the password prompt, which closes the race condition. To do this, we
moved more code from C to Julia, and removed the jl_getch() export,
instead providing jl_termios_size().

[0] https://github.com/torvalds/linux/blob/e35e5b6f695d241ffb1d223207da58a1fbcdff4b/drivers/tty/n_tty.c#L1318

We accidentally introduced a race condition in `getpass()` by having
`jl_getch()` toggle terminal modes for each keystroke.  Not only is this
slower and wasteful, it allows the kernel to receive keystrokes within a
TTY in canonical mode (where it replaces certain characters [0]) and
then reads from the kernel buffer in non-canonical mode.  This results
in us reading a `0x00` when we expected a `0x04` in certain cases on CI,
which breaks some of our tests.

The fix is to switch the TTY into raw mode once, before we ever print
the password prompt, which closes the race condition.  To do this, we
moved more code from C to Julia, and removed the `jl_getch()` export,
instead providing `jl_termios_size()`.

[0] https://github.com/torvalds/linux/blob/e35e5b6f695d241ffb1d223207da58a1fbcdff4b/drivers/tty/n_tty.c#L1318
@staticfloat staticfloat force-pushed the sf/goodnight_sweet_jl_getch_i_hardly_knew_thee branch from 0b37dbf to f93e1c8 Compare July 6, 2022 21:04
@staticfloat staticfloat requested a review from vtjnash July 6, 2022 23:48
base/util.jl Outdated Show resolved Hide resolved
Co-authored-by: Jameson Nash <[email protected]>
base/util.jl Outdated Show resolved Hide resolved
base/util.jl Outdated Show resolved Hide resolved
base/util.jl Outdated Show resolved Hide resolved
base/util.jl Outdated Show resolved Hide resolved
base/util.jl Outdated Show resolved Hide resolved
@staticfloat staticfloat merged commit 87558f6 into master Jul 8, 2022
@staticfloat staticfloat deleted the sf/goodnight_sweet_jl_getch_i_hardly_knew_thee branch July 8, 2022 19:40
@giordano giordano linked an issue Jul 10, 2022 that may be closed by this pull request
ffucci pushed a commit to ffucci/julia that referenced this pull request Aug 11, 2022
…5954)

* Remove `jl_getch()` to fix race condition in `getpass()`

We accidentally introduced a race condition in `getpass()` by having
`jl_getch()` toggle terminal modes for each keystroke.  Not only is this
slower and wasteful, it allows the kernel to receive keystrokes within a
TTY in canonical mode (where it replaces certain characters [0]) and
then reads from the kernel buffer in non-canonical mode.  This results
in us reading a `0x00` when we expected a `0x04` in certain cases on CI,
which breaks some of our tests.

The fix is to switch the TTY into raw mode once, before we ever print
the password prompt, which closes the race condition.  To do this, we
moved more code from C to Julia, and removed the `jl_getch()` export,
instead providing `jl_termios_size()`.

[0] https://github.com/torvalds/linux/blob/e35e5b6f695d241ffb1d223207da58a1fbcdff4b/drivers/tty/n_tty.c#L1318

* Update base/util.jl

Co-authored-by: Jameson Nash <[email protected]>

* Apply suggestions from code review

Co-authored-by: Jameson Nash <[email protected]>

* Apply suggestions from code review

Co-authored-by: Jameson Nash <[email protected]>

Co-authored-by: Jameson Nash <[email protected]>
pcjentsch pushed a commit to pcjentsch/julia that referenced this pull request Aug 18, 2022
…5954)

* Remove `jl_getch()` to fix race condition in `getpass()`

We accidentally introduced a race condition in `getpass()` by having
`jl_getch()` toggle terminal modes for each keystroke.  Not only is this
slower and wasteful, it allows the kernel to receive keystrokes within a
TTY in canonical mode (where it replaces certain characters [0]) and
then reads from the kernel buffer in non-canonical mode.  This results
in us reading a `0x00` when we expected a `0x04` in certain cases on CI,
which breaks some of our tests.

The fix is to switch the TTY into raw mode once, before we ever print
the password prompt, which closes the race condition.  To do this, we
moved more code from C to Julia, and removed the `jl_getch()` export,
instead providing `jl_termios_size()`.

[0] https://github.com/torvalds/linux/blob/e35e5b6f695d241ffb1d223207da58a1fbcdff4b/drivers/tty/n_tty.c#L1318

* Update base/util.jl

Co-authored-by: Jameson Nash <[email protected]>

* Apply suggestions from code review

Co-authored-by: Jameson Nash <[email protected]>

* Apply suggestions from code review

Co-authored-by: Jameson Nash <[email protected]>

Co-authored-by: Jameson Nash <[email protected]>
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.

CI: Intermittent hang in libgit2 challenge prompt test.
2 participants