Skip to content

devpts: return ESPIPE for positional I/O on PTYs - #14097

Open
ryux1 wants to merge 1 commit into
google:masterfrom
ryux1:fix/pty-positional-write-espipe
Open

devpts: return ESPIPE for positional I/O on PTYs#14097
ryux1 wants to merge 1 commit into
google:masterfrom
ryux1:fix/pty-positional-write-espipe

Conversation

@ryux1

@ryux1 ryux1 commented Aug 12, 2026

Copy link
Copy Markdown

Description

PTY master and replica file descriptions currently fall through to the default
PRead and PWrite implementations, which return EINVAL. Mark both endpoints as
denying positional reads and writes so VFS returns ESPIPE before dispatching the
operation.

This matches Linux for preadv, preadv2, pwritev, and pwritev2 with explicit
offsets while preserving preadv2 and pwritev2 with offset -1 as streaming I/O.
It also lets callers such as Zig file writers recognize PTYs as unseekable and
fall back to normal streaming writes.

Fixes #13737.

Tests

  • //test/syscalls:preadv2_test_runsc_systrap_directfs
  • //test/syscalls:preadv2_test_runsc_ptrace
  • bazel-bin/test/syscalls/linux/preadv2_test --gtest_filter=Preadv2Test.PtyWithOffset (native Linux)
  • //test/syscalls:pwritev2_test_runsc_systrap_directfs
  • //test/syscalls:pwritev2_test_runsc_ptrace
  • //test/syscalls:pwritev2_test_native (focused PTY regression)
  • //pkg/sentry/fsimpl/devpts:devpts_test
  • //pkg/sentry/fsimpl/devpts:devpts_nogo
  • //pkg/sentry/fsimpl/devpts:devpts_test_nogo

Assisted-by: Codex

@google-cla

google-cla Bot commented Aug 12, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@ryux1
ryux1 marked this pull request as ready for review August 12, 2026 23:53
@konstantin-s-bogom

Copy link
Copy Markdown
Member

While you're at this, can you also fix the preadv/preadv2 case as well?

@ryux1
ryux1 force-pushed the fix/pty-positional-write-espipe branch from 6b306d7 to 7308f5f Compare August 13, 2026 18:31
@ryux1 ryux1 changed the title devpts: return ESPIPE for positional writes to PTYs devpts: return ESPIPE for positional I/O on PTYs Aug 13, 2026
@ryux1

ryux1 commented Aug 13, 2026

Copy link
Copy Markdown
Author

While you’re at this, can you also fix the preadv/preadv2 case as well?

Done — I added DenyPRead for both the PTY master and replica, plus coverage that verifies preadv/preadv2 with explicit offsets return ESPIPE. The test also checks that preadv2 with offset -1 still performs streaming reads in both directions.

Validated with the systrap/directfs and ptrace syscall targets, the focused native regression, and the devpts test/nogo targets.

copybara-service Bot pushed a commit that referenced this pull request Aug 13, 2026
Description

PTY master and replica file descriptions currently fall through to the default
PRead and PWrite implementations, which return EINVAL. Mark both endpoints as
denying positional reads and writes so VFS returns ESPIPE before dispatching the
operation.

This matches Linux for preadv, preadv2, pwritev, and pwritev2 with explicit
offsets while preserving preadv2 and pwritev2 with offset -1 as streaming I/O.
It also lets callers such as Zig file writers recognize PTYs as unseekable and
fall back to normal streaming writes.

Fixes #13737.

Tests

- //test/syscalls:preadv2_test_runsc_systrap_directfs
- //test/syscalls:preadv2_test_runsc_ptrace
- bazel-bin/test/syscalls/linux/preadv2_test --gtest_filter=Preadv2Test.PtyWithOffset (native Linux)
- //test/syscalls:pwritev2_test_runsc_systrap_directfs
- //test/syscalls:pwritev2_test_runsc_ptrace
- //test/syscalls:pwritev2_test_native (focused PTY regression)
- //pkg/sentry/fsimpl/devpts:devpts_test
- //pkg/sentry/fsimpl/devpts:devpts_nogo
- //pkg/sentry/fsimpl/devpts:devpts_test_nogo

