sd-varlink: fix fd handling in upgrade code path
This commit fixes an issue with the fd handling in sd_varlink_call_and_upgrade() when one direction of the output FDs is unset. Thanks to Lennart for spotting this and suggesting the fix.
This commit is contained in:
committed by
Daan De Meyer
parent
73c0a79789
commit
f180ff5983
@@ -2452,26 +2452,30 @@ _public_ int sd_varlink_call_and_upgrade(
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle the case where the caller is not interested in one of the fds. We need
|
||||
* to consider the case when (input_fd == output_fd) just clear the alias
|
||||
* rather than closing it, since the other branch may hand it out. */
|
||||
/* Hand out the fds to the caller. When the caller doesn't want one direction, shut it
|
||||
* down: but avoid closing the underlying fd if the other direction still needs it
|
||||
* (i.e. when input_fd == output_fd). */
|
||||
bool same_fd = v->input_fd == v->output_fd;
|
||||
|
||||
if (ret_input_fd)
|
||||
*ret_input_fd = TAKE_FD(v->input_fd);
|
||||
else if (!same_fd) {
|
||||
else {
|
||||
(void) shutdown(v->input_fd, SHUT_RD);
|
||||
v->input_fd = safe_close(v->input_fd);
|
||||
} else
|
||||
v->input_fd = -EBADF;
|
||||
if (same_fd && ret_output_fd)
|
||||
TAKE_FD(v->input_fd); /* don't close yet, output branch needs it */
|
||||
else
|
||||
v->input_fd = safe_close(v->input_fd);
|
||||
}
|
||||
|
||||
if (ret_output_fd)
|
||||
*ret_output_fd = TAKE_FD(v->output_fd);
|
||||
else if (!same_fd) {
|
||||
else {
|
||||
(void) shutdown(v->output_fd, SHUT_WR);
|
||||
v->output_fd = safe_close(v->output_fd);
|
||||
} else
|
||||
v->output_fd = -EBADF;
|
||||
if (same_fd && ret_input_fd)
|
||||
TAKE_FD(v->output_fd);
|
||||
else
|
||||
v->output_fd = safe_close(v->output_fd);
|
||||
}
|
||||
|
||||
varlink_set_state(v, VARLINK_DISCONNECTED);
|
||||
assert(v->n_pending == 1);
|
||||
|
||||
Reference in New Issue
Block a user