mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-10 03:21:30 -10:00
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]>
49 lines
1.9 KiB
C
49 lines
1.9 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/>.
|
|
*/
|
|
|
|
#ifndef __TASK_CLOUDSYNC_PATH_H
|
|
#define __TASK_CLOUDSYNC_PATH_H
|
|
|
|
/* Kept dependency-free (only <string.h> in the .c) so the regression test
|
|
* samples/tasks/cloudsync/cloudsync_path_safety_test.c can compile the real
|
|
* predicate standalone -- no libretro-common include path required. */
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* cloud_sync_manifest_key_path:
|
|
* @key : a manifest key as supplied by the (untrusted) cloud-sync server,
|
|
* in "portable" format using '/' separators.
|
|
*
|
|
* Validates @key and returns the relative path portion -- the substring
|
|
* after the first '/' -- suitable for joining onto the local cloud-sync
|
|
* base directory. Returns NULL when @key is unsafe to use, i.e. when it is
|
|
* NULL, contains no '/', has an empty path portion, has an absolute path
|
|
* portion (leading '/'), or contains a ".." anywhere in the path portion.
|
|
*
|
|
* The NULL return is the traversal/malformed-key reject signal: a hostile
|
|
* manifest must not be able to walk out of the cloud-sync directory via
|
|
* fill_pathname_join_special. The returned pointer, when non-NULL, points
|
|
* into @key (no allocation).
|
|
*/
|
|
const char *cloud_sync_manifest_key_path(const char *key);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|