mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-09 03:29:43 -10:00
short-chain strlcpy bound fixes via strlcpy_append
Apply strlcpy_append (commit78c52ab) to seven sites flagged in the strlcpy-misuse audit, all sharing the same shape: _len = strlcpy(dst, src1, sizeof(dst)); dst[_len] = c1; dst[++_len] = c2; ... strlcpy(dst + _len, src2, sizeof(dst) - _len); None of these had a bound on _len. When src1 was longer than sizeof(dst) - 1, strlcpy returned strlen(src1) >= sizeof(dst) and: - the dst[_len], dst[++_len], ... character writes ran off the end of dst (stack buffer overflow); - the trailing strlcpy got len - _len which underflowed size_t, producing an unbounded copy. Sites: menu/drivers/materialui.c:8090 - "Draw message box". dst is msg[NAME_MAX_LENGTH] which is 128 on Xbox1, 3DS, PSP, PS2, GameCube, Wii, WiiU, PS3, Emscripten and 256 elsewhere. src1 is menu_st->input_dialog_kb_label[256] (always 256 regardless of platform). On the small- NAME_MAX_LENGTH platforms a long label drove _len up to ~255 and the chain wrote up to 127 bytes past the stack frame. Reachable from any input dialog. tasks/task_http.c:495 and tasks/task_http_emscripten.c:312 - download status string. dst is tmp[NAME_MAX_LENGTH]; src1 is the localized "Downloading" string. Same primitive on small-NAME_MAX_LENGTH platforms when a translation pushed the prefix close to the cap. menu/cbs/menu_cbs_sublabel.c:2164 - core backup CRC sublabel. The chain wrote 8 character bytes ("00000000") plus a NUL after the localized "Backup CRC: " prefix. dst is the caller's s/len; if a translation pushed the prefix close to len, the 9 byte writes ran past the caller's buffer. steam/steam.c:449/471/493 - rich-presence content strings. Three near-identical cases (CONTENT_SYSTEM, CONTENT_CORE, CONTENT_SYSTEM_CORE). Each builds "LABEL (CONTENT)" or "LABEL (N/A)" with hand-unrolled writes of " (", "N/A", "/", "A", ")", "\0" at offsets _len + N. dst is content[PATH_MAX_LENGTH] (512 on small platforms, 4096 elsewhere) and the per-character write offsets reached _len + 12 on the SYSTEM_CORE variant; long labels OOB- wrote up to 12 bytes past content. Replace each chain with a sequence of strlcpy_append calls on a single rolling cursor, with the helper handling the bound check at every step. No functional change at the buffer-fits-comfortably end; on small buffers the new code truncates cleanly instead of stack-overflowing. No new tests -- the strlcpy_append regression test from commit78c52abcovers the helper's contract; these are just additional users.
This commit is contained in:
1 parent
78c52ab36e
commit
e4462428e4
5 files changed
+44
-93
No files matched your search
@@ -2160,25 +2160,14 @@ static int action_bind_sublabel_core_backup_entry(
|
||||
const char *crc = list->list[i].alt
|
||||
? list->list[i].alt
|
||||
: list->list[i].path;
|
||||
/* Set sublabel prefix */
|
||||
size_t _len = strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_BACKUP_CRC), len);
|
||||
|
||||
size_t _len = 0;
|
||||
strlcpy_append(s, len, &_len,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_BACKUP_CRC));
|
||||
/* Add CRC string */
|
||||
if (!crc || !*crc)
|
||||
{
|
||||
s[ _len] = '0';
|
||||
s[++_len] = '0';
|
||||
s[++_len] = '0';
|
||||
s[++_len] = '0';
|
||||
s[++_len] = '0';
|
||||
s[++_len] = '0';
|
||||
s[++_len] = '0';
|
||||
s[++_len] = '0';
|
||||
s[++_len] = '\0';
|
||||
}
|
||||
strlcpy_append(s, len, &_len, "00000000");
|
||||
else
|
||||
strlcpy(s + _len, crc, len - _len);
|
||||
|
||||
strlcpy_append(s, len, &_len, crc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -8087,12 +8087,10 @@ static void materialui_frame(void *data, video_frame_info_t *video_info)
|
||||
NULL);
|
||||
|
||||
/* Draw message box */
|
||||
_len = strlcpy(msg, label, sizeof(msg));
|
||||
msg[ _len] = '\n';
|
||||
msg[++_len] = '\0';
|
||||
strlcpy(msg + _len,
|
||||
str,
|
||||
sizeof(msg) - _len);
|
||||
_len = 0;
|
||||
strlcpy_append(msg, sizeof(msg), &_len, label);
|
||||
strlcpy_append(msg, sizeof(msg), &_len, "\n");
|
||||
strlcpy_append(msg, sizeof(msg), &_len, str);
|
||||
materialui_render_messagebox(mui,
|
||||
p_disp,
|
||||
userdata, video_width, video_height,
|
||||
|
||||
+25
-60
@@ -446,82 +446,47 @@ void steam_update_presence(enum presence presence, bool force)
|
||||
}
|
||||
break;
|
||||
case STEAM_RICH_PRESENCE_FORMAT_CONTENT_SYSTEM:
|
||||
_len = strlcpy(content, label, sizeof(content));
|
||||
content[_len ] = ' ';
|
||||
content[_len+1] = '(';
|
||||
content[_len+2] = '\0';
|
||||
_len = 0;
|
||||
strlcpy_append(content, sizeof(content), &_len, label);
|
||||
strlcpy_append(content, sizeof(content), &_len, " (");
|
||||
if (core_info)
|
||||
{
|
||||
_len += 2;
|
||||
_len += strlcpy(content + _len, core_info->systemname,
|
||||
sizeof(content) - _len);
|
||||
content[_len ] = ')';
|
||||
content[_len+1] = '\0';
|
||||
strlcpy_append(content, sizeof(content), &_len,
|
||||
core_info->systemname);
|
||||
strlcpy_append(content, sizeof(content), &_len, ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
content[_len+2] = 'N';
|
||||
content[_len+3] = '/';
|
||||
content[_len+4] = 'A';
|
||||
content[_len+5] = ')';
|
||||
content[_len+6] = '\0';
|
||||
}
|
||||
strlcpy_append(content, sizeof(content), &_len, "N/A)");
|
||||
break;
|
||||
case STEAM_RICH_PRESENCE_FORMAT_CONTENT_CORE:
|
||||
_len = strlcpy(content, label, sizeof(content));
|
||||
content[_len ] = ' ';
|
||||
content[_len+1] = '(';
|
||||
content[_len+2] = '\0';
|
||||
_len = 0;
|
||||
strlcpy_append(content, sizeof(content), &_len, label);
|
||||
strlcpy_append(content, sizeof(content), &_len, " (");
|
||||
if (core_info)
|
||||
{
|
||||
_len += 2;
|
||||
_len += strlcpy(content + _len, core_info->core_name,
|
||||
sizeof(content) - _len);
|
||||
content[_len ] = ')';
|
||||
content[_len+1] = '\0';
|
||||
strlcpy_append(content, sizeof(content), &_len,
|
||||
core_info->core_name);
|
||||
strlcpy_append(content, sizeof(content), &_len, ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
content[_len+2] = 'N';
|
||||
content[_len+3] = '/';
|
||||
content[_len+4] = 'A';
|
||||
content[_len+5] = ')';
|
||||
content[_len+6] = '\0';
|
||||
}
|
||||
strlcpy_append(content, sizeof(content), &_len, "N/A)");
|
||||
break;
|
||||
case STEAM_RICH_PRESENCE_FORMAT_CONTENT_SYSTEM_CORE:
|
||||
_len = strlcpy(content, label, sizeof(content));
|
||||
content[_len ] = ' ';
|
||||
content[_len+1] = '(';
|
||||
content[_len+2] = '\0';
|
||||
_len = 0;
|
||||
strlcpy_append(content, sizeof(content), &_len, label);
|
||||
strlcpy_append(content, sizeof(content), &_len, " (");
|
||||
if (core_info)
|
||||
{
|
||||
_len += 2;
|
||||
_len += strlcpy(content + _len, core_info->systemname,
|
||||
sizeof(content) - _len);
|
||||
content[_len ] = ' ';
|
||||
content[_len+1] = '-';
|
||||
content[_len+2] = ' ';
|
||||
_len += 3;
|
||||
_len += strlcpy(content + _len, core_info->core_name,
|
||||
sizeof(content) - _len);
|
||||
content[_len ] = ')';
|
||||
content[_len+1] = '\0';
|
||||
strlcpy_append(content, sizeof(content), &_len,
|
||||
core_info->systemname);
|
||||
strlcpy_append(content, sizeof(content), &_len, " - ");
|
||||
strlcpy_append(content, sizeof(content), &_len,
|
||||
core_info->core_name);
|
||||
strlcpy_append(content, sizeof(content), &_len, ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
content[_len+2] = 'N';
|
||||
content[_len+3] = '/';
|
||||
content[_len+4] = 'A';
|
||||
content[_len+5] = ' ';
|
||||
content[_len+6] = '-';
|
||||
content[_len+7] = ' ';
|
||||
content[_len+8] = 'N';
|
||||
content[_len+9] = '/';
|
||||
content[_len+10] = 'A';
|
||||
content[_len+11] = ')';
|
||||
content[_len+12] = '\0';
|
||||
}
|
||||
strlcpy_append(content, sizeof(content), &_len,
|
||||
"N/A - N/A)");
|
||||
break;
|
||||
case STEAM_RICH_PRESENCE_FORMAT_NONE:
|
||||
default:
|
||||
|
||||
+5
-6
@@ -491,17 +491,16 @@ void* task_push_http_transfer_file(const char* url, bool mute,
|
||||
s = transfer_data->path;
|
||||
else
|
||||
s = url;
|
||||
|
||||
_len = strlcpy(tmp, msg_hash_to_str(MSG_DOWNLOADING), sizeof(tmp));
|
||||
tmp[ _len] = ':';
|
||||
tmp[++_len] = ' ';
|
||||
tmp[++_len] = '\0';
|
||||
_len = 0;
|
||||
strlcpy_append(tmp, sizeof(tmp), &_len,
|
||||
msg_hash_to_str(MSG_DOWNLOADING));
|
||||
strlcpy_append(tmp, sizeof(tmp), &_len, ": ");
|
||||
|
||||
if (string_ends_with_size(s, ".index",
|
||||
strlen(s), STRLEN_CONST(".index")))
|
||||
s = msg_hash_to_str(MSG_INDEX_FILE);
|
||||
|
||||
strlcpy(tmp + _len, s, sizeof(tmp) - _len);
|
||||
strlcpy_append(tmp, sizeof(tmp), &_len, s);
|
||||
|
||||
/* should be using type but some callers now rely on type being ignored */
|
||||
return task_push_http_transfer_generic_titled(
|
||||
|
||||
@@ -308,16 +308,16 @@ void* task_push_http_transfer_file(const char* url, bool mute,
|
||||
s = transfer_data->path;
|
||||
else
|
||||
s = url;
|
||||
|
||||
_len = strlcpy(tmp, msg_hash_to_str(MSG_DOWNLOADING), sizeof(tmp));
|
||||
tmp[ _len] = ' ';
|
||||
tmp[++_len] = '\0';
|
||||
_len = 0;
|
||||
strlcpy_append(tmp, sizeof(tmp), &_len,
|
||||
msg_hash_to_str(MSG_DOWNLOADING));
|
||||
strlcpy_append(tmp, sizeof(tmp), &_len, " ");
|
||||
|
||||
if (string_ends_with_size(s, ".index",
|
||||
strlen(s), STRLEN_CONST(".index")))
|
||||
s = msg_hash_to_str(MSG_INDEX_FILE);
|
||||
|
||||
strlcpy(tmp + _len, s, sizeof(tmp) - _len);
|
||||
strlcpy_append(tmp, sizeof(tmp), &_len, s);
|
||||
|
||||
t->title = strdup(tmp);
|
||||
return t;
|
||||
|
||||
Reference in new issue
Block a user