Browse Source

efivar package update

Signed-off-by: basebuilder_pel7x64builder0 <basebuilder@powerel.org>
master
basebuilder_pel7x64builder0 6 years ago
parent
commit
cdc0c87475
  1. 82
      SOURCES/0001-libabigail-isn-t-in-RHEL-yet-so-nerf-the-abi-check.patch
  2. 48
      SOURCES/0002-Don-t-use-_Generic-because-gcc-4.x-doesn-t-have-it.patch
  3. 34
      SOURCES/0003-popt-devel-in-RHEL-7.4-doesn-t-provide-popt.pc-so-in.patch
  4. 35
      SOURCES/0004-efi_loadopt_args_from_file-fix-leaked-file-descripto.patch
  5. 41
      SOURCES/0005-make_mac_path-fix-leaked-file-descriptor.patch
  6. 48
      SOURCES/0006-gpt_disk_get_partition_info-free-our-allocations-on-.patch
  7. 42
      SOURCES/0007-efi_generate_file_device_path-fix-one-error-case-s-f.patch
  8. 52
      SOURCES/0008-efi_va_generate_file_device_path_from_esp-handle-err.patch
  9. 40
      SOURCES/0009-efi_variable_import-fix-memory-leak-on-failure-path.patch
  10. 90
      SOURCES/0010-efidp_append_path-error-check-the-right-variable.patch
  11. 28
      SOURCES/0011-efi_variable_import-make-sure-var.data_size-is-set.patch
  12. 29
      SOURCES/0012-makeguids-free-our-input-buffer.patch
  13. 32
      SOURCES/0013-efi_variable_import-constrain-our-inputs-better.patch
  14. 40
      SOURCES/0014-efi_loadopt_create-check-buf-for-NULLness.patch
  15. 34
      SOURCES/0015-efidp_duplicate_extra-error-if-our-allocation-is-too.patch
  16. 29
      SOURCES/0016-show_errors-make-the-useful-part-here-not-be-dead-co.patch
  17. 31
      SOURCES/0017-efi_loadopt_args_from_file-make-sure-buf-is-only-NUL.patch
  18. 91
      SOURCES/0018-calls-to-sysfs_readlink-check-linkbuf-for-NULLness.patch
  19. 38
      SOURCES/0019-efivar-main-explain-efi_well_known_guids-to-the-comp.patch
  20. 44
      SOURCES/0020-dp.h-Try-to-make-covscan-believe-format-is-checking-.patch
  21. 360
      SOURCES/0021-gpt-try-to-avoid-trusting-unverified-partition-table.patch
  22. 138
      SOURCES/0022-Simplify-efidp_append_node-even-more.patch
  23. 86
      SOURCES/0023-efi_loadopt_create-avoid-NULL-dereference.patch
  24. 30
      SOURCES/0024-efi_generate_file_device_path-make-all-error-paths-u.patch
  25. 74
      SOURCES/0025-linux.c-fix-a-pile-of-sscanf-NULL-.-possibilities.patch
  26. 154
      SPECS/efivar.spec

82
SOURCES/0001-libabigail-isn-t-in-RHEL-yet-so-nerf-the-abi-check.patch

@ -0,0 +1,82 @@ @@ -0,0 +1,82 @@
From 78bda9cefdb5e29cedd379c1b9ea9fd8274d7c5d Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 13 Mar 2017 13:05:58 -0400
Subject: [PATCH 1/3] libabigail isn't in RHEL yet, so nerf the abi check.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
Make.rules | 9 ---------
Makefile | 6 +++---
src/Makefile | 5 -----
3 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/Make.rules b/Make.rules
index 88b9aa7..a7d6a23 100644
--- a/Make.rules
+++ b/Make.rules
@@ -22,15 +22,6 @@ include $(TOPDIR)/Make.version
-Wl,--version-script=$(MAP) \
-o $@ $^ $(LDLIBS)
-%.abixml : %.so
- $(ABIDW) --headers-dir $(TOPDIR)/src/include/efivar/ --out-file $@ $^
-
-%.abicheck : %.so
- $(ABIDIFF) --suppr \
- $(patsubst %.so,%.abignore,$<) \
- $(patsubst %.so,%.abixml,$<) \
- $<
-
%.o : %.c
$(CC) $(cflags) -fPIC $(CPPFLAGS) -c -o $@ $(filter %.c %.o %.S,$^)
diff --git a/Makefile b/Makefile
index 4d6d308..504a747 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ install :
$(MAKE) -C $$x $@ ; \
done
-abidw abicheck efivar efivar-static static:
+efivar efivar-static static:
$(MAKE) -C src $@
$(SUBDIRS) :
@@ -44,7 +44,7 @@ clean :
GITTAG = $(VERSION)
-test-archive: abicheck efivar.spec
+test-archive: efivar.spec
@rm -rf /tmp/efivar-$(VERSION) /tmp/efivar-$(VERSION)-tmp
@mkdir -p /tmp/efivar-$(VERSION)-tmp
@git archive --format=tar $(shell git branch | awk '/^*/ { print $$2 }') | ( cd /tmp/efivar-$(VERSION)-tmp/ ; tar x )
@@ -58,7 +58,7 @@ test-archive: abicheck efivar.spec
tag:
git tag -s $(GITTAG) refs/heads/master
-archive: abicheck abidw tag efivar.spec
+archive: tag efivar.spec
@rm -rf /tmp/efivar-$(VERSION) /tmp/efivar-$(VERSION)-tmp
@mkdir -p /tmp/efivar-$(VERSION)-tmp
@git archive --format=tar $(GITTAG) | ( cd /tmp/efivar-$(VERSION)-tmp/ ; tar x )
diff --git a/src/Makefile b/src/Makefile
index 0c16597..a5d98ec 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -32,11 +32,6 @@ all : $(TARGETS)
static : $(STATICTARGETS)
-abidw : $(patsubst %.so,%.abixml,$(LIBTARGETS))
- git commit -m "Update .abixml files" -s $^
-
-abicheck : $(patsubst %.so,%.abicheck,$(LIBTARGETS))
-
./guid-symbols.c : include/efivar/efivar-guids.h
./guids.bin : include/efivar/efivar-guids.h
./names.bin : include/efivar/efivar-guids.h
--
2.9.3

48
SOURCES/0002-Don-t-use-_Generic-because-gcc-4.x-doesn-t-have-it.patch

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
From 1b74597f9327ae2d763ae8863ac784a5a0d6bb93 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 13 Mar 2017 13:36:55 -0400
Subject: [PATCH 2/3] Don't use _Generic because gcc 4.x doesn't have it...

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/util.h | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/util.h b/src/util.h
index 0af7dbe..7ad6ce4 100644
--- a/src/util.h
+++ b/src/util.h
@@ -105,14 +105,29 @@
})
#endif
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+#if __GNUC__ >= 5 && __GNUC_MINOR__ >= 1
#define add(a, b, c) _Generic((c), \
int *: int_add(a,b,c), \
long *: long_add(a,b,c), \
unsigned long *: ulong_add(a,b,c))
-
#define mult(a, b, c) _Generic((c), \
long *: long_mult(a,b,c), \
unsigned long *: ulong_mult(a,b,c))
+#endif
+#endif
+
+#ifndef add
+#define add(a, b, c) ({ \
+ (*(c)) = ((a) + (b)); \
+ })
+#endif
+#ifndef mult
+#define mult(a, b, c) ({ \
+ (*(c)) = ((a) * (b)); \
+ })
+#endif
+
static inline int
__attribute__((unused))
--
2.9.3

