[grub] - Handle tftp implementations that don't do TFTP_GET_FILE_SIZE correctly

Peter Jones pjones at fedoraproject.org
Thu Oct 7 14:25:52 UTC 2010


commit 2a8fcd2436ad7a1d552dc6f2253889356cafea4a
Author: Peter Jones <pjones at redhat.com>
Date:   Thu Oct 7 10:25:28 2010 -0400

    - Handle tftp implementations that don't do TFTP_GET_FILE_SIZE correctly

 grub-0.97-handle-bad-tftp.patch |  118 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 118 insertions(+), 0 deletions(-)
---
diff --git a/grub-0.97-handle-bad-tftp.patch b/grub-0.97-handle-bad-tftp.patch
new file mode 100644
index 0000000..5000e14
--- /dev/null
+++ b/grub-0.97-handle-bad-tftp.patch
@@ -0,0 +1,118 @@
+From e148522a6e0fd7aeebd3dfd7e162633a3ceb0a87 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones at redhat.com>
+Date: Wed, 6 Oct 2010 14:03:36 -0400
+Subject: [PATCH] Handle bad TFTP_GET_FILE_SIZE implementation by simulating it.
+
+Some platforms, most notably the one identified below, have a broken
+tftp implementation where TFTP_GET_FILE_SIZE returns EFI_BUFFER_TOO_SHORT,
+despite the fact that there's no documented reason for it to do so and
+no buffer that should be in use.
+
+The system I've seen this on says:
+
+BIOS Vendor             American Megatrends
+Core Version            4.6.3.2
+Project Version         0ABPH 0.12 x64
+Build Date              03/05/2009 15:16:58
+MRC Version             01000000
+CSI Ref Code Version    0100
+
+This machine is a UEFI 2.0 machine.
+---
+ efi/efitftp.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ efi/pxe.c     |    1 -
+ 2 files changed, 52 insertions(+), 2 deletions(-)
+
+diff --git a/efi/efitftp.c b/efi/efitftp.c
+index 7e449b9..4984c97 100644
+--- a/efi/efitftp.c
++++ b/efi/efitftp.c
+@@ -29,6 +29,55 @@ struct tftp_info tftp_info = {
+  * BootpBootFile: X86PC/UNDI/pxelinux/bootx64.efi
+  */
+ 
++static grub_efi_status_t tftp_get_file_size_defective_buffer_fallback(
++	char *Filename,
++	grub_efi_uintn_t *Size)
++{
++	EFI_PXE_BASE_CODE_TFTP_OPCODE OpCode = EFI_PXE_BASE_CODE_TFTP_READ_FILE;
++	char *Buffer = NULL;
++	grub_efi_boolean_t Overwrite = 0;
++	grub_efi_boolean_t DontUseBuffer = 0;
++	grub_efi_uint64_t BufferSize = 4096;
++	grub_efi_uintn_t BlockSize = 512;
++	grub_efi_status_t rc = GRUB_EFI_BUFFER_TOO_SMALL;
++	char *FullPath = NULL;
++
++	while (rc == GRUB_EFI_BUFFER_TOO_SMALL) {
++		char *NewBuffer;
++		
++		if (Buffer) {
++			grub_free(Buffer);
++			Buffer = NULL;
++		}
++		BufferSize *= 2;
++		NewBuffer = grub_malloc(BufferSize);
++		if (!NewBuffer)
++			return GRUB_EFI_OUT_OF_RESOURCES;
++		Buffer = NewBuffer;
++
++		if (tftp_info.BasePath) {
++			int PathSize = 0;
++			PathSize = strlen(tftp_info.BasePath) + 2 +
++				   strlen(Filename);
++			FullPath = grub_malloc(PathSize);
++			grub_sprintf(FullPath, "%s/%s", tftp_info.BasePath,
++				     Filename);
++		} else {
++			FullPath = grub_malloc(strlen(Filename));
++			strcpy(FullPath, Filename);
++		}
++
++		rc = Call_Service_10(tftp_info.Pxe->Mtftp, tftp_info.Pxe,
++			OpCode, Buffer, Overwrite, &BufferSize, &BlockSize,
++			tftp_info.ServerIp, FullPath, NULL, DontUseBuffer);
++		if (rc == GRUB_EFI_SUCCESS || rc == GRUB_EFI_BUFFER_TOO_SMALL)
++			*Size = BufferSize;
++	}
++	grub_free(FullPath);
++	grub_free(Buffer);
++	return rc;
++}
++
+ grub_efi_status_t tftp_get_file_size(
+ 	char *Filename,
+ 	grub_efi_uintn_t *Size)
+@@ -55,6 +104,8 @@ grub_efi_status_t tftp_get_file_size(
+ 	rc = Call_Service_10(tftp_info.Pxe->Mtftp, tftp_info.Pxe, OpCode,
+ 		Buffer, Overwrite, &BufferSize, &BlockSize, tftp_info.ServerIp,
+ 		FullPath, NULL, DontUseBuffer);
++	if (rc == GRUB_EFI_BUFFER_TOO_SMALL)
++		rc = tftp_get_file_size_defective_buffer_fallback(Filename, Size);
+ 	if (rc == GRUB_EFI_SUCCESS)
+ 		*Size = BufferSize;
+ 	grub_free(FullPath);
+@@ -152,7 +203,7 @@ efi_tftp_dir (char *dirname)
+ 	filemax = -1;
+ 
+ 	rc = tftp_get_file_size(name, &size);
+-	if (rc == 0) {
++	if (rc == GRUB_EFI_SUCCESS) {
+ 		tftp_info.LastPath = grub_malloc(strlen(name) + 1);
+ 		sprintf(tftp_info.LastPath, "%s", name);
+ 		filemax = size;
+diff --git a/efi/pxe.c b/efi/pxe.c
+index 8a15f20..185ad79 100644
+--- a/efi/pxe.c
++++ b/efi/pxe.c
+@@ -320,7 +320,6 @@ static char *get_pxe_file_dir(EFI_PXE_BASE_CODE *pxe)
+ 
+ 	*DirEnd = '\0';
+ 	
+-	printf("FileDir: \"%s\"\n", FileDir);
+ 	return FileDir;
+ }
+ 
+-- 
+1.7.3.1
+


More information about the scm-commits mailing list