Coverage Report

Created: 2026-09-14 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fwupd/libfwupdplugin/fu-security-attr.c
Line
Count
Source
1
/*
2
 * Copyright 2022 Richard Hughes <richard@hughsie.com>
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
7
0
#define G_LOG_DOMAIN "FuSecurityAttr"
8
9
#include "config.h"
10
11
#include "fwupd-security-attr-private.h"
12
13
#include "fu-security-attr.h"
14
#include "fu-version-common.h"
15
16
typedef struct {
17
  FuContext *ctx;
18
} FuSecurityAttrPrivate;
19
20
0
G_DEFINE_TYPE_WITH_PRIVATE(FuSecurityAttr, fu_security_attr, FWUPD_TYPE_SECURITY_ATTR)
21
0
22
0
#define GET_PRIVATE(o) (fu_security_attr_get_instance_private(o))
23
24
/**
25
 * fu_security_attr_check_fwupd_version:
26
 * @self: a #FuSecurityAttr
27
 * @fwupd_version: a fwupd version, e.g. `2.0.7`
28
 *
29
 * Checks if this attribute was available in a given fwupd release.
30
 *
31
 * If @fwupd_version is %NULL then expect %TRUE.
32
 *
33
 * Returns: %TRUE if the fwupd release contained this attribute
34
 *
35
 * Since: 2.0.7
36
 **/
37
gboolean
38
fu_security_attr_check_fwupd_version(FuSecurityAttr *self, const gchar *fwupd_version)
39
0
{
40
0
  g_return_val_if_fail(FU_IS_SECURITY_ATTR(self), FALSE);
41
0
  if (fwupd_version == NULL)
42
0
    return TRUE;
43
0
  if (fu_security_attr_get_fwupd_version(self) == NULL)
44
0
    return TRUE;
45
0
  return fu_version_compare(fwupd_version,
46
0
          fu_security_attr_get_fwupd_version(self),
47
0
          FWUPD_VERSION_FORMAT_UNKNOWN) >= 0;
48
0
}
49
50
/**
51
 * fu_security_attr_add_bios_target_value:
52
 * @self: a #FuSecurityAttr
53
 * @id: a #FwupdBiosSetting ID or name
54
 * @needle: The substring of a target value
55
 *
56
 * Checks all configured possible values of an enumeration attribute and
57
 * if any match @needle then set as the target value.
58
 *
59
 * Since: 1.8.4
60
 **/
61
void
62
fu_security_attr_add_bios_target_value(FuSecurityAttr *self, const gchar *id, const gchar *needle)
63
0
{
64
0
  FuSecurityAttrPrivate *priv = GET_PRIVATE(self);
65
0
  FwupdBiosSetting *bios_setting;
66
0
  GPtrArray *values;
67
0
  const gchar *current;
68
69
0
  bios_setting = fu_context_get_bios_setting(priv->ctx, id);
70
0
  if (bios_setting == NULL)
71
0
    return;
72
0
  current = fwupd_bios_setting_get_current_value(bios_setting);
73
0
  fu_security_attr_set_bios_setting_id(self, fwupd_bios_setting_get_id(bios_setting));
74
0
  fu_security_attr_set_bios_setting_current_value(self, current);
75
0
  if (fwupd_bios_setting_get_kind(bios_setting) != FWUPD_BIOS_SETTING_KIND_ENUMERATION)
76
0
    return;
77
0
  if (fwupd_bios_setting_get_read_only(bios_setting))
78
0
    return;
79
0
  values = fwupd_bios_setting_get_possible_values(bios_setting);
80
0
  for (guint i = 0; i < values->len; i++) {
81
0
    const gchar *possible = g_ptr_array_index(values, i);
82
0
    g_autofree gchar *lower = g_utf8_strdown(possible, -1);
83
0
    if (g_strrstr(lower, needle)) {
84
0
      fu_security_attr_set_bios_setting_target_value(self, possible);
85
      /* this is built-in to the engine */
86
0
      if (g_strcmp0(possible, current) != 0) {
87
0
        fu_security_attr_add_flag(self, FWUPD_SECURITY_ATTR_FLAG_CAN_FIX);
88
0
        fu_security_attr_add_flag(self, FWUPD_SECURITY_ATTR_FLAG_CAN_UNDO);
89
0
      }
90
0
      return;
91
0
    }
92
0
  }
93
0
}
94
95
static FuContext *
96
fu_security_attr_get_context(FuSecurityAttr *self)
97
0
{
98
0
  FuSecurityAttrPrivate *priv = GET_PRIVATE(self);
99
0
  g_return_val_if_fail(FU_IS_SECURITY_ATTR(self), NULL);
100
0
  return priv->ctx;
101
0
}
102
103
static void
104
fu_security_attr_set_context(FuSecurityAttr *self, FuContext *ctx)
105
0
{
106
0
  FuSecurityAttrPrivate *priv = GET_PRIVATE(self);
107
0
  g_return_if_fail(FU_IS_SECURITY_ATTR(self));
108
0
  g_return_if_fail(FU_IS_CONTEXT(ctx));
109
0
  g_set_object(&priv->ctx, ctx);
110
0
}
111
112
/**
113
 * fu_security_attr_copy:
114
 * @donor: a #FuSecurityAttr
115
 *
116
 * Makes a full (deep) copy of a security attribute.
117
 *
118
 * Returns: (transfer full): a #FuSecurityAttr
119
 *
120
 * Since: 2.1.8
121
 **/
