[go: up one dir, main page]

Menu

[9e1265]: / refind / apple.c  Maximize  Restore  History

Download this file

185 lines (167 with data), 7.4 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
* refind/apple.c
* Functions specific to Apple computers
*
* Copyright (c) 2015 Roderick W. Smith
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "global.h"
#include "config.h"
#include "lib.h"
#include "screen.h"
#include "apple.h"
#include "log.h"
#include "mystrings.h"
#include "../include/refit_call_wrapper.h"
CHAR16 gCsrStatus[512];
// Get CSR (Apple's Configurable Security Restrictions; aka System Integrity
// Protection [SIP], or "rootless") status information. If the variable is not
// present and the firmware is Apple, fake it and claim it's enabled, since
// that's how OS X 10.11 treats a system with the variable absent.
EFI_STATUS GetCsrStatus(UINT32 *CsrStatus) {
UINT32 *ReturnValue = NULL;
UINTN CsrLength;
EFI_GUID CsrGuid = CSR_GUID;
EFI_STATUS Status = EFI_INVALID_PARAMETER;
if (CsrStatus) {
Status = EfivarGetRaw(&CsrGuid, L"csr-active-config", (CHAR8**) &ReturnValue, &CsrLength);
if (Status == EFI_SUCCESS) {
if (CsrLength == 4) {
*CsrStatus = *ReturnValue;
} else {
Status = EFI_BAD_BUFFER_SIZE;
SPrint(gCsrStatus, 255, L" Unknown System Integrity Protection version");
}
MyFreePool(ReturnValue);
} else if ((Status == EFI_NOT_FOUND) && (StriSubCmp(L"Apple", ST->FirmwareVendor))) {
*CsrStatus = SIP_ENABLED;
Status = EFI_SUCCESS;
} // if (Status == EFI_SUCCESS)
} // if (CsrStatus)
return Status;
} // INTN GetCsrStatus()
// Store string describing CSR status value in gCsrStatus variable, which appears
// on the Info page. If DisplayMessage is TRUE, displays the new value of
// gCsrStatus on the screen for three seconds.
VOID RecordgCsrStatus(UINT32 CsrStatus, BOOLEAN DisplayMessage) {
EG_PIXEL BGColor = COLOR_LIGHTBLUE;
switch (CsrStatus) {
case SIP_ENABLED:
SPrint(gCsrStatus, 255, L" System Integrity Protection is enabled (0x%02x)", CsrStatus);
break;
case SIP_DISABLED_10:
SPrint(gCsrStatus, 255, L" System Integrity Protection is disabled for OS X 10.x (0x%02x)",
CsrStatus);
break;
case SIP_DISABLED_11:
SPrint(gCsrStatus, 255, L" System Integrity Protection is disabled (0x%02x)", CsrStatus);
break;
default:
SPrint(gCsrStatus, 255, L" System Integrity Protection status: 0x%02x", CsrStatus);
} // switch
if (DisplayMessage) {
egDisplayMessage(gCsrStatus, &BGColor, CENTER);
PauseSeconds(3);
} // if
} // VOID RecordgCsrStatus()
// Find the current CSR status and reset it to the next one in the
// GlobalConfig.CsrValues list, or to the first value if the current
// value is not on the list.
VOID RotateCsrValue(VOID) {
UINT32 CurrentValue, TargetCsr;
UINT32_LIST *ListItem;
EFI_GUID CsrGuid = CSR_GUID;
EFI_STATUS Status;
LOG(1, LOG_LINE_SEPARATOR, L"Rotating CSR value");
Status = GetCsrStatus(&CurrentValue);
if ((Status == EFI_SUCCESS) && GlobalConfig.CsrValues) {
ListItem = GlobalConfig.CsrValues;
while ((ListItem != NULL) && (ListItem->Value != CurrentValue))
ListItem = ListItem->Next;
if (ListItem == NULL || ListItem->Next == NULL) {
TargetCsr = GlobalConfig.CsrValues->Value;
} else {
TargetCsr = ListItem->Next->Value;
}
LOG(1, LOG_LINE_NORMAL, L"CSR value was 0x%04x; setting to 0x%04x", CurrentValue, TargetCsr);
Status = EfivarSetRaw(&CsrGuid, L"csr-active-config", (CHAR8 *) &TargetCsr, 4, TRUE);
if (Status == EFI_SUCCESS) {
RecordgCsrStatus(TargetCsr, TRUE);
LOG(2, LOG_LINE_NORMAL, L"Successful setting of CSR value of 0x%04x", TargetCsr);
} else {
SPrint(gCsrStatus, 255, L" Error setting System Integrity Protection code.");
LOG(1, LOG_LINE_NORMAL, gCsrStatus);
}
} else {
LOG(1, LOG_LINE_NORMAL, L"Could not retrieve CSR value or csr_values not set");
} // if/else
} // VOID RotateCsrValue()
/*
* The below definitions and SetAppleOSInfo() function are based on a GRUB patch
* by Andreas Heider:
* https://lists.gnu.org/archive/html/grub-devel/2013-12/msg00442.html
*/
#define EFI_APPLE_SET_OS_PROTOCOL_GUID \
{ 0xc5c5da95, 0x7d5c, 0x45e6, \
{ 0xb2, 0xf1, 0x3f, 0xd5, 0x2b, 0xb1, 0x00, 0x77 } \
}
typedef struct EfiAppleSetOsInterface {
UINT64 Version;
EFI_STATUS EFIAPI (*SetOsVersion) (IN CHAR8 *Version);
EFI_STATUS EFIAPI (*SetOsVendor) (IN CHAR8 *Vendor);
} EfiAppleSetOsInterface;
// Function to tell the firmware that OS X is being launched. This is
// required to work around problems on some Macs that don't fully
// initialize some hardware (especially video displays) when third-party
// OSes are launched in EFI mode.
EFI_STATUS SetAppleOSInfo() {
CHAR16 *AppleOSVersion = NULL;
CHAR8 *AppleOSVersion8 = NULL;
EFI_STATUS Status;
EFI_GUID apple_set_os_guid = EFI_APPLE_SET_OS_PROTOCOL_GUID;
EfiAppleSetOsInterface *SetOs = NULL;
LOG(1, LOG_LINE_NORMAL, L"Setting Apple OS information, if applicable");
Status = refit_call3_wrapper(BS->LocateProtocol, &apple_set_os_guid, NULL, (VOID**) &SetOs);
// If not a Mac, ignore the call....
if ((Status != EFI_SUCCESS) || (!SetOs)) {
LOG(2, LOG_LINE_NORMAL, L"Not a Mac; not setting Apple OS information");
return EFI_SUCCESS;
}
if ((SetOs->Version != 0) && GlobalConfig.SpoofOSXVersion) {
AppleOSVersion = StrDuplicate(L"Mac OS X");
MergeStrings(&AppleOSVersion, GlobalConfig.SpoofOSXVersion, ' ');
if (AppleOSVersion) {
LOG(2, LOG_LINE_NORMAL, L"Setting Apple OS information to '%s'", AppleOSVersion);
AppleOSVersion8 = AllocateZeroPool((StrLen(AppleOSVersion) + 1) * sizeof(CHAR8));
UnicodeStrToAsciiStr(AppleOSVersion, AppleOSVersion8);
if (AppleOSVersion8) {
Status = refit_call1_wrapper (SetOs->SetOsVersion, AppleOSVersion8);
if (!EFI_ERROR(Status))
Status = EFI_SUCCESS;
MyFreePool(AppleOSVersion8);
} else {
Status = EFI_OUT_OF_RESOURCES;
Print(L"Out of resources in SetAppleOSInfo!\n");
}
if ((Status == EFI_SUCCESS) && (SetOs->Version >= 2))
Status = refit_call1_wrapper (SetOs->SetOsVendor, (CHAR8 *) "Apple Inc.");
MyFreePool(AppleOSVersion);
} // if (AppleOSVersion)
} // if
if (Status != EFI_SUCCESS)
Print(L"Unable to set firmware boot type!\n");
return (Status);
} // EFI_STATUS SetAppleOSInfo()