Skip to content
Snippets Groups Projects
Commit 5cad85d3 authored by Ludovico de Nittis's avatar Ludovico de Nittis :palm_tree:
Browse files

Add runtime content check for "overrides" and pinned libraries


When we are in a steamrt container we log the content of the
"/overrides" folder. Otherwise, if we are not in a container, we log the
content of both "pinned_libs_32" and "pinned_libs_64".

Signed-off-by: default avatarLudovico de Nittis <ludovico.denittis@collabora.com>
parent ae82c0b6
Branches
Tags
1 merge request!64Add runtime content check for "overrides" and pinned libraries
Pipeline #1822 passed
Showing
with 972 additions and 11 deletions
...@@ -463,6 +463,9 @@ main (int argc, ...@@ -463,6 +463,9 @@ main (int argc,
gchar *inst_path = NULL; gchar *inst_path = NULL;
gchar *data_path = NULL; gchar *data_path = NULL;
gchar *rt_path = NULL; gchar *rt_path = NULL;
gchar **overrides = NULL;
gchar **messages = NULL;
gchar **values = NULL;
int opt; int opt;
static const char * const multiarch_tuples[] = { SRT_ABI_I386, SRT_ABI_X86_64, NULL }; static const char * const multiarch_tuples[] = { SRT_ABI_I386, SRT_ABI_X86_64, NULL };
GList *icds; GList *icds;
...@@ -530,17 +533,99 @@ main (int argc, ...@@ -530,17 +533,99 @@ main (int argc,
json_builder_set_member_name (builder, "runtime"); json_builder_set_member_name (builder, "runtime");
json_builder_begin_object (builder); json_builder_begin_object (builder);
json_builder_set_member_name (builder, "path"); {
rt_path = srt_system_info_dup_runtime_path (info); json_builder_set_member_name (builder, "path");
json_builder_add_string_value (builder, rt_path); rt_path = srt_system_info_dup_runtime_path (info);
json_builder_set_member_name (builder, "version"); json_builder_add_string_value (builder, rt_path);
version = srt_system_info_dup_runtime_version (info); json_builder_set_member_name (builder, "version");
json_builder_add_string_value (builder, version); version = srt_system_info_dup_runtime_version (info);
json_builder_set_member_name (builder, "issues"); json_builder_add_string_value (builder, version);
json_builder_begin_array (builder); json_builder_set_member_name (builder, "issues");
runtime_issues = srt_system_info_get_runtime_issues (info); json_builder_begin_array (builder);
jsonify_runtime_issues (builder, runtime_issues); runtime_issues = srt_system_info_get_runtime_issues (info);
json_builder_end_array (builder); jsonify_runtime_issues (builder, runtime_issues);
json_builder_end_array (builder);
if (g_strcmp0 (rt_path, "/") == 0)
{
overrides = srt_system_info_list_pressure_vessel_overrides (info, &messages);
json_builder_set_member_name (builder, "overrides");
json_builder_begin_object (builder);
if (overrides != NULL && overrides[0] != NULL)
{
json_builder_set_member_name (builder, "list");
json_builder_begin_array (builder);
for (gsize i = 0; overrides[i] != NULL; i++)
json_builder_add_string_value (builder, overrides[i]);
json_builder_end_array (builder);
}
if (messages != NULL && messages[0] != NULL)
{
json_builder_set_member_name (builder, "messages");
json_builder_begin_array (builder);
for (gsize i = 0; messages[i] != NULL; i++)
json_builder_add_string_value (builder, messages[i]);
json_builder_end_array (builder);
}
json_builder_end_object (builder);
g_strfreev (overrides);
g_strfreev (messages);
}
if (rt_path != NULL && g_strcmp0 (rt_path, "/") != 0)
{
values = srt_system_info_list_pinned_libs_32 (info, &messages);
json_builder_set_member_name (builder, "pinned_libs_32");
json_builder_begin_object (builder);
if (values != NULL && values[0] != NULL)
{
json_builder_set_member_name (builder, "list");
json_builder_begin_array (builder);
for (gsize i = 0; values[i] != NULL; i++)
json_builder_add_string_value (builder, values[i]);
json_builder_end_array (builder);
}
if (messages != NULL && messages[0] != NULL)
{
json_builder_set_member_name (builder, "messages");
json_builder_begin_array (builder);
for (gsize i = 0; messages[i] != NULL; i++)
json_builder_add_string_value (builder, messages[i]);
json_builder_end_array (builder);
}
json_builder_end_object (builder);
g_strfreev (values);
g_strfreev (messages);
values = srt_system_info_list_pinned_libs_64 (info, &messages);
json_builder_set_member_name (builder, "pinned_libs_64");
json_builder_begin_object (builder);
if (values != NULL && values[0] != NULL)
{
json_builder_set_member_name (builder, "list");
json_builder_begin_array (builder);
for (gsize i = 0; values[i] != NULL; i++)
json_builder_add_string_value (builder, values[i]);
json_builder_end_array (builder);
}
if (messages != NULL && messages[0] != NULL)
{
json_builder_set_member_name (builder, "messages");
json_builder_begin_array (builder);
for (gsize i = 0; messages[i] != NULL; i++)
json_builder_add_string_value (builder, messages[i]);
json_builder_end_array (builder);
}
json_builder_end_object (builder);
g_strfreev (values);
g_strfreev (messages);
}
}
json_builder_end_object (builder); json_builder_end_object (builder);
json_builder_set_member_name (builder, "os-release"); json_builder_set_member_name (builder, "os-release");
......
...@@ -138,6 +138,54 @@ keys: ...@@ -138,6 +138,54 @@ keys:
likely to break the use of libraries from the host system, likely to break the use of libraries from the host system,
in particular the Mesa graphics drivers. in particular the Mesa graphics drivers.
**overrides**
: An object representing the libraries that have been
overridden when the Steam Runtime is running in a
`pressure-vessel` container.
These libraries are taken from the host system, instead of being
taken from the container like all other libraries.
**list**
: A human-readable array of overridden libraries.
It is currently in `find -ls` format.
**messages**
: A human-readable array of errors and warning messages about
the overridden libraries.
It is currently the output on standard error of `find -ls`.
**pinned_libs_32**
: An object representing the %SRT_ABI_I386 libraries that have been
"pinned" when the Steam Runtime is running in an
`LD_LIBRARY_PATH`-based environment.
These libraries are taken from the Steam Runtime, even if a library
of the same SONAME exists on the host system.
**list**
: A human-readable array of %SRT_ABI_I386 "pinned" libraries.
It is currently in `find -ls` format.
**messages**
: A human-readable array of errors and warning messages about the
%SRT_ABI_I386 "pinned" libraries.
It is currently the output on standard error of `find -ls`.
**pinned_libs_64**
: An object representing the %SRT_ABI_X86_64 libraries that have been
"pinned" when the Steam Runtime is running in an
`LD_LIBRARY_PATH`-based environment.
These libraries are taken from the Steam Runtime, even if a library
of the same SONAME exists on the host system.
**list**
: A human-readable array of "pinned" %SRT_ABI_X86_64 libraries.
It is currently in `find -ls` format.
**messages**
: A human-readable array of errors and warning messages about the
%SRT_ABI_X86_64 "pinned" libraries.
It is currently the output on standard error of `find -ls`.
**os-release** **os-release**
: An object describing the operating system or container in which : An object describing the operating system or container in which
**steam-runtime-system-info** was run. The keys and values are **steam-runtime-system-info** was run. The keys and values are
......
...@@ -124,6 +124,20 @@ struct _SrtSystemInfo ...@@ -124,6 +124,20 @@ struct _SrtSystemInfo
gboolean have_egl; gboolean have_egl;
gboolean have_vulkan; gboolean have_vulkan;
} icds; } icds;
struct
{
gchar **values;
gchar **messages;
gboolean have_data;
} overrides;
struct
{
gchar **values_32;
gchar **messages_32;
gchar **values_64;
gchar **messages_64;
gboolean have_data;
} pinned_libs;
SrtOsRelease os_release; SrtOsRelease os_release;
SrtTestFlags test_flags; SrtTestFlags test_flags;
Tristate can_write_uinput; Tristate can_write_uinput;
...@@ -354,6 +368,30 @@ forget_icds (SrtSystemInfo *self) ...@@ -354,6 +368,30 @@ forget_icds (SrtSystemInfo *self)
self->icds.vulkan = NULL; self->icds.vulkan = NULL;
} }
/*
* Forget any cached information about overrides.
*/
static void
forget_overrides (SrtSystemInfo *self)
{
g_clear_pointer (&self->overrides.values, g_strfreev);
g_clear_pointer (&self->overrides.messages, g_strfreev);
self->overrides.have_data = FALSE;
}
/*
* Forget any cached information about pinned libraries.
*/
static void
forget_pinned_libs (SrtSystemInfo *self)
{
g_clear_pointer (&self->pinned_libs.values_32, g_strfreev);
g_clear_pointer (&self->pinned_libs.messages_32, g_strfreev);
g_clear_pointer (&self->pinned_libs.values_64, g_strfreev);
g_clear_pointer (&self->pinned_libs.messages_64, g_strfreev);
self->pinned_libs.have_data = FALSE;
}
static void static void
srt_system_info_finalize (GObject *object) srt_system_info_finalize (GObject *object)
{ {
...@@ -362,6 +400,8 @@ srt_system_info_finalize (GObject *object) ...@@ -362,6 +400,8 @@ srt_system_info_finalize (GObject *object)
forget_icds (self); forget_icds (self);
forget_locales (self); forget_locales (self);
forget_os (self); forget_os (self);
forget_overrides (self);
forget_pinned_libs (self);
forget_runtime (self); forget_runtime (self);
forget_steam (self); forget_steam (self);
...@@ -567,6 +607,305 @@ ensure_expectations (SrtSystemInfo *self) ...@@ -567,6 +607,305 @@ ensure_expectations (SrtSystemInfo *self)
return self->expectations[0] != '\0'; return self->expectations[0] != '\0';
} }
static void
ensure_overrides_cached (SrtSystemInfo *self)
{
const gchar *argv[] = {"find", "overrides", "-ls", NULL};
const char *sysroot = NULL;
gchar *output = NULL;
gchar *messages = NULL;
gchar *overrides_path = NULL;
gchar *runtime = NULL;
int exit_status = -1;
GError *error = NULL;
if (!self->overrides.have_data)
{
if (self->env != NULL)
sysroot = g_environ_getenv (self->env, "SRT_TEST_SYSROOT");
else
sysroot = g_getenv ("SRT_TEST_SYSROOT");
self->overrides.have_data = TRUE;
runtime = srt_system_info_dup_runtime_path (self);
/* Skip checking the overridden folder if we are not in a pressure-vessel
* Steam Runtime container */
if (g_strcmp0 (runtime, "/") != 0)
goto out;
if (!g_spawn_sync (sysroot == NULL ? "/" : sysroot, /* working directory */
(gchar **) argv,
get_environ (self),
G_SPAWN_SEARCH_PATH,
NULL, /* child setup */
NULL, /* user data */
&output, /* stdout */
&messages, /* stderr */
&exit_status,
&error))
{
g_debug ("An error occurred calling the \"find\" binary: %s", error->message);
self->overrides.messages = g_new0 (gchar *, 2);
self->overrides.messages[0] = g_strdup_printf ("%s %d: %s", g_quark_to_string (error->domain), error->code, error->message);
self->overrides.messages[1] = NULL;
goto out;
}
if (exit_status != 0)
g_debug ("... wait status %d", exit_status);
if (output != NULL)
{
g_strchomp (output);
self->overrides.values = g_strsplit (output, "\n", -1);
}
if (messages != NULL)
{
g_strchomp (messages);
self->overrides.messages = g_strsplit (messages, "\n", -1);
}
}
out:
g_free (output);
g_free (messages);
g_free (overrides_path);
g_free (runtime);
g_clear_error (&error);
}
/**
* srt_system_info_list_pressure_vessel_overrides:
* @self: The #SrtSystemInfo object
* @messages: (optional) (out) (array zero-terminated=1) (transfer full): If
* not %NULL, used to return a %NULL-terminated array of diagnostic
* messages. Free with g_strfreev().
*
* If running in a Steam Runtime container using `pressure-vessel`,
* list the libraries from the container that have been overridden
* with libraries from the host system.
*
* The output is intended to be human-readable debugging information,
* rather than something to use programmatically, and its format is
* not guaranteed. It is currently in `find -ls` format.
*
* Similarly, @messages is intended to be human-readable debugging
* information. It is currently whatever was output on standard error
* by `find -ls`.
*
* Returns: (array zero-terminated=1) (transfer full) (nullable): A
* %NULL-terminated array of libraries that have been overridden,
* or %NULL if this process does not appear to be in a pressure-vessel
* container. Free with g_strfreev().
*/
gchar **
srt_system_info_list_pressure_vessel_overrides (SrtSystemInfo *self,
gchar ***messages)
{
g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), NULL);
ensure_overrides_cached (self);
if (messages != NULL)
*messages = g_strdupv (self->overrides.messages);
return g_strdupv (self->overrides.values);
}
static void
ensure_pinned_libs_cached (SrtSystemInfo *self)
{
gchar *output = NULL;
gchar *messages = NULL;
gchar *runtime = NULL;
int exit_status = -1;
GError *error = NULL;
if (!self->pinned_libs.have_data)
{
runtime = srt_system_info_dup_runtime_path (self);
self->pinned_libs.have_data = TRUE;
if (runtime == NULL || g_strcmp0 (runtime, "/") == 0)
return;
const gchar *argv[] = {"find", "pinned_libs_32", "-ls", NULL};
if (!g_spawn_sync (runtime, /* working directory */
(gchar **) argv,
get_environ (self),
G_SPAWN_SEARCH_PATH,
NULL, /* child setup */
NULL, /* user data */
&output, /* stdout */
&messages, /* stderr */
&exit_status,
&error))
{
g_debug ("An error occurred calling the \"find\" binary: %s", error->message);
self->pinned_libs.messages_32 = g_new0 (gchar *, 2);
self->pinned_libs.messages_32[0] = g_strdup_printf ("%s %d: %s", g_quark_to_string (error->domain), error->code, error->message);
self->pinned_libs.messages_32[1] = NULL;
goto out;
}
if (exit_status != 0)
g_debug ("... wait status %d", exit_status);
if (output != NULL)
{
g_strchomp (output);
self->pinned_libs.values_32 = g_strsplit (output, "\n", -1);
}
if (messages != NULL)
{
g_strchomp (messages);
self->pinned_libs.messages_32 = g_strsplit (messages, "\n", -1);
}
g_free (output);
g_free (messages);
/* Do the same check for `pinned_libs_64` */
argv[1] = "pinned_libs_64";
if (!g_spawn_sync (runtime, /* working directory */
(gchar **) argv,
get_environ (self),
G_SPAWN_SEARCH_PATH,
NULL, /* child setup */
NULL, /* user data */
&output, /* stdout */
&messages, /* stderr */
&exit_status,
&error))
{
g_debug ("An error occurred calling the \"find\" binary: %s", error->message);
self->pinned_libs.messages_64 = g_new0 (gchar *, 2);
self->pinned_libs.messages_64[0] = g_strdup_printf ("%s %d: %s", g_quark_to_string (error->domain), error->code, error->message);
self->pinned_libs.messages_64[1] = NULL;
goto out;
}
if (exit_status != 0)
g_debug ("... wait status %d", exit_status);
if (output != NULL)
{
g_strchomp (output);
self->pinned_libs.values_64 = g_strsplit (output, "\n", -1);
}
if (messages != NULL)
{
g_strchomp (messages);
self->pinned_libs.messages_64 = g_strsplit (messages, "\n", -1);
}
}
out:
g_clear_error (&error);
g_free (output);
g_free (messages);
g_free (runtime);
}
/**
* srt_system_info_list_pinned_libs_32:
* @self: The #SrtSystemInfo object
* @messages: (optional) (out) (array zero-terminated=1) (transfer full): If
* not %NULL, used to return a %NULL-terminated array of diagnostic
* messages. Free with g_strfreev().
*
* If running in an `LD_LIBRARY_PATH`-based Steam Runtime, return
* information about %SRT_ABI_I386 libraries that have been "pinned".
* Normally, the Steam Runtime infrastructure prefers to use shared
* libraries from the host OS, if available, rather than the
* library of the same `SONAME` from the Steam Runtime. However, if
* a library in the Steam Runtime is newer then the version in the
* host OS, or if it is known to be incompatible with newer
* libraries with the same `SONAME`, then the library from the
* Steam Runtime is said to have been "pinned": it is used with a
* higher precedence than libraries from the host OS.
*
* If not in an `LD_LIBRARY_PATH`-based Steam Runtime, return %NULL.
*
* The output is intended to be human-readable debugging information,
* rather than something to use programmatically, and its format is
* not guaranteed. It is currently in `find -ls` format.
*
* Similarly, @messages is intended to be human-readable debugging
* information. It is currently whatever was output on standard error
* by `find -ls`.
*
* Returns: (array zero-terminated=1) (transfer full) (element-type utf8) (nullable):
* An array of strings, or %NULL if we were unable to call "find".
* Free with g_strfreev().
*/
gchar **
srt_system_info_list_pinned_libs_32 (SrtSystemInfo *self,
gchar ***messages)
{
g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), NULL);
ensure_pinned_libs_cached (self);
if (messages != NULL)
*messages = g_strdupv (self->pinned_libs.messages_32);
return g_strdupv (self->pinned_libs.values_32);
}
/**
* srt_system_info_list_pinned_libs_64:
* @self: The #SrtSystemInfo object
* @messages: (optional) (out) (array zero-terminated=1) (transfer full): If
* not %NULL, used to return a %NULL-terminated array of diagnostic
* messages. Free with g_strfreev().
*
* If running in an `LD_LIBRARY_PATH`-based Steam Runtime, return
* information about %SRT_ABI_X86_64 libraries that have been "pinned".
* Normally, the Steam Runtime infrastructure prefers to use shared
* libraries from the host OS, if available, rather than the
* library of the same `SONAME` from the Steam Runtime. However, if
* a library in the Steam Runtime is newer then the version in the
* host OS, or if it is known to be incompatible with newer
* libraries with the same `SONAME`, then the library from the
* Steam Runtime is said to have been "pinned": it is used with a
* higher precedence than libraries from the host OS.
*
* If not in an `LD_LIBRARY_PATH`-based Steam Runtime, return %NULL.
*
* The output is intended to be human-readable debugging information,
* rather than something to use programmatically, and its format is
* not guaranteed. It is currently in `find -ls` format.
*
* Similarly, @messages is intended to be human-readable debugging
* information. It is currently whatever was output on standard error
* by `find -ls`.
*
* Returns: (array zero-terminated=1) (transfer full) (element-type utf8) (nullable):
* An array of strings, or %NULL if we were unable to call "find".
* Free with g_strfreev().
*/
gchar **
srt_system_info_list_pinned_libs_64 (SrtSystemInfo *self,
gchar ***messages)
{
g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), NULL);
ensure_pinned_libs_cached (self);
if (messages != NULL)
*messages = g_strdupv (self->pinned_libs.messages_64);
return g_strdupv (self->pinned_libs.values_64);
}
/** /**
* srt_system_info_check_libraries: * srt_system_info_check_libraries:
* @self: The #SrtSystemInfo object to use. * @self: The #SrtSystemInfo object to use.
...@@ -1044,6 +1383,8 @@ srt_system_info_set_environ (SrtSystemInfo *self, ...@@ -1044,6 +1383,8 @@ srt_system_info_set_environ (SrtSystemInfo *self,
forget_graphics_results (self); forget_graphics_results (self);
forget_locales (self); forget_locales (self);
forget_os (self); forget_os (self);
forget_overrides (self);
forget_pinned_libs (self);
g_strfreev (self->env); g_strfreev (self->env);
self->env = g_strdupv ((gchar **) env); self->env = g_strdupv ((gchar **) env);
......
...@@ -113,6 +113,14 @@ SrtSteamIssues srt_system_info_get_steam_issues (SrtSystemInfo *self); ...@@ -113,6 +113,14 @@ SrtSteamIssues srt_system_info_get_steam_issues (SrtSystemInfo *self);
gchar *srt_system_info_dup_steam_installation_path (SrtSystemInfo *self); gchar *srt_system_info_dup_steam_installation_path (SrtSystemInfo *self);
gchar *srt_system_info_dup_steam_data_path (SrtSystemInfo *self); gchar *srt_system_info_dup_steam_data_path (SrtSystemInfo *self);
gchar ** srt_system_info_list_pressure_vessel_overrides (SrtSystemInfo *self,
gchar ***messages);
gchar ** srt_system_info_list_pinned_libs_32 (SrtSystemInfo *self,
gchar ***messages);
gchar ** srt_system_info_list_pinned_libs_64 (SrtSystemInfo *self,
gchar ***messages);
SrtLocaleIssues srt_system_info_get_locale_issues (SrtSystemInfo *self); SrtLocaleIssues srt_system_info_get_locale_issues (SrtSystemInfo *self);
SrtLocale *srt_system_info_check_locale (SrtSystemInfo *self, SrtLocale *srt_system_info_check_locale (SrtSystemInfo *self,
const char *requested_name, const char *requested_name,
......
../usr/lib/os-release
\ No newline at end of file
/run/host/usr/lib/libgcc_s.so.1
\ No newline at end of file
NAME="Steam Runtime"
VERSION="1 (scout)"
ID=steamrt
ID_LIKE=ubuntu
PRETTY_NAME="Steam Runtime 1 (scout)"
VERSION_ID="1"
BUILD_ID="0.20190924.0"
VARIANT=Platform
VARIANT_ID="com.valvesoftware.steamruntime.platform-amd64_i386-scout"
/run/host/usr/lib/libgcc_s.so.1
\ No newline at end of file
...@@ -514,6 +514,10 @@ steam_presence (Fixture *f, ...@@ -514,6 +514,10 @@ steam_presence (Fixture *f,
array = json_object_get_array_member (json_sub_object, "issues"); array = json_object_get_array_member (json_sub_object, "issues");
g_assert_cmpint (json_array_get_length (array), ==, 0); g_assert_cmpint (json_array_get_length (array), ==, 0);
g_assert_false (json_object_has_member (json_sub_object, "overrides"));
g_assert_true (json_object_has_member (json_sub_object, "pinned_libs_32"));
g_assert_true (json_object_has_member (json_sub_object, "pinned_libs_64"));
g_assert_true (json_object_has_member (json, "architectures")); g_assert_true (json_object_has_member (json, "architectures"));
fake_home_clean_up (fake_home); fake_home_clean_up (fake_home);
......
...@@ -1664,6 +1664,456 @@ os_no_os_release (Fixture *f, ...@@ -1664,6 +1664,456 @@ os_no_os_release (Fixture *f,
g_strfreev (envp); g_strfreev (envp);
} }
static void
overrides (Fixture *f,
gconstpointer context)
{
SrtSystemInfo *info;
gchar **envp;
gchar **output;
gchar **issues;
gchar *sysroot;
gchar *s;
gsize i;
gboolean seen_link;
sysroot = g_build_filename (f->srcdir, "sysroots", "steamrt", NULL);
envp = g_get_environ ();
envp = g_environ_setenv (envp, "SRT_TEST_SYSROOT", sysroot, TRUE);
info = srt_system_info_new (NULL);
srt_system_info_set_environ (info, envp);
s = srt_system_info_dup_os_id (info);
g_assert_cmpstr (s, ==, "steamrt");
g_free (s);
output = srt_system_info_list_pressure_vessel_overrides (info, &issues);
/* In the steamrt test overrides folder we expect to have a symbolic
* link to "/run/host/usr/lib/libgcc_s.so.1" */
seen_link = FALSE;
/* The output is not guaranteed to be ordered */
g_debug ("overrides content:");
for (i = 0; output[i] != NULL; i++)
{
g_debug ("%s", output[i]);
if (strstr (output[i], "/run/host/usr/lib/libgcc_s.so.1") != NULL)
seen_link = TRUE;
}
/* The overrides folder contains 4 folders plus the root folder, plus one symlink,
* plus 2 ".keep" files */
g_assert_cmpint (i, ==, 8);
g_assert_true (seen_link);
g_strfreev (output);
g_assert_nonnull (issues);
g_assert_cmpstr (issues[0], ==, NULL);
g_strfreev (issues);
/* Repeat the same check, this time using the cached result */
output = srt_system_info_list_pressure_vessel_overrides (info, &issues);
seen_link = FALSE;
for (i = 0; output[i] != NULL; i++)
{
if (strstr (output[i], "/run/host/usr/lib/libgcc_s.so.1") != NULL)
seen_link = TRUE;
}
g_assert_cmpint (i, ==, 8);
g_assert_true (seen_link);
g_strfreev (output);
g_assert_nonnull (issues);
g_assert_cmpstr (issues[0], ==, NULL);
g_strfreev (issues);
g_object_unref (info);
g_free (sysroot);
g_strfreev (envp);
}
static void
overrides_issues (Fixture *f,
gconstpointer context)
{
SrtSystemInfo *info;
gchar **envp;
gchar **output;
gchar **issues;
gchar *sysroot;
gchar *lib_folder;
gsize i;
gboolean seen_link;
sysroot = g_build_filename (f->srcdir, "sysroots", "steamrt-overrides-issues", NULL);
envp = g_get_environ ();
envp = g_environ_setenv (envp, "SRT_TEST_SYSROOT", sysroot, TRUE);
info = srt_system_info_new (NULL);
srt_system_info_set_environ (info, envp);
lib_folder = g_build_filename (sysroot, "overrides", "lib", NULL);
/* Remove the read permission for the "lib" folder */
g_assert_cmpint (g_chmod (lib_folder, 0200), ==, 0);
if (g_access (lib_folder, R_OK) == 0)
{
g_test_skip ("This test can't be executed with elevated privileges");
goto out;
}
output = srt_system_info_list_pressure_vessel_overrides (info, &issues);
/* In the steamrt test overrides folder we expect to have a symbolic
* link to "/run/host/usr/lib/libgcc_s.so.1" */
seen_link = FALSE;
/* The output is not guaranteed to be ordered */
g_debug ("overrides content:");
for (i = 0; output[i] != NULL; i++)
{
g_debug ("%s", output[i]);
if (strstr (output[i], "/run/host/usr/lib/libgcc_s.so.1") != NULL)
seen_link = TRUE;
}
/* The overrides folder contains 4 folders plus the root folder, plus one symlink,
* plus 2 ".keep" files.
* We expect to not be able to open the "lib" folder, so we should have 4 less items than
* a "normal" scenario */
g_assert_cmpint (i, ==, 4);
/* We expect not to be able to reach the symlink */
g_assert_false (seen_link);
g_strfreev (output);
g_assert_nonnull (issues);
g_assert_cmpstr (strstr (issues[0], "overrides/lib"), !=, NULL);
g_strfreev (issues);
out:
/* Re set the permissions for "lib" to the default 755 */
g_chmod (lib_folder, 0755);
g_object_unref (info);
g_free (sysroot);
g_free (lib_folder);
g_strfreev (envp);
}
static void
overrides_not_available (Fixture *f,
gconstpointer context)
{
SrtSystemInfo *info;
gchar **envp;
gchar **output;
gchar **issues;
gchar *sysroot;
sysroot = g_build_filename (f->srcdir, "sysroots", "debian10", NULL);
envp = g_get_environ ();
envp = g_environ_setenv (envp, "SRT_TEST_SYSROOT", sysroot, TRUE);
info = srt_system_info_new (NULL);
srt_system_info_set_environ (info, envp);
output = srt_system_info_list_pressure_vessel_overrides (info, &issues);
g_assert_null (output);
g_assert_null (issues);
g_object_unref (info);
g_free (sysroot);
g_strfreev (envp);
}
static void
pinned_libraries (Fixture *f,
gconstpointer context)
{
SrtSystemInfo *info;
FakeHome *fake_home;
gchar *target1 = NULL;
gchar *target2 = NULL;
gchar *start = NULL;
gchar *has_pins = NULL;
gchar **values = NULL;
gchar **messages = NULL;
GFile *symlink = NULL;
gboolean seen_pins;
gsize i;
GError *error = NULL;
fake_home = fake_home_new ();
fake_home_create_structure (fake_home);
info = srt_system_info_new (NULL);
srt_system_info_set_environ (info, fake_home->env);
start = g_build_filename (fake_home->pinned_32, "libcurl.so.3", NULL);
target1 = g_build_filename (fake_home->pinned_32, "libcurl.so.4", NULL);
symlink = g_file_new_for_path (start);
g_file_make_symbolic_link (symlink, target1, NULL, &error);
g_object_unref (symlink);
g_assert_no_error (error);
target2 = g_build_filename (fake_home->i386_usr_lib_i386, "libcurl.so.4.2.0", NULL);
g_assert_cmpint (g_creat (target2, 0755), >, -1);
symlink = g_file_new_for_path (target1);
g_file_make_symbolic_link (symlink, target2, NULL, &error);
g_object_unref (symlink);
g_assert_no_error (error);
has_pins = g_build_filename (fake_home->pinned_32, "has_pins", NULL);
g_assert_cmpint (g_creat (has_pins, 0755), >, -1);
values = srt_system_info_list_pinned_libs_32 (info, &messages);
g_assert_nonnull (values);
seen_pins = FALSE;
/* The output is not guaranteed to be ordered */
g_debug ("pinned_libs_32 content:");
for (i = 0; values[i] != NULL; i++)
{
g_debug ("%s", values[i]);
if (strstr (values[i], "has_pins") != NULL)
seen_pins = TRUE;
}
/* We placed 3 files in `pinned_libs_32`. We expect to have 3 files plus the folder
* itself */
g_assert_cmpint (i, ==, 4);
g_assert_true (seen_pins);
g_strfreev (values);
g_assert_nonnull (messages);
g_assert_cmpstr (messages[0], ==, NULL);
g_strfreev (messages);
/* Repeat the same check, this time using the cached values */
values = srt_system_info_list_pinned_libs_32 (info, &messages);
g_assert_nonnull (values);
seen_pins = FALSE;
for (i = 0; values[i] != NULL; i++)
{
if (strstr (values[i], "has_pins") != NULL)
seen_pins = TRUE;
}
g_assert_cmpint (i, ==, 4);
g_assert_true (seen_pins);
g_strfreev (values);
g_assert_nonnull (messages);
g_assert_cmpstr (messages[0], ==, NULL);
g_strfreev (messages);
g_free (target1);
g_free (target2);
g_free (start);
g_free (has_pins);
/* Check pinned_libs_64.
* Set again the environ to flush the cached values */
srt_system_info_set_environ (info, fake_home->env);
start = g_build_filename (fake_home->pinned_64, "libcurl.so.3", NULL);
target1 = g_build_filename (fake_home->pinned_64, "libcurl.so.4", NULL);
symlink = g_file_new_for_path (start);
g_file_make_symbolic_link (symlink, target1, NULL, &error);
g_object_unref (symlink);
g_assert_no_error (error);
target2 = g_build_filename (fake_home->amd64_usr_lib_64, "libcurl.so.4.2.0", NULL);
g_assert_cmpint (g_creat (target2, 0755), >, -1);
symlink = g_file_new_for_path (target1);
g_file_make_symbolic_link (symlink, target2, NULL, &error);
g_object_unref (symlink);
g_assert_no_error (error);
has_pins = g_build_filename (fake_home->pinned_64, "has_pins", NULL);
g_assert_cmpint (g_creat (has_pins, 0755), >, -1);
values = srt_system_info_list_pinned_libs_64 (info, &messages);
g_assert_nonnull (values);
seen_pins = FALSE;
g_debug ("pinned_libs_64 content:");
for (i = 0; values[i] != NULL; i++)
{
g_debug ("%s", values[i]);
if (strstr (values[i], "has_pins") != NULL)
seen_pins = TRUE;
}
g_assert_cmpint (i, ==, 4);
g_assert_true (seen_pins);
g_strfreev (values);
g_assert_nonnull (messages);
g_assert_cmpstr (messages[0], ==, NULL);
g_strfreev (messages);
/* Repeat the same check, this time using the cached values */
values = srt_system_info_list_pinned_libs_64 (info, &messages);
g_assert_nonnull (values);
seen_pins = FALSE;
for (i = 0; values[i] != NULL; i++)
{
if (strstr (values[i], "has_pins") != NULL)
seen_pins = TRUE;
}
g_assert_cmpint (i, ==, 4);
g_assert_true (seen_pins);
g_strfreev (values);
g_assert_nonnull (messages);
g_assert_cmpstr (messages[0], ==, NULL);
g_strfreev (messages);
g_free (target1);
g_free (target2);
g_free (start);
g_free (has_pins);
fake_home_clean_up (fake_home);
g_object_unref (info);
}
static void
pinned_libraries_permission (Fixture *f,
gconstpointer context)
{
SrtSystemInfo *info;
FakeHome *fake_home;
gchar *no_access = NULL;
gchar **values = NULL;
gchar **messages = NULL;
gboolean seen_no_access;
gsize i;
fake_home = fake_home_new ();
fake_home_create_structure (fake_home);
info = srt_system_info_new (NULL);
srt_system_info_set_environ (info, fake_home->env);
no_access = g_build_filename (fake_home->pinned_32, "no_access", NULL);
/* Creates a folder without read permissions */
g_assert_cmpint (g_mkdir_with_parents (no_access, 0200), ==, 0);
if (g_access (no_access, R_OK) == 0)
{
g_test_skip ("This test can't be executed with elevated privileges");
goto out;
}
values = srt_system_info_list_pinned_libs_32 (info, &messages);
g_assert_nonnull (values);
seen_no_access = FALSE;
/* The output is not guaranteed to be ordered */
g_debug ("pinned_libs_32 content:");
for (i = 0; values[i] != NULL; i++)
{
g_debug ("%s", values[i]);
if (strstr (values[i], "no_access") != NULL)
seen_no_access = TRUE;
}
/* We placed 1 folder in `pinned_libs_32`. We expect to have 1 folder plus the
* parent folder itself */
g_assert_cmpint (i, ==, 2);
g_assert_true (seen_no_access);
g_strfreev (values);
g_assert_nonnull (messages);
g_assert_cmpstr (strstr (messages[0], "no_access"), !=, NULL);
g_strfreev (messages);
g_free (no_access);
/* Check pinned_libs_64.
* Set again the environ to flush the cached values */
srt_system_info_set_environ (info, fake_home->env);
no_access = g_build_filename (fake_home->pinned_64, "no_access", NULL);
g_assert_cmpint (g_mkdir_with_parents (no_access, 0311), ==, 0);
values = srt_system_info_list_pinned_libs_64 (info, &messages);
g_assert_nonnull (values);
seen_no_access = FALSE;
/* The output is not guaranteed to be ordered */
g_debug ("pinned_libs_64 content:");
for (i = 0; values[i] != NULL; i++)
{
g_debug ("%s", values[i]);
if (strstr (values[i], "no_access") != NULL)
seen_no_access = TRUE;
}
/* We placed 1 folder in `pinned_libs_32`. We expect to have 1 folder plus the
* parent folder itself */
g_assert_cmpint (i, ==, 2);
g_assert_true (seen_no_access);
g_strfreev (values);
g_assert_nonnull (messages);
g_assert_cmpstr (strstr (messages[0], "no_access"), !=, NULL);
g_strfreev (messages);
out:
g_free (no_access);
fake_home_clean_up (fake_home);
g_object_unref (info);
}
static void
pinned_libraries_missing (Fixture *f,
gconstpointer context)
{
SrtSystemInfo *info;
FakeHome *fake_home;
gchar **values = NULL;
gchar **messages = NULL;
fake_home = fake_home_new ();
fake_home_create_structure (fake_home);
info = srt_system_info_new (NULL);
srt_system_info_set_environ (info, fake_home->env);
g_assert_cmpint (g_rmdir (fake_home->pinned_32), ==, 0);
values = srt_system_info_list_pinned_libs_32 (info, &messages);
g_assert_nonnull (values);
g_assert_cmpstr (values[0], ==, NULL);
g_strfreev (values);
g_assert_nonnull (messages);
g_assert_cmpstr (strstr (messages[0], "pinned_libs_32"), !=, NULL);
g_strfreev (messages);
/* Check pinned_libs_64.
* Set again the environ to flush the cached values */
srt_system_info_set_environ (info, fake_home->env);
g_assert_cmpint (g_rmdir (fake_home->pinned_64), ==, 0);
values = srt_system_info_list_pinned_libs_64 (info, &messages);
g_assert_nonnull (values);
g_assert_cmpstr (values[0], ==, NULL);
g_strfreev (values);
g_assert_nonnull (messages);
g_assert_cmpstr (strstr (messages[0], "pinned_libs_64"), !=, NULL);
g_strfreev (messages);
fake_home_clean_up (fake_home);
g_object_unref (info);
}
int int
main (int argc, main (int argc,
char **argv) char **argv)
...@@ -1718,5 +2168,18 @@ main (int argc, ...@@ -1718,5 +2168,18 @@ main (int argc,
g_test_add ("/system-info/os/no-os-release", Fixture, NULL, g_test_add ("/system-info/os/no-os-release", Fixture, NULL,
setup, os_no_os_release, teardown); setup, os_no_os_release, teardown);
g_test_add ("/system-info/libs/overrides", Fixture, NULL,
setup, overrides, teardown);
g_test_add ("/system-info/libs/overrides_issues", Fixture, NULL,
setup, overrides_issues, teardown);
g_test_add ("/system-info/libs/overrides_not_available", Fixture, NULL,
setup, overrides_not_available, teardown);
g_test_add ("/system-info/libs/pinned_libraries", Fixture, NULL,
setup, pinned_libraries, teardown);
g_test_add ("/system-info/libs/pinned_libraries_permission", Fixture, NULL,
setup, pinned_libraries_permission, teardown);
g_test_add ("/system-info/libs/pinned_libraries_missing", Fixture, NULL,
setup, pinned_libraries_missing, teardown);
return g_test_run (); return g_test_run ();
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment