arrfab / rpms / shim

Forked from rpms/shim 4 years ago
Clone

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

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