Merge ~xypron/grub:efivarfs into ~ubuntu-core-dev/grub/+git/ubuntu:ubuntu

Proposed by Heinrich Schuchardt
Status: Superseded
Proposed branch: ~xypron/grub:efivarfs
Merge into: ~ubuntu-core-dev/grub/+git/ubuntu:ubuntu
Diff against target: 132 lines (+118/-0)
2 files modified
debian/patches/efivar-check-that-efivarfs-is-writeable.patch (+117/-0)
debian/patches/series (+1/-0)
Reviewer Review Type Date Requested Status
Ubuntu Core Development Team Pending
Review via email: mp+417181@code.launchpad.net

This proposal has been superseded by a proposal from 2022-03-21.

Commit message

efivar: check that efivarfs is writeable

Some UEFI implementations (notably U-Boot) don't implement the
SetVariable() runtime service. On these systems the GRUB installation
must be completed manually. Write a warning in this case but avoid
throwing an error. (LP: #1965288)

Signed-off-by: Heinrich Schuchardt <email address hidden>

To post a comment you must log in.

Unmerged commits

7db6e17... by Heinrich Schuchardt

efivar: check that efivarfs is writeable

Some UEFI implementations (notably U-Boot) don't implement the
SetVariable() runtime service. On these systems the GRUB installation
must be completed manually. Write a warning in this case but avoid
throwing an error. (LP: #1965288)

Signed-off-by: Heinrich Schuchardt <email address hidden>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/debian/patches/efivar-check-that-efivarfs-is-writeable.patch b/debian/patches/efivar-check-that-efivarfs-is-writeable.patch
0new file mode 1006440new file mode 100644
index 0000000..93bcf16
--- /dev/null
+++ b/debian/patches/efivar-check-that-efivarfs-is-writeable.patch
@@ -0,0 +1,117 @@
1From 5bf070ddb6cbcc5af3725908a2e092fd02352f4c Mon Sep 17 00:00:00 2001
2From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
3Date: Fri, 18 Mar 2022 15:21:33 +0100
4Subject: [PATCH 1/1] efivar: check that efivarfs is writeable
5
6Some UEFI implementations (notably U-Boot) don't implement the
7SetVariable() runtime service. On these systems the GRUB installation
8must be completed manually. Write a warning in this case but avoid
9throwing an error.
10
11Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
12---
13 grub-core/osdep/unix/efivar.c | 81 +++++++++++++++++++++++++++++++++++
14 1 file changed, 81 insertions(+)
15
16diff --git a/grub-core/osdep/unix/efivar.c b/grub-core/osdep/unix/efivar.c
17index d34df0f70..8a7ee0c94 100644
18--- a/grub-core/osdep/unix/efivar.c
19+++ b/grub-core/osdep/unix/efivar.c
20@@ -511,6 +511,79 @@ devices_equal (const_efidp a, const_efidp b)
21 return false;
22 }
23
24+/**
25+ * efivar_is_rw - detect if the efivar file system exists and is writeable
26+ *
27+ * Return: true if efivarfs is writeable
28+ */
29+static bool
30+efivar_is_rw (void)
31+{
32+ const char filename[] = "/proc/self/mounts";
33+ int fd;
34+ grub_uint64_t size;
35+ char *data = NULL, *start, *end, *pos;
36+ bool ret = false;
37+
38+ fd = grub_util_fd_open (filename, GRUB_UTIL_FD_O_RDONLY);
39+ if (fd == -1)
40+ {
41+ grub_util_warn (_("cannot open `%s': %s"), filename, strerror (errno));
42+ return 0;
43+ }
44+
45+ /*
46+ * /proc/self/mounts does not provide a filesize. So read it into an initial
47+ * buffer. If the last byte of the buffer is overwritten, retry with double
48+ * the buffer size.
49+ */
50+ size = 4096;
51+ for (;;) {
52+ ssize_t s;
53+
54+ fd = grub_util_fd_open (filename, GRUB_UTIL_FD_O_RDONLY);
55+ if (fd == -1)
56+ {
57+ grub_util_warn (_("cannot open `%s': %s"), filename, strerror (errno));
58+ return 0;
59+ }
60+
61+ grub_util_info ("size %ld", size);
62+ data = xmalloc (size);
63+ grub_memset (data, 0, size);
64+ if (!data)
65+ {
66+ grub_util_warn ("%s", _("out of memory"));
67+ goto out;
68+ }
69+ s = read(fd, data, size);
70+ if (s < 0)
71+ {
72+ grub_util_warn (_("cannot read `%s': %s"), filename, strerror (errno));
73+ goto out;
74+ }
75+ grub_util_fd_close (fd);
76+ if (!data[size - 1])
77+ break;
78+ free(data);
79+ size *= 2;
80+ }
81+
82+ start = grub_strstr (data, "efivarfs ");
83+ if (!start)
84+ goto out;
85+ end = grub_strstr (start, "\n");
86+ if (!end)
87+ goto out;
88+ pos = grub_strstr (start, " rw,");
89+ if (pos && pos < end)
90+ ret = true;
91+
92+out:
93+ grub_free (data);
94+ return ret;
95+}
96+
97 int
98 grub_install_efivar_register_efi (grub_device_t efidir_grub_dev,
99 const char *efidir, const char *efifile_path,
100@@ -528,6 +601,14 @@ grub_install_efivar_register_efi (grub_device_t efidir_grub_dev,
101 int rc;
102 bool is_boot_efi;
103
104+ /* Check if EFI variable can be written */
105+ if (!efivar_is_rw ())
106+ {
107+ grub_util_warn ("EFI variables cannot be set on this system");
108+ grub_util_warn ("You will have to complete the GRUB setup manually");
109+ return 0;
110+ }
111+
112 is_boot_efi = strstr (efidir, "/boot/efi") != NULL;
113 efidir_disk = grub_util_biosdisk_get_osdev (efidir_grub_dev->disk);
114 efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1;
115--
1162.34.1
117
diff --git a/debian/patches/series b/debian/patches/series
index 7942ada..0a4b388 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -121,3 +121,4 @@ ubuntu-os-prober-auto.patch
121efi-correct-struct-grub_efi_boot_services.patch121efi-correct-struct-grub_efi_boot_services.patch
122efi-implement-grub_efi_run_image.patch122efi-implement-grub_efi_run_image.patch
123fat-fix-listing-the-root-directory.patch123fat-fix-listing-the-root-directory.patch
124efivar-check-that-efivarfs-is-writeable.patch

Subscribers

People subscribed via source and target branches