34
SOURCES/0003-popt-devel-in-RHEL-7.4-doesn-t-provide-popt.pc-so-in.patch

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
From 262e2900dde1e03d499b3e06f389dcdd8f12f2fd Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 13 Mar 2017 14:03:55 -0400
Subject: [PATCH 3/3] popt-devel in RHEL 7.4 doesn't provide popt.pc, so
include it the other way.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/Makefile | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/Makefile b/src/Makefile
index a5d98ec..c957d84 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -56,13 +56,11 @@ libefivar.so : LIBS=dl
libefivar.so : MAP=libefivar.map
efivar : efivar.c | libefivar.so
-efivar : LIBS=efivar dl
-efivar : PKGS=popt
+efivar : LIBS=efivar dl popt
efivar-static : efivar.c $(patsubst %.o,%.static.o,$(LIBEFIVAR_OBJECTS))
efivar-static : | $(GENERATED_SOURCES)
-efivar-static : LIBS=dl
-efivar-static : PKGS=popt
+efivar-static : LIBS=dl popt
libefiboot.a : $(patsubst %.o,%.static.o,$(LIBEFIBOOT_OBJECTS))
--
2.9.3

35
SOURCES/0004-efi_loadopt_args_from_file-fix-leaked-file-descripto.patch

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
From 0967cd89ae6c1e55c1d136669e2f426752f233f4 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 14:40:26 -0400
Subject: [PATCH 04/22] efi_loadopt_args_from_file(): fix leaked file
descriptor.

In the case where we're just trying to figure out the file's size, we're
failing to close the file. So close it.

Found by covscan.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/loadopt.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/loadopt.c b/src/loadopt.c
index ce88986..a3c1ba9 100644
--- a/src/loadopt.c
+++ b/src/loadopt.c
@@ -275,8 +275,10 @@ efi_loadopt_args_from_file(uint8_t *buf, ssize_t size, char *filename)
if (rc < 0)
goto err;
- if (size == 0)
+ if (size == 0) {
+ fclose(f);
return statbuf.st_size;
+ }
if (size < statbuf.st_size) {
errno = ENOSPC;
--
2.12.2

41
SOURCES/0005-make_mac_path-fix-leaked-file-descriptor.patch

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
From f3304710b72de55249ef461c544edffd5705bdc7 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 14:42:25 -0400
Subject: [PATCH 05/22] make_mac_path(): fix leaked file descriptor.

When make_mac_path() gets an error from efidp_make_mac_addr(), it fails
to close the file descriptor to the network device. So close it. Also
ensure that the ifrn_name field is NUL terminated.

Found by covscan.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/linux.c b/src/linux.c
index 34ed479..3c77a93 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -1035,6 +1035,7 @@ make_mac_path(uint8_t *buf, ssize_t size, const char * const ifname)
memset(&ifr, 0, sizeof (ifr));
strncpy(ifr.ifr_name, ifname, IF_NAMESIZE);
+ ifr.ifr_name[IF_NAMESIZE-1] = '\0';
drvinfo.cmd = ETHTOOL_GDRVINFO;
ifr.ifr_data = (caddr_t)&drvinfo;
@@ -1062,7 +1063,8 @@ make_mac_path(uint8_t *buf, ssize_t size, const char * const ifname)
(uint8_t *)ifr.ifr_ifru.ifru_hwaddr.sa_data,
sizeof(ifr.ifr_ifru.ifru_hwaddr.sa_data));
if (sz < 0)
- return -1;
+ goto err;
+
off += sz;
ret = off;
err:
--
2.12.2

48
SOURCES/0006-gpt_disk_get_partition_info-free-our-allocations-on-.patch

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
From 939e4a8524821ccc30b34fec97416bc1b97b5455 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 14:44:43 -0400
Subject: [PATCH 06/22] gpt_disk_get_partition_info(): free our allocations on
the error path.

When gpt_disk_get_partition_info() discovers that a partition is
invalid, it returns error, but it forgets to free its allocations.

Found by covscan.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/gpt.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/src/gpt.c b/src/gpt.c
index 30cbdfd..e9c713b 100644
--- a/src/gpt.c
+++ b/src/gpt.c
@@ -640,7 +640,7 @@ gpt_disk_get_partition_info(int fd, uint32_t num, uint64_t * start,
gpt_entry *ptes = NULL, *p;
int rc = 0;
- char *report=getenv("LIBEFIBOOT_REPORT_GPT_ERRORS");
+ char *report = getenv("LIBEFIBOOT_REPORT_GPT_ERRORS");
if (report)
report_errors = 1;
@@ -662,12 +662,10 @@ gpt_disk_get_partition_info(int fd, uint32_t num, uint64_t * start,
if (report_errors)
fprintf(stderr, "partition %d is not valid\n", num);
errno = EINVAL;
- return -1;
+ rc = -1;
}
- if (ptes)
- free(ptes);
- if (gpt)
- free(gpt);
+ free(ptes);
+ free(gpt);
return rc;
}
--
2.12.2

42
SOURCES/0007-efi_generate_file_device_path-fix-one-error-case-s-f.patch

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
From 1461dc3b17aa54377bbc461bf7d5a809322dae17 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 14:46:37 -0400
Subject: [PATCH 07/22] efi_generate_file_device_path(): fix one error case's
free path.

When efi_generate_file_device_path() gets an error from
find_parent_devpath(), it currently just returns an error, rather than
freeing up its intermediate resources. So free them.

