Skip to content

Fix fd races in dup and fcntl duplication paths#2732

Open
SongXiaoXi wants to merge 1 commit into
ish-app:masterfrom
SongXiaoXi:fix_fd_racing
Open

Fix fd races in dup and fcntl duplication paths#2732
SongXiaoXi wants to merge 1 commit into
ish-app:masterfrom
SongXiaoXi:fix_fd_racing

Conversation

@SongXiaoXi

Copy link
Copy Markdown

This PR fixes a file descriptor race in the duplication paths.

Before this change, dup(), dup3(), and fcntl(F_DUPFD/F_DUPFD_CLOEXEC)
could look up an fd, drop the table lock, and only then increment the fd
refcount. A concurrent close() could free the underlying struct fd
during that window, leaving the duplication path with a stale pointer.

This patch fixes that by:

  • taking the fd reference while still holding the fdtable lock
  • keeping the dup/dup3/fcntl(F_DUPFD*) lookup and install sequence in
    the same locked region
  • making fd refcount updates use the fd lock
  • adding retained-fd helpers for fcntl paths that need to operate on an
    fd after lookup

While doing that, this also fixes standalone stdio initialization to transfer
the initial fd reference directly instead of setting the refcount to zero and
reviving it with fd_retain().

Test coverage

This PR adds a guest-side e2e regression test that compiles and runs inside
iSH and stresses:

  • dup()
  • dup2()
  • fcntl(F_DUPFD_CLOEXEC)

The test reproduces the problem on an unpatched tree and passes with this fix.

Take fd references under the fdtable lock when duplicating descriptors so
dup(), dup3(), and fcntl(F_DUPFD*) cannot race with a concurrent close()
and retain a freed fd.

This also makes fd refcount updates use the fd lock and adds retained-fd
helpers for fcntl paths that operate on an existing descriptor after the
table lookup.

Add a guest e2e regression test that stresses dup, dup2, and
fcntl(F_DUPFD_CLOEXEC) concurrently. The same test fails on an unpatched
tree and passes with this change.

While tightening refcount handling, fix stdio initialization to transfer
the original fd reference directly instead of reviving a zero-refcount fd.
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.

1 participant