X-Git-Url: https://code.delx.au/refind/blobdiff_plain/346735a39ca8b64c8278ba342a633b5acce0159b..e8d54384d2b49983ba17471527db797159bfede4:/refind/main.c diff --git a/refind/main.c b/refind/main.c index 6112b24..b923650 100644 --- a/refind/main.c +++ b/refind/main.c @@ -37,10 +37,23 @@ * Modifications copyright (c) 2012-2015 Roderick W. Smith * * Modifications distributed under the terms of the GNU General Public - * License (GPL) version 3 (GPLv3), a copy of which must be distributed - * with this source code or binaries made from it. + * License (GPL) version 3 (GPLv3), or (at your option) any later version. * */ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #include "global.h" #include "config.h" @@ -51,6 +64,7 @@ #include "menu.h" #include "mok.h" #include "gpt.h" +#include "apple.h" #include "security_policy.h" #include "driver_support.h" #include "../include/Handle.h" @@ -137,17 +151,21 @@ static REFIT_MENU_ENTRY MenuEntryShutdown = { L"Shut Down Computer", TAG_SHUTDOW REFIT_MENU_ENTRY MenuEntryReturn = { L"Return to Main Menu", TAG_RETURN, 1, 0, 0, NULL, NULL, NULL }; static REFIT_MENU_ENTRY MenuEntryExit = { L"Exit rEFInd", TAG_EXIT, 1, 0, 0, NULL, NULL, NULL }; static REFIT_MENU_ENTRY MenuEntryFirmware = { L"Reboot to Computer Setup Utility", TAG_FIRMWARE, 1, 0, 0, NULL, NULL, NULL }; +static REFIT_MENU_ENTRY MenuEntryRotateCsr = { L"Change SIP Policy", TAG_CSR_ROTATE, 1, 0, 0, NULL, NULL, NULL }; REFIT_MENU_SCREEN MainMenu = { L"Main Menu", NULL, 0, NULL, 0, NULL, 0, L"Automatic boot", L"Use arrow keys to move cursor; Enter to boot;", L"Insert or F2 for more options; Esc to refresh" }; static REFIT_MENU_SCREEN AboutMenu = { L"About", NULL, 0, NULL, 0, NULL, 0, NULL, L"Press Enter to return to main menu", L"" }; -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, - { 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 } +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, NULL, CONFIG_FILE_NAME, NULL, NULL, 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 } }; EFI_GUID GlobalGuid = EFI_GLOBAL_VARIABLE; @@ -169,11 +187,12 @@ struct LOADER_LIST { static VOID AboutrEFInd(VOID) { - CHAR16 *FirmwareVendor; + CHAR16 *FirmwareVendor; + UINT32 CsrStatus; if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.9.0.3"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.9.2.8"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2015 Roderick W. Smith"); @@ -191,6 +210,10 @@ static VOID AboutrEFInd(VOID) #else AddMenuInfoLine(&AboutMenu, L" Platform: unknown"); #endif + if (GetCsrStatus(&CsrStatus) == EFI_SUCCESS) { + RecordgCsrStatus(CsrStatus, FALSE); + AddMenuInfoLine(&AboutMenu, gCsrStatus); + } FirmwareVendor = StrDuplicate(ST->FirmwareVendor); LimitStringLength(FirmwareVendor, MAX_LINE_LENGTH); // More than ~65 causes empty info page on 800x600 display AddMenuInfoLine(&AboutMenu, PoolPrint(L" Firmware: %s %d.%02d", FirmwareVendor, ST->FirmwareRevision >> 16, @@ -276,7 +299,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 +323,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 +348,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; @@ -1873,6 +1912,7 @@ static VOID ScanForTools(VOID) { UINTN i, j, VolumeIndex; UINT64 osind; CHAR8 *b = 0; + UINT32 CsrValue; MokLocations = StrDuplicate(MOK_LOCATIONS); if (MokLocations != NULL) @@ -2003,6 +2043,14 @@ static VOID ScanForTools(VOID) { FindTool(MokLocations, MOK_NAMES, L"MOK utility", BUILTIN_ICON_TOOL_MOK_TOOL); break; + case TAG_CSR_ROTATE: + if ((GetCsrStatus(&CsrValue) == EFI_SUCCESS) && (GlobalConfig.CsrValues)) { + TempMenuEntry = CopyMenuEntry(&MenuEntryRotateCsr); + TempMenuEntry->Image = BuiltinIcon(BUILTIN_ICON_FUNC_CSR_ROTATE); + AddMenuEntry(&MainMenu, TempMenuEntry); + } // if + break; + case TAG_MEMTEST: FindTool(MEMTEST_LOCATIONS, MEMTEST_NAMES, L"Memory test utility", BUILTIN_ICON_TOOL_MEMTEST); break; @@ -2058,6 +2106,7 @@ static BOOLEAN SecureBootSetup(VOID) { Success = TRUE; } else { Print(L"Failed to install MOK Secure Boot extensions"); + PauseForKey(); } } return Success; @@ -2087,20 +2136,19 @@ static BOOLEAN SecureBootUninstall(VOID) { // If an error is encountered, leaves the value alone (it should be set to // CONFIG_FILE_NAME when GlobalConfig is initialized). static VOID SetConfigFilename(EFI_HANDLE ImageHandle) { -EFI_LOADED_IMAGE *Info; -CHAR16 *Options, *FileName; -EFI_STATUS Status; -INTN Where; + EFI_LOADED_IMAGE *Info; + CHAR16 *Options, *FileName, *SubString; + EFI_STATUS Status; -Status = refit_call3_wrapper(BS->HandleProtocol, ImageHandle, &LoadedImageProtocol, (VOID **) &Info); + Status = refit_call3_wrapper(BS->HandleProtocol, ImageHandle, &LoadedImageProtocol, (VOID **) &Info); if ((Status == EFI_SUCCESS) && (Info->LoadOptionsSize > 0)) { Options = (CHAR16 *) Info->LoadOptions; - Where = FindSubString(L" -c ", Options); - if (Where >= 0) { - FileName = StrDuplicate(&Options[Where + 4]); - Where = FindSubString(L" ", FileName); - if (Where > 0) - FileName[Where] = L'\0'; + SubString = MyStrStr(Options, L" -c "); + if (SubString) { + FileName = StrDuplicate(&SubString[4]); + if (FileName) { + LimitStringLength(FileName, 256); + } if (FileExists(SelfDir, FileName)) { GlobalConfig.ConfigFilename = FileName; @@ -2141,6 +2189,9 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) SetConfigFilename(ImageHandle); ReadConfig(GlobalConfig.ConfigFilename); + if (GlobalConfig.SpoofOSXVersion && GlobalConfig.SpoofOSXVersion[0] != L'\0') + SetAppleOSInfo(); + InitScreen(); WarnIfLegacyProblems(); MainMenu.TimeoutSeconds = GlobalConfig.Timeout; @@ -2228,6 +2279,10 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) RebootIntoFirmware(); break; + case TAG_CSR_ROTATE: + RotateCsrValue(); + break; + } // switch() } // while()