From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1U0tBu-0004ru-4b for mharc-grub-devel@gnu.org; Thu, 31 Jan 2013 07:24:30 -0500 Received: from eggs.gnu.org ([208.118.235.92]:32788) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U0tBq-0004ic-Gl for grub-devel@gnu.org; Thu, 31 Jan 2013 07:24:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U0tBk-0005Ej-L8 for grub-devel@gnu.org; Thu, 31 Jan 2013 07:24:26 -0500 Received: from mail-lb0-f172.google.com ([209.85.217.172]:58388) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U0tBk-0005EX-8y for grub-devel@gnu.org; Thu, 31 Jan 2013 07:24:20 -0500 Received: by mail-lb0-f172.google.com with SMTP id n8so3325914lbj.31 for ; Thu, 31 Jan 2013 04:24:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer; bh=G/c7uMjO/BeJrgixtlStKjGDHqD0Q/7sy3AKDSd9F4Y=; b=ICu5RhohfmEgOA3s8GQjFdx7DUjEp7kwjjdAukrUrlcH15Dsh0ReabPvsTPTua67A4 hS/i31omTXMxCDCYcDjJdH7ueQ2+QuMaWaFybqwPPEQPkcBfKgYoasOGVkkPm7NHZDhh VfFcCBwJP0VvG3U7nHD1R3w38sDmaoGjp65Km6Eg33zzklj9uMxpFGRW2mA466o0HRxF ix6Y8UnaB6F6Xgi7eMhdfm/5cIAAjp0NKQ/bUbQstnVJBx7xCxUwq62LkQ8dLNFv0I/u 9LDIr4p6kAmwi1UXpiU5R3aTpOZb3zK22G2AAf07eX9oXwJbclPOFGy7HUL/L/jmRGuT GGyQ== X-Received: by 10.112.37.200 with SMTP id a8mr3348226lbk.92.1359635058788; Thu, 31 Jan 2013 04:24:18 -0800 (PST) Received: from localhost.localdomain (ppp91-78-198-46.pppoe.mtu-net.ru. [91.78.198.46]) by mx.google.com with ESMTPS id tm10sm2359009lab.10.2013.01.31.04.24.17 (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 31 Jan 2013 04:24:17 -0800 (PST) From: Andrey Borzenkov To: grub-devel@gnu.org Subject: [PATCH] Fix prefix autodetection when booting from EFI CD-ROM Date: Thu, 31 Jan 2013 16:24:00 +0400 Message-Id: <1359635040-23786-1-git-send-email-arvidjaar@gmail.com> X-Mailer: git-send-email 1.7.10.4 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.217.172 Cc: mchang@suse.com, mjg@redhat.com X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 31 Jan 2013 12:24:28 -0000 Fix autodetection of $prefix when booted from EFI CD-ROM. Based on patch from Matthew Garrett, modified to not overwrite memory returned by device path protocol handler and rebased to current trunk. Additionally fixes potential memory leak - dup_dp was not deallocated if device path was not found. Signed-off-by: Andrey Borzenkov --- grub-core/disk/efi/efidisk.c | 121 +++++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 55 deletions(-) diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index 98cd226..15c8109 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -775,67 +775,78 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) if (! ldp) return 0; - if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE - && (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) - == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)) + if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE) { - struct grub_efidisk_get_device_name_ctx ctx; - char *dev_name; - grub_efi_device_path_t *dup_dp, *dup_ldp; - grub_disk_t parent = 0; - - /* It is necessary to duplicate the device path so that GRUB - can overwrite it. */ - dup_dp = duplicate_device_path (dp); - if (! dup_dp) - return 0; - - dup_ldp = find_last_device_path (dup_dp); - dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; - dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; - dup_ldp->length[0] = sizeof (*dup_ldp); - dup_ldp->length[1] = 0; + int is_cdrom = 0; - if (!get_diskname_from_path (dup_dp, device_name)) - return 0; - parent = grub_disk_open (device_name); - grub_free (dup_dp); - - if (! parent) - return 0; - - /* Find a partition which matches the hard drive device path. */ - ctx.partition_name = NULL; - grub_memcpy (&ctx.hd, ldp, sizeof (ctx.hd)); - if (ctx.hd.partition_start == 0 - && ctx.hd.partition_size == grub_disk_get_size (parent)) - { - dev_name = grub_strdup (parent->name); - } - else + switch (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp)) { - grub_partition_iterate (parent, grub_efidisk_get_device_name_iter, - &ctx); - - if (! ctx.partition_name) + case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE: + is_cdrom = 1; + /* Intentionally fall through */ + case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE: { + struct grub_efidisk_get_device_name_ctx ctx; + char *dev_name; + grub_efi_device_path_t *dup_dp, *dup_ldp; + grub_disk_t parent = 0; + + /* It is necessary to duplicate the device path so that GRUB + can overwrite it. */ + dup_dp = duplicate_device_path (dp); + if (! dup_dp) + return 0; + + dup_ldp = find_last_device_path (dup_dp); + dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; + dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + dup_ldp->length[0] = sizeof (*dup_ldp); + dup_ldp->length[1] = 0; + + if (!get_diskname_from_path (dup_dp, device_name)) + { + grub_free (dup_dp); + return 0; + } + grub_free (dup_dp); + if (is_cdrom) + return grub_strdup (device_name); + + parent = grub_disk_open (device_name); + if (! parent) + return 0; + + /* Find a partition which matches the hard drive device path. */ + ctx.partition_name = NULL; + grub_memcpy (&ctx.hd, ldp, sizeof (ctx.hd)); + if (ctx.hd.partition_start == 0 + && ctx.hd.partition_size == grub_disk_get_size (parent)) + { + dev_name = grub_strdup (parent->name); + } + else + { + grub_partition_iterate (parent, grub_efidisk_get_device_name_iter, + &ctx); + + if (! ctx.partition_name) + { + grub_disk_close (parent); + return 0; + } + + dev_name = grub_xasprintf ("%s,%s", parent->name, + ctx.partition_name); + grub_free (ctx.partition_name); + } grub_disk_close (parent); - return 0; - } - dev_name = grub_xasprintf ("%s,%s", parent->name, - ctx.partition_name); - grub_free (ctx.partition_name); + return dev_name; + } } - grub_disk_close (parent); - - return dev_name; - } - else - { - /* This should be an entire disk. */ - if (!get_diskname_from_path (dp, device_name)) - return 0; - return grub_strdup (device_name); } + /* This may be guessed device - floppy, cdrom or entire disk. */ + if (!get_diskname_from_path (dp, device_name)) + return 0; + return grub_strdup (device_name); } -- tg: (4b9ea2e..) u/efi-cdrom-prefix (depends on: master)