]> code.delx.au - refind/commitdiff
PRELIMINARY workaround for Shim 0.8 bug.
authorsrs5694 <srs5694@users.sourceforge.net>
Wed, 16 Sep 2015 12:24:21 +0000 (08:24 -0400)
committersrs5694 <srs5694@users.sourceforge.net>
Wed, 16 Sep 2015 12:24:21 +0000 (08:24 -0400)
NEWS.txt
docs/refind/installing.html
refind/global.h
refind/lib.c
refind/main.c

index 1ffbed417221fef7ecc1a85dbda21c6bb74edde9..c049f136a744ac0c14e0846f207b90ecbf471765 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,3 +1,12 @@
+0.9.2 (9/??/2015):
+------------------
+
+- Implemented a workaround for a bug in Shim 0.8 that prevented
+  authentication of more than one binary. If any filesystem drivers were
+  installed, the first one would be verified, leaving rEFInd to be unable
+  to launch anything else unless it was signed by a key in the computer's
+  main Secure Boot db list.
+
 0.9.1 (9/13/2015):
 ------------------
 
index 6615d1907498f229a1a0258710bd6d7be2a1bd81..4bd53f89d6ca7d23c6809cff9d596cccdb766712 100644 (file)
@@ -17,7 +17,7 @@
 href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
 
 <p>Originally written: 3/14/2012; last Web page update:
-9/13/2015, referencing rEFInd 0.9.1</p>
+9/14/2015, referencing rEFInd 0.9.1</p>
 
 
 <p>This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!</p>
@@ -258,7 +258,7 @@ $ <tt class="userinput">sudo apt-get install refind</tt></pre></pre>
 <h3>Quick <tt>install.sh</tt> Instructions</h3>
 </quickstart>
 
-<p class="sidebar"><b>Warning:</b> I've received reports that the OS X 10.11 ("El Capitan") beta has made changes to its <tt>bless</tt> utility that break the rEFInd installation procedure. I have not yet had a chance to investigate this matter. If possible, I recommend using OS X 10.10 ("Yosemite") or earlier to install rEFInd until this issue is resolved. If this is not possible, you might want to use the <a href="#osx">manual OS X installation instructions,</a> but be aware that you'll have to experiment with the <tt>bless</tt> command yourself to figure out what works.</p>
+<p class="sidebar"><b>Warning:</b> I've received reports that the OS X 10.11 ("El Capitan") beta has made changes to the OS that break the rEFInd installation procedure. This problem has been publicly reported as a bug in <tt>bless</tt>&mdash;see, for instance, <a href="http://www.openradar.me/22397509">here</a> and <a href="http://www.openradar.me/22170141">here.</a> It seems to be related to a new feature called System Integrity Protection. If possible, I recommend using OS X 10.10 ("Yosemite") or earlier to install rEFInd until this issue is resolved. It's reportedly possible to disable this feature by booting to recovery mode (by holding down Alt while booting) and typing <tt class="userinput">csrutil disable</tt> in a Terminal. After installing rEFInd, you can re-enable this feature by repeating the process, but typing <tt class="userinput">csrutil enable</tt>.</p>
 
 <p>By default, the <tt>install.sh</tt> script installs rEFInd to your disk's ESP. Under Mac OS X, you can instead install rEFInd to your current OS X boot partition by passing the script the <tt>--notesp</tt> option, or to a non-boot HFS+ partition by using the <tt>--ownhfs <tt class="variable">devicefile</tt></tt> option. Under either OS, you can install to something other than the currently-running OS by using the <tt>--root <tt class="variable">/mountpoint</tt></tt> option. (See <a href="#table1">Table 1</a> for details.)</p>
 
@@ -514,7 +514,7 @@ Filesystem     1K-blocks  Used Available Use% Mounted on
 <h3>Installing rEFInd Manually Using Mac OS X</h3>
 </a>
 
-<p class="sidebar"><b>Warning:</b> I've received reports that the OS X 10.11 ("El Capitan") beta has made changes to its <tt>bless</tt> utility that break the rEFInd installation procedure. I have not yet had a chance to investigate this matter. If possible, I recommend using OS X 10.10 ("Yosemite") or earlier to install rEFInd until this issue is resolved. If you experiment with the <tt>bless</tt> command and figure out what's changed, please <a href="mailto:rodsmith@rodsbooks.com">contact me</a> so that I can pass on this information.</p>
+<p class="sidebar"><b>Warning:</b> I've received reports that the OS X 10.11 ("El Capitan") beta has made changes to the OS that break the rEFInd installation procedure. This problem has been publicly reported as a bug in <tt>bless</tt>&mdash;see, for instance, <a href="http://www.openradar.me/22397509">here</a> and <a href="http://www.openradar.me/22170141">here.</a> It seems to be related to a new feature called System Integrity Protection. If possible, I recommend using OS X 10.10 ("Yosemite") or earlier to install rEFInd until this issue is resolved. It's reportedly possible to disable this feature by booting to recovery mode (by holding down Alt while booting) and typing <tt class="userinput">csrutil disable</tt> in a Terminal. After installing rEFInd, you can re-enable this feature by repeating the process, but typing <tt class="userinput">csrutil enable</tt>.</p>
 
 <p>Before installing rEFInd on a Mac, you must determine whether it uses a 32-bit or 64-bit EFI implementation. Most Intel-based Macs have 64-bit EFIs, so you should use the <tt>refind_x64.efi</tt> file with them; but very early Intel-based Macs have 32-bit EFIs (and sometimes 32-bit CPUs), which require the <tt>refind_ia32.efi</tt> file. You can determine whether your Mac needs the <i>x</i>86-64 or IA32 build by typing the following command in a Mac Terminal window:</p>
 
