Skip to content

Commit 4ce5c3a

Browse files
smcvslouken
authored andcommitted
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. (cherry picked from commit 91198ba) Mitigates: ValveSoftware/steam-for-linux#9605 Signed-off-by: Simon McVittie <[email protected]>
1 parent a3d4fd7 commit 4ce5c3a

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

src/core/linux/SDL_dbus.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,19 @@ static SDL_DBusContext dbus;
3636

3737
static int LoadDBUSSyms(void)
3838
{
39+
#define SDL_DBUS_SYM2_OPTIONAL(x, y) \
40+
dbus.x = SDL_LoadFunction(dbus_handle, #y)
41+
3942
#define SDL_DBUS_SYM2(x, y) \
4043
if (!(dbus.x = SDL_LoadFunction(dbus_handle, #y))) \
4144
return -1
4245

4346
#define SDL_DBUS_SYM(x) \
4447
SDL_DBUS_SYM2(x, dbus_##x)
4548

49+
#define SDL_DBUS_SYM_OPTIONAL(x) \
50+
SDL_DBUS_SYM2_OPTIONAL(x, dbus_##x)
51+
4652
SDL_DBUS_SYM(bus_get_private);
4753
SDL_DBUS_SYM(bus_register);
4854
SDL_DBUS_SYM(bus_add_match);
@@ -80,6 +86,7 @@ static int LoadDBUSSyms(void)
8086
SDL_DBUS_SYM(error_is_set);
8187
SDL_DBUS_SYM(error_free);
8288
SDL_DBUS_SYM(get_local_machine_id);
89+
SDL_DBUS_SYM_OPTIONAL(try_get_local_machine_id);
8390
SDL_DBUS_SYM(free);
8491
SDL_DBUS_SYM(free_string_array);
8592
SDL_DBUS_SYM(shutdown);
@@ -493,6 +500,40 @@ SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit)
493500

494501
return SDL_TRUE;
495502
}
503+
504+
/*
505+
* Get the machine ID if possible. Result must be freed with dbus->free().
506+
*/
507+
char *SDL_DBus_GetLocalMachineId(void)
508+
{
509+
DBusError err;
510+
char *result;
511+
512+
dbus.error_init(&err);
513+
514+
if (dbus.try_get_local_machine_id) {
515+
/* Available since dbus 1.12.0, has proper error-handling */
516+
result = dbus.try_get_local_machine_id(&err);
517+
} else {
518+
/* Available since time immemorial, but has no error-handling:
519+
* if the machine ID can't be read, many versions of libdbus will
520+
* treat that as a fatal mis-installation and abort() */
521+
result = dbus.get_local_machine_id();
522+
}
523+
524+
if (result) {
525+
return result;
526+
}
527+
528+
if (dbus.error_is_set(&err)) {
529+
SDL_SetError("%s: %s", err.name, err.message);
530+
dbus.error_free(&err);
531+
} else {
532+
SDL_SetError("Error getting D-Bus machine ID");
533+
}
534+
535+
return NULL;
536+
}
496537
#endif
497538

498539
/* vi: set ts=4 sw=4 expandtab: */

src/core/linux/SDL_dbus.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ typedef struct SDL_DBusContext
7272
dbus_bool_t (*error_is_set)(const DBusError *);
7373
void (*error_free)(DBusError *);
7474
char *(*get_local_machine_id)(void);
75+
char *(*try_get_local_machine_id)(DBusError *);
7576
void (*free)(void *);
7677
void (*free_string_array)(char **);
7778
void (*shutdown)(void);
@@ -95,6 +96,8 @@ extern SDL_bool SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, const c
9596
extern void SDL_DBus_ScreensaverTickle(void);
9697
extern SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit);
9798

99+
extern char *SDL_DBus_GetLocalMachineId(void);
100+
98101
#endif /* HAVE_DBUS_DBUS_H */
99102

100103
#endif /* SDL_dbus_h_ */

src/core/linux/SDL_ibus.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,12 @@ static char *IBus_GetDBusAddressFilename(void)
410410
(void)SDL_snprintf(config_dir, sizeof(config_dir), "%s/.config", home_env);
411411
}
412412

413-
key = dbus->get_local_machine_id();
413+
key = SDL_DBus_GetLocalMachineId();
414+
415+
if (key == NULL) {
416+
SDL_free(display);
417+
return NULL;
418+
}
414419

415420
SDL_memset(file_path, 0, sizeof(file_path));
416421
(void)SDL_snprintf(file_path, sizeof(file_path), "%s/ibus/bus/%s-%s-%s",

0 commit comments

Comments
 (0)