Assisted-by: Codex
FUTURE_COPYBARA_INTEGRATE_REVIEW=#14097 from ryux1:fix/pty-positional-write-espipe 7308f5f
PiperOrigin-RevId: 964247273
copybara-service Bot pushed a commit that referenced this pull request Aug 13, 2026
Description

PTY master and replica file descriptions currently fall through to the default
PRead and PWrite implementations, which return EINVAL. Mark both endpoints as
denying positional reads and writes so VFS returns ESPIPE before dispatching the
operation.

This matches Linux for preadv, preadv2, pwritev, and pwritev2 with explicit
offsets while preserving preadv2 and pwritev2 with offset -1 as streaming I/O.
It also lets callers such as Zig file writers recognize PTYs as unseekable and
fall back to normal streaming writes.

Fixes #13737.

Tests

- //test/syscalls:preadv2_test_runsc_systrap_directfs
- //test/syscalls:preadv2_test_runsc_ptrace
- bazel-bin/test/syscalls/linux/preadv2_test --gtest_filter=Preadv2Test.PtyWithOffset (native Linux)
- //test/syscalls:pwritev2_test_runsc_systrap_directfs
- //test/syscalls:pwritev2_test_runsc_ptrace
- //test/syscalls:pwritev2_test_native (focused PTY regression)
- //pkg/sentry/fsimpl/devpts:devpts_test
- //pkg/sentry/fsimpl/devpts:devpts_nogo
- //pkg/sentry/fsimpl/devpts:devpts_test_nogo

Assisted-by: Codex
FUTURE_COPYBARA_INTEGRATE_REVIEW=#14097 from ryux1:fix/pty-positional-write-espipe 7308f5f
PiperOrigin-RevId: 964247273
copybara-service Bot pushed a commit that referenced this pull request Aug 13, 2026
Description

PTY master and replica file descriptions currently fall through to the default
PRead and PWrite implementations, which return EINVAL. Mark both endpoints as
denying positional reads and writes so VFS returns ESPIPE before dispatching the
operation.

This matches Linux for preadv, preadv2, pwritev, and pwritev2 with explicit
offsets while preserving preadv2 and pwritev2 with offset -1 as streaming I/O.
It also lets callers such as Zig file writers recognize PTYs as unseekable and
fall back to normal streaming writes.

Fixes #13737.

Tests

- //test/syscalls:preadv2_test_runsc_systrap_directfs
- //test/syscalls:preadv2_test_runsc_ptrace
- bazel-bin/test/syscalls/linux/preadv2_test --gtest_filter=Preadv2Test.PtyWithOffset (native Linux)
- //test/syscalls:pwritev2_test_runsc_systrap_directfs
- //test/syscalls:pwritev2_test_runsc_ptrace
- //test/syscalls:pwritev2_test_native (focused PTY regression)
- //pkg/sentry/fsimpl/devpts:devpts_test
- //pkg/sentry/fsimpl/devpts:devpts_nogo
- //pkg/sentry/fsimpl/devpts:devpts_test_nogo

Assisted-by: Codex
FUTURE_COPYBARA_INTEGRATE_REVIEW=#14097 from ryux1:fix/pty-positional-write-espipe 7308f5f
PiperOrigin-RevId: 964247273
copybara-service Bot pushed a commit that referenced this pull request Aug 14, 2026
Description

PTY master and replica file descriptions currently fall through to the default
PRead and PWrite implementations, which return EINVAL. Mark both endpoints as
denying positional reads and writes so VFS returns ESPIPE before dispatching the
operation.

This matches Linux for preadv, preadv2, pwritev, and pwritev2 with explicit
offsets while preserving preadv2 and pwritev2 with offset -1 as streaming I/O.
It also lets callers such as Zig file writers recognize PTYs as unseekable and
fall back to normal streaming writes.

Fixes #13737.

Tests

