Files
RetroArch/tasks/task_cloudsync_path.c
T
Anthony SchemelandClaude Opus 5.5 4ee62a575f security: validate replay, UPnP and cloud sync input (#19628)
Three places trust data that comes from outside RetroArch:

- replay_set_serialized_data reads the embedded replay length from the
  save state. A negative value, or one shorter than the replay header,
  was passed on to the seek and write that restore the replay. Refuse
  such states.
- natt_parse_desc_node walks the IGD description XML a router serves.
  On a node without children it recursed with a NULL child and then
  read child->next, so a leaf node or an empty root crashed it. It
  also recursed only into childless nodes, so a <service> nested in
  <root>/<device>/<serviceList>, the normal UPnP shape, was never
  found. It now always recurses into children and checks the
  serviceType and controlURL text before using it.
- task_cloud_sync_fetch_server_file took the local path from a
  server-supplied manifest key as strchr(key, '/') + 1. A key without
  '/' read from address 1, and a key containing ".." or an absolute
  path was joined onto the sync directory, so a hostile server could
  write outside it. Such keys are now refused and counted as a
  failure.

The description walk moves to network/natt_desc.c and the key check
to tasks/task_cloudsync_path.c, so the new sample tests
(samples/tasks/natt_desc, and cloudsync_path_safety_test beside the
existing cloudsync test) compile the shipped code directly. Both are
added to Linux-samples-tasks.yml.

Tested on Linux: full build; touched files also compile with
C89_BUILD=1 without warnings. The workflow's commands for both new
steps pass, and the existing cloudsync test still passes under
SANITIZER=address. With the old parser or the old key handling
substituted, each test segfaults.

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-09-26 17:22:37 +02:00

34 lines
1.2 KiB
C

/* RetroArch - A frontend for libretro.
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "task_cloudsync_path.h"
const char *cloud_sync_manifest_key_path(const char *key)
{
const char *slash = key ? strchr(key, '/') : NULL;
const char *path = slash ? slash + 1 : NULL;
/* Reject: NULL/'/'-less key (path == NULL), empty path portion,
* absolute path portion, or any ".." traversal component. */
if ( !path
|| !*path
|| *path == '/'
|| strstr(path, "..") != NULL)
return NULL;
return path;
}