Coverage Report

Created: 2026-06-15 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fwupd/libfwupdplugin/fu-ifd-bios.c
Line
Count
Source
1
/*
2
 * Copyright 2021 Richard Hughes <richard@hughsie.com>
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
7
27.0k
#define G_LOG_DOMAIN "FuIfdBios"
8
9
#include "config.h"
10
11
#include "fu-common.h"
12
#include "fu-efi-volume.h"
13
#include "fu-ifd-bios.h"
14
#include "fu-input-stream.h"
15
16
/**
17
 * FuIfdBios:
18
 *
19
 * An Intel BIOS section.
20
 *
21
 * See also: [class@FuFirmware]
22
 */
23
24
4.01k
G_DEFINE_TYPE(FuIfdBios, fu_ifd_bios, FU_TYPE_IFD_IMAGE)
25
4.01k
26
4.01k
#define FU_IFD_BIOS_FIT_SIGNATURE 0x5449465F
27
4.01k
28
4.01k
static gboolean
29
4.01k
fu_ifd_bios_parse(FuFirmware *firmware,
30
4.01k
      GInputStream *stream,
31
4.01k
      FuFirmwareParseFlags flags,
32
4.01k
      GError **error)
33
4.01k
{
34
4.01k
  gsize offset = 0;
35
4.01k
  gsize streamsz = 0;
36
4.01k
  guint img_cnt = 0;
37
38
  /* get size */
39
4.01k
  if (!fu_input_stream_size(stream, &streamsz, error))
40
0
    return FALSE;
41
42
  /* read each volume in order */
43
34.4k
  while (offset < streamsz) {
44
31.3k
    g_autoptr(FuFirmware) firmware_tmp = fu_efi_volume_new();
45
31.3k
    g_autoptr(GError) error_local = NULL;
46
47
    /* FV */
48
31.3k
    if (!fu_firmware_parse_stream(firmware_tmp, stream, offset, flags, &error_local)) {
49
27.0k
      g_debug("failed to read volume @0x%x of 0x%x: %s",
50
27.0k
        (guint)offset,
51
27.0k
        (guint)streamsz,
52
27.0k
        error_local->message);
53
27.0k
      if (!fu_size_checked_inc(&offset, 4 * FU_KB, error)) {
54
0
        g_prefix_error_literal(error, "BIOS volume scan offset overflow: ");
55
0
        return FALSE;
56
0
      }
57
27.0k
      continue;
58
27.0k
    }
59
4.30k
    if (fu_firmware_get_size(firmware_tmp) < 0x800) {
60
822
      g_set_error(error,
61
822
            FWUPD_ERROR,
62
822
            FWUPD_ERROR_INVALID_DATA,
63
822
            "EFI_VOLUME @0x%x too small (0x%x bytes)",
64
822
            (guint)offset,
65
822
            (guint)fu_firmware_get_size(firmware_tmp));
66
822
      return FALSE;
67
822
    }
68
3.48k
    fu_firmware_set_offset(firmware_tmp, offset);
69
3.48k
    if (!fu_firmware_add_image(firmware, firmware_tmp, error))
70
52
      return FALSE;
71
72
    /* next! */
73
3.43k
    if (!fu_size_checked_inc(&offset, fu_firmware_get_size(firmware_tmp), error))
74
0
      return FALSE;
75
3.43k
    img_cnt++;
76
3.43k
  }
77
78
  /* found nothing */
79
3.14k
  if (img_cnt == 0) {
80
2.32k
    g_set_error_literal(error,
81
2.32k
            FWUPD_ERROR,
82
2.32k
            FWUPD_ERROR_INVALID_FILE,
83
2.32k
            "no EFI firmware volumes");
84
2.32k
    return FALSE;
85
2.32k
  }
86
87
  /* success */
88
823
  return TRUE;
89
3.14k
}
90
91
static void
92
fu_ifd_bios_init(FuIfdBios *self)
93
4.01k
{
94
4.01k
  fu_firmware_set_alignment(FU_FIRMWARE(self), FU_FIRMWARE_ALIGNMENT_4K);
95
4.01k
  fu_firmware_add_image_gtype(FU_FIRMWARE(self), FU_TYPE_EFI_VOLUME);
96
4.01k
#ifdef HAVE_FUZZER
97
4.01k
  fu_firmware_set_images_max(FU_FIRMWARE(self), 10);
98
4.01k
  fu_firmware_set_size_max(FU_FIRMWARE(self), 1 * FU_MB);
99
#else
100
  fu_firmware_set_images_max(FU_FIRMWARE(self), 1024);
101
  fu_firmware_set_size_max(FU_FIRMWARE(self), 1 * FU_GB);
102
#endif
103
4.01k
}
104
105
static void
106
fu_ifd_bios_class_init(FuIfdBiosClass *klass)
107
1
{
108
1
  FuFirmwareClass *firmware_class = FU_FIRMWARE_CLASS(klass);
109
1
  firmware_class->parse = fu_ifd_bios_parse;
110
1
}
111
112
/**
113
 * fu_ifd_bios_new:
114
 *
115
 * Creates a new #FuFirmware
116
 *
117
 * Since: 1.6.2
118
 **/
119
FuFirmware *
120
fu_ifd_bios_new(void)
121
0
{
122
0
  return FU_FIRMWARE(g_object_new(FU_TYPE_IFD_BIOS, NULL));
123
0
}