- //test/syscalls:preadv2_test_runsc_systrap_directfs
- //test/syscalls:preadv2_test_runsc_ptrace
- bazel-bin/test/syscalls/linux/preadv2_test --gtest_filter=Preadv2Test.PtyWithOffset (native Linux)
- //test/syscalls:pwritev2_test_runsc_systrap_directfs
- //test/syscalls:pwritev2_test_runsc_ptrace
- //test/syscalls:pwritev2_test_native (focused PTY regression)
- //pkg/sentry/fsimpl/devpts:devpts_test
- //pkg/sentry/fsimpl/devpts:devpts_nogo
- //pkg/sentry/fsimpl/devpts:devpts_test_nogo

Assisted-by: Codex
FUTURE_COPYBARA_INTEGRATE_REVIEW=#14097 from ryux1:fix/pty-positional-write-espipe 7308f5f
PiperOrigin-RevId: 964247273
copybara-service Bot pushed a commit that referenced this pull request Aug 14, 2026
Description

PTY master and replica file descriptions currently fall through to the default
PRead and PWrite implementations, which return EINVAL. Mark both endpoints as
denying positional reads and writes so VFS returns ESPIPE before dispatching the
operation.

This matches Linux for preadv, preadv2, pwritev, and pwritev2 with explicit
offsets while preserving preadv2 and pwritev2 with offset -1 as streaming I/O.
It also lets callers such as Zig file writers recognize PTYs as unseekable and
fall back to normal streaming writes.

Fixes #13737.

Tests

- //test/syscalls:preadv2_test_runsc_systrap_directfs
- //test/syscalls:preadv2_test_runsc_ptrace
- bazel-bin/test/syscalls/linux/preadv2_test --gtest_filter=Preadv2Test.PtyWithOffset (native Linux)
- //test/syscalls:pwritev2_test_runsc_systrap_directfs
- //test/syscalls:pwritev2_test_runsc_ptrace
- //test/syscalls:pwritev2_test_native (focused PTY regression)
- //pkg/sentry/fsimpl/devpts:devpts_test
- //pkg/sentry/fsimpl/devpts:devpts_nogo
- //pkg/sentry/fsimpl/devpts:devpts_test_nogo

Assisted-by: Codex
FUTURE_COPYBARA_INTEGRATE_REVIEW=#14097 from ryux1:fix/pty-positional-write-espipe 7308f5f
PiperOrigin-RevId: 964247273
copybara-service Bot pushed a commit that referenced this pull request Aug 14, 2026
Description

PTY master and replica file descriptions currently fall through to the default
PRead and PWrite implementations, which return EINVAL. Mark both endpoints as
denying positional reads and writes so VFS returns ESPIPE before dispatching the
operation.

This matches Linux for preadv, preadv2, pwritev, and pwritev2 with explicit
offsets while preserving preadv2 and pwritev2 with offset -1 as streaming I/O.
It also lets callers such as Zig file writers recognize PTYs as unseekable and
fall back to normal streaming writes.

Fixes #13737.

Tests

- //test/syscalls:preadv2_test_runsc_systrap_directfs
- //test/syscalls:preadv2_test_runsc_ptrace
- bazel-bin/test/syscalls/linux/preadv2_test --gtest_filter=Preadv2Test.PtyWithOffset (native Linux)
- //test/syscalls:pwritev2_test_runsc_systrap_directfs
- //test/syscalls:pwritev2_test_runsc_ptrace
- //test/syscalls:pwritev2_test_native (focused PTY regression)
- //pkg/sentry/fsimpl/devpts:devpts_test
- //pkg/sentry/fsimpl/devpts:devpts_nogo
- //pkg/sentry/fsimpl/devpts:devpts_test_nogo

Assisted-by: Codex
FUTURE_COPYBARA_INTEGRATE_REVIEW=#14097 from ryux1:fix/pty-positional-write-espipe 7308f5f
PiperOrigin-RevId: 964247273
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pty: pwritev/pwritev2 with an offset return EINVAL; Linux returns ESPIPE

2 participants