From a8ebd0f551ab19b7cb75f262c67a2e36a4801f6d Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Thu, 5 Mar 2026 22:09:54 +0000 Subject: [PATCH] DocumentsTree: Put `resolvePath` under a strict directory whitelist --- .../org/citra/citra_emu/utils/DocumentsTree.kt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/DocumentsTree.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/DocumentsTree.kt index ae020e952..de5881db7 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/DocumentsTree.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/DocumentsTree.kt @@ -10,6 +10,8 @@ import androidx.core.net.toUri import androidx.documentfile.provider.DocumentFile import org.citra.citra_emu.CitraApplication import org.citra.citra_emu.model.CheapDocument +import org.citra.citra_emu.utils.BuildUtil +import java.io.IOException import java.net.URLDecoder import java.nio.file.Paths import java.util.StringTokenizer @@ -261,6 +263,17 @@ class DocumentsTree { @Synchronized private fun resolvePath(filepath: String): DocumentsNode? { + if (!BuildUtil.isGooglePlayBuild) { + var isLegalPath = false + kotlinDirectoryAccessWhitelist.forEach { + if (filepath.startsWith(it)) { + isLegalPath = true + } + } + if (!isLegalPath) { + throw IOException("Attempted to resolve forbidden path: " + filepath) + } + } root ?: return null val tokens = StringTokenizer(filepath, DELIMITER, false) var iterator = root @@ -352,5 +365,10 @@ class DocumentsTree { companion object { const val DELIMITER = "/" + val kotlinDirectoryAccessWhitelist = arrayOf( + "/config/", + "/log/", + "/gpu_drivers/", + ) } }