index e8d57eb72a90b5095992b32ff0bdb43535db4596..875fc20464a4f30760309d39e8c686af31d2dbd5 100644 (file)
@@ -272,40 +272,41 @@ typedef struct {
 } LEGACY_ENTRY;
 
 typedef struct {
-   BOOLEAN       TextOnly;
-   BOOLEAN       ScanAllLinux;
-   BOOLEAN       DeepLegacyScan;
-   BOOLEAN       EnableAndLockVMX;
-   BOOLEAN       FoldLinuxKernels;
-   UINTN         RequestedScreenWidth;
-   UINTN         RequestedScreenHeight;
-   UINTN         BannerBottomEdge;
-   UINTN         RequestedTextMode;
-   UINTN         Timeout;
-   UINTN         HideUIFlags;
-   UINTN         MaxTags;     // max. number of OS entries to show simultaneously in graphics mode
-   UINTN         GraphicsFor;
-   UINTN         LegacyType;
-   UINTN         ScanDelay;
-   UINTN         ScreensaverTime;
-   UINTN         IconSizes[3];
-   UINTN         BannerScale;
-   REFIT_VOLUME  *DiscoveredRoot;
-   CHAR16        *BannerFileName;
-   EG_IMAGE      *ScreenBackground;
-   CHAR16        *ConfigFilename;
-   CHAR16        *SelectionSmallFileName;
-   CHAR16        *SelectionBigFileName;
-   CHAR16        *DefaultSelection;
-   CHAR16        *AlsoScan;
-   CHAR16        *DontScanVolumes;
-   CHAR16        *DontScanDirs;
-   CHAR16        *DontScanFiles;
-   CHAR16        *WindowsRecoveryFiles;
-   CHAR16        *DriverDirs;
-   CHAR16        *IconsDir;
-   UINTN         ShowTools[NUM_TOOLS];
-   CHAR8         ScanFor[NUM_SCAN_OPTIONS]; // codes of types of loaders for which to scan
+   BOOLEAN          TextOnly;
+   BOOLEAN          ScanAllLinux;
+   BOOLEAN          DeepLegacyScan;
+   BOOLEAN          EnableAndLockVMX;
+   BOOLEAN          FoldLinuxKernels;
+   UINTN            RequestedScreenWidth;
+   UINTN            RequestedScreenHeight;
+   UINTN            BannerBottomEdge;
+   UINTN            RequestedTextMode;
+   UINTN            Timeout;
+   UINTN            HideUIFlags;
+   UINTN            MaxTags;     // max. number of OS entries to show simultaneously in graphics mode
+   UINTN            GraphicsFor;
+   UINTN            LegacyType;
+   UINTN            ScanDelay;
+   UINTN            ScreensaverTime;
+   UINTN            IconSizes[3];
+   UINTN            BannerScale;
+   REFIT_VOLUME     *DiscoveredRoot;
+   EFI_DEVICE_PATH  *SelfDevicePath;
+   CHAR16           *BannerFileName;
+   EG_IMAGE         *ScreenBackground;
+   CHAR16           *ConfigFilename;
+   CHAR16           *SelectionSmallFileName;
+   CHAR16           *SelectionBigFileName;
+   CHAR16           *DefaultSelection;
+   CHAR16           *AlsoScan;
+   CHAR16           *DontScanVolumes;
+   CHAR16           *DontScanDirs;
+   CHAR16           *DontScanFiles;
+   CHAR16           *WindowsRecoveryFiles;
+   CHAR16           *DriverDirs;
+   CHAR16           *IconsDir;
+   UINTN            ShowTools[NUM_TOOLS];
+   CHAR8            ScanFor[NUM_SCAN_OPTIONS]; // codes of types of loaders for which to scan
 } REFIT_CONFIG;
 
 // Global variables
index 40c1814791f7dbae2580d3905159e6c378d76aa8..6bf2d5d2dc96c3d709818626cf33c288b880b7d7 100644 (file)
@@ -193,6 +193,7 @@ EFI_STATUS InitRefitLib(IN EFI_HANDLE ImageHandle)
 
     // find the current directory
     DevicePathAsString = DevicePathToStr(SelfLoadedImage->FilePath);
