mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[misc] harden usage of uprintf()
* Passing a non-formatting buffer as first parameter of uprintf() can lead to an exception if this buffer happens to contain a '%' character, so usage of uprintf() with string buffers that may contain '%' should be sanitized. * Also drop the _uprintf/_uprintfs aliases as they are no longer required.
This commit is contained in:
parent
1a3a155e8c
commit
fffd4d1160
12 changed files with 37 additions and 31 deletions
|
@ -29,9 +29,9 @@ struct error_table {
|
||||||
struct et_list;
|
struct et_list;
|
||||||
|
|
||||||
/* For use with Rufus */
|
/* For use with Rufus */
|
||||||
extern void _uprintf(const char *format, ...);
|
extern void uprintf(const char *format, ...);
|
||||||
#define VA_ARGS(...) , ##__VA_ARGS__
|
#define VA_ARGS(...) , ##__VA_ARGS__
|
||||||
#define com_err(src, err, fmt, ...) _uprintf("%s: [%08X] " # fmt, src?src:"ext2fs", err - EXT2_ET_BASE VA_ARGS(__VA_ARGS__))
|
#define com_err(src, err, fmt, ...) uprintf("%s: [%08X] " # fmt, src?src:"ext2fs", err - EXT2_ET_BASE VA_ARGS(__VA_ARGS__))
|
||||||
|
|
||||||
extern char const *error_message (long);
|
extern char const *error_message (long);
|
||||||
extern void (*com_err_hook) (const char *, long, const char *, va_list);
|
extern void (*com_err_hook) (const char *, long, const char *, va_list);
|
||||||
|
|
|
@ -1290,7 +1290,7 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, BOOL bZeroDrive)
|
||||||
}
|
}
|
||||||
assert((uintptr_t)sec_buf % SelectedDrive.SectorSize == 0);
|
assert((uintptr_t)sec_buf % SelectedDrive.SectorSize == 0);
|
||||||
sec_buf_pos = 0;
|
sec_buf_pos = 0;
|
||||||
bled_init(_uprintf, NULL, sector_write, update_progress, NULL, &FormatStatus);
|
bled_init(uprintf, NULL, sector_write, update_progress, NULL, &FormatStatus);
|
||||||
bled_ret = bled_uncompress_with_handles(hSourceImage, hPhysicalDrive, img_report.compression_type);
|
bled_ret = bled_uncompress_with_handles(hSourceImage, hPhysicalDrive, img_report.compression_type);
|
||||||
bled_exit();
|
bled_exit();
|
||||||
uprintfs("\r\n");
|
uprintfs("\r\n");
|
||||||
|
|
|
@ -513,7 +513,7 @@ void PrintStatusInfo(BOOL info, BOOL debug, unsigned int duration, int msg_id, .
|
||||||
va_start(args, msg_id);
|
va_start(args, msg_id);
|
||||||
safe_vsnprintf(msg_cur, MSG_LEN, format, args);
|
safe_vsnprintf(msg_cur, MSG_LEN, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
msg_cur[MSG_LEN-1] = '\0';
|
msg_cur[MSG_LEN - 1] = '\0';
|
||||||
|
|
||||||
if ((duration != 0) || (!bStatusTimerArmed))
|
if ((duration != 0) || (!bStatusTimerArmed))
|
||||||
OutputMessage(info, msg_cur);
|
OutputMessage(info, msg_cur);
|
||||||
|
@ -534,8 +534,9 @@ void PrintStatusInfo(BOOL info, BOOL debug, unsigned int duration, int msg_id, .
|
||||||
va_start(args, msg_id);
|
va_start(args, msg_id);
|
||||||
safe_vsnprintf(buf, MSG_LEN, format, args);
|
safe_vsnprintf(buf, MSG_LEN, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
buf[MSG_LEN-1] = '\0';
|
buf[MSG_LEN - 1] = '\0';
|
||||||
uprintf(buf);
|
// buf may(?) containt a '%' so don't feed it as a naked format string
|
||||||
|
uprintf("%s", buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -945,7 +945,7 @@ static DWORD WINAPI DownloadISOThread(LPVOID param)
|
||||||
free(sig);
|
free(sig);
|
||||||
uprintf("Download signature is valid ✓");
|
uprintf("Download signature is valid ✓");
|
||||||
uncompressed_size = *((uint64_t*)&compressed[5]);
|
uncompressed_size = *((uint64_t*)&compressed[5]);
|
||||||
if ((uncompressed_size < 1 * MB) && (bled_init(_uprintf, NULL, NULL, NULL, NULL, &FormatStatus) >= 0)) {
|
if ((uncompressed_size < 1 * MB) && (bled_init(uprintf, NULL, NULL, NULL, NULL, &FormatStatus) >= 0)) {
|
||||||
fido_script = malloc((size_t)uncompressed_size);
|
fido_script = malloc((size_t)uncompressed_size);
|
||||||
size = bled_uncompress_from_buffer_to_buffer(compressed, dwCompressedSize, fido_script, (size_t)uncompressed_size, BLED_COMPRESSION_LZMA);
|
size = bled_uncompress_from_buffer_to_buffer(compressed, dwCompressedSize, fido_script, (size_t)uncompressed_size, BLED_COMPRESSION_LZMA);
|
||||||
bled_exit();
|
bled_exit();
|
||||||
|
|
|
@ -493,7 +493,8 @@ static DWORD WINAPI SearchProcessThread(LPVOID param)
|
||||||
// If we're switching process and found a match, print it
|
// If we're switching process and found a match, print it
|
||||||
if (bFound) {
|
if (bFound) {
|
||||||
static_sprintf (tmp, "● [%06u] %s (%s)", (uint32_t)pid[cur_pid], cmdline, access_rights_str[access_rights & 0x7]);
|
static_sprintf (tmp, "● [%06u] %s (%s)", (uint32_t)pid[cur_pid], cmdline, access_rights_str[access_rights & 0x7]);
|
||||||
vuprintf(tmp);
|
// tmp may contain a '%' so don't feed it as a naked format string
|
||||||
|
vuprintf("%s", tmp);
|
||||||
StrArrayAdd(&BlockingProcess, tmp, TRUE);
|
StrArrayAdd(&BlockingProcess, tmp, TRUE);
|
||||||
bFound = FALSE;
|
bFound = FALSE;
|
||||||
access_rights = 0;
|
access_rights = 0;
|
||||||
|
|
|
@ -2255,7 +2255,8 @@ DWORD CheckDriveAccess(DWORD dwTimeOut, BOOL bPrompt)
|
||||||
proceed = FALSE;
|
proceed = FALSE;
|
||||||
uprintf("Found potentially blocking process(es) against %s:", &PhysicalPath[4]);
|
uprintf("Found potentially blocking process(es) against %s:", &PhysicalPath[4]);
|
||||||
for (j = 0; j < BlockingProcess.Index; j++)
|
for (j = 0; j < BlockingProcess.Index; j++)
|
||||||
uprintf(BlockingProcess.String[j]);
|
// BlockingProcess.String[j] may contain a '%' so don't feed it as a naked format string
|
||||||
|
uprintf("%s", BlockingProcess.String[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2275,7 +2276,8 @@ DWORD CheckDriveAccess(DWORD dwTimeOut, BOOL bPrompt)
|
||||||
proceed = FALSE;
|
proceed = FALSE;
|
||||||
uprintf("Found potentially blocking process(es) against %s", drive_name);
|
uprintf("Found potentially blocking process(es) against %s", drive_name);
|
||||||
for (j = 0; j < BlockingProcess.Index; j++)
|
for (j = 0; j < BlockingProcess.Index; j++)
|
||||||
uprintf(BlockingProcess.String[j]);
|
// BlockingProcess.String[j] may contain a '%' so don't feed it as a naked format string
|
||||||
|
uprintf("%s", BlockingProcess.String[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3547,7 +3549,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||||
if (list_params) {
|
if (list_params) {
|
||||||
uprintf("Command line arguments:");
|
uprintf("Command line arguments:");
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
uprintf(argv[i]);
|
// argv[i] may contain a '%' so don't feed it as a naked format string.
|
||||||
|
uprintf("%s", argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
16
src/rufus.h
16
src/rufus.h
|
@ -172,20 +172,18 @@ static __inline void static_repchr(char* p, char s, char r) {
|
||||||
#define to_unix_path(str) static_repchr(str, '\\', '/')
|
#define to_unix_path(str) static_repchr(str, '\\', '/')
|
||||||
#define to_windows_path(str) static_repchr(str, '/', '\\')
|
#define to_windows_path(str) static_repchr(str, '/', '\\')
|
||||||
|
|
||||||
extern void _uprintf(const char *format, ...);
|
extern void uprintf(const char *format, ...);
|
||||||
extern void _uprintfs(const char *str);
|
extern void uprintfs(const char *str);
|
||||||
#define uprintf(...) _uprintf(__VA_ARGS__)
|
#define vuprintf(...) do { if (verbose) uprintf(__VA_ARGS__); } while(0)
|
||||||
#define uprintfs(s) _uprintfs(s)
|
#define vvuprintf(...) do { if (verbose > 1) uprintf(__VA_ARGS__); } while(0)
|
||||||
#define vuprintf(...) do { if (verbose) _uprintf(__VA_ARGS__); } while(0)
|
#define suprintf(...) do { if (!bSilent) uprintf(__VA_ARGS__); } while(0)
|
||||||
#define vvuprintf(...) do { if (verbose > 1) _uprintf(__VA_ARGS__); } while(0)
|
#define uuprintf(...) do { if (usb_debug) uprintf(__VA_ARGS__); } while(0)
|
||||||
#define suprintf(...) do { if (!bSilent) _uprintf(__VA_ARGS__); } while(0)
|
|
||||||
#define uuprintf(...) do { if (usb_debug) _uprintf(__VA_ARGS__); } while(0)
|
|
||||||
#define ubprintf(...) do { safe_sprintf(&ubuffer[ubuffer_pos], UBUFFER_SIZE - ubuffer_pos - 4, __VA_ARGS__); \
|
#define ubprintf(...) do { safe_sprintf(&ubuffer[ubuffer_pos], UBUFFER_SIZE - ubuffer_pos - 4, __VA_ARGS__); \
|
||||||
ubuffer_pos = strlen(ubuffer); ubuffer[ubuffer_pos++] = '\r'; ubuffer[ubuffer_pos++] = '\n'; \
|
ubuffer_pos = strlen(ubuffer); ubuffer[ubuffer_pos++] = '\r'; ubuffer[ubuffer_pos++] = '\n'; \
|
||||||
ubuffer[ubuffer_pos] = 0; } while(0)
|
ubuffer[ubuffer_pos] = 0; } while(0)
|
||||||
#define ubflush() do { if (ubuffer_pos) uprintf("%s", ubuffer); ubuffer_pos = 0; } while(0)
|
#define ubflush() do { if (ubuffer_pos) uprintf("%s", ubuffer); ubuffer_pos = 0; } while(0)
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#define duprintf(...) _uprintf(__VA_ARGS__)
|
#define duprintf uprintf
|
||||||
#else
|
#else
|
||||||
#define duprintf(...)
|
#define duprintf(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_ACCEPTFILES
|
EXSTYLE WS_EX_ACCEPTFILES
|
||||||
CAPTION "Rufus 3.23.2025"
|
CAPTION "Rufus 3.23.2026"
|
||||||
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
||||||
|
@ -392,8 +392,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 3,23,2025,0
|
FILEVERSION 3,23,2026,0
|
||||||
PRODUCTVERSION 3,23,2025,0
|
PRODUCTVERSION 3,23,2026,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -411,13 +411,13 @@ BEGIN
|
||||||
VALUE "Comments", "https://rufus.ie"
|
VALUE "Comments", "https://rufus.ie"
|
||||||
VALUE "CompanyName", "Akeo Consulting"
|
VALUE "CompanyName", "Akeo Consulting"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "3.23.2025"
|
VALUE "FileVersion", "3.23.2026"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||||
VALUE "OriginalFilename", "rufus-3.23.exe"
|
VALUE "OriginalFilename", "rufus-3.23.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "3.23.2025"
|
VALUE "ProductVersion", "3.23.2026"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -762,8 +762,8 @@ DWORD RunCommand(const char* cmd, const char* dir, BOOL log)
|
||||||
output = malloc(dwAvail + 1);
|
output = malloc(dwAvail + 1);
|
||||||
if ((output != NULL) && (ReadFile(hOutputRead, output, dwAvail, &dwRead, NULL)) && (dwRead != 0)) {
|
if ((output != NULL) && (ReadFile(hOutputRead, output, dwAvail, &dwRead, NULL)) && (dwRead != 0)) {
|
||||||
output[dwAvail] = 0;
|
output[dwAvail] = 0;
|
||||||
// coverity[tainted_string]
|
// output may contain a '%' so don't feed it as a naked format string
|
||||||
uprintf(output);
|
uprintf("%s", output);
|
||||||
}
|
}
|
||||||
free(output);
|
free(output);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* Rufus: The Reliable USB Formatting Utility
|
* Rufus: The Reliable USB Formatting Utility
|
||||||
* Standard User I/O Routines (logging, status, error, etc.)
|
* Standard User I/O Routines (logging, status, error, etc.)
|
||||||
|
* Copyright © 2011-2023 Pete Batard <pete@akeo.ie>
|
||||||
* Copyright © 2020 Mattiwatti <mattiwatti@gmail.com>
|
* Copyright © 2020 Mattiwatti <mattiwatti@gmail.com>
|
||||||
* Copyright © 2011-2021 Pete Batard <pete@akeo.ie>
|
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -46,7 +46,7 @@ HWND hStatus;
|
||||||
size_t ubuffer_pos = 0;
|
size_t ubuffer_pos = 0;
|
||||||
char ubuffer[UBUFFER_SIZE]; // Buffer for ubpushf() messages we don't log right away
|
char ubuffer[UBUFFER_SIZE]; // Buffer for ubpushf() messages we don't log right away
|
||||||
|
|
||||||
void _uprintf(const char *format, ...)
|
void uprintf(const char *format, ...)
|
||||||
{
|
{
|
||||||
static char buf[4096];
|
static char buf[4096];
|
||||||
char* p = buf;
|
char* p = buf;
|
||||||
|
@ -82,7 +82,7 @@ void _uprintf(const char *format, ...)
|
||||||
free(wbuf);
|
free(wbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _uprintfs(const char* str)
|
void uprintfs(const char* str)
|
||||||
{
|
{
|
||||||
wchar_t* wstr;
|
wchar_t* wstr;
|
||||||
wstr = utf8_to_wchar(str);
|
wstr = utf8_to_wchar(str);
|
||||||
|
|
|
@ -211,7 +211,7 @@ static BOOL IsCompressedBootableImage(const char* path)
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
FormatStatus = 0;
|
FormatStatus = 0;
|
||||||
bled_init(_uprintf, NULL, NULL, NULL, NULL, &FormatStatus);
|
bled_init(uprintf, NULL, NULL, NULL, NULL, &FormatStatus);
|
||||||
dc = bled_uncompress_to_buffer(path, (char*)buf, MBR_SIZE, file_assoc[i].type);
|
dc = bled_uncompress_to_buffer(path, (char*)buf, MBR_SIZE, file_assoc[i].type);
|
||||||
bled_exit();
|
bled_exit();
|
||||||
if (dc != MBR_SIZE) {
|
if (dc != MBR_SIZE) {
|
||||||
|
|
|
@ -673,6 +673,8 @@ BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
|
||||||
static_sprintf(cmd, "%s\\bcdboot.exe %s\\Windows /v /f %s /s %s", sysnative_dir, drive_name,
|
static_sprintf(cmd, "%s\\bcdboot.exe %s\\Windows /v /f %s /s %s", sysnative_dir, drive_name,
|
||||||
HAS_BOOTMGR_BIOS(img_report) ? (HAS_BOOTMGR_EFI(img_report) ? "ALL" : "BIOS") : "UEFI",
|
HAS_BOOTMGR_BIOS(img_report) ? (HAS_BOOTMGR_EFI(img_report) ? "ALL" : "BIOS") : "UEFI",
|
||||||
(use_esp) ? ms_efi : drive_name);
|
(use_esp) ? ms_efi : drive_name);
|
||||||
|
// I don't believe we can ever have a stray '%' in cmd, but just in case...
|
||||||
|
assert(strchr(cmd, '%') == NULL);
|
||||||
uprintf(cmd);
|
uprintf(cmd);
|
||||||
if (RunCommand(cmd, sysnative_dir, usb_debug) != 0) {
|
if (RunCommand(cmd, sysnative_dir, usb_debug) != 0) {
|
||||||
// Try to continue... but report a failure
|
// Try to continue... but report a failure
|
||||||
|
@ -698,6 +700,7 @@ BOOL SetupWinToGo(DWORD DriveIndex, const char* drive_name, BOOL use_esp)
|
||||||
uprintf("Disabling use of the Windows Recovery Environment using command:");
|
uprintf("Disabling use of the Windows Recovery Environment using command:");
|
||||||
static_sprintf(cmd, "%s\\bcdedit.exe /store %s\\EFI\\Microsoft\\Boot\\BCD /set {default} recoveryenabled no",
|
static_sprintf(cmd, "%s\\bcdedit.exe /store %s\\EFI\\Microsoft\\Boot\\BCD /set {default} recoveryenabled no",
|
||||||
sysnative_dir, (use_esp) ? ms_efi : drive_name);
|
sysnative_dir, (use_esp) ? ms_efi : drive_name);
|
||||||
|
assert(strchr(cmd, '%') == NULL);
|
||||||
uprintf(cmd);
|
uprintf(cmd);
|
||||||
RunCommand(cmd, sysnative_dir, usb_debug);
|
RunCommand(cmd, sysnative_dir, usb_debug);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue