liboeffis: protect from interrupted system calls

In various places, including the DBUS calls which can take some time, if
a SIGALRM triggers, the call will fail.

To prevent this from happening, use the wrappers when possible and make
sure to block the SIGALRM signal when issuing DBUS calls.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
This commit is contained in:
Olivier Fourdan 2022-12-06 14:26:57 +01:00 committed by Peter Hutterer
parent 8bcbc53c0f
commit 39f3ec007b

View file

@ -130,7 +130,7 @@ DEFINE_UNREF_CLEANUP_FUNC(source);
static void
tickle(struct oeffis *oeffis)
{
write(oeffis->pipefd[1], "kitzel", 6);
xwrite(oeffis->pipefd[1], "kitzel", 6);
}
static void
@ -160,7 +160,7 @@ tickled(struct source *source, void *data)
{
/* Nothing to do here, just drain the data */
char buf[64];
read(source_get_fd(source), buf, sizeof(buf));
xread(source_get_fd(source), buf, sizeof(buf));
}
_public_ struct oeffis *
@ -181,7 +181,7 @@ oeffis_new(void *user_data)
/* set up a pipe we can write to to force the epoll to wake up even when
* nothing else happens */
int rc = pipe2(oeffis->pipefd, O_CLOEXEC|O_NONBLOCK);
int rc = xpipe2(oeffis->pipefd, O_CLOEXEC|O_NONBLOCK);
if (rc < 0)
return NULL;
@ -205,7 +205,7 @@ oeffis_get_eis_fd(struct oeffis *oeffis)
return -1;
}
return dup(oeffis->eis_fd);
return xdup(oeffis->eis_fd);
}
_public_ enum oeffis_event_type
@ -328,15 +328,18 @@ portal_connect_to_eis(struct oeffis *oeffis)
sd_bus *bus = oeffis->bus;
int eisfd;
int rc = sd_bus_call_method(bus, oeffis->busname,
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.RemoteDesktop",
"ConnectToEIS",
&error,
&response,
"oa{sv}",
oeffis->session_path,
0);
int rc = 0;
with_signals_blocked(SIGALRM) {
rc = sd_bus_call_method(bus, oeffis->busname,
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.RemoteDesktop",
"ConnectToEIS",
&error,
&response,
"oa{sv}",
oeffis->session_path,
0);
}
if (rc < 0) {
oeffis_disconnect(oeffis, "Failed to call ConnectToEIS: %s", strerror(-rc));
@ -350,7 +353,7 @@ portal_connect_to_eis(struct oeffis *oeffis)
}
/* the fd is owned by the message */
rc = xerrno(dup(eisfd));
rc = xerrno(xdup(eisfd));
if (rc < 0) {
oeffis_disconnect(oeffis, "Failed to dup fd: %s", strerror(-rc));
return;
@ -401,13 +404,17 @@ portal_setup_request(struct oeffis *oeffis, sd_bus_message_handler_t response_ha
_cleanup_free_ char *token = xdp_token();
_cleanup_free_ char *handle = xdp_request_path(oeffis->sender_name, token);
int rc = sd_bus_match_signal(bus, &slot,
oeffis->busname,
handle,
"org.freedesktop.portal.Request",
"Response",
response_handler,
oeffis);
int rc = 0;
with_signals_blocked(SIGALRM) {
rc = sd_bus_match_signal(bus, &slot,
oeffis->busname,
handle,
"org.freedesktop.portal.Request",
"Response",
response_handler,
oeffis);
}
if (rc < 0) {
oeffis_disconnect(oeffis, "Failed to subscribe to Request.Response signal: %s", strerror(-rc));
return rc;
@ -463,20 +470,22 @@ portal_start(struct oeffis *oeffis)
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_unref_(sd_bus_message) *response = NULL;
sd_bus *bus = oeffis->bus;
rc = sd_bus_call_method(bus,
oeffis->busname,
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.RemoteDesktop",
"Start",
&error,
&response,
"osa{sv}",
oeffis->session_path,
"", /* parent window */
1,
"handle_token", /* string key */
"s", token /* variant string */
);
with_signals_blocked(SIGALRM) {
rc = sd_bus_call_method(bus,
oeffis->busname,
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.RemoteDesktop",
"Start",
&error,
&response,
"osa{sv}",
oeffis->session_path,
"", /* parent window */
1,
"handle_token", /* string key */
"s", token /* variant string */
);
}
if (rc < 0) {
oeffis_disconnect(oeffis, "Failed to call method: %s", strerror(-rc));
@ -534,21 +543,23 @@ portal_select_devices(struct oeffis *oeffis)
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_unref_(sd_bus_message) *response = NULL;
rc = sd_bus_call_method(bus,
oeffis->busname,
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.RemoteDesktop",
"SelectDevices",
&error,
&response,
"oa{sv}",
oeffis->session_path,
2,
"handle_token", /* string key */
"s", token, /* variant string */
"types", /* string key */
"u", oeffis->devices
);
with_signals_blocked(SIGALRM) {
rc = sd_bus_call_method(bus,
oeffis->busname,
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.RemoteDesktop",
"SelectDevices",
&error,
&response,
"oa{sv}",
oeffis->session_path,
2,
"handle_token", /* string key */
"s", token, /* variant string */
"types", /* string key */
"u", oeffis->devices
);
}
if (rc < 0) {
oeffis_disconnect(oeffis, "Failed to call method: %s", strerror(-rc));
@ -671,19 +682,21 @@ portal_init(struct oeffis *oeffis, const char *busname)
return;
}
rc = sd_bus_call_method(bus,
busname,
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.RemoteDesktop",
"CreateSession",
&error,
&response,
"a{sv}", 2,
"handle_token", /* string key */
"s", token, /* variant string */
"session_handle_token", /* string key */
"s", session_token /* variant string */
);
with_signals_blocked(SIGALRM) {
rc = sd_bus_call_method(bus,
busname,
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.RemoteDesktop",
"CreateSession",
&error,
&response,
"a{sv}", 2,
"handle_token", /* string key */
"s", token, /* variant string */
"session_handle_token", /* string key */
"s", session_token /* variant string */
);
}
if (rc < 0) {
oeffis_disconnect(oeffis, "Failed to call method: %s", strerror(-rc));