+    GlobalConfig.SelfDevicePath = FileDevicePath(SelfLoadedImage->DeviceHandle, DevicePathAsString);
     CleanUpPathNameSlashes(DevicePathAsString);
     MyFreePool(SelfDirPath);
     Temp = FindPath(DevicePathAsString);
index 9e2ee29735d2d5e751c2795d48d7de6ee59c2c6a..f674ecf318cc891f1b3b7f265a8c36dfe1757675 100644 (file)
@@ -145,7 +145,7 @@ static REFIT_MENU_SCREEN AboutMenu      = { L"About", NULL, 0, NULL, 0, NULL, 0,
 
 REFIT_CONFIG GlobalConfig = { FALSE, TRUE, FALSE, FALSE, TRUE,  0, 0, 0, DONT_CHANGE_TEXT_MODE, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC,
                               0, 0, { DEFAULT_BIG_ICON_SIZE / 4, DEFAULT_SMALL_ICON_SIZE, DEFAULT_BIG_ICON_SIZE }, BANNER_NOSCALE,
-                              NULL, NULL, NULL, CONFIG_FILE_NAME, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                              NULL, NULL, NULL, NULL, CONFIG_FILE_NAME, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               { TAG_SHELL, TAG_MEMTEST, TAG_GDISK, TAG_APPLE_RECOVERY, TAG_WINDOWS_RECOVERY, TAG_MOK_TOOL,
                                 TAG_ABOUT, TAG_SHUTDOWN, TAG_REBOOT, TAG_FIRMWARE, 0, 0, 0, 0, 0, 0, 0, 0 }
                             };
@@ -173,7 +173,7 @@ static VOID AboutrEFInd(VOID)
 
     if (AboutMenu.EntryCount == 0) {
         AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
-        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.9.1");
+        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.9.1.1");
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2015 Roderick W. Smith");
@@ -276,7 +276,7 @@ EFI_STATUS StartEFIImageList(IN EFI_DEVICE_PATH **DevicePaths,
                              IN BOOLEAN IsDriver)
 {
     EFI_STATUS              Status, ReturnStatus;
-    EFI_HANDLE              ChildImageHandle;
+    EFI_HANDLE              ChildImageHandle, ChildImageHandle2;
     EFI_LOADED_IMAGE        *ChildLoadedImage = NULL;
     REFIT_VOLUME            *Volume = NULL;
     UINTN                   DevicePathIndex;
@@ -300,7 +300,7 @@ EFI_STATUS StartEFIImageList(IN EFI_DEVICE_PATH **DevicePaths,
     if (Verbose)
     Print(L"Starting %s\nUsing load options '%s'\n", ImageTitle, FullLoadOptions ? FullLoadOptions : L"");
 
-    // load the image into memory (and execute it, in the case of a shim/MOK image).
+    // load the image into memory
     ReturnStatus = Status = EFI_NOT_FOUND;  // in case the list is empty
     for (DevicePathIndex = 0; DevicePaths[DevicePathIndex] != NULL; DevicePathIndex++) {
         FindVolumeAndFilename(DevicePaths[DevicePathIndex], &Volume, &Filename);
@@ -325,6 +325,22 @@ EFI_STATUS StartEFIImageList(IN EFI_DEVICE_PATH **DevicePaths,
             //                                            ImageData, ImageSize, &ChildImageHandle);
             ReturnStatus = Status = refit_call6_wrapper(BS->LoadImage, FALSE, SelfImageHandle, DevicePaths[DevicePathIndex],
                                                         NULL, 0, &ChildImageHandle);
+            if (secure_mode() && ShimLoaded()) {
+                // Load ourself into memory. This is a trick to work around a bug in Shim 0.8,
+                // which ties itself into the BS->LoadImage() and BS->StartImage() functions and
+                // then unregisters itself from the EFI system table when its replacement
+                // StartImage() function is called *IF* the previous LoadImage() was for the same
+                // program. The result is that rEFInd can validate only the first program it
+                // launches (often a filesystem driver). Loading a second program (rEFInd itself,
+                // here, to keep it smaller than a kernel) works around this problem. See the
+                // replacements.c file in Shim, and especially its start_image() function, for
+                // the source of the problem.
+                // NOTE: This doesn't check the return status or handle errors. It could
+                // conceivably do weird things if, say, rEFInd were on a USB drive that the
+                // user pulls before launching a program.
+                refit_call6_wrapper(BS->LoadImage, FALSE, SelfImageHandle, GlobalConfig.SelfDevicePath,
+                                    NULL, 0, &ChildImageHandle2);
+            }
         } else {
             Print(L"Invalid loader file!\n");
             ReturnStatus = EFI_LOAD_ERROR;