From 212181db82ab76f17fa7a647fe725b5a2bfafa34e19be3615d99b4de48f026fe Mon Sep 17 00:00:00 2001 From: Stephan Kulow Date: Tue, 19 Feb 2013 11:36:40 +0000 Subject: [PATCH 1/2] Accepting request 155796 from home:duwe:branches:Base:System - Apply critical upstream fixes o for memory leaking variable creation. [bnc#746324] o to improve spec conformance by removing device path padding. o to work around broken Apple firmware. OBS-URL: https://build.opensuse.org/request/show/155796 OBS-URL: https://build.opensuse.org/package/show/Base:System/efibootmgr?expand=0&rev=8 --- efibootmgr-0.5.4-catchup.diff | 223 ++++++++++++++++++++++++++++++ efibootmgr-0.5.4-sector-size.diff | 140 +++++++++++++++++++ efibootmgr.changes | 8 ++ efibootmgr.spec | 6 +- 4 files changed, 376 insertions(+), 1 deletion(-) create mode 100644 efibootmgr-0.5.4-catchup.diff create mode 100644 efibootmgr-0.5.4-sector-size.diff diff --git a/efibootmgr-0.5.4-catchup.diff b/efibootmgr-0.5.4-catchup.diff new file mode 100644 index 0000000..e12cc8d --- /dev/null +++ b/efibootmgr-0.5.4-catchup.diff @@ -0,0 +1,223 @@ +--- + Makefile | 2 - + doc/ChangeLog | 66 ++++++++++++++++++++++++++++++++++++++++++++ + src/efibootmgr/efibootmgr.c | 9 +++++- + src/include/efi.h | 2 + + src/lib/disk.c | 1 + src/lib/efivars_sysfs.c | 4 ++ + src/lib/gpt.c | 6 ++-- + src/man/man8/efibootmgr.8 | 10 ++++-- + 8 files changed, 92 insertions(+), 8 deletions(-) + +--- a/doc/ChangeLog ++++ b/doc/ChangeLog +@@ -1,3 +1,69 @@ ++commit de0ca446e7e5439306f7f54806d1a15310588426 ++Author: Jordan Hargrave ++Date: Thu Nov 29 10:11:43 2012 -0600 ++ ++ Add patches from fedora release ++ * Wed Nov 28 2012 Matthew Garrett - 0.5.4-14 ++ - efibootmgr-0.5.4-Work-around-broken-Apple-firmware.patch ++ Resolves: #873629 ++ - efibootmgr-0.5.4-Remove-device-path-padding-on-non-Itanium.patch - improve ++ spec conformance ++ ++commit 9392250bd8668ef7544530d17800dc0271cd8bf3 ++Author: Jordan Hargrave ++Date: Tue Apr 24 12:58:57 2012 -0500 ++ ++ From: Lane Winner ++ ++ make_boot_var does not check for failed status with create_variable. ++ This can result in a memory leak. ++ Additionally the user should be notified of the problem. ++ ++ We encounter this issue on one system after filling up the UEFI boot list ++ with dummy devices. ++ ++ The patch fix the problem. It was verified on a Mensa system using RHEL 6.0 ++ ++ Signed-off-by: Yinghai Lu ++ ++commit 8602b3c41701572669b1f8b9c45409d98405eca2 ++Author: Peter Jones ++Date: Wed Jul 14 11:26:49 2010 -0700 ++ ++ Handle sector_size != 512. ++ ++ Disks can have 4kB sectors now, so don't just bail out when that's the ++ case. ++ ++commit fb3d9a8d9bfd580d23b14b384a393510e0a749ac ++Author: Matt Domsch ++Date: Thu Jul 23 14:20:19 2009 -0500 ++ ++ fix disk minor number discovery ++ ++ Raymund Will noted disk_info_from_fd() incorrectly used logical && ++ instead of bitwise & when obtaining the minor number. ++ ++ Reported in https://bugzilla.novell.com/show_bug.cgi?id=524529#c1 ++ ++commit acac7412e8e0819fc66cdadc06ad4ca535f29b35 ++Author: Matt Domsch ++Date: Thu Jul 23 14:18:11 2009 -0500 ++ ++ fix minor memory leak ++ ++ David Binderman noted new_data was being allocated but not freed. Not ++ a big deal as the program exits soon thereafter (and is thus freed), ++ but worth fixing anyhow. ++ ++ Fixes https://bugzilla.novell.com/show_bug.cgi?id=524529#c1 ++ ++commit c8d6ceaa7b33f952bcf32bc017ce8b5d7d659267 ++Author: Matt Domsch ++Date: Fri Jan 11 15:09:12 2008 -0600 ++ ++ update ChangeLog ++ + commit 6e6bf6fc7665851798a6c2c92893ebb629e42aff + Author: Matt Domsch + Date: Fri Jan 11 15:08:12 2008 -0600 +--- a/src/efibootmgr/efibootmgr.c ++++ b/src/efibootmgr/efibootmgr.c +@@ -239,6 +239,7 @@ warn_duplicate_name(list_t *boot_list) + static var_entry_t * + make_boot_var(list_t *boot_list) + { ++ efi_status_t status; + var_entry_t *boot; + int free_number; + list_t *pos; +@@ -271,7 +272,12 @@ make_boot_var(list_t *boot_list) + free(boot); + return NULL; + } +- create_variable(&boot->var_data); ++ ++ status = create_variable(&boot->var_data); ++ if (status != EFI_SUCCESS) { ++ free(boot); ++ return NULL; ++ } + list_add_tail(&boot->list, boot_list); + return boot; + } +@@ -328,6 +334,7 @@ add_to_boot_order(uint16_t num) + /* Now new_data has what we need */ + memcpy(&(boot_order.Data), new_data, new_data_size); + boot_order.DataSize = new_data_size; ++ free(new_data); + return create_or_edit_variable(&boot_order); + } + +--- a/src/include/efi.h ++++ b/src/include/efi.h +@@ -294,7 +294,9 @@ typedef struct { + uint8_t signature[16]; + uint8_t mbr_type; + uint8_t signature_type; ++#ifdef __ia64 + uint8_t padding[6]; /* Emperically needed */ ++#endif + } __attribute__((packed)) HARDDRIVE_DEVICE_PATH; + + typedef struct { +--- a/src/lib/efivars_sysfs.c ++++ b/src/lib/efivars_sysfs.c +@@ -55,6 +55,10 @@ sysfs_read_variable(const char *name, ef + return EFI_INVALID_PARAMETER; + } + close(fd); ++ /* latest apple firmware sets high bit which appears invalid ++ to the linux kernel if we write it back so lets zero it out ++ if it is set since it would be invalid to set it anyway */ ++ var->Attributes = var->Attributes & ~(1 << 31); + return var->Status; + } + +--- a/src/man/man8/efibootmgr.8 ++++ b/src/man/man8/efibootmgr.8 +@@ -3,7 +3,7 @@ + .\" + .\" Please send any bug reports, improvements, comments, patches, + .\" etc. to Steve Cheng . +-.TH "EFIBOOTMGR" "8" "11 August 2005" "" "" ++.TH "EFIBOOTMGR" "8" "11 January 2012" "" "" + + .SH NAME + efibootmgr \- manipulate the EFI Boot Manager +@@ -127,6 +127,9 @@ the data, so you can pass any binary or + 1. + .SS "DISPLAYING THE CURRENT SETTINGS (MUST BE ROOT)." + .PP ++.PP ++.nf ++.B + [root@localhost ~]# efibootmgr + BootCurrent: 0004 + BootNext: 0003 +@@ -137,6 +140,7 @@ Boot0001* CD-ROM Drive(device:FF) + Boot0002* Hard Drive(Device:80)/HD(Part1,Sig00112233) + Boot0003* PXE Boot: MAC(00D0B7C15D91) + Boot0004* Linux ++.fi + .PP + This shows: + .RS +@@ -217,8 +221,8 @@ You create the boot entry with: + \fBefibootmgr -c -i eth0 -H 222F -U 500 -L netboot\fR + .SH "BUGS" + .PP +-Please direct any bugs, features, patches, etc. to Matt Domsch +-\&. ++Please direct any bugs, features, patches, etc. to Jordan Hargrave ++\&. + .SH "AUTHOR" + .PP + This man page was generated by dann frazier for the +--- a/Makefile ++++ b/Makefile +@@ -4,7 +4,7 @@ + RELEASE_MAJOR := 0 + RELEASE_MINOR := 5 + RELEASE_SUBLEVEL := 4 +- RELEASE_EXTRALEVEL := ++ RELEASE_EXTRALEVEL := .suse2 + RELEASE_NAME := efibootmgr + RELEASE_STRING := $(RELEASE_NAME)-$(RELEASE_MAJOR).$(RELEASE_MINOR).$(RELEASE_SUBLEVEL)$(RELEASE_EXTRALEVEL) + +--- a/src/lib/disk.c ++++ b/src/lib/disk.c +@@ -471,6 +471,7 @@ disk_get_partition_info (int fd, + int rc=0; + int sector_size = get_sector_size(fd); + ++ + mbr_size = lcm(sizeof(*mbr), sector_size); + if ((rc = posix_memalign(&mbr_sector, sector_size, mbr_size)) != 0) + goto error; +--- a/src/lib/gpt.c ++++ b/src/lib/gpt.c +@@ -215,8 +215,8 @@ read_lastoddsector(int fd, uint64_t lba, + static ssize_t + read_lba(int fd, uint64_t lba, void *buffer, size_t bytes) + { +- int sector_size = get_sector_size(fd); +- off_t offset = lba * sector_size; ++ int sector_size = get_sector_size(fd); ++ off_t offset = lba * sector_size; + ssize_t bytesread; + void *iobuf; + size_t iobuf_size; +@@ -229,7 +229,7 @@ read_lba(int fd, uint64_t lba, void *buf + memset(iobuf, 0, bytes); + + +- lseek(fd, offset, SEEK_SET); ++ lseek(fd, offset, SEEK_SET); + bytesread = read(fd, iobuf, iobuf_size); + memcpy(buffer, iobuf, bytes); + free(iobuf); diff --git a/efibootmgr-0.5.4-sector-size.diff b/efibootmgr-0.5.4-sector-size.diff new file mode 100644 index 0000000..5b3f2a1 --- /dev/null +++ b/efibootmgr-0.5.4-sector-size.diff @@ -0,0 +1,140 @@ +From b8af2c229031e274a2c61293a1a634e515a56d27 Mon Sep 17 00:00:00 2001 +In-Reply-To: <1279121617-17961-1-git-send-email-pjones@redhat.com> +References: <1279121617-17961-1-git-send-email-pjones@redhat.com> +From: Peter Jones +Date: Wed, 14 Jul 2010 14:55:17 -0400 +Subject: [efibootmgr patch] Handle sector_size != 512. + +Disks can have 4kB sectors now, so don't just bail out when that's the +case. +--- + src/include/disk.h | 3 +++ + src/lib/disk.c | 42 ++++++++++++++++++++++++++++++++---------- + src/lib/gpt.c | 24 +++++++++++------------- + 3 files changed, 46 insertions(+), 23 deletions(-) + +--- a/src/include/disk.h ++++ b/src/include/disk.h +@@ -65,6 +65,9 @@ enum _interface_type {interface_type_unk + ata, atapi, scsi, usb, + i1394, fibre, i2o, md}; + ++ ++unsigned int lcm(unsigned int x, unsigned int y); ++ + int disk_get_pci(int fd, + unsigned char *bus, + unsigned char *device, +--- a/src/lib/disk.c ++++ b/src/lib/disk.c +@@ -420,6 +420,27 @@ get_sector_size(int filedes) + return sector_size; + } + ++/************************************************************ ++ * lcm ++ * Requires: ++ * - numbers of which to find the lowest common multiple ++ * Modifies: nothing ++ * Returns: ++ * lowest common multiple of x and y ++ ************************************************************/ ++unsigned int ++lcm(unsigned int x, unsigned int y) ++{ ++ unsigned int m = x, n = y, o; ++ ++ while ((o = m % n)) { ++ m = n; ++ n = o; ++ } ++ ++ return (x / n) * y; ++} ++ + /** + * disk_get_partition_info() + * @fd - open file descriptor to disk +@@ -442,26 +463,26 @@ disk_get_partition_info (int fd, + uint8_t *mbr_type, uint8_t *signature_type) + { + legacy_mbr *mbr; +- void *mbr_unaligned; ++ void *mbr_sector; ++ size_t mbr_size; + off_t offset; + int this_bytes_read = 0; + int gpt_invalid=0, mbr_invalid=0; + int rc=0; + int sector_size = get_sector_size(fd); + +- if (sizeof(*mbr) != sector_size) +- return 1; +- mbr_unaligned = malloc(sizeof(*mbr)+sector_size-1); +- mbr = (legacy_mbr *) +- (((unsigned long)mbr_unaligned + sector_size - 1) & +- ~(unsigned long)(sector_size-1)); +- memset(mbr, 0, sizeof(*mbr)); ++ mbr_size = lcm(sizeof(*mbr), sector_size); ++ if ((rc = posix_memalign(&mbr_sector, sector_size, mbr_size)) != 0) ++ goto error; ++ memset(mbr_sector, '\0', mbr_size); ++ + offset = lseek(fd, 0, SEEK_SET); +- this_bytes_read = read(fd, mbr, sizeof(*mbr)); ++ this_bytes_read = read(fd, mbr_sector, mbr_size); + if (this_bytes_read < sizeof(*mbr)) { + rc=1; + goto error_free_mbr; + } ++ mbr = (legacy_mbr *)mbr_sector; + gpt_invalid = gpt_disk_get_partition_info(fd, num, + start, size, + signature, +@@ -479,7 +500,8 @@ disk_get_partition_info (int fd, + } + } + error_free_mbr: +- free(mbr_unaligned); ++ free(mbr_sector); ++ error: + return rc; + } + +--- a/src/lib/gpt.c ++++ b/src/lib/gpt.c +@@ -218,23 +218,21 @@ read_lba(int fd, uint64_t lba, void *buf + int sector_size = get_sector_size(fd); + off_t offset = lba * sector_size; + ssize_t bytesread; +- void *aligned; +- void *unaligned; ++ void *iobuf; ++ size_t iobuf_size; ++ int rc; + +- if (bytes % sector_size) +- return EINVAL; +- +- unaligned = malloc(bytes+sector_size-1); +- aligned = (void *) +- (((unsigned long)unaligned + sector_size - 1) & +- ~(unsigned long)(sector_size-1)); +- memset(aligned, 0, bytes); ++ iobuf_size = lcm(bytes, sector_size); ++ rc = posix_memalign(&iobuf, sector_size, iobuf_size); ++ if (rc) ++ return rc; ++ memset(iobuf, 0, bytes); + + + lseek(fd, offset, SEEK_SET); +- bytesread = read(fd, aligned, bytes); +- memcpy(buffer, aligned, bytesread); +- free(unaligned); ++ bytesread = read(fd, iobuf, iobuf_size); ++ memcpy(buffer, iobuf, bytes); ++ free(iobuf); + + /* Kludge. This is necessary to read/write the last + block of an odd-sized disk, until Linux 2.5.x kernel fixes. diff --git a/efibootmgr.changes b/efibootmgr.changes index de23ed5..249e9e4 100644 --- a/efibootmgr.changes +++ b/efibootmgr.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Feb 12 16:38:47 UTC 2013 - rw@suse.com + +- Apply critical upstream fixes + o for memory leaking variable creation. [bnc#746324] + o to improve spec conformance by removing device path padding. + o to work around broken Apple firmware. + ------------------------------------------------------------------- Tue Jun 12 16:51:40 UTC 2012 - mgorse@suse.com diff --git a/efibootmgr.spec b/efibootmgr.spec index 8690c08..25363a8 100644 --- a/efibootmgr.spec +++ b/efibootmgr.spec @@ -1,7 +1,7 @@ # # spec file for package efibootmgr # -# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -25,6 +25,8 @@ Release: 0 Url: http://linux.dell.com/efibootmgr/ Source: http://linux.dell.com/efibootmgr/efibootmgr-%{version}.tar.gz Patch0: %{name}-%{version}.diff +Patch1: %{name}-%{version}-sector-size.diff +Patch2: %{name}-%{version}-catchup.diff BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: pciutils-devel BuildRequires: zlib-devel @@ -39,6 +41,8 @@ information about the EFI can be found at %prep %setup -q %patch0 -p1 +%patch1 -p1 +%patch2 -p1 chmod +x tools/install.pl %build From 92b00c0ba2fc1d2a1bfaed741212077aaf93f9de65750a48458e175be157d441 Mon Sep 17 00:00:00 2001 From: Stephan Kulow Date: Tue, 19 Feb 2013 12:08:49 +0000 Subject: [PATCH 2/2] efibootmgr-0.5.4-sector-size.diff efibootmgr-0.5.4-catchup.diff OBS-URL: https://build.opensuse.org/package/show/Base:System/efibootmgr?expand=0&rev=9 --- efibootmgr.changes | 2 ++ 1 file changed, 2 insertions(+) diff --git a/efibootmgr.changes b/efibootmgr.changes index 249e9e4..adaefac 100644 --- a/efibootmgr.changes +++ b/efibootmgr.changes @@ -5,6 +5,8 @@ Tue Feb 12 16:38:47 UTC 2013 - rw@suse.com o for memory leaking variable creation. [bnc#746324] o to improve spec conformance by removing device path padding. o to work around broken Apple firmware. + efibootmgr-0.5.4-sector-size.diff + efibootmgr-0.5.4-catchup.diff ------------------------------------------------------------------- Tue Jun 12 16:51:40 UTC 2012 - mgorse@suse.com