1
1
Fork 0
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:
Pete Batard 2023-04-20 17:43:24 +01:00
parent 1a3a155e8c
commit fffd4d1160
No known key found for this signature in database
GPG key ID: 38E0CF5E69EDD671
12 changed files with 37 additions and 31 deletions

View file

@ -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);

View file

@ -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");

View file

@ -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);
} }
} }

View file

@ -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();

View file

@ -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;

View file

@ -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 {

View file

@ -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

View file

@ -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"

View file

@ -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);
} }

View file

@ -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);

View file

@ -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) {

View file

@ -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);