[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;
/* For use with Rufus */
extern void _uprintf(const char *format, ...);
extern void uprintf(const char *format, ...);
#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 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);
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_exit();
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);
safe_vsnprintf(msg_cur, MSG_LEN, format, args);
va_end(args);
msg_cur[MSG_LEN-1] = '\0';
msg_cur[MSG_LEN - 1] = '\0';
if ((duration != 0) || (!bStatusTimerArmed))
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);
safe_vsnprintf(buf, MSG_LEN, format, args);
va_end(args);
buf[MSG_LEN-1] = '\0';
uprintf(buf);
buf[MSG_LEN - 1] = '\0';
// 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);
uprintf("Download signature is valid ✓");
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);
size = bled_uncompress_from_buffer_to_buffer(compressed, dwCompressedSize, fido_script, (size_t)uncompressed_size, BLED_COMPRESSION_LZMA);
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 (bFound) {
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);
bFound = FALSE;
access_rights = 0;

View File

@ -2255,7 +2255,8 @@ DWORD CheckDriveAccess(DWORD dwTimeOut, BOOL bPrompt)
proceed = FALSE;
uprintf("Found potentially blocking process(es) against %s:", &PhysicalPath[4]);
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;
uprintf("Found potentially blocking process(es) against %s", drive_name);
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) {
uprintf("Command line arguments:");
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 {

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_windows_path(str) static_repchr(str, '/', '\\')
extern void _uprintf(const char *format, ...);
extern void _uprintfs(const char *str);
#define uprintf(...) _uprintf(__VA_ARGS__)
#define uprintfs(s) _uprintfs(s)
#define vuprintf(...) do { if (verbose) _uprintf(__VA_ARGS__); } while(0)
#define vvuprintf(...) do { if (verbose > 1) _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)
extern void uprintf(const char *format, ...);
extern void uprintfs(const char *str);
#define vuprintf(...) do { if (verbose) uprintf(__VA_ARGS__); } while(0)
#define vvuprintf(...) do { if (verbose > 1) 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__); \
ubuffer_pos = strlen(ubuffer); ubuffer[ubuffer_pos++] = '\r'; ubuffer[ubuffer_pos++] = '\n'; \
ubuffer[ubuffer_pos] = 0; } while(0)
#define ubflush() do { if (ubuffer_pos) uprintf("%s", ubuffer); ubuffer_pos = 0; } while(0)
#ifdef _DEBUG
#define duprintf(...) _uprintf(__VA_ARGS__)
#define duprintf uprintf
#else
#define duprintf(...)
#endif

View File

@ -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 3.23.2025"
CAPTION "Rufus 3.23.2026"
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 3,23,2025,0
PRODUCTVERSION 3,23,2025,0
FILEVERSION 3,23,2026,0
PRODUCTVERSION 3,23,2026,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", "3.23.2025"
VALUE "FileVersion", "3.23.2026"
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-3.23.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "3.23.2025"
VALUE "ProductVersion", "3.23.2026"
END
END
BLOCK "VarFileInfo"

View File

@ -762,8 +762,8 @@ DWORD RunCommand(const char* cmd, const char* dir, BOOL log)
output = malloc(dwAvail + 1);
if ((output != NULL) && (ReadFile(hOutputRead, output, dwAvail, &dwRead, NULL)) && (dwRead != 0)) {
output[dwAvail] = 0;
// coverity[tainted_string]
uprintf(output);
// output may contain a '%' so don't feed it as a naked format string
uprintf("%s", output);
}
free(output);
}

View File

@ -1,8 +1,8 @@
/*
* Rufus: The Reliable USB Formatting Utility
* Standard User I/O Routines (logging, status, error, etc.)
* Copyright © 2011-2023 Pete Batard <pete@akeo.ie>
* 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
* it under the terms of the GNU General Public License as published by
@ -46,7 +46,7 @@ HWND hStatus;
size_t ubuffer_pos = 0;
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];
char* p = buf;
@ -82,7 +82,7 @@ void _uprintf(const char *format, ...)
free(wbuf);
}
void _uprintfs(const char* str)
void uprintfs(const char* str)
{
wchar_t* wstr;
wstr = utf8_to_wchar(str);

View File

@ -211,7 +211,7 @@ static BOOL IsCompressedBootableImage(const char* path)
if (buf == NULL)
return FALSE;
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);
bled_exit();
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,
HAS_BOOTMGR_BIOS(img_report) ? (HAS_BOOTMGR_EFI(img_report) ? "ALL" : "BIOS") : "UEFI",
(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);
if (RunCommand(cmd, sysnative_dir, usb_debug) != 0) {
// 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:");
static_sprintf(cmd, "%s\\bcdedit.exe /store %s\\EFI\\Microsoft\\Boot\\BCD /set {default} recoveryenabled no",
sysnative_dir, (use_esp) ? ms_efi : drive_name);
assert(strchr(cmd, '%') == NULL);
uprintf(cmd);
RunCommand(cmd, sysnative_dir, usb_debug);