File shim-fix-dhcpv4-path-generation.patch of Package shim

From e62b69a5b0b87c6df7a4fc23906134945309e927 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 20 Nov 2013 12:20:23 -0500
Subject: [PATCH 1/2] Fix path generation for Dhcpv4 bootloader.

Right now we always look for e.g. "\grubx64.efi", which is completely
wrong.  This makes it look for the path shim was loaded from and modify
that to end in a sanitized version of our default loader name.

Resolves: rhbz#1032583

Signed-off-by: Peter Jones <pjones@redhat.com>
---
 include/str.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
 netboot.c     | 28 +++++++++++++++++++++-------
 2 files changed, 66 insertions(+), 7 deletions(-)
 create mode 100644 include/str.h

diff --git a/include/str.h b/include/str.h
new file mode 100644
index 0000000..0f3e003
--- /dev/null
+++ b/include/str.h
@@ -0,0 +1,45 @@
+#ifndef SHIM_STR_H
+#define SHIM_STR_H
+
+static inline
+__attribute__((unused))
+unsigned long strnlena(const CHAR8 *s, unsigned long n)
+{
+	unsigned long i;
+	for (i = 0; i <= n; i++)
+		if (s[i] == '\0')
+			break;
+	return i;
+}
+
+static inline
+__attribute__((unused))
+CHAR8 *
+strncpya(CHAR8 *dest, const CHAR8 *src, unsigned long n)
+{
+	unsigned long i;
+
+	for (i = 0; i < n && src[i] != '\0'; i++)
+		dest[i] = src[i];
+	for (; i < n; i++)
+		dest[i] = '\0';
+
+	return dest;
+}
+
+static inline
+__attribute__((unused))
+CHAR8 *
+strcata(CHAR8 *dest, const CHAR8 *src)
+{
+	unsigned long dest_len = strlena(dest);
+	unsigned long i;
+
+	for (i = 0; src[i] != '\0'; i++)
+		dest[dest_len + i] = src[i];
+	dest[dest_len + i] = '\0';
+
+	return dest;
+}
+
+#endif /* SHIM_STR_H */
diff --git a/netboot.c b/netboot.c
index a83c82a..1732dc7 100644
--- a/netboot.c
+++ b/netboot.c
@@ -38,6 +38,7 @@
 #include <string.h>
 #include "shim.h"
 #include "netboot.h"
+#include "str.h"
 
 static inline unsigned short int __swap16(unsigned short int x)
 {
@@ -305,19 +306,32 @@ static EFI_STATUS parseDhcp6()
 
 static EFI_STATUS parseDhcp4()
 {
-	CHAR8 *template = (CHAR8 *)DEFAULT_LOADER_CHAR;
-	full_path = AllocateZeroPool(strlen(template)+1);
+	CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
+	UINTN template_len = strlen(template) + 1;
+
+	UINTN dir_len = strnlena(pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, 127);
+	UINTN i;
+	UINT8 *dir = pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile;
+
+	for (i = dir_len; i >= 0; i--) {
+		if (dir[i] == '/')
+			break;
+	}
+	dir_len = (i >= 0) ? i + 1 : 0;
+
+	full_path = AllocateZeroPool(dir_len + template_len);
 
 	if (!full_path)
 		return EFI_OUT_OF_RESOURCES;
 
+	if (dir_len > 0) {
+		strncpya(full_path, dir, dir_len);
+		if (full_path[dir_len-1] == '/' && template[0] == '/')
+			full_path[dir_len-1] = '\0';
+	}
+	strcata(full_path, template);
 	memcpy(&tftp_addr.v4, pxe->Mode->DhcpAck.Dhcpv4.BootpSiAddr, 4);
 
-	memcpy(full_path, template, strlen(template));
-
-	/* Note we don't capture the filename option here because we know its shim.efi
-	 * We instead assume the filename at the end of the path is going to be grubx64.efi
-	 */
 	return EFI_SUCCESS;
 }
 
-- 
1.8.1.4


From 27129a5a05d1947e6f7479766e8281d50d6031f6 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 21 Nov 2013 11:26:08 -0500
Subject: [PATCH 2/2] Lengths that might be -1 can't be unsigned, Peter.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
 netboot.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/netboot.c b/netboot.c
index 1732dc7..07e2773 100644
--- a/netboot.c
+++ b/netboot.c
@@ -307,10 +307,10 @@ static EFI_STATUS parseDhcp6()
 static EFI_STATUS parseDhcp4()
 {
 	CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
-	UINTN template_len = strlen(template) + 1;
+	INTN template_len = strlen(template) + 1;
 
-	UINTN dir_len = strnlena(pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, 127);
-	UINTN i;
+	INTN dir_len = strnlena(pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, 127);
+	INTN i;
 	UINT8 *dir = pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile;
 
 	for (i = dir_len; i >= 0; i--) {
@@ -329,6 +329,8 @@ static EFI_STATUS parseDhcp4()
 		if (full_path[dir_len-1] == '/' && template[0] == '/')
 			full_path[dir_len-1] = '\0';
 	}
+	if (dir_len == 0 && dir[0] != '/' && template[0] == '/')
+		template++;
 	strcata(full_path, template);
 	memcpy(&tftp_addr.v4, pxe->Mode->DhcpAck.Dhcpv4.BootpSiAddr, 4);
 
-- 
1.8.1.4

openSUSE Build Service is sponsored by