mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-89964: Do not execute anything in untrusted projects.
There are 0 or more opened projects in the Platform. Each of which might be trusrted or untrusted. For untrusted project, its basePath (whatever it means) and roots of all its modules are called "prohibited". We shouldn't start anything if it sits in on the aforementioned "prohibited" paths. GitOrigin-RevId: 9a7c2da916bd95eaf07a72a6cfa83593cf1ec205
This commit is contained in:
committed by
intellij-monorepo-bot
parent
fb18825b0a
commit
c45e93b7c2
@@ -36,6 +36,8 @@ jvm_library(
|
||||
"//platform/execution-impl",
|
||||
"//platform/eel-impl",
|
||||
"//platform/eel-impl-base",
|
||||
"//platform/platform-impl:ide-impl",
|
||||
"//platform/projectModel-impl",
|
||||
]
|
||||
)
|
||||
|
||||
@@ -79,6 +81,8 @@ jvm_library(
|
||||
"//platform/execution-impl:execution-impl_test_lib",
|
||||
"//platform/eel-impl:eel-impl_test_lib",
|
||||
"//platform/eel-impl-base:eel-impl-base_test_lib",
|
||||
"//platform/platform-impl:ide-impl_test_lib",
|
||||
"//platform/projectModel-impl:projectModel-impl_test_lib",
|
||||
]
|
||||
)
|
||||
### auto-generated section `build intellij.python.community.execService` end
|
||||
|
||||
@@ -56,5 +56,7 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.execution.impl" />
|
||||
<orderEntry type="module" module-name="intellij.platform.eel.impl" />
|
||||
<orderEntry type="module" module-name="intellij.platform.eel.impl.base" />
|
||||
<orderEntry type="module" module-name="intellij.platform.ide.impl" />
|
||||
<orderEntry type="module" module-name="intellij.platform.projectModel.impl" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -7,5 +7,6 @@ py.exec.fileNotFound=File {0} not found on {1}
|
||||
py.exec.error.not.zero=Exit code is not zero
|
||||
py.exec.error.unexpected.output=Unexpected output {0}
|
||||
py.exec.target.name.default="Local"
|
||||
py.exec.error.not.trusted=Could not start {0}: project is not trusted
|
||||
|
||||
py.exec.target.binaries.are.not.supported=Target binaries are not supported
|
||||
|
||||
+39
-1
@@ -1,24 +1,37 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.python.community.execService.impl.processLaunchers
|
||||
|
||||
import com.intellij.ide.trustedProjects.TrustedProjects
|
||||
import com.intellij.openapi.diagnostic.fileLogger
|
||||
import com.intellij.openapi.diagnostic.trace
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
import com.intellij.platform.eel.EelExecApi
|
||||
import com.intellij.platform.eel.EelProcess
|
||||
import com.intellij.platform.eel.ExecuteProcessException
|
||||
import com.intellij.platform.eel.impl.base.ProcessFunctions
|
||||
import com.intellij.platform.eel.path.EelPath
|
||||
import com.intellij.platform.eel.provider.asEelPath
|
||||
import com.intellij.platform.eel.provider.asNioPath
|
||||
import com.intellij.platform.eel.provider.getEelDescriptor
|
||||
import com.intellij.platform.eel.provider.toEelApi
|
||||
import com.intellij.platform.eel.provider.utils.EelPathUtils
|
||||
import com.intellij.platform.eel.spawnProcess
|
||||
import com.intellij.project.stateStore
|
||||
import com.intellij.python.community.execService.BinOnEel
|
||||
import com.intellij.python.community.execService.TtySize
|
||||
import com.intellij.python.community.execService.impl.PyExecBundle
|
||||
import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.errorProcessing.Exe
|
||||
import com.jetbrains.python.errorProcessing.ExecErrorReason
|
||||
import com.jetbrains.python.sdk.getModuleRoots
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
private val log = fileLogger()
|
||||
|
||||
internal suspend fun createProcessLauncherOnEel(binOnEel: BinOnEel, launchRequest: LaunchRequest): ProcessLauncher {
|
||||
val exePath: EelPath = with(binOnEel) {
|
||||
(if (path.isAbsolute) path else workDir?.resolve(binOnEel.path) ?: path.toAbsolutePath()).asEelPath()
|
||||
@@ -61,8 +74,23 @@ private class EelProcessCommands(
|
||||
|
||||
override suspend fun start(): Result<Process, ExecErrorReason.CantStart> {
|
||||
var workDir = binOnEel.workDir
|
||||
workDir = if (workDir != null && !workDir.isAbsolute) workDir.toRealPath() else workDir
|
||||
workDir = withContext(Dispatchers.IO) { if (workDir != null && !workDir.isAbsolute) workDir.toRealPath() else workDir }
|
||||
|
||||
// If project is untrusted we should not execute anything there
|
||||
val nioPathToExec = withContext(Dispatchers.IO) {
|
||||
path.asNioPath().toAbsolutePath()
|
||||
}
|
||||
val pathIsProhibited = getProhibitedPaths().any { prohibitedParent ->
|
||||
nioPathToExec.startsWith(prohibitedParent) ||
|
||||
(workDir != null && workDir.startsWith(prohibitedParent))
|
||||
}
|
||||
if (pathIsProhibited) {
|
||||
log.trace { "Prohibited exec $nioPathToExec" }
|
||||
return Result.failure(ExecErrorReason.CantStart(null, PyExecBundle.message("py.exec.error.not.trusted", nioPathToExec)))
|
||||
}
|
||||
|
||||
try {
|
||||
log.trace { "Spawning $nioPathToExec" }
|
||||
val eelProcess = path.descriptor.toEelApi().exec.spawnProcess(path)
|
||||
.scope(scopeToBind)
|
||||
.args(args)
|
||||
@@ -78,3 +106,13 @@ private class EelProcessCommands(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List of roots of all untrusted projects
|
||||
*/
|
||||
private suspend fun getProhibitedPaths(): List<Path> = withContext(Dispatchers.Default) {
|
||||
val untrustedProjects = ProjectManager.getInstance().openProjects.filter { !TrustedProjects.isProjectTrusted(it) }
|
||||
return@withContext untrustedProjects.flatMap { project ->
|
||||
setOf(project.stateStore.projectBasePath) + project.getModuleRoots().map { it.toNioPath() }
|
||||
}.map { it.toAbsolutePath() }
|
||||
}
|
||||
Reference in New Issue
Block a user