diff --git a/libfwupdplugin/fu-efivar.c b/libfwupdplugin/fu-efivar.c index 39f738990..8e266f571 100644 --- a/libfwupdplugin/fu-efivar.c +++ b/libfwupdplugin/fu-efivar.c @@ -395,6 +395,51 @@ fu_efivar_get_names (const gchar *guid, GError **error) return g_steal_pointer (&names); } +/** + * fu_efivar_space_used: + * @error: A #GError + * + * Gets the total size used by all EFI variables. This may be less than the size reported by the + * kernel as some (hopefully small) variables are hidden from userspace. + * + * Returns: total allocated size of all visible variables, or %G_MAXUINT64 on error + * + * Since: 1.5.1 + **/ +guint64 +fu_efivar_space_used (GError **error) +{ + const gchar *fn; + guint64 total = 0; + g_autoptr(GDir) dir = NULL; + g_autofree gchar *path = fu_efivar_get_path (); + + /* stat each file */ + dir = g_dir_open (path, 0, error); + if (dir == NULL) + return G_MAXUINT64; + while ((fn = g_dir_read_name (dir)) != NULL) { + guint64 sz; + g_autofree gchar *pathfn = g_build_filename (path, fn, NULL); + g_autoptr(GFile) file = g_file_new_for_path (pathfn); + g_autoptr(GFileInfo) info = NULL; + + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE "," + G_FILE_ATTRIBUTE_STANDARD_SIZE, + G_FILE_QUERY_INFO_NONE, + NULL, error); + if (info == NULL) + return G_MAXUINT64; + sz = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE); + if (sz == 0) + sz = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE); + total += sz; + } + + /* success */ + return total; +} /** * fu_efivar_set_data: * @guid: Globally unique identifier diff --git a/libfwupdplugin/fu-efivar.h b/libfwupdplugin/fu-efivar.h index 688fd2319..9269db117 100644 --- a/libfwupdplugin/fu-efivar.h +++ b/libfwupdplugin/fu-efivar.h @@ -24,6 +24,7 @@ #define FU_EFIVAR_ATTR_APPEND_WRITE (1 << 6) gboolean fu_efivar_supported (GError **error); +guint64 fu_efivar_space_used (GError **error); gboolean fu_efivar_exists (const gchar *guid, const gchar *name); gboolean fu_efivar_get_data (const gchar *guid, diff --git a/libfwupdplugin/fu-self-test.c b/libfwupdplugin/fu-self-test.c index beaa866ec..57af04951 100644 --- a/libfwupdplugin/fu-self-test.c +++ b/libfwupdplugin/fu-self-test.c @@ -1824,6 +1824,7 @@ fu_efivar_func (void) gboolean ret; gsize sz = 0; guint32 attr = 0; + guint64 total; g_autofree guint8 *data = NULL; g_autoptr(GError) error = NULL; g_autoptr(GPtrArray) names = NULL; @@ -1833,6 +1834,11 @@ fu_efivar_func (void) g_assert_no_error (error); g_assert_true (ret); + /* check we can get the space used */ + total = fu_efivar_space_used (&error); + g_assert_no_error (error); + g_assert_cmpint (total, ==, 0x2000); + /* check existing keys */ g_assert_false (fu_efivar_exists (FU_EFIVAR_GUID_EFI_GLOBAL, "NotGoingToExist")); g_assert_true (fu_efivar_exists (FU_EFIVAR_GUID_EFI_GLOBAL, "SecureBoot")); diff --git a/libfwupdplugin/fwupdplugin.map b/libfwupdplugin/fwupdplugin.map index 22007b07a..4ff42bc00 100644 --- a/libfwupdplugin/fwupdplugin.map +++ b/libfwupdplugin/fwupdplugin.map @@ -669,3 +669,9 @@ LIBFWUPDPLUGIN_1.5.0 { fu_udev_device_get_subsystem_vendor; local: *; } LIBFWUPDPLUGIN_1.4.7; + +LIBFWUPDPLUGIN_1.5.1 { + global: + fu_efivar_space_used; + local: *; +} LIBFWUPDPLUGIN_1.5.0; diff --git a/plugins/uefi-dbx/fu-plugin-uefi-dbx.c b/plugins/uefi-dbx/fu-plugin-uefi-dbx.c index 9b9315eb2..4a418cd93 100644 --- a/plugins/uefi-dbx/fu-plugin-uefi-dbx.c +++ b/plugins/uefi-dbx/fu-plugin-uefi-dbx.c @@ -18,6 +18,7 @@ void fu_plugin_init (FuPlugin *plugin) { fu_plugin_set_build_hash (plugin, FU_BUILD_HASH); + fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_METADATA_SOURCE, "uefi"); } gboolean diff --git a/plugins/uefi/fu-plugin-uefi.c b/plugins/uefi/fu-plugin-uefi.c index ba0b683ab..f4891cb26 100644 --- a/plugins/uefi/fu-plugin-uefi.c +++ b/plugins/uefi/fu-plugin-uefi.c @@ -608,7 +608,9 @@ gboolean fu_plugin_startup (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); + guint64 nvram_total; g_autofree gchar *esp_path = NULL; + g_autofree gchar *nvram_total_str = NULL; g_autoptr(GError) error_local = NULL; /* some platforms have broken SMBIOS data */ @@ -632,6 +634,11 @@ fu_plugin_startup (FuPlugin *plugin, GError **error) /* are the EFI dirs set up so we can update each device */ if (!fu_efivar_supported (error)) return FALSE; + nvram_total = fu_efivar_space_used (error); + if (nvram_total == G_MAXUINT64) + return FALSE; + nvram_total_str = g_format_size_full (nvram_total, G_FORMAT_SIZE_LONG_FORMAT); + fu_plugin_add_report_metadata (plugin, "EfivarNvramUsed", nvram_total_str); /* override the default ESP path */ esp_path = fu_plugin_get_config_value (plugin, "OverrideESPMountPoint");