Emit a critical warning if a plugin tries to use HWIDs in ->init()

The HWIDs are only available for ->setup() and ->coldplug().
This commit is contained in:
Richard Hughes 2022-10-25 11:17:10 +01:00 committed by Mario Limonciello
parent ee8c63b56a
commit 2c321ac29b
4 changed files with 73 additions and 20 deletions

View File

@ -37,6 +37,7 @@ typedef struct {
guint battery_level; guint battery_level;
guint battery_threshold; guint battery_threshold;
FuBiosSettings *host_bios_settings; FuBiosSettings *host_bios_settings;
gboolean loaded_hwinfo;
} FuContextPrivate; } FuContextPrivate;
enum { SIGNAL_SECURITY_CHANGED, SIGNAL_LAST }; enum { SIGNAL_SECURITY_CHANGED, SIGNAL_LAST };
@ -76,6 +77,10 @@ fu_context_get_smbios_string(FuContext *self, guint8 structure_type, guint8 offs
{ {
FuContextPrivate *priv = GET_PRIVATE(self); FuContextPrivate *priv = GET_PRIVATE(self);
g_return_val_if_fail(FU_IS_CONTEXT(self), NULL); g_return_val_if_fail(FU_IS_CONTEXT(self), NULL);
if (!priv->loaded_hwinfo) {
g_critical("cannot use SMBIOS before calling ->load_hwinfo()");
return NULL;
}
return fu_smbios_get_string(priv->smbios, structure_type, offset, NULL); return fu_smbios_get_string(priv->smbios, structure_type, offset, NULL);
} }
@ -100,6 +105,11 @@ fu_context_get_smbios_data(FuContext *self, guint8 structure_type, GError **erro
g_return_val_if_fail(FU_IS_CONTEXT(self), NULL); g_return_val_if_fail(FU_IS_CONTEXT(self), NULL);
/* must be valid and non-zero length */ /* must be valid and non-zero length */
if (!priv->loaded_hwinfo) {
g_critical("cannot use SMBIOS before calling ->load_hwinfo()");
g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, "no data");
return NULL;
}
blob = fu_smbios_get_data(priv->smbios, structure_type, error); blob = fu_smbios_get_data(priv->smbios, structure_type, error);
if (blob == NULL) if (blob == NULL)
return NULL; return NULL;
@ -130,6 +140,10 @@ fu_context_get_smbios_integer(FuContext *self, guint8 type, guint8 offset)
{ {
FuContextPrivate *priv = GET_PRIVATE(self); FuContextPrivate *priv = GET_PRIVATE(self);
g_return_val_if_fail(FU_IS_CONTEXT(self), G_MAXUINT); g_return_val_if_fail(FU_IS_CONTEXT(self), G_MAXUINT);
if (!priv->loaded_hwinfo) {
g_critical("cannot use SMBIOS before calling ->load_hwinfo()");
return G_MAXUINT;
}
return fu_smbios_get_integer(priv->smbios, type, offset, NULL); return fu_smbios_get_integer(priv->smbios, type, offset, NULL);
} }
@ -224,6 +238,10 @@ fu_context_has_hwid_guid(FuContext *self, const gchar *guid)
{ {
FuContextPrivate *priv = GET_PRIVATE(self); FuContextPrivate *priv = GET_PRIVATE(self);
g_return_val_if_fail(FU_IS_CONTEXT(self), FALSE); g_return_val_if_fail(FU_IS_CONTEXT(self), FALSE);
if (!priv->loaded_hwinfo) {
g_critical("cannot use HWIDs before calling ->load_hwinfo()");
return FALSE;
}
return fu_hwids_has_guid(priv->hwids, guid); return fu_hwids_has_guid(priv->hwids, guid);
} }
@ -243,6 +261,10 @@ fu_context_get_hwid_guids(FuContext *self)
{ {
FuContextPrivate *priv = GET_PRIVATE(self); FuContextPrivate *priv = GET_PRIVATE(self);
g_return_val_if_fail(FU_IS_CONTEXT(self), NULL); g_return_val_if_fail(FU_IS_CONTEXT(self), NULL);
if (!priv->loaded_hwinfo) {
g_critical("cannot use HWIDs before calling ->load_hwinfo()");
return NULL;
}
return fu_hwids_get_guids(priv->hwids); return fu_hwids_get_guids(priv->hwids);
} }
@ -264,6 +286,10 @@ fu_context_get_hwid_value(FuContext *self, const gchar *key)
FuContextPrivate *priv = GET_PRIVATE(self); FuContextPrivate *priv = GET_PRIVATE(self);
g_return_val_if_fail(FU_IS_CONTEXT(self), NULL); g_return_val_if_fail(FU_IS_CONTEXT(self), NULL);
g_return_val_if_fail(key != NULL, NULL); g_return_val_if_fail(key != NULL, NULL);
if (!priv->loaded_hwinfo) {
g_critical("cannot use HWIDs before calling ->load_hwinfo()");
return NULL;
}
return fu_hwids_get_value(priv->hwids, key); return fu_hwids_get_value(priv->hwids, key);
} }
@ -286,6 +312,11 @@ fu_context_get_hwid_replace_value(FuContext *self, const gchar *keys, GError **e
FuContextPrivate *priv = GET_PRIVATE(self); FuContextPrivate *priv = GET_PRIVATE(self);
g_return_val_if_fail(FU_IS_CONTEXT(self), NULL); g_return_val_if_fail(FU_IS_CONTEXT(self), NULL);
g_return_val_if_fail(keys != NULL, NULL); g_return_val_if_fail(keys != NULL, NULL);
if (!priv->loaded_hwinfo) {
g_critical("cannot use HWIDs before calling ->load_hwinfo()");
g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, "no data");
return NULL;
}
return fu_hwids_get_replace_values(priv->hwids, keys, error); return fu_hwids_get_replace_values(priv->hwids, keys, error);
} }
@ -614,6 +645,7 @@ fu_context_load_hwinfo(FuContext *self, GError **error)
g_warning("Failed to load SMBIOS: %s", error_smbios->message); g_warning("Failed to load SMBIOS: %s", error_smbios->message);
if (!fu_hwids_setup(priv->hwids, priv->smbios, &error_hwids)) if (!fu_hwids_setup(priv->hwids, priv->smbios, &error_hwids))
g_warning("Failed to load HWIDs: %s", error_hwids->message); g_warning("Failed to load HWIDs: %s", error_hwids->message);
priv->loaded_hwinfo = TRUE;
/* set the hwid flags */ /* set the hwid flags */
guids = fu_context_get_hwid_guids(self); guids = fu_context_get_hwid_guids(self);

