Browse Source

[core] fix a crash due to overzealous MSVC optimizations

* Visual 2022 version 17.14.2 changes the way it performs optimizations with /O2
  which results in innocuous C statements, such as invoking strtoul() twice on
  the same line, and using the pointer returned by the first call in the second,
  crashing the application with a read access violation (when built as RELEASE).
* To alleviate that, we break down the Syslinux strtoul() invocation, as well as
  harden our Syslinux version processing while we're at it.
* Hopefully this is the only line of code where the new mode of MSVC optimisation
  creates a problem with...
* Closes #2740.
pull/2746/head
Pete Batard 2 months ago
parent
commit
207a330979
No known key found for this signature in database GPG Key ID: 38E0CF5E69EDD671
  1. 10
      src/rufus.rc
  2. 14
      src/syslinux.c

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.8.2248"
CAPTION "Rufus 4.8.2249"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@ -407,8 +407,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,8,2248,0
PRODUCTVERSION 4,8,2248,0
FILEVERSION 4,8,2249,0
PRODUCTVERSION 4,8,2249,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -426,13 +426,13 @@ BEGIN
VALUE "Comments", "https://rufus.ie"
VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "4.8.2248"
VALUE "FileVersion", "4.8.2249"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2025 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
VALUE "OriginalFilename", "rufus-4.8.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "4.8.2248"
VALUE "ProductVersion", "4.8.2249"
END
END
BLOCK "VarFileInfo"

14
src/syslinux.c

@ -400,8 +400,9 @@ out:
uint16_t GetSyslinuxVersion(char* buf, size_t buf_size, char** ext)
{
size_t i, j, k;
char *p;
uint16_t version;
char *p = NULL;
unsigned long version_ul[2];
uint16_t version = 0;
const char LINUX[] = { 'L', 'I', 'N', 'U', 'X', ' ' };
static char* nullstr = "";
char unauthorized[] = {'<', '>', ':', '|', '*', '?', '\\', '/'};
@ -418,10 +419,17 @@ uint16_t GetSyslinuxVersion(char* buf, size_t buf_size, char** ext)
|| ((buf[i - 3] == 'S') && (buf[i - 2] == 'Y') && (buf[i - 1] == 'S')) ))
continue;
i += sizeof(LINUX);
version = (((uint8_t)strtoul(&buf[i], &p, 10)) << 8) + (uint8_t)strtoul(&p[1], &p, 10);
version_ul[0] = strtoul(&buf[i], &p, 10);
// Our buffer is either from our internal legit syslinux (i.e. with a NUL terminated
// version string) or from a buffer that has been NUL-terminated through read_file(),
// so the string we work with in p is always NUL terminated at this stage.
assert(version_ul[0] < 256);
if (version_ul[0] < 256) {
version_ul[1] = strtoul(&p[1], &p, 10);
assert(version_ul[1] < 256);
if (version_ul[1] < 256)
version = (uint16_t)((version_ul[0] << 8) + version_ul[1]);
}
if (version == 0)
continue;
// Ensure that our extra version string starts with a slash

Loading…
Cancel
Save