mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-17 15:47:46 +00:00
Add many new plugins to support for the Host Security ID
The HSI specification is currently incomplete and in active development. Sample output for my Lenovo P50 Laptop: Host Security ID: HSI:2+UA! HSI-1 ✔ UEFI dbx: OK ✔ TPM: v2.0 ✔ SPI: Write disabled ✔ SPI: Lock enabled ✔ SPI: SMM required ✔ UEFI Secure Boot: Enabled HSI-2 ✔ TPM Reconstruction: Matched PCR0 reading HSI-3 ✘ Linux Kernel S3 Sleep: Deep sleep available HSI-4 ✘ Intel CET: Unavailable Runtime Suffix -U ✔ Firmware Updates: Newest release is 8 months old Runtime Suffix -A ✔ Firmware Attestation: OK Runtime Suffix -! ✔ fwupd plugins: OK ✔ Linux Kernel: OK ✔ Linux Kernel: Locked down ✘ Linux Swap: Not encrypted
This commit is contained in:
parent
f58ac7316c
commit
c1eda7d516
@ -329,6 +329,8 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
|
||||
/usr/lib/udev/rules.d/*.rules
|
||||
/usr/lib/systemd/system-shutdown/fwupd.shutdown
|
||||
%dir %{_libdir}/fwupd-plugins-3
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_acpi_dmar.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_acpi_facp.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_altos.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_amt.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_ata.so
|
||||
@ -352,7 +354,11 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
|
||||
%endif
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_fresco_pd.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_jabra.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_linux_lockdown.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_linux_sleep.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_linux_spi_lpc.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_linux_swap.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_linux_tainted.so
|
||||
%if 0%{?have_modem_manager}
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_modem_manager.so
|
||||
%endif
|
||||
|
8
plugins/acpi-dmar/README.md
Normal file
8
plugins/acpi-dmar/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
DMA Protection
|
||||
==============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This plugin checks if DMA remapping for Thunderbolt devices is available. The
|
||||
result will be stored in an security attribute for HSI.
|
81
plugins/acpi-dmar/fu-acpi-dmar.c
Normal file
81
plugins/acpi-dmar/fu-acpi-dmar.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "fu-common.h"
|
||||
#include "fu-acpi-dmar.h"
|
||||
|
||||
struct _FuAcpiDmar {
|
||||
GObject parent_instance;
|
||||
gboolean opt_in;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (FuAcpiDmar, fu_acpi_dmar, G_TYPE_OBJECT)
|
||||
|
||||
#define DMAR_DMA_CTRL_PLATFORM_OPT_IN_FLAG 2
|
||||
|
||||
FuAcpiDmar *
|
||||
fu_acpi_dmar_new (GBytes *blob, GError **error)
|
||||
{
|
||||
FuAcpiDmar *self = g_object_new (FU_TYPE_ACPI_DMAR, NULL);
|
||||
gchar creator_id[5] = { '\0' };
|
||||
gchar oem_table_id[9] = { '\0' };
|
||||
gchar signature[5] = { '\0' };
|
||||
gsize bufsz = 0;
|
||||
guint8 flags = 0;
|
||||
const guint8 *buf = g_bytes_get_data (blob, &bufsz);
|
||||
|
||||
/* parse table */
|
||||
if (!fu_memcpy_safe ((guint8 *) signature, sizeof(signature), 0x0, /* dst */
|
||||
buf, bufsz, 0x00, /* src */
|
||||
sizeof(signature) - 1, error))
|
||||
return FALSE;
|
||||
if (strcmp (signature, "DMAR") != 0) {
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"Not a DMAR table, got %s",
|
||||
signature);
|
||||
return FALSE;
|
||||
}
|
||||
if (!fu_memcpy_safe ((guint8 *) oem_table_id, sizeof(oem_table_id), 0x0,/* dst */
|
||||
buf, bufsz, 0x10, /* src */
|
||||
sizeof(oem_table_id) - 1, error))
|
||||
return FALSE;
|
||||
g_debug ("OemTableId: %s", oem_table_id);
|
||||
if (!fu_memcpy_safe ((guint8 *) creator_id, sizeof(creator_id), 0x0, /* dst */
|
||||
buf, bufsz, 0x1c, /* src */
|
||||
sizeof(creator_id) - 1, error))
|
||||
return FALSE;
|
||||
g_debug ("CreatorId: %s", creator_id);
|
||||
if (!fu_memcpy_safe (&flags, sizeof(flags), 0x0, /* dst */
|
||||
buf, bufsz, 0x25, /* src */
|
||||
sizeof(flags), error))
|
||||
return FALSE;
|
||||
g_debug ("Flags: 0x%02x", flags);
|
||||
self->opt_in = (flags & DMAR_DMA_CTRL_PLATFORM_OPT_IN_FLAG) > 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_acpi_dmar_get_opt_in (FuAcpiDmar *self)
|
||||
{
|
||||
g_return_val_if_fail (FU_IS_ACPI_DMAR (self), FALSE);
|
||||
return self->opt_in;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_acpi_dmar_class_init (FuAcpiDmarClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
fu_acpi_dmar_init (FuAcpiDmar *self)
|
||||
{
|
||||
}
|
16
plugins/acpi-dmar/fu-acpi-dmar.h
Normal file
16
plugins/acpi-dmar/fu-acpi-dmar.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#define FU_TYPE_ACPI_DMAR (fu_acpi_dmar_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (FuAcpiDmar, fu_acpi_dmar, FU, ACPI_DMAR, GObject)
|
||||
|
||||
FuAcpiDmar *fu_acpi_dmar_new (GBytes *blob,
|
||||
GError **error);
|
||||
gboolean fu_acpi_dmar_get_opt_in (FuAcpiDmar *self);
|
61
plugins/acpi-dmar/fu-plugin-acpi-dmar.c
Normal file
61
plugins/acpi-dmar/fu-plugin-acpi-dmar.c
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fu-plugin-vfuncs.h"
|
||||
#include "fu-hash.h"
|
||||
#include "fu-acpi-dmar.h"
|
||||
|
||||
void
|
||||
fu_plugin_init (FuPlugin *plugin)
|
||||
{
|
||||
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_add_security_attrs (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
g_autofree gchar *fn = NULL;
|
||||
g_autofree gchar *path = NULL;
|
||||
g_autoptr(FuAcpiDmar) dmar = NULL;
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* only Intel */
|
||||
if (!fu_common_is_cpu_intel ())
|
||||
return;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("org.uefi.ACPI.Dmar");
|
||||
fwupd_security_attr_set_level (attr, FWUPD_SECURITY_ATTR_LEVEL_THEORETICAL);
|
||||
fwupd_security_attr_set_name (attr, "Pre-boot kernel DMA protection");
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* load DMAR table */
|
||||
path = fu_common_get_path (FU_PATH_KIND_ACPI_TABLES);
|
||||
fn = g_build_filename (path, "DMAR", NULL);
|
||||
blob = fu_common_get_contents_bytes (fn, &error_local);
|
||||
if (blob == NULL) {
|
||||
g_warning ("failed to load %s: %s", fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Could not load DMAR");
|
||||
return;
|
||||
}
|
||||
dmar = fu_acpi_dmar_new (blob, &error_local);
|
||||
if (dmar == NULL) {
|
||||
g_warning ("failed to parse %s: %s", fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Could not parse DMAR");
|
||||
return;
|
||||
}
|
||||
if (!fu_acpi_dmar_get_opt_in (dmar)) {
|
||||
fwupd_security_attr_set_result (attr, "Unavailable");
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
}
|
65
plugins/acpi-dmar/fu-self-test.c
Normal file
65
plugins/acpi-dmar/fu-self-test.c
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fwupd.h>
|
||||
|
||||
#include "fu-common.h"
|
||||
|
||||
#include "fu-acpi-dmar.h"
|
||||
|
||||
static void
|
||||
fu_acpi_dmar_opt_in_func (void)
|
||||
{
|
||||
g_autoptr(FuAcpiDmar) dmar = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
g_autofree gchar *fn = NULL;
|
||||
|
||||
fn = g_build_filename (TESTDATADIR, "DMAR", NULL);
|
||||
blob = fu_common_get_contents_bytes (fn, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (blob);
|
||||
dmar = fu_acpi_dmar_new (blob, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (dmar);
|
||||
g_assert_true (fu_acpi_dmar_get_opt_in (dmar));
|
||||
}
|
||||
|
||||
static void
|
||||
fu_acpi_dmar_opt_out_func (void)
|
||||
{
|
||||
g_autoptr(FuAcpiDmar) dmar = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
g_autofree gchar *fn = NULL;
|
||||
|
||||
fn = g_build_filename (TESTDATADIR, "DMAR-OPTOUT", NULL);
|
||||
blob = fu_common_get_contents_bytes (fn, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (blob);
|
||||
dmar = fu_acpi_dmar_new (blob, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (dmar);
|
||||
g_assert_false (fu_acpi_dmar_get_opt_in (dmar));
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
/* only critical and error are fatal */
|
||||
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
|
||||
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
|
||||
|
||||
/* tests go here */
|
||||
g_test_add_func ("/acpi-dmar/opt-in", fu_acpi_dmar_opt_in_func);
|
||||
g_test_add_func ("/acpi-dmar/opt-out", fu_acpi_dmar_opt_out_func);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
51
plugins/acpi-dmar/meson.build
Normal file
51
plugins/acpi-dmar/meson.build
Normal file
@ -0,0 +1,51 @@
|
||||
cargs = ['-DG_LOG_DOMAIN="FuPluginAcpiDmar"']
|
||||
|
||||
shared_module('fu_plugin_acpi_dmar',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-plugin-acpi-dmar.c',
|
||||
'fu-acpi-dmar.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
install : true,
|
||||
install_dir: plugin_dir,
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
c_args : cargs,
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
],
|
||||
)
|
||||
|
||||
if get_option('tests')
|
||||
testdatadir = join_paths(meson.current_source_dir(), 'tests')
|
||||
cargs += '-DTESTDATADIR="' + testdatadir + '"'
|
||||
e = executable(
|
||||
'acpi-dmar-self-test',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-self-test.c',
|
||||
'fu-acpi-dmar.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
],
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
c_args : cargs,
|
||||
)
|
||||
test('acpi-dmar-self-test', e)
|
||||
endif
|
BIN
plugins/acpi-dmar/tests/DMAR
Normal file
BIN
plugins/acpi-dmar/tests/DMAR
Normal file
Binary file not shown.
BIN
plugins/acpi-dmar/tests/DMAR-OPTOUT
Normal file
BIN
plugins/acpi-dmar/tests/DMAR-OPTOUT
Normal file
Binary file not shown.
8
plugins/acpi-facp/README.md
Normal file
8
plugins/acpi-facp/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
ACPI FACP
|
||||
=========
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This plugin checks if S2I sleep is available. The result will be stored in an
|
||||
security attribute for HSI.
|
54
plugins/acpi-facp/fu-acpi-facp.c
Normal file
54
plugins/acpi-facp/fu-acpi-facp.c
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "fu-common.h"
|
||||
#include "fu-acpi-facp.h"
|
||||
|
||||
struct _FuAcpiFacp {
|
||||
GObject parent_instance;
|
||||
gboolean get_s2i;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (FuAcpiFacp, fu_acpi_facp, G_TYPE_OBJECT)
|
||||
|
||||
#define LOW_POWER_S0_IDLE_CAPABLE (1 << 21)
|
||||
|
||||
FuAcpiFacp *
|
||||
fu_acpi_facp_new (GBytes *blob, GError **error)
|
||||
{
|
||||
FuAcpiFacp *self = g_object_new (FU_TYPE_ACPI_FACP, NULL);
|
||||
gsize bufsz = 0;
|
||||
guint32 flags = 0;
|
||||
const guint8 *buf = g_bytes_get_data (blob, &bufsz);
|
||||
|
||||
/* parse table */
|
||||
if (!fu_common_read_uint32_safe (buf, bufsz, 0x70, &flags, G_LITTLE_ENDIAN, error))
|
||||
return FALSE;
|
||||
g_debug ("Flags: 0x%04x", flags);
|
||||
self->get_s2i = (flags & LOW_POWER_S0_IDLE_CAPABLE) > 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_acpi_facp_get_s2i (FuAcpiFacp *self)
|
||||
{
|
||||
g_return_val_if_fail (FU_IS_ACPI_FACP (self), FALSE);
|
||||
return self->get_s2i;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_acpi_facp_class_init (FuAcpiFacpClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
fu_acpi_facp_init (FuAcpiFacp *self)
|
||||
{
|
||||
}
|
16
plugins/acpi-facp/fu-acpi-facp.h
Normal file
16
plugins/acpi-facp/fu-acpi-facp.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#define FU_TYPE_ACPI_FACP (fu_acpi_facp_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (FuAcpiFacp, fu_acpi_facp, FU, ACPI_FACP, GObject)
|
||||
|
||||
FuAcpiFacp *fu_acpi_facp_new (GBytes *blob,
|
||||
GError **error);
|
||||
gboolean fu_acpi_facp_get_s2i (FuAcpiFacp *self);
|
57
plugins/acpi-facp/fu-plugin-acpi-facp.c
Normal file
57
plugins/acpi-facp/fu-plugin-acpi-facp.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fu-plugin-vfuncs.h"
|
||||
#include "fu-hash.h"
|
||||
#include "fu-acpi-facp.h"
|
||||
|
||||
void
|
||||
fu_plugin_init (FuPlugin *plugin)
|
||||
{
|
||||
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_add_security_attrs (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
g_autofree gchar *fn = NULL;
|
||||
g_autofree gchar *path = NULL;
|
||||
g_autoptr(FuAcpiFacp) facp = NULL;
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("org.uefi.ACPI.Facp");
|
||||
fwupd_security_attr_set_level (attr, FWUPD_SECURITY_ATTR_LEVEL_THEORETICAL);
|
||||
fwupd_security_attr_set_name (attr, "Suspend2Idle");
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* load FACP table */
|
||||
path = fu_common_get_path (FU_PATH_KIND_ACPI_TABLES);
|
||||
fn = g_build_filename (path, "FACP", NULL);
|
||||
blob = fu_common_get_contents_bytes (fn, &error_local);
|
||||
if (blob == NULL) {
|
||||
g_warning ("failed to load %s: %s", fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Could not load FACP");
|
||||
return;
|
||||
}
|
||||
facp = fu_acpi_facp_new (blob, &error_local);
|
||||
if (facp == NULL) {
|
||||
g_warning ("failed to parse %s: %s", fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Could not parse FACP");
|
||||
return;
|
||||
}
|
||||
if (!fu_acpi_facp_get_s2i (facp)) {
|
||||
fwupd_security_attr_set_result (attr, "Default set as suspend-to-ram (S3)");
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
}
|
64
plugins/acpi-facp/fu-self-test.c
Normal file
64
plugins/acpi-facp/fu-self-test.c
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fwupd.h>
|
||||
|
||||
#include "fu-common.h"
|
||||
|
||||
#include "fu-acpi-facp.h"
|
||||
|
||||
static void
|
||||
fu_acpi_facp_s2i_disabled_func (void)
|
||||
{
|
||||
g_autofree gchar *fn = NULL;
|
||||
g_autoptr(FuAcpiFacp) facp = NULL;
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
fn = g_build_filename (TESTDATADIR, "FACP", NULL);
|
||||
blob = fu_common_get_contents_bytes (fn, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (blob);
|
||||
facp = fu_acpi_facp_new (blob, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (facp);
|
||||
g_assert_false (fu_acpi_facp_get_s2i (facp));
|
||||
}
|
||||
|
||||
static void
|
||||
fu_acpi_facp_s2i_enabled_func (void)
|
||||
{
|
||||
g_autofree gchar *fn = NULL;
|
||||
g_autoptr(FuAcpiFacp) facp = NULL;
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
fn = g_build_filename (TESTDATADIR, "FACP-S2I", NULL);
|
||||
blob = fu_common_get_contents_bytes (fn, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (blob);
|
||||
facp = fu_acpi_facp_new (blob, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (facp);
|
||||
g_assert_true (fu_acpi_facp_get_s2i (facp));
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
/* only critical and error are fatal */
|
||||
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
|
||||
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
|
||||
|
||||
/* tests go here */
|
||||
g_test_add_func ("/acpi-facp/s2i{disabled}", fu_acpi_facp_s2i_disabled_func);
|
||||
g_test_add_func ("/acpi-facp/s2i{enabled}", fu_acpi_facp_s2i_enabled_func);
|
||||
return g_test_run ();
|
||||
}
|
51
plugins/acpi-facp/meson.build
Normal file
51
plugins/acpi-facp/meson.build
Normal file
@ -0,0 +1,51 @@
|
||||
cargs = ['-DG_LOG_DOMAIN="FuPluginAcpiFacp"']
|
||||
|
||||
shared_module('fu_plugin_acpi_facp',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-plugin-acpi-facp.c',
|
||||
'fu-acpi-facp.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
install : true,
|
||||
install_dir: plugin_dir,
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
c_args : cargs,
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
],
|
||||
)
|
||||
|
||||
if get_option('tests')
|
||||
testdatadir = join_paths(meson.current_source_dir(), 'tests')
|
||||
cargs += '-DTESTDATADIR="' + testdatadir + '"'
|
||||
e = executable(
|
||||
'acpi-facp-self-test',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-self-test.c',
|
||||
'fu-acpi-facp.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
],
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
c_args : cargs,
|
||||
)
|
||||
test('acpi-facp-self-test', e)
|
||||
endif
|
BIN
plugins/acpi-facp/tests/FACP
Normal file
BIN
plugins/acpi-facp/tests/FACP
Normal file
Binary file not shown.
BIN
plugins/acpi-facp/tests/FACP-S2I
Normal file
BIN
plugins/acpi-facp/tests/FACP-S2I
Normal file
Binary file not shown.
@ -10,23 +10,29 @@
|
||||
#include "fu-hash.h"
|
||||
#include "fu-cpu-device.h"
|
||||
|
||||
struct FuPluginData {
|
||||
gboolean has_cet;
|
||||
};
|
||||
|
||||
void
|
||||
fu_plugin_init (FuPlugin *plugin)
|
||||
{
|
||||
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
||||
fu_plugin_alloc_data (plugin, sizeof (FuPluginData));
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_plugin_coldplug (FuPlugin *plugin, GError **error)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
gsize length;
|
||||
g_autofree gchar *data = NULL;
|
||||
g_autofree gchar *buf = NULL;
|
||||
g_auto(GStrv) lines = NULL;
|
||||
|
||||
if (!g_file_get_contents ("/proc/cpuinfo", &data, &length, error))
|
||||
if (!g_file_get_contents ("/proc/cpuinfo", &buf, &length, error))
|
||||
return FALSE;
|
||||
|
||||
lines = g_strsplit (data, "\n\n", 0);
|
||||
lines = g_strsplit (buf, "\n\n", 0);
|
||||
for (guint i = 0; lines[i] != NULL; i++) {
|
||||
g_autoptr(FuCpuDevice) dev = NULL;
|
||||
if (strlen (lines[i]) == 0)
|
||||
@ -34,8 +40,36 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error)
|
||||
dev = fu_cpu_device_new (lines[i]);
|
||||
if (!fu_device_setup (FU_DEVICE (dev), error))
|
||||
return FALSE;
|
||||
if (fu_cpu_device_has_shstk (dev) &&
|
||||
fu_cpu_device_has_ibt (dev))
|
||||
data->has_cet = TRUE;
|
||||
fu_plugin_device_add (plugin, FU_DEVICE (dev));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_add_security_attrs (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
|
||||
/* only Intel */
|
||||
if (!fu_common_is_cpu_intel ())
|
||||
return;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("com.intel.CET");
|
||||
fwupd_security_attr_set_level (attr, FWUPD_SECURITY_ATTR_LEVEL_SYSTEM_PROTECTION);
|
||||
fwupd_security_attr_set_name (attr, "Intel CET");
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* check for CET */
|
||||
if (!data->has_cet) {
|
||||
fwupd_security_attr_set_result (attr, "Unavailable");
|
||||
return;
|
||||
}
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
fwupd_security_attr_set_result (attr, "SHSTK+IBT");
|
||||
}
|
||||
|
8
plugins/linux-lockdown/README.md
Normal file
8
plugins/linux-lockdown/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
Linux Kernel Lockdown
|
||||
=====================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This plugin checks if the currently running kernel is locked down. The result
|
||||
will be stored in an security attribute for HSI.
|
94
plugins/linux-lockdown/fu-plugin-linux-lockdown.c
Normal file
94
plugins/linux-lockdown/fu-plugin-linux-lockdown.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fu-plugin-vfuncs.h"
|
||||
#include "fu-hash.h"
|
||||
|
||||
struct FuPluginData {
|
||||
GFile *file;
|
||||
GFileMonitor *monitor;
|
||||
};
|
||||
|
||||
void
|
||||
fu_plugin_init (FuPlugin *plugin)
|
||||
{
|
||||
fu_plugin_alloc_data (plugin, sizeof (FuPluginData));
|
||||
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_destroy (FuPlugin *plugin)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
if (data->file != NULL)
|
||||
g_object_unref (data->file);
|
||||
if (data->monitor != NULL)
|
||||
g_object_unref (data->monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_linux_lockdown_changed_cb (GFileMonitor *monitor,
|
||||
GFile *file,
|
||||
GFile *other_file,
|
||||
GFileMonitorEvent event_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
FuPlugin *plugin = FU_PLUGIN (user_data);
|
||||
fu_plugin_security_changed (plugin);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_plugin_startup (FuPlugin *plugin, GError **error)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
g_autofree gchar *path = NULL;
|
||||
g_autofree gchar *fn = NULL;
|
||||
|
||||
path = fu_common_get_path (FU_PATH_KIND_SYSFSDIR_SECURITY);
|
||||
fn = g_build_filename (path, "lockdown", NULL);
|
||||
data->file = g_file_new_for_path (fn);
|
||||
data->monitor = g_file_monitor (data->file, G_FILE_MONITOR_NONE, NULL, error);
|
||||
if (data->monitor == NULL)
|
||||
return FALSE;
|
||||
g_signal_connect (data->monitor, "changed",
|
||||
G_CALLBACK (fu_plugin_linux_lockdown_changed_cb), plugin);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_add_security_attrs (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
gsize bufsz = 0;
|
||||
g_autofree gchar *buf = NULL;
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("org.kernel.CheckLockdown");
|
||||
fwupd_security_attr_set_name (attr, "Linux Kernel");
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE);
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* load file */
|
||||
if (!g_file_load_contents (data->file, NULL, &buf, &bufsz, NULL, &error_local)) {
|
||||
g_autofree gchar *fn = g_file_get_path (data->file);
|
||||
g_warning ("could not open %s: %s", fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Could not open file");
|
||||
return;
|
||||
}
|
||||
if (g_strstr_len (buf, bufsz, "[integrity]") == NULL &&
|
||||
g_strstr_len (buf, bufsz, "[confidentiality]") == NULL) {
|
||||
fwupd_security_attr_set_result (attr, "Not locked down");
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
fwupd_security_attr_set_result (attr, "Locked down");
|
||||
}
|
23
plugins/linux-lockdown/meson.build
Normal file
23
plugins/linux-lockdown/meson.build
Normal file
@ -0,0 +1,23 @@
|
||||
cargs = ['-DG_LOG_DOMAIN="FuPluginLinuxLockdown"']
|
||||
|
||||
shared_module('fu_plugin_linux_lockdown',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-plugin-linux-lockdown.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
install : true,
|
||||
install_dir: plugin_dir,
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
c_args : cargs,
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
],
|
||||
)
|
8
plugins/linux-sleep/README.md
Normal file
8
plugins/linux-sleep/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
Linux Kernel Sleep
|
||||
==================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This plugin checks if s3 sleep is available. The result will be stored in an
|
||||
security attribute for HSI.
|
47
plugins/linux-sleep/fu-plugin-linux-sleep.c
Normal file
47
plugins/linux-sleep/fu-plugin-linux-sleep.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fu-plugin-vfuncs.h"
|
||||
#include "fu-hash.h"
|
||||
|
||||
void
|
||||
fu_plugin_init (FuPlugin *plugin)
|
||||
{
|
||||
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_add_security_attrs (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
gsize bufsz = 0;
|
||||
g_autofree gchar *buf = NULL;
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GFile) file = g_file_new_for_path ("/sys/power/mem_sleep");
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("org.kernel.CheckS3Sleep");
|
||||
fwupd_security_attr_set_level (attr, FWUPD_SECURITY_ATTR_LEVEL_THEORETICAL);
|
||||
fwupd_security_attr_set_name (attr, "Linux Kernel S3 Sleep");
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* load file */
|
||||
if (!g_file_load_contents (file, NULL, &buf, &bufsz, NULL, &error_local)) {
|
||||
g_autofree gchar *fn = g_file_get_path (file);
|
||||
g_warning ("could not open %s: %s", fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Deep sleep status unavailable");
|
||||
return;
|
||||
}
|
||||
if (g_strstr_len (buf, bufsz, "[deep]") != NULL) {
|
||||
fwupd_security_attr_set_result (attr, "System configured to suspend-to-ram (S3)");
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
}
|
23
plugins/linux-sleep/meson.build
Normal file
23
plugins/linux-sleep/meson.build
Normal file
@ -0,0 +1,23 @@
|
||||
cargs = ['-DG_LOG_DOMAIN="FuPluginLinuxSleep"']
|
||||
|
||||
shared_module('fu_plugin_linux_sleep',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-plugin-linux-sleep.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
install : true,
|
||||
install_dir: plugin_dir,
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
c_args : cargs,
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
],
|
||||
)
|
8
plugins/linux-spi-lpc/README.md
Normal file
8
plugins/linux-spi-lpc/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
Linux SPI LPC
|
||||
=============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This plugin checks if the system SPI chip is locked. The result will be stored
|
||||
in an security attribute for HSI.
|
139
plugins/linux-spi-lpc/fu-plugin-linux-spi-lpc.c
Normal file
139
plugins/linux-spi-lpc/fu-plugin-linux-spi-lpc.c
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#include "fu-plugin-vfuncs.h"
|
||||
#include "fu-hash.h"
|
||||
|
||||
#define FU_PLUGIN_LINUX_SPI_LPC_SYSFS_DIR "/sys/kernel/security/spi"
|
||||
|
||||
void
|
||||
fu_plugin_init (FuPlugin *plugin)
|
||||
{
|
||||
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_add_security_attr_bioswe (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
gsize bufsz = 0;
|
||||
g_autofree gchar *buf = NULL;
|
||||
g_autofree gchar *fn = NULL;
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("org.kernel.BIOSWE");
|
||||
fwupd_security_attr_set_level (attr, FWUPD_SECURITY_ATTR_LEVEL_CRITICAL);
|
||||
fwupd_security_attr_set_name (attr, "SPI");
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* load file */
|
||||
fn = g_build_filename (FU_PLUGIN_LINUX_SPI_LPC_SYSFS_DIR, "bioswe", NULL);
|
||||
if (!g_file_get_contents (fn, &buf, &bufsz, &error_local)) {
|
||||
g_warning ("could not open %s: %s", fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Could not open file");
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (buf, "0\n") != 0) {
|
||||
fwupd_security_attr_set_result (attr, "Write enabled");
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
fwupd_security_attr_set_result (attr, "Write disabled");
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_add_security_attr_ble (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
gsize bufsz = 0;
|
||||
g_autofree gchar *buf = NULL;
|
||||
g_autofree gchar *fn = NULL;
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("org.kernel.BLE");
|
||||
fwupd_security_attr_set_level (attr, FWUPD_SECURITY_ATTR_LEVEL_CRITICAL);
|
||||
fwupd_security_attr_set_name (attr, "SPI");
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* load file */
|
||||
fn = g_build_filename (FU_PLUGIN_LINUX_SPI_LPC_SYSFS_DIR, "ble", NULL);
|
||||
if (!g_file_get_contents (fn, &buf, &bufsz, &error_local)) {
|
||||
g_warning ("could not open %s: %s", fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Could not open file");
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (buf, "1\n") != 0) {
|
||||
fwupd_security_attr_set_result (attr, "Lock disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
fwupd_security_attr_set_result (attr, "Lock enabled");
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_add_security_attr_smm_bwp (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
gsize bufsz = 0;
|
||||
g_autofree gchar *buf = NULL;
|
||||
g_autofree gchar *fn = NULL;
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("org.kernel.SMM_BWP");
|
||||
fwupd_security_attr_set_level (attr, FWUPD_SECURITY_ATTR_LEVEL_CRITICAL);
|
||||
fwupd_security_attr_set_name (attr, "BIOS region of SPI");
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* load file */
|
||||
fn = g_build_filename (FU_PLUGIN_LINUX_SPI_LPC_SYSFS_DIR, "smm_bwp", NULL);
|
||||
if (!g_file_get_contents (fn, &buf, &bufsz, &error_local)) {
|
||||
g_warning ("could not open %s: %s", fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Could not open file");
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (buf, "1\n") != 0) {
|
||||
fwupd_security_attr_set_result (attr, "Writable by OS");
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
fwupd_security_attr_set_result (attr, "Writable only through BIOS");
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_add_security_attrs (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
/* only Intel */
|
||||
if (!fu_common_is_cpu_intel ())
|
||||
return;
|
||||
|
||||
/* maybe the kernel module does not exist */
|
||||
if (!g_file_test (FU_PLUGIN_LINUX_SPI_LPC_SYSFS_DIR, G_FILE_TEST_IS_DIR)) {
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
attr = fwupd_security_attr_new ("org.kernel.BIOSWE");
|
||||
fwupd_security_attr_set_level (attr, FWUPD_SECURITY_ATTR_LEVEL_CRITICAL);
|
||||
fwupd_security_attr_set_name (attr, "SPI");
|
||||
fwupd_security_attr_set_result (attr, "Kernel support not present");
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* look for the three files in sysfs */
|
||||
fu_plugin_add_security_attr_bioswe (plugin, attrs);
|
||||
fu_plugin_add_security_attr_ble (plugin, attrs);
|
||||
fu_plugin_add_security_attr_smm_bwp (plugin, attrs);
|
||||
}
|
23
plugins/linux-spi-lpc/meson.build
Normal file
23
plugins/linux-spi-lpc/meson.build
Normal file
@ -0,0 +1,23 @@
|
||||
cargs = ['-DG_LOG_DOMAIN="FuPluginLinuxSpiLpc"']
|
||||
|
||||
shared_module('fu_plugin_linux_spi_lpc',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-plugin-linux-spi-lpc.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
install : true,
|
||||
install_dir: plugin_dir,
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
c_args : cargs,
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
],
|
||||
)
|
@ -5,4 +5,4 @@ Introduction
|
||||
------------
|
||||
|
||||
This plugin checks if the currently available swap partitions and files are
|
||||
all encrypted.
|
||||
all encrypted. The result will be stored in an security attribute for HSI.
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "fu-linux-swap.h"
|
||||
|
||||
struct FuPluginData {
|
||||
GFile *file;
|
||||
GFileMonitor *monitor;
|
||||
};
|
||||
|
||||
@ -25,6 +26,8 @@ void
|
||||
fu_plugin_destroy (FuPlugin *plugin)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
if (data->file != NULL)
|
||||
g_object_unref (data->file);
|
||||
if (data->monitor != NULL)
|
||||
g_object_unref (data->monitor);
|
||||
}
|
||||
@ -36,41 +39,72 @@ fu_plugin_linux_swap_changed_cb (GFileMonitor *monitor,
|
||||
GFileMonitorEvent event_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_debug ("swap changed");
|
||||
FuPlugin *plugin = FU_PLUGIN (user_data);
|
||||
fu_plugin_security_changed (plugin);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_plugin_startup (FuPlugin *plugin, GError **error)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
gsize bufsz = 0;
|
||||
g_autofree gchar *buf = NULL;
|
||||
g_autofree gchar *fn = NULL;
|
||||
g_autofree gchar *procfs = NULL;
|
||||
g_autoptr(FuLinuxSwap) swap = NULL;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
|
||||
procfs = fu_common_get_path (FU_PATH_KIND_PROCFS);
|
||||
fn = g_build_filename (procfs, "swaps", NULL);
|
||||
file = g_file_new_for_path (fn);
|
||||
data->monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, error);
|
||||
data->file = g_file_new_for_path (fn);
|
||||
data->monitor = g_file_monitor (data->file, G_FILE_MONITOR_NONE, NULL, error);
|
||||
if (data->monitor == NULL)
|
||||
return FALSE;
|
||||
g_signal_connect (data->monitor, "changed",
|
||||
G_CALLBACK (fu_plugin_linux_swap_changed_cb), plugin);
|
||||
|
||||
/* load list of linux_swaps */
|
||||
if (!g_file_get_contents (fn, &buf, &bufsz, error)) {
|
||||
g_prefix_error (error, "could not open %s: ", fn);
|
||||
return FALSE;
|
||||
}
|
||||
swap = fu_linux_swap_new (buf, bufsz, error);
|
||||
if (swap == NULL) {
|
||||
g_prefix_error (error, "could not parse %s: ", fn);
|
||||
return FALSE;
|
||||
}
|
||||
g_debug ("swap %s and %s",
|
||||
fu_linux_swap_get_enabled (swap) ? "enabled" : "disabled",
|
||||
fu_linux_swap_get_encrypted (swap) ? "encrypted" : "unencrypted");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_add_security_attrs (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
gsize bufsz = 0;
|
||||
g_autofree gchar *buf = NULL;
|
||||
g_autoptr(FuLinuxSwap) swap = NULL;
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("org.kernel.Swap");
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE);
|
||||
fwupd_security_attr_set_name (attr, "Linux Swap");
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* load list of swaps */
|
||||
if (!g_file_load_contents (data->file, NULL, &buf, &bufsz, NULL, &error_local)) {
|
||||
g_autofree gchar *fn = g_file_get_path (data->file);
|
||||
g_warning ("could not open %s: %s", fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Could not open file");
|
||||
return;
|
||||
}
|
||||
swap = fu_linux_swap_new (buf, bufsz, &error_local);
|
||||
if (swap == NULL) {
|
||||
g_autofree gchar *fn = g_file_get_path (data->file);
|
||||
g_warning ("could not parse %s: %s", fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Could not parse file");
|
||||
return;
|
||||
}
|
||||
|
||||
/* none configured */
|
||||
if (!fu_linux_swap_get_enabled (swap)) {
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
/* add security attribute */
|
||||
if (!fu_linux_swap_get_encrypted (swap)) {
|
||||
fwupd_security_attr_set_result (attr, "Not encrypted");
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
fwupd_security_attr_set_result (attr, "Encrypted");
|
||||
}
|
||||
|
8
plugins/linux-tainted/README.md
Normal file
8
plugins/linux-tainted/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
Linux Kernel Tainted
|
||||
====================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This plugin checks if the currently running kernel is tainted. The result will
|
||||
be stored in an security attribute for HSI.
|
92
plugins/linux-tainted/fu-plugin-linux-tainted.c
Normal file
92
plugins/linux-tainted/fu-plugin-linux-tainted.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fu-plugin-vfuncs.h"
|
||||
#include "fu-hash.h"
|
||||
|
||||
struct FuPluginData {
|
||||
GFile *file;
|
||||
GFileMonitor *monitor;
|
||||
};
|
||||
|
||||
void
|
||||
fu_plugin_init (FuPlugin *plugin)
|
||||
{
|
||||
fu_plugin_alloc_data (plugin, sizeof (FuPluginData));
|
||||
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_destroy (FuPlugin *plugin)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
if (data->file != NULL)
|
||||
g_object_unref (data->file);
|
||||
if (data->monitor != NULL)
|
||||
g_object_unref (data->monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_linux_tainted_changed_cb (GFileMonitor *monitor,
|
||||
GFile *file,
|
||||
GFile *other_file,
|
||||
GFileMonitorEvent event_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
FuPlugin *plugin = FU_PLUGIN (user_data);
|
||||
fu_plugin_security_changed (plugin);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_plugin_startup (FuPlugin *plugin, GError **error)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
g_autofree gchar *fn = NULL;
|
||||
g_autofree gchar *procfs = NULL;
|
||||
|
||||
procfs = fu_common_get_path (FU_PATH_KIND_PROCFS);
|
||||
fn = g_build_filename (procfs, "sys", "kernel", "tainted", NULL);
|
||||
data->file = g_file_new_for_path (fn);
|
||||
data->monitor = g_file_monitor (data->file, G_FILE_MONITOR_NONE, NULL, error);
|
||||
if (data->monitor == NULL)
|
||||
return FALSE;
|
||||
g_signal_connect (data->monitor, "changed",
|
||||
G_CALLBACK (fu_plugin_linux_tainted_changed_cb), plugin);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_add_security_attrs (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
gsize bufsz = 0;
|
||||
g_autofree gchar *buf = NULL;
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("org.kernel.CheckTainted");
|
||||
fwupd_security_attr_set_name (attr, "Linux Kernel");
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE);
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* load file */
|
||||
if (!g_file_load_contents (data->file, NULL, &buf, &bufsz, NULL, &error_local)) {
|
||||
g_autofree gchar *fn = g_file_get_path (data->file);
|
||||
g_warning ("could not open %s: %s", fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Could not open file");
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (buf, "0\n") != 0) {
|
||||
fwupd_security_attr_set_result (attr, "Tainted");
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
}
|
23
plugins/linux-tainted/meson.build
Normal file
23
plugins/linux-tainted/meson.build
Normal file
@ -0,0 +1,23 @@
|
||||
cargs = ['-DG_LOG_DOMAIN="FuPluginLinuxTainted"']
|
||||
|
||||
shared_module('fu_plugin_linux_tainted',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-plugin-linux-tainted.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
install : true,
|
||||
install_dir: plugin_dir,
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
c_args : cargs,
|
||||
dependencies : [
|
||||
plugin_deps,
|
||||
],
|
||||
)
|
@ -1,3 +1,5 @@
|
||||
subdir('acpi-dmar')
|
||||
subdir('acpi-facp')
|
||||
subdir('ccgx')
|
||||
subdir('cpu')
|
||||
subdir('dfu')
|
||||
@ -7,7 +9,11 @@ subdir('ep963x')
|
||||
subdir('fastboot')
|
||||
subdir('fresco-pd')
|
||||
subdir('jabra')
|
||||
subdir('linux-lockdown')
|
||||
subdir('linux-sleep')
|
||||
subdir('linux-spi-lpc')
|
||||
subdir('linux-swap')
|
||||
subdir('linux-tainted')
|
||||
subdir('steelseries')
|
||||
subdir('dell-dock')
|
||||
subdir('nitrokey')
|
||||
|
@ -131,16 +131,23 @@ fu_plugin_add_security_attrs (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("org.trustedcomputinggroup.TpmEventLog");
|
||||
fwupd_security_attr_set_level (attr, FWUPD_SECURITY_ATTR_LEVEL_IMPORTANT);
|
||||
fwupd_security_attr_set_name (attr, "TPM Reconstruction");
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* check reconstructed to PCR0 */
|
||||
if (!fu_plugin_get_enabled (plugin)) {
|
||||
fwupd_security_attr_set_result (attr, "No binary bios measurements available");
|
||||
} else if (data->reconstructed) {
|
||||
fwupd_security_attr_set_result (attr, "Matched PCR0 reading");
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (!data->reconstructed) {
|
||||
fwupd_security_attr_set_result (attr, "Did not match PCR0 reading");
|
||||
return;
|
||||
}
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
fwupd_security_attr_set_result (attr, "Matched PCR0 reading");
|
||||
}
|
||||
|
@ -11,10 +11,52 @@
|
||||
|
||||
#include "fu-tpm-device.h"
|
||||
|
||||
struct FuPluginData {
|
||||
gboolean has_tpm;
|
||||
gboolean has_tpm_v20;
|
||||
};
|
||||
|
||||
void
|
||||
fu_plugin_init (FuPlugin *plugin)
|
||||
{
|
||||
fu_plugin_alloc_data (plugin, sizeof (FuPluginData));
|
||||
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
||||
fu_plugin_add_udev_subsystem (plugin, "tpm");
|
||||
fu_plugin_set_device_gtype (plugin, FU_TYPE_TPM_DEVICE);
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_device_added (FuPlugin *plugin, FuDevice *dev)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
data->has_tpm = TRUE;
|
||||
if (g_strcmp0 (fu_tpm_device_get_family (FU_TPM_DEVICE (dev)), "2.0") == 0)
|
||||
data->has_tpm_v20 = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_add_security_attrs (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("org.trustedcomputinggroup.Tpm");
|
||||
fwupd_security_attr_set_level (attr, FWUPD_SECURITY_ATTR_LEVEL_CRITICAL);
|
||||
fwupd_security_attr_set_name (attr, "TPM");
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* check exists, and in v2.0 mode */
|
||||
if (!data->has_tpm) {
|
||||
fwupd_security_attr_set_result (attr, "Not found");
|
||||
return;
|
||||
}
|
||||
if (!data->has_tpm_v20) {
|
||||
fwupd_security_attr_set_result (attr, "Not in v2.0 mode");
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
fwupd_security_attr_set_result (attr, "v2.0");
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
struct _FuTpmDevice {
|
||||
FuUdevDevice parent_instance;
|
||||
gchar *family;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (FuTpmDevice, fu_tpm_device, FU_TYPE_UDEV_DEVICE)
|
||||
@ -22,6 +23,12 @@ static void Esys_Finalize_autoptr_cleanup (ESYS_CONTEXT *esys_context)
|
||||
}
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ESYS_CONTEXT, Esys_Finalize_autoptr_cleanup)
|
||||
|
||||
const gchar *
|
||||
fu_tpm_device_get_family (FuTpmDevice *self)
|
||||
{
|
||||
return self->family;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_tpm_device_probe (FuUdevDevice *device, GError **error)
|
||||
{
|
||||
@ -134,6 +141,7 @@ fu_tpm_device_convert_manufacturer (const gchar *manufacturer)
|
||||
static gboolean
|
||||
fu_tpm_device_setup (FuDevice *device, GError **error)
|
||||
{
|
||||
FuTpmDevice *self = FU_TPM_DEVICE (device);
|
||||
FwupdVersionFormat verfmt;
|
||||
TSS2_RC rc;
|
||||
const gchar *tmp;
|
||||
@ -141,7 +149,6 @@ fu_tpm_device_setup (FuDevice *device, GError **error)
|
||||
guint32 version1 = 0;
|
||||
guint32 version2 = 0;
|
||||
guint64 version_raw;
|
||||
g_autofree gchar *family = NULL;
|
||||
g_autofree gchar *id1 = NULL;
|
||||
g_autofree gchar *id2 = NULL;
|
||||
g_autofree gchar *id3 = NULL;
|
||||
@ -171,8 +178,8 @@ fu_tpm_device_setup (FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
/* lookup guaranteed details from TPM */
|
||||
family = fu_tpm_device_get_string (ctx, TPM2_PT_FAMILY_INDICATOR, error);
|
||||
if (family == NULL) {
|
||||
self->family = fu_tpm_device_get_string (ctx, TPM2_PT_FAMILY_INDICATOR, error);
|
||||
if (self->family == NULL) {
|
||||
g_prefix_error (error, "failed to read TPM family");
|
||||
return FALSE;
|
||||
}
|
||||
@ -202,9 +209,9 @@ fu_tpm_device_setup (FuDevice *device, GError **error)
|
||||
fu_device_add_instance_id (device, id1);
|
||||
id2 = g_strdup_printf ("TPM\\VEN_%s&MOD_%s", manufacturer, model);
|
||||
fu_device_add_instance_id (device, id2);
|
||||
id3 = g_strdup_printf ("TPM\\VEN_%s&DEV_%04X&VER_%s", manufacturer, tpm_type, family);
|
||||
id3 = g_strdup_printf ("TPM\\VEN_%s&DEV_%04X&VER_%s", manufacturer, tpm_type, self->family);
|
||||
fu_device_add_instance_id (device, id3);
|
||||
id4 = g_strdup_printf ("TPM\\VEN_%s&MOD_%s&VER_%s", manufacturer, model, family);
|
||||
id4 = g_strdup_printf ("TPM\\VEN_%s&MOD_%s&VER_%s", manufacturer, model, self->family);
|
||||
fu_device_add_instance_id (device, id4);
|
||||
|
||||
/* enforce vendors can only ship updates for their own hardware */
|
||||
@ -245,6 +252,8 @@ fu_tpm_device_init (FuTpmDevice *self)
|
||||
static void
|
||||
fu_tpm_device_finalize (GObject *object)
|
||||
{
|
||||
FuTpmDevice *self = FU_TPM_DEVICE (object);
|
||||
g_free (self->family);
|
||||
G_OBJECT_CLASS (fu_tpm_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -10,3 +10,5 @@
|
||||
|
||||
#define FU_TYPE_TPM_DEVICE (fu_tpm_device_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (FuTpmDevice, fu_tpm_device, FU, TPM_DEVICE, FuUdevDevice)
|
||||
|
||||
const gchar *fu_tpm_device_get_family (FuTpmDevice *self);
|
||||
|
@ -5,4 +5,4 @@ Introduction
|
||||
------------
|
||||
|
||||
This plugin checks if the UEFI dbx contains all the most recent blacklisted
|
||||
checksums.
|
||||
checksums. The result will be stored in an security attribute for HSI.
|
||||
|
@ -32,6 +32,17 @@ fu_plugin_destroy (FuPlugin *plugin)
|
||||
|
||||
gboolean
|
||||
fu_plugin_startup (FuPlugin *plugin, GError **error)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
data->fn = fu_uefi_dbx_get_dbxupdate (error);
|
||||
if (data->fn == NULL)
|
||||
return FALSE;
|
||||
g_debug ("using %s", data->fn);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_add_security_attrs (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
GPtrArray *checksums;
|
||||
@ -41,46 +52,55 @@ fu_plugin_startup (FuPlugin *plugin, GError **error)
|
||||
g_autofree guint8 *buf_update = NULL;
|
||||
g_autoptr(FuUefiDbxFile) dbx_system = NULL;
|
||||
g_autoptr(FuUefiDbxFile) dbx_update = NULL;
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* get binary blob */
|
||||
data->fn = fu_uefi_dbx_get_dbxupdate (error);
|
||||
if (data->fn == NULL) {
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("org.uefi.SecureBoot.dbx");
|
||||
fwupd_security_attr_set_level (attr, FWUPD_SECURITY_ATTR_LEVEL_CRITICAL);
|
||||
fwupd_security_attr_set_name (attr, "UEFI dbx");
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* no binary blob */
|
||||
if (!fu_plugin_get_enabled (plugin)) {
|
||||
g_autofree gchar *dbxdir = NULL;
|
||||
g_autofree gchar *result = NULL;
|
||||
dbxdir = fu_common_get_path (FU_PATH_KIND_EFIDBXDIR);
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"file can be downloaded from %s and decompressed into %s: ",
|
||||
result = g_strdup_printf ("DBX can be downloaded from %s and decompressed into %s: ",
|
||||
FU_UEFI_DBX_DATA_URL, dbxdir);
|
||||
return FALSE;
|
||||
fwupd_security_attr_set_result (attr, result);
|
||||
return;
|
||||
}
|
||||
|
||||
/* get update dbx */
|
||||
if (!g_file_get_contents (data->fn, (gchar **) &buf_update, &bufsz, error)) {
|
||||
g_prefix_error (error, "failed to load %s: ", data->fn);
|
||||
return FALSE;
|
||||
if (!g_file_get_contents (data->fn, (gchar **) &buf_update, &bufsz, &error_local)) {
|
||||
g_warning ("failed to load %s: %s", data->fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Failed to load update DBX");
|
||||
return;
|
||||
}
|
||||
dbx_update = fu_uefi_dbx_file_new (buf_update, bufsz,
|
||||
FU_UEFI_DBX_FILE_PARSE_FLAGS_IGNORE_HEADER,
|
||||
error);
|
||||
&error_local);
|
||||
if (dbx_update == NULL) {
|
||||
g_prefix_error (error, "could not parse %s: ", data->fn);
|
||||
return FALSE;
|
||||
g_warning ("failed to parse %s: %s", data->fn, error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Failed to parse update DBX");
|
||||
return;
|
||||
}
|
||||
|
||||
/* get system dbx */
|
||||
if (!fu_efivar_get_data ("d719b2cb-3d3a-4596-a3bc-dad00e67656f", "dbx",
|
||||
&buf_system, &bufsz, NULL, error)) {
|
||||
g_prefix_error (error, "failed to get dbx: ");
|
||||
return FALSE;
|
||||
&buf_system, &bufsz, NULL, &error_local)) {
|
||||
g_warning ("failed to load EFI dbx: %s", error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Failed to load EFI DBX");
|
||||
return;
|
||||
}
|
||||
dbx_system = fu_uefi_dbx_file_new (buf_system, bufsz,
|
||||
FU_UEFI_DBX_FILE_PARSE_FLAGS_NONE,
|
||||
error);
|
||||
&error_local);
|
||||
if (dbx_system == NULL) {
|
||||
g_prefix_error (error, "could not parse variable: ");
|
||||
return FALSE;
|
||||
g_warning ("failed to parse EFI dbx: %s", error_local->message);
|
||||
fwupd_security_attr_set_result (attr, "Failed to parse EFI DBX");
|
||||
return;
|
||||
}
|
||||
|
||||
/* look for each checksum in the update in the system version */
|
||||
@ -88,11 +108,18 @@ fu_plugin_startup (FuPlugin *plugin, GError **error)
|
||||
for (guint i = 0; i < checksums->len; i++) {
|
||||
const gchar *checksum = g_ptr_array_index (checksums, i);
|
||||
if (!fu_uefi_dbx_file_has_checksum (dbx_system, checksum)) {
|
||||
g_debug ("%s missing from the system dbx", checksum);
|
||||
g_debug ("%s missing from the system DBX", checksum);
|
||||
missing_cnt += 1;
|
||||
}
|
||||
}
|
||||
if (missing_cnt > 0)
|
||||
g_warning ("%u hashes missing", missing_cnt);
|
||||
return TRUE;
|
||||
|
||||
/* add security attribute */
|
||||
if (missing_cnt > 0) {
|
||||
g_autofree gchar *summary = g_strdup_printf ("%u hashes missing", missing_cnt);
|
||||
fwupd_security_attr_set_result (attr, summary);
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
}
|
||||
|
@ -91,6 +91,28 @@ fu_plugin_get_results (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_add_security_attrs (FuPlugin *plugin, FuSecurityAttrs *attrs)
|
||||
{
|
||||
g_autoptr(FwupdSecurityAttr) attr = NULL;
|
||||
|
||||
/* create attr */
|
||||
attr = fwupd_security_attr_new ("com.uefi.SecureBoot");
|
||||
fwupd_security_attr_set_level (attr, FWUPD_SECURITY_ATTR_LEVEL_CRITICAL);
|
||||
fwupd_security_attr_set_name (attr, "UEFI Secure Boot");
|
||||
fu_security_attrs_append (attrs, attr);
|
||||
|
||||
/* SB disabled */
|
||||
if (!fu_efivar_secure_boot_enabled ()) {
|
||||
fwupd_security_attr_set_result (attr, "Disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
fwupd_security_attr_set_result (attr, "Enabled");
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_plugin_uefi_get_splash_data (guint width, guint height, GError **error)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user