From c6784d9f6f2bcb648072486d90390e3760c579c6 Mon Sep 17 00:00:00 2001 From: Eliseo Martínez Date: Tue, 17 Mar 2015 19:08:44 +0100 Subject: coverity/105985: Resource leak: RI. Problem : Resource leak @ 94, 98, 102. Diagnostic : Real issue. Rationale : Coverity doesn't know that uv_pipe_open will save file descriptor to close them later. So, it signals file descriptors being leaked. This would then seem like a false positive we can fix by teaching coverity about uv_pipe_open through model file. But then we realize that the above is only true if uv_pipe_open succeeds. It it fails, then descriptors are really being leaked, which is why this is considered a real issue and not a false positive after all. Resolution : Add error handling to correctly close descriptors if uv_pipe_open fails at any point. Add model for uv_pipe_open so that Coverity knows it will save descriptors when no error. Helped-by: oni-link --- src/nvim/os/pty_process.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/os/pty_process.c b/src/nvim/os/pty_process.c index a1edebb846..ed98d3e0c0 100644 --- a/src/nvim/os/pty_process.c +++ b/src/nvim/os/pty_process.c @@ -70,6 +70,23 @@ void pty_process_destroy(Job *job) job->process = NULL; } +static bool set_pipe_duplicating_descriptor(int fd, uv_pipe_t *pipe) +{ + int fd_dup = dup(fd); + if (fd_dup < 0) { + ELOG("Failed to dup descriptor %d: %s", fd, strerror(errno)); + return false; + } + int uv_result = uv_pipe_open(pipe, fd_dup); + if (uv_result) { + ELOG("Failed to set pipe to descriptor %d: %s", + fd_dup, uv_strerror(uv_result)); + close(fd_dup); + return false; + } + return true; +} + static const unsigned int KILL_RETRIES = 5; static const unsigned int KILL_TIMEOUT = 2; // seconds @@ -102,16 +119,19 @@ bool pty_process_spawn(Job *job) goto error; } - if (job->opts.writable) { - uv_pipe_open(&ptyproc->proc_stdin, dup(master)); + if (job->opts.writable + && !set_pipe_duplicating_descriptor(master, &ptyproc->proc_stdin)) { + goto error; } - if (job->opts.stdout_cb) { - uv_pipe_open(&ptyproc->proc_stdout, dup(master)); + if (job->opts.stdout_cb + && !set_pipe_duplicating_descriptor(master, &ptyproc->proc_stdout)) { + goto error; } - if (job->opts.stderr_cb) { - uv_pipe_open(&ptyproc->proc_stderr, dup(master)); + if (job->opts.stderr_cb + && !set_pipe_duplicating_descriptor(master, &ptyproc->proc_stderr)) { + goto error; } uv_signal_init(uv_default_loop(), &ptyproc->schld); -- cgit