Blame SOURCES/0012-Fix-path-generation-for-Dhcpv4-bootloader.patch

4210fa
From e62b69a5b0b87c6df7a4fc23906134945309e927 Mon Sep 17 00:00:00 2001
4210fa
From: Peter Jones <pjones@redhat.com>
4210fa
Date: Wed, 20 Nov 2013 12:20:23 -0500
4210fa
Subject: [PATCH 12/74] Fix path generation for Dhcpv4 bootloader.
4210fa
4210fa
Right now we always look for e.g. "\grubx64.efi", which is completely
4210fa
wrong.  This makes it look for the path shim was loaded from and modify
4210fa
that to end in a sanitized version of our default loader name.
4210fa
4210fa
Resolves: rhbz#1032583
4210fa
4210fa
Signed-off-by: Peter Jones <pjones@redhat.com>
4210fa
---
4210fa
 include/str.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
4210fa
 netboot.c     | 28 +++++++++++++++++++++-------
4210fa
 2 files changed, 66 insertions(+), 7 deletions(-)
4210fa
 create mode 100644 include/str.h
4210fa
4210fa
diff --git a/include/str.h b/include/str.h
4210fa
new file mode 100644
4210fa
index 0000000..0f3e003
4210fa
--- /dev/null
4210fa
+++ b/include/str.h
4210fa
@@ -0,0 +1,45 @@
4210fa
+#ifndef SHIM_STR_H
4210fa
+#define SHIM_STR_H
4210fa
+
4210fa
+static inline
4210fa
+__attribute__((unused))
4210fa
+unsigned long strnlena(const CHAR8 *s, unsigned long n)
4210fa
+{
4210fa
+	unsigned long i;
4210fa
+	for (i = 0; i <= n; i++)
4210fa
+		if (s[i] == '\0')
4210fa
+			break;
4210fa
+	return i;
4210fa
+}
4210fa
+
4210fa
+static inline
4210fa
+__attribute__((unused))
4210fa
+CHAR8 *
4210fa
+strncpya(CHAR8 *dest, const CHAR8 *src, unsigned long n)
4210fa
+{
4210fa
+	unsigned long i;
4210fa
+
4210fa
+	for (i = 0; i < n && src[i] != '\0'; i++)
4210fa
+		dest[i] = src[i];
4210fa
+	for (; i < n; i++)
4210fa
+		dest[i] = '\0';
4210fa
+
4210fa
+	return dest;
4210fa
+}
4210fa
+
4210fa
+static inline
4210fa
+__attribute__((unused))
4210fa
+CHAR8 *
4210fa
+strcata(CHAR8 *dest, const CHAR8 *src)
4210fa
+{
4210fa
+	unsigned long dest_len = strlena(dest);
4210fa
+	unsigned long i;
4210fa
+
4210fa
+	for (i = 0; src[i] != '\0'; i++)
4210fa
+		dest[dest_len + i] = src[i];
4210fa
+	dest[dest_len + i] = '\0';
4210fa
+
4210fa
+	return dest;
4210fa
+}
4210fa
+
4210fa
+#endif /* SHIM_STR_H */
4210fa
diff --git a/netboot.c b/netboot.c
4210fa
index a83c82a..1732dc7 100644
4210fa
--- a/netboot.c
4210fa
+++ b/netboot.c
4210fa
@@ -38,6 +38,7 @@
4210fa
 #include <string.h>
4210fa
 #include "shim.h"
4210fa
 #include "netboot.h"
4210fa
+#include "str.h"
4210fa
 
4210fa
 static inline unsigned short int __swap16(unsigned short int x)
4210fa
 {
4210fa
@@ -305,19 +306,32 @@ static EFI_STATUS parseDhcp6()
4210fa
 
4210fa
 static EFI_STATUS parseDhcp4()
4210fa
 {
4210fa
-	CHAR8 *template = (CHAR8 *)DEFAULT_LOADER_CHAR;
4210fa
-	full_path = AllocateZeroPool(strlen(template)+1);
4210fa
+	CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
4210fa
+	UINTN template_len = strlen(template) + 1;
4210fa
+
4210fa
+	UINTN dir_len = strnlena(pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, 127);
4210fa
+	UINTN i;
4210fa
+	UINT8 *dir = pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile;
4210fa
+
4210fa
+	for (i = dir_len; i >= 0; i--) {
4210fa
+		if (dir[i] == '/')
4210fa
+			break;
4210fa
+	}
4210fa
+	dir_len = (i >= 0) ? i + 1 : 0;
4210fa
+
4210fa
+	full_path = AllocateZeroPool(dir_len + template_len);
4210fa
 
4210fa
 	if (!full_path)
4210fa
 		return EFI_OUT_OF_RESOURCES;
4210fa
 
4210fa
+	if (dir_len > 0) {
4210fa
+		strncpya(full_path, dir, dir_len);
4210fa
+		if (full_path[dir_len-1] == '/' && template[0] == '/')
4210fa
+			full_path[dir_len-1] = '\0';
4210fa
+	}
4210fa
+	strcata(full_path, template);
4210fa
 	memcpy(&tftp_addr.v4, pxe->Mode->DhcpAck.Dhcpv4.BootpSiAddr, 4);
4210fa
 
4210fa
-	memcpy(full_path, template, strlen(template));
4210fa
-
4210fa
-	/* Note we don't capture the filename option here because we know its shim.efi
4210fa
-	 * We instead assume the filename at the end of the path is going to be grubx64.efi
4210fa
-	 */
4210fa
 	return EFI_SUCCESS;
4210fa
 }
4210fa
 
4210fa
-- 
4210fa
1.9.3
4210fa