File grub-0.97-bz670266-handle-bad-TFTP_GET_FILE_SIZE.patch of Package grub
From 8f276b40d983a7a2144836ebb3079dd8392cc8fc Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 13 Feb 2012 09:24:37 -0500
Subject: [PATCH] Handle bad TFTP_GET_FILE_SIZE implementation.
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..07af2ff 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.7.6