Found by covscan.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/creator.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/creator.c b/src/creator.c
index ca01964..6d662b7 100644
--- a/src/creator.c
+++ b/src/creator.c
@@ -345,7 +345,7 @@ efi_generate_file_device_path(uint8_t *buf, ssize_t size,
rc = find_parent_devpath(child_devpath, &parent_devpath);
if (rc < 0) {
efi_error("could not find parent device for file");
- return -1;
+ goto err;
}
rc = get_partition_number(child_devpath);
@@ -369,7 +369,7 @@ err:
if (child_devpath)
free(child_devpath);
if (parent_devpath)
- free(parent_devpath);
+ free(parent_devpath);
if (relpath)
free(relpath);
errno = saved_errno;
--
2.12.2

52
SOURCES/0008-efi_va_generate_file_device_path_from_esp-handle-err.patch

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
From 537d3d37d1091080362e11a6fa99b9f31cb48e53 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 14:48:49 -0400
Subject: [PATCH 08/22] efi_va_generate_file_device_path_from_esp(): handle
errors better.

When efi_va_generate_file_device_path_from_esp() gets an error from
efidp_make_edd10() or make_blockdev_path(), it fails to close the file
descriptor it uses to do ioctl() against the disk. So make it use the
common error path for those as well.

Found by covscan.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/creator.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/creator.c b/src/creator.c
index 6d662b7..ccd0faf 100644
--- a/src/creator.c
+++ b/src/creator.c
@@ -180,7 +180,7 @@ efi_va_generate_file_device_path_from_esp(uint8_t *buf, ssize_t size,
uint32_t options, va_list ap)
{
int rc;
- ssize_t ret = -1, off=0, sz;
+ ssize_t ret = -1, off = 0, sz;
struct disk_info info = { 0, };
int fd = -1;
int saved_errno;
@@ -215,7 +215,7 @@ efi_va_generate_file_device_path_from_esp(uint8_t *buf, ssize_t size,
sz = efidp_make_edd10(buf, size, info.edd10_devicenum);
if (sz < 0) {
efi_error("could not make EDD 1.0 device path");
- return -1;
+ goto err;
}
off = sz;
} else if (!(options & EFIBOOT_ABBREV_FILE)
@@ -228,7 +228,7 @@ efi_va_generate_file_device_path_from_esp(uint8_t *buf, ssize_t size,
sz = make_blockdev_path(buf, size, &info);
if (sz < 0) {
efi_error("could not create device path");
- return -1;
+ goto err;
}
off += sz;
}
--
2.12.2

40
SOURCES/0009-efi_variable_import-fix-memory-leak-on-failure-path.patch

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
From 1ae1196e74d5bac16e63a9c453f88da9c28b5c4a Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 14:52:48 -0400
Subject: [PATCH 09/22] efi_variable_import(): fix memory leak on failure path.

When one of our allocations fails, we leak the other one. Woops.

Found by covscan.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/export.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/export.c b/src/export.c
index 7f2d4dd..89af720 100644
--- a/src/export.c
+++ b/src/export.c
@@ -96,11 +96,14 @@ efi_variable_import(uint8_t *data, size_t size, efi_variable_t **var_out)
ptr += sizeof (uint32_t);
if (name_len < 1 ||
- name_len != ((data + size) - ptr - data_len))
- return -1;
- if (data_len < 1 ||
- data_len != ((data + size) - ptr - name_len))
+ name_len != ((data + size) - ptr - data_len) ||
+ data_len < 1 ||
+ data_len != ((data + size) - ptr - name_len)) {
+ int saved_errno = errno;
+ free(var.guid);
+ errno = saved_errno;
return -1;
+ }
var.name = calloc(1, name_len + 1);
if (!var.name) {
--
2.12.2

90
SOURCES/0010-efidp_append_path-error-check-the-right-variable.patch

@ -0,0 +1,90 @@ @@ -0,0 +1,90 @@
From 62e8de172dfa707990e3f2721954290499c0e14f Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 14:54:15 -0400
Subject: [PATCH 10/22] efidp_append_path(): error check the right variable.

We do lsz=efidp_size(dp); rsz=efidp_size(dn); and then we error check
lsz twice. One should be rsz.

We also actually do the whole thing with lsz twice anyway, and fail to
check that dp isn't NULL first.

We're also not error checking that the buffer from our addition is
actually large enough to hold something meaningful. So do that too.

None of that is right, so fix it.

Covscan completely failed to notice this, but complained about something
irrelevant later on in the code that's a result.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/dp.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/src/dp.c b/src/dp.c
index e9a257e..e700af9 100644
--- a/src/dp.c
+++ b/src/dp.c
@@ -139,7 +139,7 @@ efidp_append_path(const_efidp dp0, const_efidp dp1, efidp *out)
}
rsz = efidp_size(dp1);
- if (lsz < 0) {
+ if (rsz < 0) {
efi_error("efidp_size(dp1) returned error");
return -1;
}
@@ -166,6 +166,13 @@ efidp_append_path(const_efidp dp0, const_efidp dp1, efidp *out)
efi_error("arithmetic overflow computing allocation size");
return -1;
}
+
+ if (newsz < (ssize_t)sizeof(efidp_header)) {
+ errno = EINVAL;
+ efi_error("allocation for new device path is smaller than device path header.");
+ return -1;
+ }
+
new = malloc(newsz);
if (!new) {
efi_error("allocation failed");
@@ -195,10 +202,11 @@ efidp_append_node(const_efidp dp, const_efidp dn, efidp *out)
return rc;
}
- lsz = efidp_size(dp);
- if (lsz < 0) {
- efi_error("efidp_size(dp) returned error");
- return -1;
+ if (!dp && dn) {
+ rc = efidp_duplicate_path(dn, out);
+ if (rc < 0)
+ efi_error("efidp_duplicate_path() failed");
+ return rc;
}
if (dp && !dn) {
@@ -209,13 +217,17 @@ efidp_append_node(const_efidp dp, const_efidp dn, efidp *out)
}
lsz = efidp_size(dp);
- if (lsz < 0)
+ if (lsz < 0) {
+ efi_error("efidp_size(dp) returned error");
return -1;
+ }
rsz = efidp_node_size(dn);
- if (rsz < 0)
+ if (rsz < 0) {
+ efi_error("efidp_size(dn) returned error");
return -1;
+ }
if (!dp && dn) {
if (add(rsz, sizeof(end_entire), &newsz)) {
--
2.12.2

28
SOURCES/0011-efi_variable_import-make-sure-var.data_size-is-set.patch

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
From bc5f74e97ff48b89028a5f3cd0064401b37c0951 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 14:56:53 -0400
Subject: [PATCH 11/22] efi_variable_import(): make sure var.data_size is set.

Covscan noticed that var.data_size isn't set when we memcpy the
structure. It should be set.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/export.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/src/export.c b/src/export.c
index 89af720..27ce501 100644
--- a/src/export.c
+++ b/src/export.c
@@ -118,6 +118,7 @@ efi_variable_import(uint8_t *data, size_t size, efi_variable_t **var_out)
var.name[i] = wname[i] & 0xff;
ptr += name_len * 2;
+ var.data_size = data_len;
var.data = malloc(data_len);
if (!var.data) {
int saved_errno = errno;
--
2.12.2

29
SOURCES/0012-makeguids-free-our-input-buffer.patch

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
From a09b1f454d01799f4976cb1396348bd850e7223a Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 14:59:57 -0400
Subject: [PATCH 12/22] makeguids: free our input buffer.

Covscan noticed this, but didn't notice that this is a short lived
program that just parses some tables during the build. It *sooo*
doesn't matter.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/makeguids.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/src/makeguids.c b/src/makeguids.c
index da2f5f7..6a76c46 100644
--- a/src/makeguids.c
+++ b/src/makeguids.c
@@ -212,6 +212,7 @@ main(int argc, char *argv[])
close(in);
close(guidout);
close(nameout);
+ free(inbuf);
return 0;
}
--
2.12.2

32
SOURCES/0013-efi_variable_import-constrain-our-inputs-better.patch

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
From f6dc880cb1684d1836ade34e44c7710029c174e2 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 15:02:27 -0400
Subject: [PATCH 13/22] efi_variable_import(): constrain our inputs better.

efi_variable_import() could plausibly pass NULL to memcpy() if buf is 0
and size is < 0, though that should never be the case. Make the input
checking return EINVAL if that's the case.

Found by Covscan.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/loadopt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/loadopt.c b/src/loadopt.c
index a3c1ba9..d4c2d46 100644
--- a/src/loadopt.c
+++ b/src/loadopt.c
@@ -302,7 +302,7 @@ __attribute__((__visibility__ ("default")))
efi_loadopt_args_as_utf8(uint8_t *buf, ssize_t size, uint8_t *utf8)
{
ssize_t req;
- if (!buf && size > 0) {
+ if (!buf && size != 0) {
errno = EINVAL;
return -1;
}
--
2.12.2

40
SOURCES/0014-efi_loadopt_create-check-buf-for-NULLness.patch

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
From 20e9ecb4a4b327a32dc639a7ff826af5089e3fbf Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 15:04:24 -0400
Subject: [PATCH 14/22] efi_loadopt_create(): check buf for NULLness.

Found by covscan.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/loadopt.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/src/loadopt.c b/src/loadopt.c
index d4c2d46..8db8074 100644
--- a/src/loadopt.c
+++ b/src/loadopt.c
@@ -46,13 +46,20 @@ efi_loadopt_create(uint8_t *buf, ssize_t size, uint32_t attributes,
ssize_t sz = sizeof (attributes)
+ sizeof (uint16_t) + desc_len
+ dp_size + optional_data_size;
+
if (size == 0)
return sz;
+
if (size < sz) {
errno = ENOSPC;
return -1;
}
+ if (!buf) {
+ errno = EINVAL;
+ return -1;
+ }
+
if (!optional_data && optional_data_size != 0) {
errno = EINVAL;
return -1;
--
2.12.2

34
SOURCES/0015-efidp_duplicate_extra-error-if-our-allocation-is-too.patch

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
From 32f6b0d5974e39dbcce89d9ab8551e35eb8fdaab Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 15:14:33 -0400
Subject: [PATCH 15/22] efidp_duplicate_extra(): error if our allocation is too
small.

Covscan believes we might pass 0 to calloc(), though I suspect this is
because it doesn't fully grok add().

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/dp.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/src/dp.c b/src/dp.c
index e700af9..eadb397 100644
--- a/src/dp.c
+++ b/src/dp.c
@@ -81,6 +81,12 @@ efidp_duplicate_extra(const_efidp dp, efidp *out, size_t extra)
return -1;
}
+ if (plus < (ssize_t)sizeof(efidp_header)) {
+ errno = EINVAL;
+ efi_error("allocation for new device path is smaller than device path header.");
+ return -1;
+ }
+
new = calloc(1, plus);
if (!new) {
efi_error("allocation failed");
--
2.12.2

29
SOURCES/0016-show_errors-make-the-useful-part-here-not-be-dead-co.patch

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
From 878c81f02e9cabbc990028b2cf87442813eb39f5 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 15:18:05 -0400
Subject: [PATCH 16/22] show_errors(): make the useful part here not be dead
code.

Woops.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/efivar.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/efivar.c b/src/efivar.c
index cbefe8b..38d19e1 100644
--- a/src/efivar.c
+++ b/src/efivar.c
@@ -61,7 +61,7 @@ static int verbose_errors = 0;
static void
show_errors(void)
{
- int rc = 0;
+ int rc = 1;
if (!verbose_errors)
return;
--
2.12.2

31
SOURCES/0017-efi_loadopt_args_from_file-make-sure-buf-is-only-NUL.patch

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
From d251242a71ef01626444180c630330bcfb0ca69e Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 15:19:18 -0400
Subject: [PATCH 17/22] efi_loadopt_args_from_file(): make sure buf is only
NULL if size is.

This avoids passing NULL to fread().

Found by covscan.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/loadopt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/loadopt.c b/src/loadopt.c
index 8db8074..5301f3d 100644
--- a/src/loadopt.c
+++ b/src/loadopt.c
@@ -269,7 +269,7 @@ efi_loadopt_args_from_file(uint8_t *buf, ssize_t size, char *filename)
int saved_errno;
FILE *f;
- if (!buf && size > 0) {
+ if (!buf && size != 0) {
errno = -EINVAL;
return -1;
}
--
2.12.2

91
SOURCES/0018-calls-to-sysfs_readlink-check-linkbuf-for-NULLness.patch

@ -0,0 +1,91 @@ @@ -0,0 +1,91 @@
From 38039634f722eb6e3ef4221e3f37c19a1bc96ae7 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 15:21:13 -0400
Subject: [PATCH 18/22] calls to sysfs_readlink(): check linkbuf for NULLness.

If linkbuf were NULL, sysfs_readlink() would have returned an error, but
covscan can't figure that out, so it thinks linkbuf might be NULL.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/linux.c b/src/linux.c
index 3c77a93..85b4ee3 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -53,7 +53,7 @@ set_disk_and_part_name(struct disk_info *info)
rc = sysfs_readlink(&linkbuf, "/sys/dev/block/%"PRIu64":%"PRIu32,
info->major, info->minor);
- if (rc < 0)
+ if (rc < 0 || !linkbuf)
return -1;
char *ultimate;
@@ -141,7 +141,7 @@ get_partition_number(const char *devpath)
min = minor(statbuf.st_rdev);
rc = sysfs_readlink(&linkbuf, "/sys/dev/block/%u:%u", maj, min);
- if (rc < 0)
+ if (rc < 0 || !linkbuf)
return -1;
rc = read_sysfs_file(&partbuf, "/sys/dev/block/%s/partition", linkbuf);
@@ -170,7 +170,7 @@ find_parent_devpath(const char * const child, char **parent)
/* look up full path symlink */
ret = sysfs_readlink(&linkbuf, "/sys/class/block/%s", node);
- if (ret < 0)
+ if (ret < 0 || !linkbuf)
return ret;
/* strip child */
@@ -747,7 +747,7 @@ make_blockdev_path(uint8_t *buf, ssize_t size, struct disk_info *info)
rc = sysfs_readlink(&linkbuf, "/sys/dev/block/%"PRIu64":%u",
info->major, info->minor);
- if (rc < 0)
+ if (rc < 0 || !linkbuf)
return -1;
/*
@@ -771,7 +771,7 @@ make_blockdev_path(uint8_t *buf, ssize_t size, struct disk_info *info)
return -1;
tmppath[loff] = '\0';
rc = sysfs_readlink(&driverbuf, "/sys/dev/block/%s/driver", tmppath);
- if (rc < 0)
+ if (rc < 0 || !driverbuf)
return -1;
char *driver = strrchr(driverbuf, '/');
@@ -867,7 +867,7 @@ make_blockdev_path(uint8_t *buf, ssize_t size, struct disk_info *info)
rc = sysfs_readlink(&linkbuf, "/sys/class/block/%s/device",
info->disk_name);
- if (rc < 0)
+ if (rc < 0 || !linkbuf)
return 0;
rc = sscanf(linkbuf, "../../../%d:%d:%d:%"PRIu64,
@@ -1001,14 +1001,14 @@ make_net_pci_path(uint8_t *buf, ssize_t size, const char * const ifname)
int rc;
rc = sysfs_readlink(&linkbuf, "/sys/class/net/%s", ifname);
- if (rc < 0)
+ if (rc < 0 || !linkbuf)
return -1;
/*
* the sysfs path basically looks like:
* ../../devices/$PCI_STUFF/net/$IFACE
*/
- rc = sscanf(linkbuf+loff, "../../devices/%n", &lsz);
+ rc = sscanf(linkbuf, "../../devices/%n", &lsz);
if (rc != 0)
return -1;
loff += lsz;
--
2.12.2

38
SOURCES/0019-efivar-main-explain-efi_well_known_guids-to-the-comp.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
From 089265335dfb746a77ec15a917c12e8c77a41240 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 15:34:28 -0400
Subject: [PATCH 19/22] efivar main(): explain efi_well_known_guids to the
compiler better.

Covscan doesn't quite understand that this _is_ an array, so make it
look even more like one.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/efivar.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/efivar.c b/src/efivar.c
index 38d19e1..3ed9a84 100644
--- a/src/efivar.c
+++ b/src/efivar.c
@@ -461,13 +461,13 @@ int main(int argc, char *argv[])
case ACTION_LIST_GUIDS: {
efi_guid_t sentinal = {0xffffffff,0xffff,0xffff,0xffff,
{0xff,0xff,0xff,0xff,0xff,0xff}};
- extern struct guidname efi_well_known_guids;
- extern struct guidname efi_well_known_guids_end;
+ extern struct guidname efi_well_known_guids[];
+ extern struct guidname *efi_well_known_guids_end;
intptr_t start = (intptr_t)&efi_well_known_guids;
intptr_t end = (intptr_t)&efi_well_known_guids_end;
unsigned int i;
- struct guidname *guid = &efi_well_known_guids;
+ struct guidname *guid = &efi_well_known_guids[0];
for (i = 0; i < (end-start) / sizeof(*guid); i++) {
if (!efi_guid_cmp(&sentinal, &guid[i].guid))
break;
--
2.12.2

44
SOURCES/0020-dp.h-Try-to-make-covscan-believe-format-is-checking-.patch

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
From 9d74090cea256021e68b204c4770a5df28398cbd Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 1 May 2017 15:59:09 -0400
Subject: [PATCH 20/22] dp.h: Try to make covscan believe format() is checking
its bounds.

covscan doesn't grok that size and off wind up being proxies for buf's
NULL check. Hilarity ensues.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/dp.h | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/dp.h b/src/dp.h
index d6775a6..c14a9ec 100644
--- a/src/dp.h
+++ b/src/dp.h
@@ -28,11 +28,17 @@
#include "ucs2.h"
#define format(buf, size, off, dp_type, fmt, args...) ({ \
- ssize_t _x = 0; \
- if ((off) >= 0) { \
- _x = snprintf(((buf)+(off)), \
- ((size)?((size)-(off)):0), \
- fmt, ## args); \
+ ssize_t _insize = 0; \
+ void *_inbuf = NULL; \
+ if ((buf) != NULL && (size) > 0) { \
+ _inbuf = (buf) + (off); \
+ _insize = (size) - (off); \
+ } \
+ if ((off) >= 0 && \
+ ((buf == NULL && _insize == 0) || \
+ (buf != NULL && _insize >= 0))) { \
+ ssize_t _x = 0; \
+ _x = snprintf(_inbuf, _insize, fmt, ## args); \
if (_x < 0) { \
efi_error( \
"could not build %s DP string", \
--
2.12.2

360
SOURCES/0021-gpt-try-to-avoid-trusting-unverified-partition-table.patch

@ -0,0 +1,360 @@ @@ -0,0 +1,360 @@
From 29a53c93ce063c8272e44f4981201a4752fc6ba1 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 9 May 2017 14:20:13 -0400
Subject: [PATCH 21/24] gpt: try to avoid trusting unverified partition table
data.

Covscan complains thusly:
4. efivar-31/src/gpt.c:338: tainted_data_return: Function "alloc_read_gpt_header" returns tainted data.
7. efivar-31/src/gpt.c:311:2: tainted_data_argument: Function "read_lba" taints argument "gpt".
12. efivar-31/src/gpt.c:245:2: tainted_data_argument: Calling function "read" taints parameter "*iobuf". [Note: The source code implementation of the function has been overridden by a builtin model.]
13. efivar-31/src/gpt.c:246:2: tainted_data_transitive: "memcpy" taints argument "buffer" because argument "iobuf" is tainted. [Note: The source code implementation of the function has been overridden by a builtin model.]
16. efivar-31/src/gpt.c:316:2: return_tainted_data: Returning tainted variable "gpt".
17. efivar-31/src/gpt.c:338: var_assign: Assigning: "*gpt" = "alloc_read_gpt_header", which taints "*gpt".
26. efivar-31/src/gpt.c:382: tainted_data: Passing tainted variable "(*gpt)->num_partition_entries" to a tainted sink.
27. efivar-31/src/gpt.c:272:15: var_assign_alias: Assigning: "count" = "(__u32)(__le32)gpt->num_partition_entries * (__u32)(__le32)gpt->sizeof_partition_entry". Both are now tainted.
30. efivar-31/src/gpt.c:278:2: tainted_data_sink_lv_call: Passing tainted variable "count" to tainted data sink "malloc".

Hopefully this patch validates num_partition_entries and
sizeof_partition_entry well enough...

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/disk.c | 3 +-
src/gpt.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
src/gpt.h | 3 +-
3 files changed, 173 insertions(+), 23 deletions(-)

diff --git a/src/disk.c b/src/disk.c
index 91d636d..0a7a769 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -225,7 +225,8 @@ get_partition_info(int fd, uint32_t options,
signature,
mbr_type,
signature_type,
- (options & EFIBOOT_OPTIONS_IGNORE_PMBR_ERR)?1:0);
+ (options & EFIBOOT_OPTIONS_IGNORE_PMBR_ERR)?1:0,
+ sector_size);
if (gpt_invalid) {
mbr_invalid = msdos_disk_get_partition_info(fd,
(options & EFIBOOT_OPTIONS_WRITE_SIGNATURE)?1:0,
diff --git a/src/gpt.c b/src/gpt.c
index e9c713b..7baa992 100644
--- a/src/gpt.c
+++ b/src/gpt.c
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/param.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <unistd.h>
@@ -266,11 +267,10 @@ read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)
* Notes: remember to free pte when you're done!
*/
static gpt_entry *
-alloc_read_gpt_entries(int fd, gpt_header * gpt)
+alloc_read_gpt_entries(int fd, uint32_t nptes, uint32_t ptesz, uint64_t ptelba)
{
gpt_entry *pte;
- size_t count = __le32_to_cpu(gpt->num_partition_entries) *
- __le32_to_cpu(gpt->sizeof_partition_entry);
+ size_t count = nptes * ptesz;
if (!count)
return NULL;
@@ -280,8 +280,7 @@ alloc_read_gpt_entries(int fd, gpt_header * gpt)
return NULL;
memset(pte, 0, count);
- if (!read_lba(fd, __le64_to_cpu(gpt->partition_entry_lba), pte,
- count)) {
+ if (!read_lba(fd, ptelba, pte, count)) {
free(pte);
return NULL;
}
@@ -317,6 +316,65 @@ alloc_read_gpt_header(int fd, uint64_t lba)
}
/**
+ * validate_nptes(): Tries to ensure that nptes is a reasonable value
+ * @first_block is the beginning LBA to bound the table
+ * @pte_start is the starting LBA of the partition table
+ * @last_block is the end LBA of to bound the table
+ * @ptesz is the size of a partition table entry
+ * @nptes is the number of entries we have.
+ * @blksz is the block size of the device.
+ *
+ * Description: returns 0 if the partition table doesn't fit, 1 if it does
+ */
+static int
+validate_nptes(uint64_t first_block, uint64_t pte_start, uint64_t last_block,
+ uint32_t ptesz, uint32_t nptes, uint32_t blksz)
+{
+ uint32_t min_entry_size = sizeof(gpt_entry);
+ uint32_t min_entry_size_mod = 128 - sizeof(gpt_entry) % 128;
+ uint64_t max_blocks, max_bytes;
+
+ if (min_entry_size_mod == 128)
+ min_entry_size_mod = 0;
+ min_entry_size += min_entry_size_mod;
+
+ if (ptesz < min_entry_size)
+ return 0;
+
+ if (pte_start < first_block || pte_start > last_block)
+ return 0;
+
+ max_blocks = last_block - pte_start;
+ if (UINT64_MAX / blksz < max_blocks)
+ return 0;
+
+ max_bytes = max_blocks * blksz;
+ if (UINT64_MAX / ptesz < max_bytes)
+ return 0;
+
+ if (ptesz > max_bytes / nptes)
+ return 0;
+
+ if (max_bytes / ptesz < nptes)
+ return 0;
+
+ return 1;
+}
+
+static int
+check_lba(uint64_t lba, uint64_t lastlba, char *name)
+{
+ if (lba > lastlba) {
+ if (report_errors)
+ fprintf(stderr,
+ "Invalid %s LBA %"PRIx64" max:%"PRIx64"\n",
+ name, lba, lastlba);
+ return 0;
+ }
+ return 1;
+}
+
+/**
* is_gpt_valid() - tests one GPT header and PTEs for validity
* @fd is an open file descriptor to the whole disk
* @lba is the logical block address of the GPT header to test
@@ -328,10 +386,12 @@ alloc_read_gpt_header(int fd, uint64_t lba)
*/
static int
is_gpt_valid(int fd, uint64_t lba,
- gpt_header ** gpt, gpt_entry ** ptes)
+ gpt_header ** gpt, gpt_entry ** ptes,
+ uint32_t logical_block_size)
{
int rc = 0; /* default to not valid */
uint32_t crc, origcrc;
+ uint64_t max_device_lba = last_lba(fd);
if (!gpt || !ptes)
return 0;
@@ -343,7 +403,7 @@ is_gpt_valid(int fd, uint64_t lba,
if (report_errors)
fprintf(stderr,
"GUID Partition Table Header signature is wrong"
- ": %" PRIx64" != %" PRIx64 "\n",
+ ": %"PRIx64" != %"PRIx64"\n",
(uint64_t)__le64_to_cpu((*gpt)->signature),
GPT_HEADER_SIGNATURE);
free(*gpt);
@@ -351,6 +411,20 @@ is_gpt_valid(int fd, uint64_t lba,
return rc;
}
+ uint32_t hdrsz = __le32_to_cpu((*gpt)->header_size);
+ uint32_t hdrmin = MAX(92,
+ sizeof(gpt_header) - sizeof((*gpt)->reserved2));
+ if (hdrsz < hdrmin || hdrsz > logical_block_size) {
+ if (report_errors)
+ fprintf(stderr,
+ "GUID Partition Table Header size is invalid (%d < %d < %d)\n",
+ hdrmin, hdrsz,
+ logical_block_size);
+ free (*gpt);
+ *gpt = NULL;
+ return rc;
+ }
+
/* Check the GUID Partition Table Header CRC */
origcrc = __le32_to_cpu((*gpt)->header_crc32);
(*gpt)->header_crc32 = 0;
@@ -369,26 +443,97 @@ is_gpt_valid(int fd, uint64_t lba,
/* Check that the my_lba entry points to the LBA
* that contains the GPT we read */
- if (__le64_to_cpu((*gpt)->my_lba) != lba) {
+ uint64_t mylba = __le64_to_cpu((*gpt)->my_lba);
+ uint64_t altlba = __le64_to_cpu((*gpt)->alternate_lba);
+ if (mylba != lba && altlba != lba) {
if (report_errors)
fprintf(stderr,
- "my_lba %"PRIx64 "x != lba %"PRIx64 "x.\n",
- (uint64_t)__le64_to_cpu((*gpt)->my_lba), lba);
+ "lba %"PRIx64" != lba %"PRIx64".\n",
+ mylba, lba);
+err:
free(*gpt);
*gpt = NULL;
return 0;
}
- if (!(*ptes = alloc_read_gpt_entries(fd, *gpt))) {
+ if (!check_lba(mylba, max_device_lba, "GPT"))
+ goto err;
+
+ if (!check_lba(altlba, max_device_lba, "GPT Alt"))
+ goto err;
+
+ uint64_t ptelba = __le64_to_cpu((*gpt)->partition_entry_lba);
+ uint64_t fulba = __le64_to_cpu((*gpt)->first_usable_lba);
+ uint64_t lulba = __le64_to_cpu((*gpt)->last_usable_lba);
+ uint32_t nptes = __le32_to_cpu((*gpt)->num_partition_entries);
+ uint32_t ptesz = __le32_to_cpu((*gpt)->sizeof_partition_entry);
+
+ if (!check_lba(ptelba, max_device_lba, "PTE"))
+ goto err;
+ if (!check_lba(fulba, max_device_lba, "First Usable"))
+ goto err;
+ if (!check_lba(lulba, max_device_lba, "Last Usable"))
+ goto err;
+
+ if (ptesz < sizeof(gpt_entry) || ptesz % 128 != 0) {
+ if (report_errors)
+ fprintf(stderr,
+ "Invalid GPT entry size is %d.\n",
+ ptesz);
+ goto err;
+ }
+
+ /* There's really no good answer to maximum bounds, but this large
+ * would be completely absurd, so... */
+ if (nptes > 1024) {
+ if (report_errors)
+ fprintf(stderr,
+ "Not honoring insane number of Partition Table Entries 0x%"PRIx32".\n",
+ nptes);
+
+ goto err;
+ }
+
+ if (ptesz > 4096) {
+ if (report_errors)
+ fprintf(stderr,
+ "Not honoring insane Partition Table Entry size 0x%"PRIx32".\n",
+ ptesz);
+ goto err;
+ }
+
+ uint64_t pte_blocks;
+ uint64_t firstlba, lastlba;
+
+ if (altlba > mylba) {
+ firstlba = mylba + 1;
+ lastlba = fulba;
+ pte_blocks = fulba - ptelba;
+ rc = validate_nptes(firstlba, ptelba, fulba,
+ ptesz, nptes, logical_block_size);
+ } else {
+ firstlba = lulba;
+ lastlba = mylba;
+ pte_blocks = mylba - ptelba;
+ rc = validate_nptes(lulba, ptelba, mylba,
+ ptesz, nptes, logical_block_size);
+ }
+ if (!rc) {
+ if (report_errors)
+ fprintf(stderr,
+ "%"PRIu32" partition table entries with size 0x%"PRIx32" doesn't fit in 0x%"PRIx64" blocks between 0x%"PRIx64" and 0x%"PRIx64".\n",
+ nptes, ptesz, pte_blocks, firstlba, lastlba);
+ goto err;
+ }
+
+ if (!(*ptes = alloc_read_gpt_entries(fd, nptes, ptesz, ptelba))) {
free(*gpt);
*gpt = NULL;
return 0;
}
/* Check the GUID Partition Entry Array CRC */
- crc = efi_crc32(*ptes,
- __le32_to_cpu((*gpt)->num_partition_entries) *
- __le32_to_cpu((*gpt)->sizeof_partition_entry));
+ crc = efi_crc32(*ptes, nptes * ptesz);
if (crc != __le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
if (report_errors)
fprintf(stderr,
@@ -519,7 +664,7 @@ compare_gpts(gpt_header *pgpt, gpt_header *agpt, uint64_t lastlba)
*/
static int
find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes,
- int ignore_pmbr_err)
+ int ignore_pmbr_err, int logical_block_size)
{
int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
gpt_header *pgpt = NULL, *agpt = NULL;
@@ -535,16 +680,18 @@ find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes,
lastlba = last_lba(fd);
good_pgpt = is_gpt_valid(fd, GPT_PRIMARY_PARTITION_TABLE_LBA,
- &pgpt, &pptes);
+ &pgpt, &pptes, logical_block_size);
if (good_pgpt) {
good_agpt = is_gpt_valid(fd,
__le64_to_cpu(pgpt->alternate_lba),
- &agpt, &aptes);
+ &agpt, &aptes, logical_block_size);
if (!good_agpt) {
- good_agpt = is_gpt_valid(fd, lastlba, &agpt, &aptes);
+ good_agpt = is_gpt_valid(fd, lastlba, &agpt, &aptes,
+ logical_block_size);
}
} else {
- good_agpt = is_gpt_valid(fd, lastlba, &agpt, &aptes);
+ good_agpt = is_gpt_valid(fd, lastlba, &agpt, &aptes,
+ logical_block_size);
}
/* The obviously unsuccessful case */
@@ -634,7 +781,7 @@ __attribute__((__visibility__ ("hidden")))
gpt_disk_get_partition_info(int fd, uint32_t num, uint64_t * start,
uint64_t * size, uint8_t *signature,
uint8_t * mbr_type, uint8_t * signature_type,
- int ignore_pmbr_error)
+ int ignore_pmbr_error, int logical_block_size)
{
gpt_header *gpt = NULL;
gpt_entry *ptes = NULL, *p;
@@ -644,7 +791,8 @@ gpt_disk_get_partition_info(int fd, uint32_t num, uint64_t * start,
if (report)
report_errors = 1;
- rc = find_valid_gpt(fd, &gpt, &ptes, ignore_pmbr_error);
+ rc = find_valid_gpt(fd, &gpt, &ptes, ignore_pmbr_error,
+ logical_block_size);
if (rc < 0)
return rc;
diff --git a/src/gpt.h b/src/gpt.h
index 2249b59..678ee37 100644
--- a/src/gpt.h
+++ b/src/gpt.h
@@ -147,7 +147,8 @@ extern int gpt_disk_get_partition_info (int fd, uint32_t num, uint64_t *start,
uint64_t *size, uint8_t *signature,
uint8_t *mbr_type,
uint8_t *signature_type,
- int ignore_pmbr_error)
+ int ignore_pmbr_error,
+ int logical_sector_size)
__attribute__((__nonnull__ (3, 4, 5, 6, 7)))
__attribute__((__visibility__ ("hidden")));
--
2.12.2

138
SOURCES/0022-Simplify-efidp_append_node-even-more.patch

@ -0,0 +1,138 @@ @@ -0,0 +1,138 @@
From 6e59831ea44426736c2ac615c5145c427418086a Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 9 May 2017 15:15:55 -0400
Subject: [PATCH 22/24] Simplify efidp_append_node() even more.

Covscan rightly notices that now we've got enough tests on dp and dn
that some of them are provably dead code.

So take a bunch out.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/dp.c | 94 +++++++++++++++++++---------------------------------------------
1 file changed, 28 insertions(+), 66 deletions(-)

diff --git a/src/dp.c b/src/dp.c
index eadb397..14f4cfe 100644
--- a/src/dp.c
+++ b/src/dp.c
@@ -196,78 +196,38 @@ int
__attribute__((__visibility__ ("default")))
efidp_append_node(const_efidp dp, const_efidp dn, efidp *out)
{
- ssize_t lsz, rsz, newsz;
+ ssize_t lsz = 0, rsz = 0, newsz;
int rc;
- if (!dp && !dn) {
- rc = efidp_duplicate_path(
- (const_efidp)(const efidp_header * const)&end_entire,
- out);
- if (rc < 0)
- efi_error("efidp_duplicate_path() failed");
- return rc;
- }
-
- if (!dp && dn) {
- rc = efidp_duplicate_path(dn, out);
- if (rc < 0)
- efi_error("efidp_duplicate_path() failed");
- return rc;
- }
-
- if (dp && !dn) {
- rc = efidp_duplicate_path(dp, out);
- if (rc < 0)
- efi_error("efidp_duplicate_path() failed");
- return rc;
- }
-
- lsz = efidp_size(dp);
- if (lsz < 0) {
- efi_error("efidp_size(dp) returned error");
- return -1;
- }
-
-
- rsz = efidp_node_size(dn);
- if (rsz < 0) {
- efi_error("efidp_size(dn) returned error");
- return -1;
- }
-
- if (!dp && dn) {
- if (add(rsz, sizeof(end_entire), &newsz)) {
- errno = EOVERFLOW;
- efi_error(
- "arithmetic overflow computing allocation size");
- return -1;
- }
- efidp new = malloc(rsz + sizeof (end_entire));
- if (!new) {
- efi_error("allocation failed");
+ if (dp) {
+ lsz = efidp_size(dp);
+ if (lsz < 0) {
+ efi_error("efidp_size(dp) returned error");
return -1;
}
- memcpy(new, dn, dn->length);
- memcpy((uint8_t *)new + dn->length, &end_entire,
- sizeof (end_entire));
- *out = new;
- return 0;
- }
+ const_efidp le;
+ le = dp;
+ while (1) {
+ if (efidp_type(le) == EFIDP_END_TYPE &&
+ efidp_subtype(le) == EFIDP_END_ENTIRE) {
+ ssize_t lesz = efidp_size(le);
+ lsz -= lesz;
+ break;
+ }
- const_efidp le;
- le = dp;
- while (1) {
- if (efidp_type(le) == EFIDP_END_TYPE &&
- efidp_subtype(le) == EFIDP_END_ENTIRE) {
- ssize_t lesz = efidp_size(le);
- lsz -= lesz;
- break;
+ rc = efidp_get_next_end(le, &le);
+ if (rc < 0) {
+ efi_error("efidp_get_next_end() returned error");
+ return -1;
+ }
}
+ }
- rc = efidp_get_next_end(le, &le);
- if (rc < 0) {
- efi_error("efidp_get_next_end() returned error");
+ if (dn) {
+ rsz = efidp_node_size(dn);
+ if (rsz < 0) {
+ efi_error("efidp_size(dn) returned error");
return -1;
}
}
@@ -285,8 +245,10 @@ efidp_append_node(const_efidp dp, const_efidp dn, efidp *out)
}
*out = new;
- memcpy(new, dp, lsz);
- memcpy((uint8_t *)new + lsz, dn, rsz);
+ if (dp)
+ memcpy(new, dp, lsz);
+ if (dn)
+ memcpy((uint8_t *)new + lsz, dn, rsz);
memcpy((uint8_t *)new + lsz + rsz, &end_entire, sizeof (end_entire));
return 0;
--
2.12.2

86
SOURCES/0023-efi_loadopt_create-avoid-NULL-dereference.patch

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
From e9ce922ddf2ec6c1095f42ee9857f369084761c3 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 9 May 2017 15:34:08 -0400
Subject: [PATCH 23/24] efi_loadopt_create(): avoid NULL dereference

covscan rightly points out that dp is allowed to be NULL (and so is
buf), so we can't pass those in to memcpy() in those cases.

So don't.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/loadopt.c | 46 +++++++++++++++++++++++++++-------------------
1 file changed, 27 insertions(+), 19 deletions(-)

diff --git a/src/loadopt.c b/src/loadopt.c
index 5301f3d..cf0886d 100644
--- a/src/loadopt.c
+++ b/src/loadopt.c
@@ -56,36 +56,44 @@ efi_loadopt_create(uint8_t *buf, ssize_t size, uint32_t attributes,
}
if (!buf) {
+invalid:
errno = EINVAL;
return -1;
}
- if (!optional_data && optional_data_size != 0) {
- errno = EINVAL;
- return -1;
- }
+ if (!optional_data && optional_data_size != 0)
+ goto invalid;
- if (!dp && dp_size == 0) {
- errno = EINVAL;
- return -1;
- }
+ if ((!dp && dp_size == 0) || dp_size < 0)
+ goto invalid;
+
+ if (dp) {
+ if (!efidp_is_valid(dp, dp_size))
+ goto invalid;
- uint8_t *pos = buf;
+ if (efidp_size(dp) != dp_size)
+ goto invalid;
+ }
- *(uint32_t *)pos = attributes;
- pos += sizeof (attributes);
+ if (buf) {
+ uint8_t *pos = buf;
+ *(uint32_t *)pos = attributes;
+ pos += sizeof (attributes);
- *(uint16_t *)pos = dp_size;
- pos += sizeof (uint16_t);
+ *(uint16_t *)pos = dp_size;
+ pos += sizeof (uint16_t);
- utf8_to_ucs2((uint16_t *)pos, desc_len, 1, (uint8_t *)description);
- pos += desc_len;
+ utf8_to_ucs2((uint16_t *)pos, desc_len, 1,
+ (uint8_t *)description);
+ pos += desc_len;
- memcpy(pos, dp, dp_size);
- pos += dp_size;
+ if (dp)
+ memcpy(pos, dp, dp_size);
+ pos += dp_size;
- if (optional_data && optional_data_size > 0)
- memcpy(pos, optional_data, optional_data_size);
+ if (optional_data && optional_data_size > 0)
+ memcpy(pos, optional_data, optional_data_size);
+ }
return sz;
}
--
2.12.2

30
SOURCES/0024-efi_generate_file_device_path-make-all-error-paths-u.patch

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
From 1995ef6d9459931170f5718221104d7eb8c35eba Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 9 May 2017 16:32:09 -0400
Subject: [PATCH 24/26] efi_generate_file_device_path(): make all error paths
use "goto err;"

Honestly I'm just trying to shut coverity up about checking
child_devpath for NULL-ness twice on the other two error paths.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/creator.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/creator.c b/src/creator.c
index ccd0faf..21fc6b0 100644
--- a/src/creator.c
+++ b/src/creator.c
@@ -339,7 +339,7 @@ efi_generate_file_device_path(uint8_t *buf, ssize_t size,
rc = find_file(filepath, &child_devpath, &relpath);
if (rc < 0) {
efi_error("could not canonicalize fs path");
- return -1;
+ goto err;
}
rc = find_parent_devpath(child_devpath, &parent_devpath);
--
2.12.2

74
SOURCES/0025-linux.c-fix-a-pile-of-sscanf-NULL-.-possibilities.patch

@ -0,0 +1,74 @@ @@ -0,0 +1,74 @@
From d8cef3fe75ef8ca3e2622230c81caba06c3476bd Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 9 May 2017 16:33:27 -0400
Subject: [PATCH 25/26] linux.c: fix a pile of sscanf(NULL, ...) possibilities.

Covscan apparently can't figure out that rc!=error == buf!=NULL.

None of these should ever actually happen, because we're checking for
the error cases from the functions that should fill them in, but hey,
belt and suspenders.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/linux.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/linux.c b/src/linux.c
index 85b4ee3..f419ad4 100644
--- a/src/linux.c
+++ b/src/linux.c
@@ -297,7 +297,7 @@ sysfs_sata_get_port_info(uint32_t print_id, struct disk_info *info)
rc = read_sysfs_file(&buf, "/sys/class/ata_port/ata%d/port_no",
print_id);
- if (rc <= 0)
+ if (rc <= 0 || buf == NULL)
return -1;
rc = sscanf((char *)buf, "%d", &info->sata_info.ata_port);
@@ -361,12 +361,12 @@ sysfs_parse_nvme(uint8_t *buf, ssize_t size, ssize_t *off,
rc = read_sysfs_file(&filebuf,
"/sys/class/block/nvme%dn%d/eui",
ctrl_id, ns_id);
- if (rc < 0 && errno == ENOENT) {
+ if ((rc < 0 && errno == ENOENT) || filebuf == NULL) {
rc = read_sysfs_file(&filebuf,
"/sys/class/block/nvme%dn%d/device/eui",
ctrl_id, ns_id);
}
- if (rc >= 0) {
+ if (rc >= 0 && filebuf != NULL) {
uint8_t eui[8];
if (rc < 23) {
errno = EINVAL;
@@ -606,7 +606,7 @@ sysfs_parse_sas(uint8_t *buf, ssize_t size, ssize_t *off,
rc = read_sysfs_file(&filebuf,
"/sys/class/block/%s/device/sas_address",
disk_name);
- if (rc < 0)
+ if (rc < 0 || filebuf == NULL)
return -1;
rc = sscanf((char *)filebuf, "%"PRIx64, &sas_address);
@@ -656,7 +656,7 @@ make_pci_path(uint8_t *buf, ssize_t size, char *pathstr, ssize_t *pathoff)
rc = read_sysfs_file(&fbuf,
"/sys/devices/pci%04x:%02x/firmware_node/hid",
root_domain, root_bus);
- if (rc < 0)
+ if (rc < 0 || fbuf == NULL)
return -1;
uint16_t tmp16 = 0;
@@ -679,7 +679,7 @@ make_pci_path(uint8_t *buf, ssize_t size, char *pathstr, ssize_t *pathoff)
rc = read_sysfs_file(&fbuf,
"/sys/devices/pci%4x:%02x/firmware_node/uid",
root_domain, root_bus);
- if (rc <= 0 && errno != ENOENT)
+ if ((rc <= 0 && errno != ENOENT) || fbuf == NULL)
return -1;
if (rc > 0) {
rc = sscanf((char *)fbuf, "%"PRIu64"\n", &acpi_uid_int);
--
2.12.2

154
SPECS/efivar.spec

@ -0,0 +1,154 @@ @@ -0,0 +1,154 @@
Name: efivar
Version: 31
Release: 4%{?dist}
Summary: Tools to manage UEFI variables
License: LGPLv2.1
URL: https://github.com/rhinstaller/efivar
Requires: %{name}-libs = %{version}-%{release}
ExclusiveArch: x86_64 aarch64

BuildRequires: popt popt-devel popt-static git glibc-static
Source0: https://github.com/rhinstaller/efivar/releases/download/efivar-%{version}/efivar-%{version}.tar.bz2
Patch0001: 0001-libabigail-isn-t-in-RHEL-yet-so-nerf-the-abi-check.patch
Patch0002: 0002-Don-t-use-_Generic-because-gcc-4.x-doesn-t-have-it.patch
Patch0003: 0003-popt-devel-in-RHEL-7.4-doesn-t-provide-popt.pc-so-in.patch
Patch0004: 0004-efi_loadopt_args_from_file-fix-leaked-file-descripto.patch
Patch0005: 0005-make_mac_path-fix-leaked-file-descriptor.patch
Patch0006: 0006-gpt_disk_get_partition_info-free-our-allocations-on-.patch
Patch0007: 0007-efi_generate_file_device_path-fix-one-error-case-s-f.patch
Patch0008: 0008-efi_va_generate_file_device_path_from_esp-handle-err.patch
Patch0009: 0009-efi_variable_import-fix-memory-leak-on-failure-path.patch
Patch0010: 0010-efidp_append_path-error-check-the-right-variable.patch
Patch0011: 0011-efi_variable_import-make-sure-var.data_size-is-set.patch
Patch0012: 0012-makeguids-free-our-input-buffer.patch
Patch0013: 0013-efi_variable_import-constrain-our-inputs-better.patch
Patch0014: 0014-efi_loadopt_create-check-buf-for-NULLness.patch
Patch0015: 0015-efidp_duplicate_extra-error-if-our-allocation-is-too.patch
Patch0016: 0016-show_errors-make-the-useful-part-here-not-be-dead-co.patch
Patch0017: 0017-efi_loadopt_args_from_file-make-sure-buf-is-only-NUL.patch
Patch0018: 0018-calls-to-sysfs_readlink-check-linkbuf-for-NULLness.patch
Patch0019: 0019-efivar-main-explain-efi_well_known_guids-to-the-comp.patch
Patch0020: 0020-dp.h-Try-to-make-covscan-believe-format-is-checking-.patch
Patch0021: 0021-gpt-try-to-avoid-trusting-unverified-partition-table.patch
Patch0022: 0022-Simplify-efidp_append_node-even-more.patch
Patch0023: 0023-efi_loadopt_create-avoid-NULL-dereference.patch
Patch0024: 0024-efi_generate_file_device_path-make-all-error-paths-u.patch
Patch0025: 0025-linux.c-fix-a-pile-of-sscanf-NULL-.-possibilities.patch

%description
efivar provides a simple command line interface to the UEFI variable facility.

%package libs
Summary: Library to manage UEFI variables

%description libs
Library to allow for the simple manipulation of UEFI variables.

%package devel
Summary: Development headers for libefivar
Requires: %{name}-libs = %{version}-%{release}

%description devel
development headers required to use libefivar.

%prep
%setup -q -n %{name}-%{version}
git init
git config user.email "example@example.com"
git config user.name "RHEL Ninjas"
git add .
git commit -a -q -m "%{version} baseline."
git am %{patches} </dev/null
git config --unset user.email
git config --unset user.name

%build
make libdir=%{_libdir} bindir=%{_bindir} CFLAGS="$RPM_OPT_FLAGS -flto" LDFLAGS="$RPM_LD_FLAGS -flto"

%install
rm -rf $RPM_BUILD_ROOT
%makeinstall

%clean
rm -rf $RPM_BUILD_ROOT

%post libs -p /sbin/ldconfig

%postun libs -p /sbin/ldconfig

%files
%{!?_licensedir:%global license %%doc}
%license COPYING
%doc README.md
%{_bindir}/efivar
%exclude %{_bindir}/efivar-static
%{_mandir}/man1/*

%files devel
%{_mandir}/man3/*
%{_includedir}/*
%{_libdir}/*.so
%{_libdir}/pkgconfig/*.pc

%files libs
%{_libdir}/*.so.*

%changelog
* Tue May 09 2017 Peter Jones <pjones@redhat.com> - 31-4
- Fix a bunch of coverity issues.
Related: rhbz#1380825
Related: rhbz#1310779

* Tue May 09 2017 Peter Jones <pjones@redhat.com> - 31-3
- Fix a bunch of coverity issues.
Related: rhbz#1380825
Related: rhbz#1310779

* Tue May 09 2017 Peter Jones <pjones@redhat.com> - 31-2
- Fix a bunch of coverity issues.
Related: rhbz#1380825
Related: rhbz#1310779

* Mon Mar 13 2017 Peter Jones <pjones@redhat.com> - 31-1
- Update to efivar 31
Related: rhbz#1380825
Related: rhbz#1310779

* Wed Aug 20 2014 Peter Jones <pjones@redhat.com> - 0.11-1
- Update to 0.11

* Sat Aug 16 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.10-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild

* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.10-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild

* Fri May 02 2014 Peter Jones <pjones@redhat.com> - 0.10-1
- Update package to 0.10.
- Fixes a build error due to different cflags in the builders vs updstream
makefile.

* Fri May 02 2014 Peter Jones <pjones@redhat.com> - 0.9-0.1
- Update package to 0.9.

* Tue Apr 01 2014 Peter Jones <pjones@redhat.com> - 0.8-0.1
- Update package to 0.8 as well.

* Fri Oct 25 2013 Peter Jones <pjones@redhat.com> - 0.7-1
- Update package to 0.7
- adds --append support to the binary.

* Fri Sep 06 2013 Peter Jones <pjones@redhat.com> - 0.6-1
- Update package to 0.6
- fixes to documentation from lersek
- more validation of uefi guids
- use .xz for archives

* Thu Sep 05 2013 Peter Jones <pjones@redhat.com> - 0.5-0.1
- Update to 0.5

* Mon Jun 17 2013 Peter Jones <pjones@redhat.com> - 0.4-0.2
- Fix ldconfig invocation

* Mon Jun 17 2013 Peter Jones <pjones@redhat.com> - 0.4-0.1
- Initial spec file
Loading…
Cancel
Save