Repository navigation
[pulse] a directory stream created by fdopendir owns its descriptor - #2298
Merged
Merged
Conversation
`fdopendir(3)` takes over the descriptor it is given: the caller must not use or close it, and
`closedir` releases it. Pulse had no model for `fdopendir`, so the descriptor kept its obligation
and closing the stream never discharged it.
```c
int list_dir(void) {
int fd = open("mydir", O_RDONLY);
if (fd < 0) return -1;
DIR* dir = fdopendir(fd);
if (!dir) { close(fd); return -1; }
closedir(dir); // false positive: resource leak on fd
return 0;
}
```
Model the ownership transfer: the stream returned by `fdopendir` owns the descriptor, and a
failure leaves the descriptor with the caller. Leaks of the stream itself, and of a descriptor
left over by a failed `fdopendir`, are still reported.
Fixes meta#1419.
## Test plan
New `fdopendirClosed_ok` and three leak controls in `c/pulse/fdopendir.c`: the stream dropped
without `closedir`, the descriptor dropped after a failed `fdopendir`, and a descriptor never
handed over at all. The codetoanalyze tests pass.
VladimirMakaev
added a commit
to VladimirMakaev/infer
that referenced
this pull request
Nov 4, 2026
Pulse missed leaks of descriptors from `dup`, `pipe`, `popen` and others, and a failed `fdopen` closed the descriptor. `fdopendir` here is upstream's model, not this commit's: facebook/infer meta#2298 (a07b05c) landed it while this PR was open. The binding and matcher are upstream's, written with this file's helpers because `FileDescriptor` and `FClose` carry a `Procname.t` on frontier, so upstream's body does not type-check here. Expected test output regenerated for the combination with earlier frontier commits: infer/tests/codetoanalyze/c/pulse/issues.exp, infer/tests/codetoanalyze/cpp/pulse/issues.exp, infer/tests/codetoanalyze/cpp/pulse/issues.exp-11 Adapted to earlier frontier commits (integration fixes or overlap with them): infer/src/pulse/PulseModelsC.ml, infer/src/pulse/PulseOperations.ml, infer/tests/codetoanalyze/cpp/pulse/leaks.cpp Upstream-PR: facebook/infer 2148 PR-Head: e554ac2 PR-Base: 9cc2641
VladimirMakaev
added a commit
to VladimirMakaev/infer
that referenced
this pull request
Nov 5, 2026
Pulse missed leaks of descriptors from `dup`, `pipe`, `popen` and others, and a failed `fdopen` closed the descriptor. `fdopendir` here is upstream's model, not this commit's: facebook/infer meta#2298 (a07b05c) landed it while this PR was open. The binding and matcher are upstream's, written with this file's helpers because `FileDescriptor` and `FClose` carry a `Procname.t` on frontier, so upstream's body does not type-check here. Expected test output regenerated for the combination with earlier frontier commits: infer/tests/codetoanalyze/c/pulse/issues.exp, infer/tests/codetoanalyze/cpp/pulse/issues.exp, infer/tests/codetoanalyze/cpp/pulse/issues.exp-11 Adapted to earlier frontier commits (integration fixes or overlap with them): infer/src/pulse/PulseModelsC.ml, infer/src/pulse/PulseOperations.ml, infer/tests/codetoanalyze/cpp/pulse/leaks.cpp Upstream-PR: facebook/infer 2148 PR-Head: e554ac2 PR-Base: 9cc2641
VladimirMakaev
added a commit
to VladimirMakaev/infer
that referenced
this pull request
Nov 5, 2026
Pulse missed leaks of descriptors from `dup`, `pipe`, `popen` and others, and a failed `fdopen` closed the descriptor. `fdopendir` here is upstream's model, not this commit's: facebook/infer meta#2298 (a07b05c) landed it while this PR was open. The binding and matcher are upstream's, written with this file's helpers because `FileDescriptor` and `FClose` carry a `Procname.t` on frontier, so upstream's body does not type-check here. Expected test output regenerated for the combination with earlier frontier commits: infer/tests/codetoanalyze/c/pulse/issues.exp, infer/tests/codetoanalyze/cpp/pulse/issues.exp, infer/tests/codetoanalyze/cpp/pulse/issues.exp-11 Adapted to earlier frontier commits (integration fixes or overlap with them): infer/src/pulse/PulseModelsC.ml, infer/src/pulse/PulseOperations.ml, infer/tests/codetoanalyze/cpp/pulse/leaks.cpp Upstream-PR: facebook/infer 2148 PR-Head: e554ac2 PR-Base: 9cc2641
VladimirMakaev
added a commit
to VladimirMakaev/infer
that referenced
this pull request
Nov 6, 2026
Pulse missed leaks of descriptors from `dup`, `pipe`, `popen` and others, and a failed `fdopen` closed the descriptor. `fdopendir` here is upstream's model, not this commit's: facebook/infer meta#2298 (a07b05c) landed it while this PR was open. The binding and matcher are upstream's, written with this file's helpers because `FileDescriptor` and `FClose` carry a `Procname.t` on frontier, so upstream's body does not type-check here. Expected test output regenerated for the combination with earlier frontier commits: infer/tests/codetoanalyze/c/pulse/issues.exp, infer/tests/codetoanalyze/cpp/pulse/issues.exp, infer/tests/codetoanalyze/cpp/pulse/issues.exp-11 Adapted to earlier frontier commits (integration fixes or overlap with them): infer/src/pulse/PulseModelsC.ml, infer/src/pulse/PulseOperations.ml, infer/tests/codetoanalyze/cpp/pulse/leaks.cpp Upstream-PR: facebook/infer 2148 PR-Head: e554ac2 PR-Base: 9cc2641
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fdopendir(3)takes over the descriptor it is given: the caller must not use or close it, andclosedirreleases it. Pulse had no model forfdopendir, so the descriptor kept its obligationand closing the stream never discharged it.
Model the ownership transfer: the stream returned by
fdopendirowns the descriptor, and afailure leaves the descriptor with the caller. Leaks of the stream itself, and of a descriptor
left over by a failed
fdopendir, are still reported.Fixes #1419.
Test plan
New
fdopendirClosed_okand three leak controls inc/pulse/fdopendir.c: the stream droppedwithout
closedir, the descriptor dropped after a failedfdopendir, and a descriptor neverhanded over at all. The codetoanalyze tests pass.