mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-09-19 09:48:14 +00:00
ibus: Handle error when getting the D-Bus machine ID
It is possible for retrieving the machine ID to fail, either because dbus was installed incorrectly (machine ID absent or corrupt), or in 32-bit builds, because stat() on the machine ID fails with EOVERFLOW if it has an out-of-range timestamp or inode number. dbus has historically treated this as a faulty installation, raising a warning which by default causes the process to crash. Unfortunately, dbus_get_local_machine_id() never had a way to report errors, so it has no alternative for that (bad) error handling. In dbus >= 1.12.0, we can use dbus_try_get_local_machine_id() to get the same information, but with the ability to cope gracefully with errors. ibus won't work in this situation, but that's better than crashing. Mitigates: https://github.com/ValveSoftware/steam-for-linux/issues/9605 Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:

committed by
Sam Lantinga

parent
3ddbeab88f
commit
91198baed4
@@ -33,10 +33,16 @@ static SDL_DBusContext dbus;
|
|||||||
|
|
||||||
static int LoadDBUSSyms(void)
|
static int LoadDBUSSyms(void)
|
||||||
{
|
{
|
||||||
|
#define SDL_DBUS_SYM2_OPTIONAL(TYPE, x, y) \
|
||||||
|
dbus.x = (TYPE)SDL_LoadFunction(dbus_handle, #y)
|
||||||
|
|
||||||
#define SDL_DBUS_SYM2(TYPE, x, y) \
|
#define SDL_DBUS_SYM2(TYPE, x, y) \
|
||||||
if (!(dbus.x = (TYPE)SDL_LoadFunction(dbus_handle, #y))) \
|
if (!(dbus.x = (TYPE)SDL_LoadFunction(dbus_handle, #y))) \
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
#define SDL_DBUS_SYM_OPTIONAL(TYPE, x) \
|
||||||
|
SDL_DBUS_SYM2_OPTIONAL(TYPE, x, dbus_##x)
|
||||||
|
|
||||||
#define SDL_DBUS_SYM(TYPE, x) \
|
#define SDL_DBUS_SYM(TYPE, x) \
|
||||||
SDL_DBUS_SYM2(TYPE, x, dbus_##x)
|
SDL_DBUS_SYM2(TYPE, x, dbus_##x)
|
||||||
|
|
||||||
@@ -77,6 +83,7 @@ static int LoadDBUSSyms(void)
|
|||||||
SDL_DBUS_SYM(dbus_bool_t (*)(const DBusError *), error_is_set);
|
SDL_DBUS_SYM(dbus_bool_t (*)(const DBusError *), error_is_set);
|
||||||
SDL_DBUS_SYM(void (*)(DBusError *), error_free);
|
SDL_DBUS_SYM(void (*)(DBusError *), error_free);
|
||||||
SDL_DBUS_SYM(char *(*)(void), get_local_machine_id);
|
SDL_DBUS_SYM(char *(*)(void), get_local_machine_id);
|
||||||
|
SDL_DBUS_SYM_OPTIONAL(char *(*)(DBusError *), try_get_local_machine_id);
|
||||||
SDL_DBUS_SYM(void (*)(void *), free);
|
SDL_DBUS_SYM(void (*)(void *), free);
|
||||||
SDL_DBUS_SYM(void (*)(char **), free_string_array);
|
SDL_DBUS_SYM(void (*)(char **), free_string_array);
|
||||||
SDL_DBUS_SYM(void (*)(void), shutdown);
|
SDL_DBUS_SYM(void (*)(void), shutdown);
|
||||||
@@ -502,4 +509,38 @@ void SDL_DBus_PumpEvents(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the machine ID if possible. Result must be freed with dbus->free().
|
||||||
|
*/
|
||||||
|
char *SDL_DBus_GetLocalMachineId(void)
|
||||||
|
{
|
||||||
|
DBusError err;
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
dbus.error_init(&err);
|
||||||
|
|
||||||
|
if (dbus.try_get_local_machine_id) {
|
||||||
|
/* Available since dbus 1.12.0, has proper error-handling */
|
||||||
|
result = dbus.try_get_local_machine_id(&err);
|
||||||
|
} else {
|
||||||
|
/* Available since time immemorial, but has no error-handling:
|
||||||
|
* if the machine ID can't be read, many versions of libdbus will
|
||||||
|
* treat that as a fatal mis-installation and abort() */
|
||||||
|
result = dbus.get_local_machine_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dbus.error_is_set(&err)) {
|
||||||
|
SDL_SetError("%s: %s", err.name, err.message);
|
||||||
|
dbus.error_free(&err);
|
||||||
|
} else {
|
||||||
|
SDL_SetError("Error getting D-Bus machine ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -75,6 +75,7 @@ typedef struct SDL_DBusContext
|
|||||||
dbus_bool_t (*error_is_set)(const DBusError *);
|
dbus_bool_t (*error_is_set)(const DBusError *);
|
||||||
void (*error_free)(DBusError *);
|
void (*error_free)(DBusError *);
|
||||||
char *(*get_local_machine_id)(void);
|
char *(*get_local_machine_id)(void);
|
||||||
|
char *(*try_get_local_machine_id)(DBusError *);
|
||||||
void (*free)(void *);
|
void (*free)(void *);
|
||||||
void (*free_string_array)(char **);
|
void (*free_string_array)(char **);
|
||||||
void (*shutdown)(void);
|
void (*shutdown)(void);
|
||||||
@@ -99,6 +100,7 @@ extern void SDL_DBus_ScreensaverTickle(void);
|
|||||||
extern SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit);
|
extern SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit);
|
||||||
|
|
||||||
extern void SDL_DBus_PumpEvents(void);
|
extern void SDL_DBus_PumpEvents(void);
|
||||||
|
extern char *SDL_DBus_GetLocalMachineId(void);
|
||||||
|
|
||||||
#endif /* HAVE_DBUS_DBUS_H */
|
#endif /* HAVE_DBUS_DBUS_H */
|
||||||
|
|
||||||
|
@@ -411,7 +411,12 @@ static char *IBus_GetDBusAddressFilename(void)
|
|||||||
(void)SDL_snprintf(config_dir, sizeof(config_dir), "%s/.config", home_env);
|
(void)SDL_snprintf(config_dir, sizeof(config_dir), "%s/.config", home_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
key = dbus->get_local_machine_id();
|
key = SDL_DBus_GetLocalMachineId();
|
||||||
|
|
||||||
|
if (key == NULL) {
|
||||||
|
SDL_free(display);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_memset(file_path, 0, sizeof(file_path));
|
SDL_memset(file_path, 0, sizeof(file_path));
|
||||||
(void)SDL_snprintf(file_path, sizeof(file_path), "%s/ibus/bus/%s-%s-%s",
|
(void)SDL_snprintf(file_path, sizeof(file_path), "%s/ibus/bus/%s-%s-%s",
|
||||||
|
Reference in New Issue
Block a user