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]

Reply via email to