This is an automated email from the ASF dual-hosted git repository.
dongjoon-hyun pushed a commit to branch branch-4.x
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/branch-4.x by this push:
new 3d5d1fefdade [SPARK-57920][CORE][SQL][YARN] Use `Files.createTempFile`
to create temporary files with owner-only permissions
3d5d1fefdade is described below
commit 3d5d1fefdade4b028dc486dc880ffd53bfd347e9
Author: Dongjoon Hyun <[email protected]>
AuthorDate: Fri Jul 3 03:20:55 2026 -0700
[SPARK-57920][CORE][SQL][YARN] Use `Files.createTempFile` to create
temporary files with owner-only permissions
### What changes were proposed in this pull request?
This PR aims to use `java.nio.file.Files.createTempFile` instead of
`java.io.File.createTempFile` in the main source code (`Utils`, `yarn.Client`,
`PythonRDD`, `RowQueue`, `LogBlockWriter`, `StandaloneResourceUtils`) to create
temporary files with owner-only permissions (`600`) on POSIX file systems.
### Why are the changes needed?
`File.createTempFile` creates files with umask-based default permissions
(typically `644`), while `Files.createTempFile` guarantees `600`. Some of these
temp files may contain sensitive data (fetched keytabs, YARN conf archives) and
are not always created under a `chmod 700` directory.
### Does this PR introduce _any_ user-facing change?
No functional change. On POSIX systems, these temporary files are now
created with owner-only permissions.
### How was this patch tested?
Pass the CIs.
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Fable 5
Closes #56982 from dongjoon-hyun/SPARK-57920.
Authored-by: Dongjoon Hyun <[email protected]>
Signed-off-by: Dongjoon Hyun <[email protected]>
(cherry picked from commit fae36fb978bb20ce2819b90782356b09833b7df8)
Signed-off-by: Dongjoon Hyun <[email protected]>
---
core/src/main/scala/org/apache/spark/api/python/PythonRDD.scala | 3 ++-
.../scala/org/apache/spark/deploy/StandaloneResourceUtils.scala | 3 ++-
core/src/main/scala/org/apache/spark/storage/LogBlockWriter.scala | 3 ++-
core/src/main/scala/org/apache/spark/util/Utils.scala | 4 ++--
.../yarn/src/main/scala/org/apache/spark/deploy/yarn/Client.scala | 8 ++++----
.../scala/org/apache/spark/sql/execution/python/RowQueue.scala | 3 ++-
6 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/core/src/main/scala/org/apache/spark/api/python/PythonRDD.scala
b/core/src/main/scala/org/apache/spark/api/python/PythonRDD.scala
index 45bf30675148..bb59a7e5bb8b 100644
--- a/core/src/main/scala/org/apache/spark/api/python/PythonRDD.scala
+++ b/core/src/main/scala/org/apache/spark/api/python/PythonRDD.scala
@@ -21,6 +21,7 @@ import java.io._
import java.net._
import java.nio.channels.{Channels, SocketChannel}
import java.nio.charset.StandardCharsets
+import java.nio.file.Files
import java.util.{ArrayList => JArrayList, List => JList, Map => JMap}
import scala.collection.mutable
@@ -852,7 +853,7 @@ private[spark] class PythonBroadcast(@transient var path:
String) extends Serial
if (!diskBlockManager.containsBlock(blockId)) {
Utils.tryOrIOException {
val dir = new File(Utils.getLocalDir(SparkEnv.get.conf))
- val file = File.createTempFile("broadcast", "", dir)
+ val file = Files.createTempFile(dir.toPath, "broadcast", "").toFile
val out = new FileOutputStream(file)
Utils.tryWithSafeFinally {
val size = Utils.copyStream(in, out)
diff --git
a/core/src/main/scala/org/apache/spark/deploy/StandaloneResourceUtils.scala
b/core/src/main/scala/org/apache/spark/deploy/StandaloneResourceUtils.scala
index 5a1d58897703..918d2afd1ed6 100644
--- a/core/src/main/scala/org/apache/spark/deploy/StandaloneResourceUtils.scala
+++ b/core/src/main/scala/org/apache/spark/deploy/StandaloneResourceUtils.scala
@@ -109,7 +109,8 @@ private[spark] object StandaloneResourceUtils extends
Logging {
logError(errMsg, e)
throw new SparkException(errMsg.message, e)
}
- val resourcesFile = File.createTempFile(s"resource-$compShortName-",
".json", dir)
+ val resourcesFile = Files.createTempFile(dir.toPath,
s"resource-$compShortName-", ".json")
+ .toFile
tmpFile.renameTo(resourcesFile)
Some(resourcesFile)
}
diff --git a/core/src/main/scala/org/apache/spark/storage/LogBlockWriter.scala
b/core/src/main/scala/org/apache/spark/storage/LogBlockWriter.scala
index 5645f59d383d..36573100f0f6 100644
--- a/core/src/main/scala/org/apache/spark/storage/LogBlockWriter.scala
+++ b/core/src/main/scala/org/apache/spark/storage/LogBlockWriter.scala
@@ -20,6 +20,7 @@ package org.apache.spark.storage
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
+import java.nio.file.Files
import org.apache.commons.io.output.CountingOutputStream
@@ -61,7 +62,7 @@ private[spark] class LogBlockWriter(
private def initialize(): Unit = {
try {
val dir = new File(Utils.getLocalDir(sparkConf))
- tmpFile = File.createTempFile(s"spark_log_$logBlockType", "", dir)
+ tmpFile = Files.createTempFile(dir.toPath, s"spark_log_$logBlockType",
"").toFile
val fos = new FileOutputStream(tmpFile, false)
val bos = new BufferedOutputStream(fos, bufferSize)
cos = new CountingOutputStream(bos)
diff --git a/core/src/main/scala/org/apache/spark/util/Utils.scala
b/core/src/main/scala/org/apache/spark/util/Utils.scala
index 2b03a068f132..39f9ca8a472c 100644
--- a/core/src/main/scala/org/apache/spark/util/Utils.scala
+++ b/core/src/main/scala/org/apache/spark/util/Utils.scala
@@ -517,8 +517,8 @@ private[spark] object Utils
in: InputStream,
destFile: File,
fileOverwrite: Boolean): Unit = {
- val tempFile = File.createTempFile("fetchFileTemp", null,
- new File(destFile.getParentFile.getAbsolutePath))
+ val tempFile = Files.createTempFile(
+ new File(destFile.getParentFile.getAbsolutePath).toPath,
"fetchFileTemp", null).toFile
logInfo(log"Fetching ${MDC(LogKeys.URL, url)} to ${MDC(FILE_ABSOLUTE_PATH,
tempFile)}")
try {
diff --git
a/resource-managers/yarn/src/main/scala/org/apache/spark/deploy/yarn/Client.scala
b/resource-managers/yarn/src/main/scala/org/apache/spark/deploy/yarn/Client.scala
index 5f25b0b55338..667975f4aec7 100644
---
a/resource-managers/yarn/src/main/scala/org/apache/spark/deploy/yarn/Client.scala
+++
b/resource-managers/yarn/src/main/scala/org/apache/spark/deploy/yarn/Client.scala
@@ -710,8 +710,8 @@ private[spark] class Client(
log"libraries under SPARK_HOME.")
val jarsDir = new File(YarnCommandBuilderUtils.findJarsDir(
sparkConf.getenv("SPARK_HOME")))
- val jarsArchive = File.createTempFile(LOCALIZED_LIB_DIR, ".zip",
- new File(Utils.getLocalDir(sparkConf)))
+ val jarsArchive = Files.createTempFile(
+ Paths.get(Utils.getLocalDir(sparkConf)), LOCALIZED_LIB_DIR,
".zip").toFile
val bufferSize = sparkConf.get(BUFFER_SIZE)
Using.resource(new ZipOutputStream(
new BufferedOutputStream(new FileOutputStream(jarsArchive),
bufferSize))) {
@@ -898,8 +898,8 @@ private[spark] class Client(
}
}
- val confArchive = File.createTempFile(LOCALIZED_CONF_DIR, ".zip",
- new File(Utils.getLocalDir(sparkConf)))
+ val confArchive = Files.createTempFile(
+ Paths.get(Utils.getLocalDir(sparkConf)), LOCALIZED_CONF_DIR,
".zip").toFile
val confStream = new ZipOutputStream(new FileOutputStream(confArchive))
logDebug(s"Creating an archive with the config files for distribution at
$confArchive.")
diff --git
a/sql/core/src/main/scala/org/apache/spark/sql/execution/python/RowQueue.scala
b/sql/core/src/main/scala/org/apache/spark/sql/execution/python/RowQueue.scala
index 9f980be51d51..c0531fcf303c 100644
---
a/sql/core/src/main/scala/org/apache/spark/sql/execution/python/RowQueue.scala
+++
b/sql/core/src/main/scala/org/apache/spark/sql/execution/python/RowQueue.scala
@@ -18,6 +18,7 @@
package org.apache.spark.sql.execution.python
import java.io._
+import java.nio.file.Files
import com.google.common.io.Closeables
@@ -190,7 +191,7 @@ case class HybridRowQueue(
extends HybridQueue[UnsafeRow, RowQueue](memManager, tempDir, serMgr) {
override protected def createDiskQueue(): RowQueue = {
- DiskRowQueue(File.createTempFile("buffer", "", tempDir), numFields, serMgr)
+ DiskRowQueue(Files.createTempFile(tempDir.toPath, "buffer", "").toFile,
numFields, serMgr)
}
override protected def createInMemoryQueue(page: MemoryBlock): RowQueue = {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]