122
FuSecurityAttr *
123
fu_security_attr_copy(FuSecurityAttr *donor)
124
0
{
125
0
  g_autoptr(FuSecurityAttr) self = g_object_new(FU_TYPE_SECURITY_ATTR, NULL);
126
0
  fu_security_attr_set_context(self, fu_security_attr_get_context(donor));
127
0
  fwupd_security_attr_incorporate(FWUPD_SECURITY_ATTR(self), FWUPD_SECURITY_ATTR(donor));
128
0
  fwupd_security_attr_set_created(
129
0
      FWUPD_SECURITY_ATTR(self),
130
0
      fwupd_security_attr_get_created(FWUPD_SECURITY_ATTR(donor)));
131
0
  return g_steal_pointer(&self);
132
0
}
133
134
static void
135
fu_security_attr_init(FuSecurityAttr *self)
136
0
{
137
0
}
138
139
static void
140
fu_security_attr_dispose(GObject *object)
141
0
{
142
0
  FuSecurityAttr *self = FU_SECURITY_ATTR(object);
143
0
  FuSecurityAttrPrivate *priv = GET_PRIVATE(self);
144
0
  g_clear_object(&priv->ctx);
145
0
  G_OBJECT_CLASS(fu_security_attr_parent_class)->dispose(object);
146
0
}
147
148
static void
149
fu_security_attr_class_init(FuSecurityAttrClass *klass)
150
0
{
151
0
  GObjectClass *object_class = G_OBJECT_CLASS(klass);
152
0
  object_class->dispose = fu_security_attr_dispose;
153
0
}
154
155
/**
156
 * fu_security_attr_new:
157
 * @ctx: a #FuContext
158
 * @appstream_id: (nullable): the AppStream component ID, e.g. `com.intel.BiosGuard`
159
 *
160
 * Creates a new #FuSecurityAttr with context set.
161
 *
162
 * Returns: (transfer full): a #FuSecurityAttr
163
 *
164
 * Since: 1.8.4
165
 **/
166
FuSecurityAttr *
167
fu_security_attr_new(FuContext *ctx, const gchar *appstream_id)
168
0
{
169
0
  g_autoptr(FuSecurityAttr) self = g_object_new(FU_TYPE_SECURITY_ATTR, NULL);
170
0
  g_return_val_if_fail(FU_IS_CONTEXT(ctx), NULL);
171
0
  if (appstream_id != NULL)
172
0
    fu_security_attr_set_appstream_id(FWUPD_SECURITY_ATTR(self), appstream_id);
173
0
  fu_security_attr_set_context(self, ctx);
174
0
  return g_steal_pointer(&self);
175
0
}