mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[iso] attempt to fix the clusterfuck of GRUB 2.06 incompatible versions
* As was *ENTIRELY PREDICTIBLE*, the lack of timely releases from the GRUB project has resulted in distro maintainers (Ubuntu, Fedora, etc.) taking matters in their own hand and applying patches on top of their 2.06 version. However, these patches result in 2.06 bootloaders that are incompatible with 2.06 modules that don't have the same patches applied. Especially this now results in the infamous "452: out of range pointer" error message when using patched modules with unpatched bootloader or unpatched modules with patched bootloaders. * Making this issue worse, we also have distro maintainers who won't add a suffix to their GRUB version, AS ONE SHOULD DO WHEN ONE APPLIES TONS OF PATCHES ON TOP OF A PROJECT'S SOURCE, and MISreport their non 2.06 GRUB as "2.06", and, because we can't detect what patches are needed from modules themselves (unlike what is the case for grub_debug_is_enabled), we have no way of telling incompatible GRUB 2.06 binaries from one another. * As a result, we have no choice but to append a sanitized version of the ISO label to the GRUB version, as a means to differentiate between incompatible versions, and tweak our existing bootloader download mechanism to *ATTEMPT* to download a compatible 'core.img' from our server... where we will have to waste a lot of time adding new binaries and symlinks to try to make all these GRUB "2.06" based images work, and will probably miss quite few with the end results that users who are just trying to install Linux will be left stranded. * Again, I have to point out how the end result of regular users wanting to try Linux and being unable to do so is the *DIRECT* result of the GRUB project maintainers having sat on a 2-year influx of CONTINUOUS patches, and thinking that "Release Early, Release Often" is only a gimmick, and not something that should apply to their project, even as they have been warned before, by yours truly, that *NOT* releasing on a timely basis is causing actual grievances... That's because, had the GRUB maintainers released on a timely basis (at least once a year) Fedora and Ubuntu would be using vanilla GRUB 2.07 with the memory patches, and we wouldn't be trying to mix that with old GRUB 2.06 binaries. * For more on this, see #2233, noting that we will need to apply a compatibility breaking change during the 4.1 release, to revert the patches we applied to the default 2.06 'core.img' in pbatard/rufus-web@320b800592.
This commit is contained in:
parent
23d89d9764
commit
3a0f7d3813
5 changed files with 131 additions and 44 deletions
48
src/iso.c
48
src/iso.c
|
@ -887,7 +887,6 @@ void GetGrubVersion(char* buf, size_t buf_size)
|
|||
const char* grub_version_str[] = { "GRUB version %s", "GRUB version %s" };
|
||||
const char* grub_debug_is_enabled_str = "grub_debug_is_enabled";
|
||||
const size_t max_string_size = 32; // The strings above *MUST* be no longer than this value
|
||||
char *p, unauthorized[] = {'<', '>', ':', '|', '*', '?', '\\', '/'};
|
||||
size_t i, j;
|
||||
BOOL has_grub_debug_is_enabled = FALSE;
|
||||
|
||||
|
@ -902,13 +901,9 @@ void GetGrubVersion(char* buf, size_t buf_size)
|
|||
has_grub_debug_is_enabled = TRUE;
|
||||
}
|
||||
}
|
||||
// Sanitize the string
|
||||
for (p = &img_report.grub2_version[0]; *p; p++) {
|
||||
for (i = 0; i < sizeof(unauthorized); i++) {
|
||||
if (*p == unauthorized[i])
|
||||
*p = '_';
|
||||
}
|
||||
}
|
||||
|
||||
uprintf(" Reported Grub version: %s", img_report.grub2_version);
|
||||
|
||||
// <Shakes fist angrily> "KASPERSKYYYYYY!!!..." (https://github.com/pbatard/rufus/issues/467)
|
||||
// But seriously, these guys should know better than "security" through obscurity...
|
||||
if (img_report.grub2_version[0] == '0')
|
||||
|
@ -931,16 +926,33 @@ void GetGrubVersion(char* buf, size_t buf_size)
|
|||
// if [ -e /boot/grub2/i386-pc/normal.mod ]; then set prefix = ...
|
||||
// you still must embed 'configfile.mod' and 'normal.mod' in 'core.img' in order
|
||||
// to do that, which ends up tripling the file size...
|
||||
// Also, as mentioned above, Fedora have started applying *BREAKING* patches
|
||||
// willy-nilly, without bothering to alter the GRUB version string.
|
||||
// Soooo, since the universe is conspiring against us and since we already have
|
||||
// a facility for it, we'll use it to dowload the relevant 'core.img' by
|
||||
// appending a missing version suffix as needed...
|
||||
// Also, as mentioned above, Fedora, Ubuntu and others have started applying
|
||||
// *BREAKING* patches willy-nilly, without bothering to alter the GRUB version
|
||||
// string. And it gets worse with 2.06 since there are patches we can't detect
|
||||
// that will produce "452: out of range pointer" whether they are applied OR NOT
|
||||
// (meaning that if you use a patched GRUB 2.06 with unpatched GRUB 2.06 modules
|
||||
// you will get the error, and if you use unpatched with patched modules, you
|
||||
// will also get the error).
|
||||
// Soooo, since the universe, and project maintainers who do not REALISE that
|
||||
// NOT RELEASING IN A TIMELY MANNER *DOES* HAVE VERY NEGATIVE CONSEQUENCES FOR
|
||||
// END USERS, are conspiring against us, and since we already have a facility
|
||||
// for it, we'll use it to dowload the relevant 'core.img' by appending a missing
|
||||
// version suffix as needed. Especially, if GRUB only identifies itself as '2.06'
|
||||
// we'll append a sanitized version of the ISO label to try to differentiate
|
||||
// between GRUB 2.06 incompatible versions...
|
||||
if (img_report.grub2_version[0] != 0) {
|
||||
if (has_grub_debug_is_enabled)
|
||||
strcat(img_report.grub2_version, "-fedora");
|
||||
// Make sure we append '-nonstandard' and '-gdie' before the sanitized label.
|
||||
BOOL append_label = (safe_strcmp(img_report.grub2_version, "2.06") == 0);
|
||||
// Must be in the same order as we have on the server
|
||||
if (img_report.has_grub2 > 1)
|
||||
strcat(img_report.grub2_version, "-nonstandard");
|
||||
safe_strcat(img_report.grub2_version, sizeof(img_report.grub2_version), "-nonstandard");
|
||||
if (has_grub_debug_is_enabled)
|
||||
safe_strcat(img_report.grub2_version, sizeof(img_report.grub2_version), "-gdie");
|
||||
if (append_label) {
|
||||
safe_strcat(img_report.grub2_version, sizeof(img_report.grub2_version), "-");
|
||||
safe_strcat(img_report.grub2_version, sizeof(img_report.grub2_version), img_report.label);
|
||||
}
|
||||
sanitize_label(img_report.grub2_version);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1188,9 +1200,7 @@ out:
|
|||
free(buf);
|
||||
DeleteFileU(path);
|
||||
}
|
||||
if (img_report.grub2_version[0] != 0) {
|
||||
uprintf(" Detected Grub version: %s", img_report.grub2_version);
|
||||
} else {
|
||||
if (img_report.grub2_version[0] == 0) {
|
||||
uprintf(" Could not detect Grub version");
|
||||
img_report.has_grub2 = 0;
|
||||
}
|
||||
|
|
64
src/parser.c
64
src/parser.c
|
@ -1480,3 +1480,67 @@ void* get_data_from_asn1(const uint8_t* buf, size_t buf_len, const char* oid_str
|
|||
free(oid);
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanitize an ISO volume label or GRUB version, so that we can use it for bootloader lookup.
|
||||
* Note that this call modifies the string passed as parameter.
|
||||
*/
|
||||
int sanitize_label(char* label)
|
||||
{
|
||||
// Notice: Do not add "-beta" to this list as we have existing GRUB lookups for
|
||||
// "grub-2.02-beta2" and stuff...
|
||||
static const char* remove[] = { "-i386", "-i686", "-amd64", "-x86-64", ".x86-64",
|
||||
"-x64", "-armhf", "-arm64", "-aarch64", "-32-bit", "-64-bit", "-32bit", "-64bit",
|
||||
"-intel", "-cd", "-dvd", "-standard", "-live", "-install", "-server", "-net",
|
||||
"-desktop", "-lts", "-studio", "-baseos", "-kde", "-xfce", "-lxde", "-gnome",
|
||||
"-mate", "-unstable", "-debug", "-release", "-final", "-stream", "-cinnamon",
|
||||
"-cinn", "-leap", "-tumbleweed", "-budgie", "-ws", "-iot", "-ostree", ".iso"
|
||||
};
|
||||
size_t i, len;
|
||||
char *s;
|
||||
|
||||
len = strlen(label);
|
||||
for (i = 0; i < len; i++) {
|
||||
char c = label[i];
|
||||
// Convert to lowercase
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
c += 0x20;
|
||||
// Convert non alphanum (except '.') to dash
|
||||
if ((c < '0' && c != '.') || (c > '9' && c < 'a') || (c > 'z'))
|
||||
c = '-';
|
||||
label[i] = c;
|
||||
}
|
||||
|
||||
// Remove all leading '-'
|
||||
for (i = 0; i < len && label[i] == '-'; i++);
|
||||
if (i != 0)
|
||||
memcpy(label, &label[i], len - i);
|
||||
len = strlen(label);
|
||||
if (len <= 1)
|
||||
return -1;
|
||||
|
||||
// Remove all trailing '-'
|
||||
for (i = len - 1; i > 0 && label[i] == '-'; i--)
|
||||
label[i] = 0;
|
||||
len = strlen(label);
|
||||
if (len <= 1)
|
||||
return -1;
|
||||
|
||||
// Remove all duplicate '-' (non-optimized!)
|
||||
for (i = 0; len >= 2 && i < len - 2; i++) {
|
||||
if (label[i] == '-' && label[i + 1] == '-') {
|
||||
memcpy(&label[i + 1], &label[i + 2], len - i - 1);
|
||||
len--;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove specific substrings
|
||||
for (i = 0; i < ARRAYSIZE(remove); i++) {
|
||||
s = strstr(label, remove[i]);
|
||||
if (s != NULL)
|
||||
strcpy(s, &s[strlen(remove[i])]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
50
src/rufus.c
50
src/rufus.c
|
@ -1118,7 +1118,7 @@ static void DisplayISOProps(void)
|
|||
PRINT_ISO_PROP(HAS_KOLIBRIOS(img_report), " Uses: KolibriOS");
|
||||
PRINT_ISO_PROP(HAS_REACTOS(img_report), " Uses: ReactOS");
|
||||
PRINT_ISO_PROP(img_report.has_grub4dos, " Uses: Grub4DOS");
|
||||
PRINT_ISO_PROP(img_report.has_grub2, " Uses: GRUB2");
|
||||
PRINT_ISO_PROP(img_report.has_grub2, " Uses: GRUB2 (%s)", img_report.grub2_version);
|
||||
if (img_report.has_efi == 0x80)
|
||||
uprintf(" Uses: EFI (through '%s')", img_report.efi_img_path);
|
||||
else
|
||||
|
@ -1430,7 +1430,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
|
|||
const char* ldlinux = "ldlinux";
|
||||
const char* syslinux = "syslinux";
|
||||
const char* ldlinux_ext[3] = { "sys", "bss", "c32" };
|
||||
char tmp[MAX_PATH], tmp2[MAX_PATH];
|
||||
char tmp[MAX_PATH], tmp2[MAX_PATH], c;
|
||||
|
||||
syslinux_ldlinux_len[0] = 0; syslinux_ldlinux_len[1] = 0;
|
||||
safe_free(grub2_buf);
|
||||
|
@ -1658,23 +1658,17 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
|
|||
static_sprintf(tmp, "%s-%s", grub, img_report.grub2_version);
|
||||
IGNORE_RETVAL(_mkdir(tmp));
|
||||
IGNORE_RETVAL(_chdir(tmp));
|
||||
static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, grub, img_report.grub2_version, core_img);
|
||||
grub2_len = (long)DownloadSignedFile(tmp, core_img, hMainDialog, FALSE);
|
||||
if ((grub2_len == 0) && (DownloadStatus == 404)) {
|
||||
// Manjaro (always them!) are using "2.03.5" as identifier, so we must detect first dot...
|
||||
BOOL first_dot = TRUE;
|
||||
// Couldn't locate the file on the server => try to download without the version extra
|
||||
uprintf("Extended version was not found, trying main version...");
|
||||
static_strcpy(tmp2, img_report.grub2_version);
|
||||
// Isolate the #.### part
|
||||
for (i = 0; ((tmp2[i] >= '0') && (tmp2[i] <= '9')) || ((tmp2[i] == '.') && first_dot); i++) {
|
||||
if (tmp2[i] == '.')
|
||||
first_dot = FALSE;
|
||||
}
|
||||
tmp2[i] = 0;
|
||||
static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, grub, tmp2, core_img);
|
||||
grub2_len = (long)DownloadSignedFile(tmp, core_img, hMainDialog, FALSE);
|
||||
// The following loops through the grub2 version (which may have the ISO label appended)
|
||||
// and breaks it according to '.' or '-' until it finds a match on the server.
|
||||
//
|
||||
for (i = (int)strlen(img_report.grub2_version), grub2_len = 0; i > 0 && grub2_len <= 0; i--) {
|
||||
c = img_report.grub2_version[i];
|
||||
if (c != 0 && c != '.' && c != '-')
|
||||
continue;
|
||||
img_report.grub2_version[i] = 0;
|
||||
static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, grub, img_report.grub2_version, core_img);
|
||||
grub2_len = (long)DownloadSignedFile(tmp, core_img, hMainDialog, FALSE);
|
||||
img_report.grub2_version[i] = c;
|
||||
}
|
||||
if (grub2_len <= 0) {
|
||||
PrintInfo(0, MSG_195, "Grub2");
|
||||
|
@ -3829,7 +3823,25 @@ extern int TestChecksum(void);
|
|||
// Ctrl-T => Alternate Test mode that doesn't require a full rebuild
|
||||
if ((ctrl_without_focus || ((GetKeyState(VK_CONTROL) & 0x8000) && (msg.message == WM_KEYDOWN)))
|
||||
&& (msg.wParam == 'T')) {
|
||||
TestChecksum();
|
||||
char tmp[256], c;
|
||||
char label[256] = "2.06-blah-bli-ubutnu.23.2.1-blo";
|
||||
size_t i;
|
||||
for (i = strlen(label); i > 0; i--) {
|
||||
c = label[i];
|
||||
if (c != 0 && c != '.' && c != '-')
|
||||
continue;
|
||||
label[i] = 0;
|
||||
static_sprintf(tmp, "%s/%s-%s/core.img", FILES_URL, "grub", label);
|
||||
uprintf(tmp);
|
||||
label[i] = c;
|
||||
}
|
||||
// TestChecksum();
|
||||
//FILE* fd = fopen("D:\\ISOs\\vol.txt", "r");
|
||||
//while (fgets(label, 256, fd) != NULL) {
|
||||
// sanitize_label(label);
|
||||
// uprintf(label);
|
||||
//}
|
||||
//fclose(fd);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -403,7 +403,7 @@ typedef struct {
|
|||
uint16_t sl_version; // Syslinux/Isolinux version
|
||||
char sl_version_str[12];
|
||||
char sl_version_ext[32];
|
||||
char grub2_version[64];
|
||||
char grub2_version[192];
|
||||
} RUFUS_IMG_REPORT;
|
||||
|
||||
/* Isolate the Syslinux version numbers */
|
||||
|
@ -676,6 +676,7 @@ extern char* replace_in_token_data(const char* filename, const char* token, cons
|
|||
extern char* replace_char(const char* src, const char c, const char* rep);
|
||||
extern void parse_update(char* buf, size_t len);
|
||||
extern void* get_data_from_asn1(const uint8_t* buf, size_t buf_len, const char* oid_str, uint8_t asn1_type, size_t* data_len);
|
||||
extern int sanitize_label(char* label);
|
||||
extern int IsHDD(DWORD DriveIndex, uint16_t vid, uint16_t pid, const char* strid);
|
||||
extern char* GetSignatureName(const char* path, const char* country_code, BOOL bSilent);
|
||||
extern uint64_t GetSignatureTimeStamp(const char* path);
|
||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
|||
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_ACCEPTFILES
|
||||
CAPTION "Rufus 4.0.2038"
|
||||
CAPTION "Rufus 4.0.2039"
|
||||
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
||||
|
@ -392,8 +392,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,0,2038,0
|
||||
PRODUCTVERSION 4,0,2038,0
|
||||
FILEVERSION 4,0,2039,0
|
||||
PRODUCTVERSION 4,0,2039,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -411,13 +411,13 @@ BEGIN
|
|||
VALUE "Comments", "https://rufus.ie"
|
||||
VALUE "CompanyName", "Akeo Consulting"
|
||||
VALUE "FileDescription", "Rufus"
|
||||
VALUE "FileVersion", "4.0.2038"
|
||||
VALUE "FileVersion", "4.0.2039"
|
||||
VALUE "InternalName", "Rufus"
|
||||
VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)"
|
||||
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||
VALUE "OriginalFilename", "rufus-4.0.exe"
|
||||
VALUE "ProductName", "Rufus"
|
||||
VALUE "ProductVersion", "4.0.2038"
|
||||
VALUE "ProductVersion", "4.0.2039"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
Loading…
Reference in a new issue