View File

@ -37,6 +37,9 @@ _test_add_fake_devices_from_dir(FuPlugin *plugin, const gchar *path)
ret = fu_context_load_quirks(ctx, FU_QUIRKS_LOAD_FLAG_NO_CACHE, &error); ret = fu_context_load_quirks(ctx, FU_QUIRKS_LOAD_FLAG_NO_CACHE, &error);
g_assert_no_error(error); g_assert_no_error(error);
g_assert_true(ret); g_assert_true(ret);
ret = fu_context_load_hwinfo(ctx, &error);
g_assert_no_error(error);
g_assert_true(ret);
while ((basename = g_dir_read_name(dir)) != NULL) { while ((basename = g_dir_read_name(dir)) != NULL) {
g_autofree gchar *fn = g_build_filename(path, basename, NULL); g_autofree gchar *fn = g_build_filename(path, basename, NULL);
@ -81,6 +84,9 @@ fu_plugin_synaptics_mst_none_func(void)
ret = fu_context_load_quirks(ctx, FU_QUIRKS_LOAD_FLAG_NO_CACHE, &error); ret = fu_context_load_quirks(ctx, FU_QUIRKS_LOAD_FLAG_NO_CACHE, &error);
g_assert_no_error(error); g_assert_no_error(error);
g_assert_true(ret); g_assert_true(ret);
ret = fu_context_load_hwinfo(ctx, &error);
g_assert_no_error(error);
g_assert_true(ret);
plugin = fu_plugin_new_from_gtype(fu_synaptics_mst_plugin_get_type(), ctx); plugin = fu_plugin_new_from_gtype(fu_synaptics_mst_plugin_get_type(), ctx);
g_signal_connect(FU_PLUGIN(plugin), g_signal_connect(FU_PLUGIN(plugin),
@ -121,6 +127,9 @@ fu_plugin_synaptics_mst_tb16_func(void)
ret = fu_context_load_quirks(ctx, FU_QUIRKS_LOAD_FLAG_NO_CACHE, &error); ret = fu_context_load_quirks(ctx, FU_QUIRKS_LOAD_FLAG_NO_CACHE, &error);
g_assert_no_error(error); g_assert_no_error(error);
g_assert_true(ret); g_assert_true(ret);
ret = fu_context_load_hwinfo(ctx, &error);
g_assert_no_error(error);
g_assert_true(ret);
plugin = fu_plugin_new_from_gtype(fu_synaptics_mst_plugin_get_type(), ctx); plugin = fu_plugin_new_from_gtype(fu_synaptics_mst_plugin_get_type(), ctx);
g_signal_connect(FU_PLUGIN(plugin), g_signal_connect(FU_PLUGIN(plugin),

View File

@ -101,6 +101,7 @@ struct _FuEngine {
gboolean only_trusted; gboolean only_trusted;
gboolean write_history; gboolean write_history;
gboolean host_emulation; gboolean host_emulation;
gboolean has_hwinfo;
guint percentage; guint percentage;
FuHistory *history; FuHistory *history;
FuIdle *idle; FuIdle *idle;
@ -1887,8 +1888,11 @@ fu_engine_check_requirement(FuEngine *self,
} }
/* ensure hardware requirement */ /* ensure hardware requirement */
if (g_strcmp0(xb_node_get_element(req), "hardware") == 0) if (g_strcmp0(xb_node_get_element(req), "hardware") == 0) {
if (!self->has_hwinfo)
return TRUE;
return fu_engine_check_requirement_hardware(self, req, error); return fu_engine_check_requirement_hardware(self, req, error);
}
/* ensure client requirement */ /* ensure client requirement */
if (g_strcmp0(xb_node_get_element(req), "client") == 0) if (g_strcmp0(xb_node_get_element(req), "client") == 0)
@ -2195,18 +2199,20 @@ fu_engine_get_report_metadata(FuEngine *self, GError **error)
g_hash_table_insert(hash, g_strdup("HostBkc"), g_strdup(tmp)); g_hash_table_insert(hash, g_strdup("HostBkc"), g_strdup(tmp));
/* DMI data */ /* DMI data */
tmp = fu_context_get_hwid_value(self->ctx, FU_HWIDS_KEY_PRODUCT_NAME); if (self->has_hwinfo) {
if (tmp != NULL) tmp = fu_context_get_hwid_value(self->ctx, FU_HWIDS_KEY_PRODUCT_NAME);
g_hash_table_insert(hash, g_strdup("HostProduct"), g_strdup(tmp)); if (tmp != NULL)
tmp = fu_context_get_hwid_value(self->ctx, FU_HWIDS_KEY_FAMILY); g_hash_table_insert(hash, g_strdup("HostProduct"), g_strdup(tmp));
if (tmp != NULL) tmp = fu_context_get_hwid_value(self->ctx, FU_HWIDS_KEY_FAMILY);
g_hash_table_insert(hash, g_strdup("HostFamily"), g_strdup(tmp)); if (tmp != NULL)
tmp = fu_context_get_hwid_value(self->ctx, FU_HWIDS_KEY_PRODUCT_SKU); g_hash_table_insert(hash, g_strdup("HostFamily"), g_strdup(tmp));
if (tmp != NULL) tmp = fu_context_get_hwid_value(self->ctx, FU_HWIDS_KEY_PRODUCT_SKU);
g_hash_table_insert(hash, g_strdup("HostSku"), g_strdup(tmp)); if (tmp != NULL)
tmp = fu_context_get_hwid_value(self->ctx, FU_HWIDS_KEY_MANUFACTURER); g_hash_table_insert(hash, g_strdup("HostSku"), g_strdup(tmp));
if (tmp != NULL) tmp = fu_context_get_hwid_value(self->ctx, FU_HWIDS_KEY_MANUFACTURER);
g_hash_table_insert(hash, g_strdup("HostVendor"), g_strdup(tmp)); if (tmp != NULL)
g_hash_table_insert(hash, g_strdup("HostVendor"), g_strdup(tmp));
}
/* kernel version is often important for debugging failures */ /* kernel version is often important for debugging failures */
#ifdef HAVE_UTSNAME_H #ifdef HAVE_UTSNAME_H
@ -7600,7 +7606,6 @@ fu_engine_load(FuEngine *self, FuEngineLoadFlags flags, FuProgress *progress, GE
{ {
FuPlugin *plugin_uefi; FuPlugin *plugin_uefi;
FuQuirksLoadFlags quirks_flags = FU_QUIRKS_LOAD_FLAG_NONE; FuQuirksLoadFlags quirks_flags = FU_QUIRKS_LOAD_FLAG_NONE;
GPtrArray *guids;
const gchar *host_emulate = g_getenv("FWUPD_HOST_EMULATE"); const gchar *host_emulate = g_getenv("FWUPD_HOST_EMULATE");
guint backend_cnt = 0; guint backend_cnt = 0;
g_autoptr(GPtrArray) checksums_approved = NULL; g_autoptr(GPtrArray) checksums_approved = NULL;
@ -7769,6 +7774,7 @@ fu_engine_load(FuEngine *self, FuEngineLoadFlags flags, FuProgress *progress, GE
if (flags & FU_ENGINE_LOAD_FLAG_HWINFO) { if (flags & FU_ENGINE_LOAD_FLAG_HWINFO) {
if (!fu_context_load_hwinfo(self->ctx, error)) if (!fu_context_load_hwinfo(self->ctx, error))
return FALSE; return FALSE;
self->has_hwinfo = TRUE;
} }
fu_progress_step_done(progress); fu_progress_step_done(progress);
@ -7882,15 +7888,18 @@ fu_engine_load(FuEngine *self, FuEngineLoadFlags flags, FuProgress *progress, GE
fu_progress_step_done(progress); fu_progress_step_done(progress);
/* set quirks for each hwid */ /* set quirks for each hwid */
guids = fu_context_get_hwid_guids(self->ctx); if (self->has_hwinfo) {
for (guint i = 0; i < guids->len; i++) { GPtrArray *guids = fu_context_get_hwid_guids(self->ctx);
const gchar *hwid = g_ptr_array_index(guids, i); for (guint i = 0; i < guids->len; i++) {
fu_engine_load_quirks_for_hwid(self, hwid); const gchar *hwid = g_ptr_array_index(guids, i);
fu_engine_load_quirks_for_hwid(self, hwid);
}
} }
fu_progress_step_done(progress); fu_progress_step_done(progress);
/* set up battery threshold */ /* set up battery threshold */
fu_engine_context_set_battery_threshold(self->ctx); if (self->has_hwinfo)
fu_engine_context_set_battery_threshold(self->ctx);
/* watch the device list for updates and proxy */ /* watch the device list for updates and proxy */
g_signal_connect(FU_DEVICE_LIST(self->device_list), g_signal_connect(FU_DEVICE_LIST(self->device_list),

View File

@ -1480,7 +1480,10 @@ fu_engine_require_hwid_func(gconstpointer user_data)
fu_engine_set_silo(engine, silo_empty); fu_engine_set_silo(engine, silo_empty);
/* load engine to get FuConfig set up */ /* load engine to get FuConfig set up */
ret = fu_engine_load(engine, FU_ENGINE_LOAD_FLAG_NO_CACHE, progress, &error); ret = fu_engine_load(engine,
FU_ENGINE_LOAD_FLAG_NO_CACHE | FU_ENGINE_LOAD_FLAG_HWINFO,
progress,
&error);
g_assert_no_error(error); g_assert_no_error(error);
g_assert_true(ret); g_assert_true(ret);