sd-bus: cleanup ssh sessions (Closes: #8076)
we still invoke ssh unnecessarily when there in incompatible or erreneous input
The fallow-up to finish that would make the code a bit more verbose,
as it would require repeating this bit:
```
r = bus_connect_transport(arg_transport, arg_host, false, &bus);
if (r < 0) {
log_error_errno(r, "Failed to create bus connection: %m");
goto finish;
}
sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
```
in every verb, after parsing.
v2: add waitpid() to avoid a zombie process, switch to SIGTERM from SIGKILL
v3: refactor, wait in bus_start_address()
This commit is contained in:
@@ -296,6 +296,7 @@ struct sd_bus {
|
||||
unsigned n_memfd_cache;
|
||||
|
||||
pid_t original_pid;
|
||||
pid_t busexec_pid;
|
||||
|
||||
sd_event_source *input_io_event_source;
|
||||
sd_event_source *output_io_event_source;
|
||||
|
||||
@@ -937,18 +937,18 @@ int bus_socket_connect(sd_bus *b) {
|
||||
|
||||
int bus_socket_exec(sd_bus *b) {
|
||||
int s[2], r;
|
||||
pid_t pid;
|
||||
|
||||
assert(b);
|
||||
assert(b->input_fd < 0);
|
||||
assert(b->output_fd < 0);
|
||||
assert(b->exec_path);
|
||||
assert(b->busexec_pid == 0);
|
||||
|
||||
r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
r = safe_fork_full("(sd-busexec)", s+1, 1, FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS, &pid);
|
||||
r = safe_fork_full("(sd-busexec)", s+1, 1, FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS, &b->busexec_pid);
|
||||
if (r < 0) {
|
||||
safe_close_pair(s);
|
||||
return r;
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
#include <netdb.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
@@ -1099,6 +1101,13 @@ static int bus_parse_next_address(sd_bus *b) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void bus_kill_exec(sd_bus *bus) {
|
||||
if (pid_is_valid(bus->busexec_pid) > 0) {
|
||||
sigterm_wait(bus->busexec_pid);
|
||||
bus->busexec_pid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int bus_start_address(sd_bus *b) {
|
||||
int r;
|
||||
|
||||
@@ -1108,6 +1117,8 @@ static int bus_start_address(sd_bus *b) {
|
||||
bus_close_io_fds(b);
|
||||
bus_close_inotify_fd(b);
|
||||
|
||||
bus_kill_exec(b);
|
||||
|
||||
/* If you provide multiple different bus-addresses, we
|
||||
* try all of them in order and use the first one that
|
||||
* succeeds. */
|
||||
@@ -1506,6 +1517,9 @@ _public_ void sd_bus_close(sd_bus *bus) {
|
||||
if (bus_pid_changed(bus))
|
||||
return;
|
||||
|
||||
/* Don't leave ssh hanging around */
|
||||
bus_kill_exec(bus);
|
||||
|
||||
bus_set_state(bus, BUS_CLOSED);
|
||||
|
||||
sd_bus_detach_event(bus);
|
||||
@@ -1523,6 +1537,9 @@ _public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) {
|
||||
if (!bus)
|
||||
return NULL;
|
||||
|
||||
/* Have to do this before flush() to prevent hang */
|
||||
bus_kill_exec(bus);
|
||||
|
||||
sd_bus_flush(bus);
|
||||
sd_bus_close(bus);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user