已关闭
Fix CVE-2025-54920 #84
chenyanpan创建于 8月16日关闭于 6 天前
Fix CVE-2025-54920 #84
已关闭
共 3 个文件变更+226-1
| @@ -0,0 +1,130 @@ | |||
| 1 | +From a618545f789ca8e9abbc33359dbf8b65404d9dde Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: PJ Fanning <pjfanning@users.noreply.github.com> | ||
| 3 | +Date: Sat, 28 Jun 2025 19:04:10 +0800 | ||
| 4 | +Subject: [PATCH 1/2] [SPARK-52381][CORE] JsonProtocol: Only accept subclasses | ||
| 5 | + of SparkListenerEvent | ||
| 6 | + | ||
| 7 | +### What changes were proposed in this pull request? | ||
| 8 | + | ||
| 9 | +JsonProtocol tidy up. Only parse JSON relating to Spark events. | ||
| 10 | +https://issues.apache.org/jira/browse/SPARK-52381 | ||
| 11 | + | ||
| 12 | +### Why are the changes needed? | ||
| 13 | + | ||
| 14 | +Tidier code and https://lists.apache.org/thread/9zwkdo85wcdfppgqvbhjly8wdgf595yp | ||
| 15 | + | ||
| 16 | +### Does this PR introduce _any_ user-facing change? | ||
| 17 | + | ||
| 18 | +No | ||
| 19 | + | ||
| 20 | +### How was this patch tested? | ||
| 21 | + | ||
| 22 | +Unit test | ||
| 23 | + | ||
| 24 | +### Was this patch authored or co-authored using generative AI tooling? | ||
| 25 | + | ||
| 26 | +No | ||
| 27 | + | ||
| 28 | +Closes #51061 from pjfanning/SPARK-52381. | ||
| 29 | + | ||
| 30 | +Authored-by: PJ Fanning <pjfanning@users.noreply.github.com> | ||
| 31 | +Signed-off-by: yangjie01 <yangjie01@baidu.com> | ||
| 32 | +--- | ||
| 33 | + .../org/apache/spark/util/JsonProtocol.scala | 10 +++++-- | ||
| 34 | + .../apache/spark/util/JsonProtocolSuite.scala | 30 +++++++++++++++++++ | ||
| 35 | + 2 files changed, 38 insertions(+), 2 deletions(-) | ||
| 36 | + | ||
| 37 | +diff --git a/core/src/main/scala/org/apache/spark/util/JsonProtocol.scala b/core/src/main/scala/org/apache/spark/util/JsonProtocol.scala | ||
| 38 | +index d5d7c449f23d6..7b99714d76764 100644 | ||
| 39 | +--- a/core/src/main/scala/org/apache/spark/util/JsonProtocol.scala | ||
| 40 | ++++ b/core/src/main/scala/org/apache/spark/util/JsonProtocol.scala | ||
| 41 | + private[spark] object JsonProtocol extends JsonUtils { | ||
| 42 | + case `stageExecutorMetrics` => stageExecutorMetricsFromJson(json) | ||
| 43 | + case `blockUpdate` => blockUpdateFromJson(json) | ||
| 44 | + case `resourceProfileAdded` => resourceProfileAddedFromJson(json) | ||
| 45 | +- case other => mapper.readValue(json.toString, Utils.classForName(other)) | ||
| 46 | +- .asInstanceOf[SparkListenerEvent] | ||
| 47 | ++ case other => | ||
| 48 | ++ val otherClass = Utils.classForName(other) | ||
| 49 | ++ if (classOf[SparkListenerEvent].isAssignableFrom(otherClass)) { | ||
| 50 | ++ mapper.readValue(json.toString, otherClass) | ||
| 51 | ++ .asInstanceOf[SparkListenerEvent] | ||
| 52 | ++ } else { | ||
| 53 | ++ throw new SparkException(s"Unknown event type: $other") | ||
| 54 | ++ } | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | +diff --git a/core/src/test/scala/org/apache/spark/util/JsonProtocolSuite.scala b/core/src/test/scala/org/apache/spark/util/JsonProtocolSuite.scala | ||
| 59 | +index cfba4c02c9440..8c3c18d818a0a 100644 | ||
| 60 | +--- a/core/src/test/scala/org/apache/spark/util/JsonProtocolSuite.scala | ||
| 61 | ++++ b/core/src/test/scala/org/apache/spark/util/JsonProtocolSuite.scala | ||
| 62 | + class JsonProtocolSuite extends SparkFunSuite { | ||
| 63 | + // stages that have completed even before the job start event is emitted. | ||
| 64 | + testEvent(jobStart, sparkEventToJsonString(jobStart)) | ||
| 65 | + } | ||
| 66 | ++ | ||
| 67 | ++ test("SPARK-52381: handle class not found") { | ||
| 68 | ++ val unknownJson = | ||
| 69 | ++ """{ | ||
| 70 | ++ | "Event" : "com.example.UnknownEvent", | ||
| 71 | ++ | "foo" : "foo" | ||
| 72 | ++ |}""".stripMargin | ||
| 73 | ++ try { | ||
| 74 | ++ jsonProtocol.sparkEventFromJson(unknownJson) | ||
| 75 | ++ fail("Expected ClassNotFoundException for unknown event type") | ||
| 76 | ++ } catch { | ||
| 77 | ++ case e: ClassNotFoundException => | ||
| 78 | ++ } | ||
| 79 | ++ } | ||
| 80 | ++ | ||
| 81 | ++ test("SPARK-52381: only read classes that extend SparkListenerEvent") { | ||
| 82 | ++ val unknownJson = | ||
| 83 | ++ """{ | ||
| 84 | ++ | "Event" : "org.apache.spark.SparkException", | ||
| 85 | ++ | "foo" : "foo" | ||
| 86 | ++ |}""".stripMargin | ||
| 87 | ++ try { | ||
| 88 | ++ jsonProtocol.sparkEventFromJson(unknownJson) | ||
| 89 | ++ fail("Expected SparkException for unknown event type") | ||
| 90 | ++ } catch { | ||
| 91 | ++ case e: SparkException => | ||
| 92 | ++ assert(e.getMessage.startsWith("Unknown event type")) | ||
| 93 | ++ } | ||
| 94 | ++ } | ||
| 95 | ++ | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + | ||
| 99 | + | ||
| 100 | +From e59f2b3e75f07b16a69de89e5bf05e9acb6d3cd4 Mon Sep 17 00:00:00 2001 | ||
| 101 | +From: PJ Fanning <pjfanning@users.noreply.github.com> | ||
| 102 | +Date: Sat, 28 Jun 2025 21:05:11 +0100 | ||
| 103 | +Subject: [PATCH 2/2] compile issue | ||
| 104 | + | ||
| 105 | +--- | ||
| 106 | + .../test/scala/org/apache/spark/util/JsonProtocolSuite.scala | 4 ++-- | ||
| 107 | + 1 file changed, 2 insertions(+), 2 deletions(-) | ||
| 108 | + | ||
| 109 | +diff --git a/core/src/test/scala/org/apache/spark/util/JsonProtocolSuite.scala b/core/src/test/scala/org/apache/spark/util/JsonProtocolSuite.scala | ||
| 110 | +index 8c3c18d818a0a..bd3158910bb66 100644 | ||
| 111 | +--- a/core/src/test/scala/org/apache/spark/util/JsonProtocolSuite.scala | ||
| 112 | ++++ b/core/src/test/scala/org/apache/spark/util/JsonProtocolSuite.scala | ||
| 113 | + class JsonProtocolSuite extends SparkFunSuite { | ||
| 114 | + | "foo" : "foo" | ||
| 115 | + |}""".stripMargin | ||
| 116 | + try { | ||
| 117 | +- jsonProtocol.sparkEventFromJson(unknownJson) | ||
| 118 | ++ JsonProtocol.sparkEventFromJson(unknownJson) | ||
| 119 | + fail("Expected ClassNotFoundException for unknown event type") | ||
| 120 | + } catch { | ||
| 121 | + case e: ClassNotFoundException => | ||
| 122 | + class JsonProtocolSuite extends SparkFunSuite { | ||
| 123 | + | "foo" : "foo" | ||
| 124 | + |}""".stripMargin | ||
| 125 | + try { | ||
| 126 | +- jsonProtocol.sparkEventFromJson(unknownJson) | ||
| 127 | ++ JsonProtocol.sparkEventFromJson(unknownJson) | ||
| 128 | + fail("Expected SparkException for unknown event type") | ||
| 129 | + } catch { | ||
| 130 | + case e: SparkException => | ||
| @@ -0,0 +1,88 @@ | |||
| 1 | +From 8435ae3ddc96e063bf4e08f67b30fe35f90aa271 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: PJ Fanning <pjfanning@users.noreply.github.com> | ||
| 3 | +Date: Mon, 30 Jun 2025 10:55:38 +0800 | ||
| 4 | +Subject: [PATCH] [SPARK-52381][CORE][4.0] JsonProtocol: Only accept subclasses | ||
| 5 | + of SparkListenerEvent | ||
| 6 | + | ||
| 7 | +JsonProtocol tidy up. Only parse JSON relating to Spark events. | ||
| 8 | +https://issues.apache.org/jira/browse/SPARK-52381 | ||
| 9 | + | ||
| 10 | +Tidier code and https://lists.apache.org/thread/9zwkdo85wcdfppgqvbhjly8wdgf595yp | ||
| 11 | + | ||
| 12 | +No | ||
| 13 | + | ||
| 14 | +Unit test | ||
| 15 | + | ||
| 16 | +No | ||
| 17 | + | ||
| 18 | +Closes #51312 from pjfanning/SPARK-52381-br4.0. | ||
| 19 | + | ||
| 20 | +Authored-by: PJ Fanning <pjfanning@users.noreply.github.com> | ||
| 21 | +Signed-off-by: yangjie01 <yangjie01@baidu.com> | ||
| 22 | +--- | ||
| 23 | + .../org/apache/spark/util/JsonProtocol.scala | 10 +++++-- | ||
| 24 | + .../apache/spark/util/JsonProtocolSuite.scala | 30 +++++++++++++++++++ | ||
| 25 | + 2 files changed, 38 insertions(+), 2 deletions(-) | ||
| 26 | + | ||
| 27 | +diff --git a/core/src/main/scala/org/apache/spark/util/JsonProtocol.scala b/core/src/main/scala/org/apache/spark/util/JsonProtocol.scala | ||
| 28 | +index 377caf776deb0..3b4bc242b4668 100644 | ||
| 29 | +--- a/core/src/main/scala/org/apache/spark/util/JsonProtocol.scala | ||
| 30 | ++++ b/core/src/main/scala/org/apache/spark/util/JsonProtocol.scala | ||
| 31 | + private[spark] object JsonProtocol extends JsonUtils { | ||
| 32 | + case `stageExecutorMetrics` => stageExecutorMetricsFromJson(json) | ||
| 33 | + case `blockUpdate` => blockUpdateFromJson(json) | ||
| 34 | + case `resourceProfileAdded` => resourceProfileAddedFromJson(json) | ||
| 35 | +- case other => mapper.readValue(json.toString, Utils.classForName(other)) | ||
| 36 | +- .asInstanceOf[SparkListenerEvent] | ||
| 37 | ++ case other => | ||
| 38 | ++ val otherClass = Utils.classForName(other) | ||
| 39 | ++ if (classOf[SparkListenerEvent].isAssignableFrom(otherClass)) { | ||
| 40 | ++ mapper.readValue(json.toString, otherClass) | ||
| 41 | ++ .asInstanceOf[SparkListenerEvent] | ||
| 42 | ++ } else { | ||
| 43 | ++ throw new SparkException(s"Unknown event type: $other") | ||
| 44 | ++ } | ||
| 45 | + } | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | +diff --git a/core/src/test/scala/org/apache/spark/util/JsonProtocolSuite.scala b/core/src/test/scala/org/apache/spark/util/JsonProtocolSuite.scala | ||
| 49 | +index 8105df64705a4..8af8c8579232f 100644 | ||
| 50 | +--- a/core/src/test/scala/org/apache/spark/util/JsonProtocolSuite.scala | ||
| 51 | ++++ b/core/src/test/scala/org/apache/spark/util/JsonProtocolSuite.scala | ||
| 52 | + class JsonProtocolSuite extends SparkFunSuite { | ||
| 53 | + val jobFailedEvent = JsonProtocol.sparkEventFromJson(exJobFailureNoStackJson) | ||
| 54 | + testEvent(jobFailedEvent, exJobFailureExpectedJson) | ||
| 55 | + } | ||
| 56 | ++ | ||
| 57 | ++ test("SPARK-52381: handle class not found") { | ||
| 58 | ++ val unknownJson = | ||
| 59 | ++ """{ | ||
| 60 | ++ | "Event" : "com.example.UnknownEvent", | ||
| 61 | ++ | "foo" : "foo" | ||
| 62 | ++ |}""".stripMargin | ||
| 63 | ++ try { | ||
| 64 | ++ JsonProtocol.sparkEventFromJson(unknownJson) | ||
| 65 | ++ fail("Expected ClassNotFoundException for unknown event type") | ||
| 66 | ++ } catch { | ||
| 67 | ++ case e: ClassNotFoundException => | ||
| 68 | ++ } | ||
| 69 | ++ } | ||
| 70 | ++ | ||
| 71 | ++ test("SPARK-52381: only read classes that extend SparkListenerEvent") { | ||
| 72 | ++ val unknownJson = | ||
| 73 | ++ """{ | ||
| 74 | ++ | "Event" : "org.apache.spark.SparkException", | ||
| 75 | ++ | "foo" : "foo" | ||
| 76 | ++ |}""".stripMargin | ||
| 77 | ++ try { | ||
| 78 | ++ JsonProtocol.sparkEventFromJson(unknownJson) | ||
| 79 | ++ fail("Expected SparkException for unknown event type") | ||
| 80 | ++ } catch { | ||
| 81 | ++ case e: SparkException => | ||
| 82 | ++ assert(e.getMessage.startsWith("Unknown event type")) | ||
| 83 | ++ } | ||
| 84 | ++ } | ||
| 85 | ++ | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + | ||
| @@ -4,7 +4,7 @@ | |||
| 4 | Summary: A unified analytics engine for large-scale data processing. | 4 | Summary: A unified analytics engine for large-scale data processing. |
| 5 | Name: spark | 5 | Name: spark |
| 6 | Version: 3.5.0 | 6 | Version: 3.5.0 |
| 7 | -Release: 6 | 7 | +Release: 7 |
| 8 | License: Apache 2.0 | 8 | License: Apache 2.0 |
| 9 | URL: http://spark.apache.org/ | 9 | URL: http://spark.apache.org/ |
| 10 | Source0: https://github.com/apache/spark/archive/v%{version}.tar.gz | 10 | Source0: https://github.com/apache/spark/archive/v%{version}.tar.gz |
| @@ -24,6 +24,8 @@ Patch1002: 1002-Added-support-for-building-the-riscv64-protoc-gen-gr.patch | |||
| 24 | Patch1003: 1003-Added-support-for-building-the-loongarch64-protoc-bi.patch | 24 | Patch1003: 1003-Added-support-for-building-the-loongarch64-protoc-bi.patch |
| 25 | Patch1004: 1004-Add-protoc-java-support-for-loongarch64.patch | 25 | Patch1004: 1004-Add-protoc-java-support-for-loongarch64.patch |
| 26 | Patch1005: 1005-Added-support-for-building-the-loongarch64-protoc-ge.patch | 26 | Patch1005: 1005-Added-support-for-building-the-loongarch64-protoc-ge.patch |
| 27 | +Patch1006: backport-CVE-2025-54920-1.patch | ||
| 28 | +Patch1007: backport-CVE-2025-54920-2.patch | ||
| 27 | 29 | ||
| 28 | %ifarch riscv64 loongarch64 | 30 | %ifarch riscv64 loongarch64 |
| 29 | BuildRequires: protobuf-devel protobuf-compiler | 31 | BuildRequires: protobuf-devel protobuf-compiler |
| @@ -91,6 +93,8 @@ tar -mxf %{SOURCE6} -C %{_builddir}/%{name}-%{version}/%{name}-prep_dir | |||
| 91 | pushd %{_builddir}/%{name}-%{version}/%{name}-prep_dir/grpc-java-1.56.0 | 93 | pushd %{_builddir}/%{name}-%{version}/%{name}-prep_dir/grpc-java-1.56.0 |
| 92 | %patch1002 -p1 | 94 | %patch1002 -p1 |
| 93 | %patch1005 -p1 | 95 | %patch1005 -p1 |
| 96 | +%patch -P 1006 -p1 | ||
| 97 | +%patch -P 1007 -p1 | ||
| 94 | sed -i "s,@HOME@,${HOME},g" build.gradle | 98 | sed -i "s,@HOME@,${HOME},g" build.gradle |
| 95 | sed -i 's|https\\://services.gradle.org/distributions|file://%{_tmppath}/source|g' gradle/wrapper/gradle-wrapper.properties | 99 | sed -i 's|https\\://services.gradle.org/distributions|file://%{_tmppath}/source|g' gradle/wrapper/gradle-wrapper.properties |
| 96 | %ifarch riscv64 | 100 | %ifarch riscv64 |
| @@ -125,6 +129,9 @@ cp -rf ../%{name}-%{version} %{buildroot}/opt/apache-%{name}-%{version} | |||
| 125 | 129 | ||
| 126 | 130 | ||
| 127 | %changelog | 131 | %changelog |
| 132 | +* Tue Aug 18 2026 chenyanpan <chenyanpan@xfusion.com> - 3.5.0-7 | ||
| 133 | +- Fix CVE-2025-54920 | ||
| 134 | + | ||
| 128 | * Wed Oct 15 2025 Wenlong Zhang <zhangwenlong@loongson.cn> - 3.5.0-6 | 135 | * Wed Oct 15 2025 Wenlong Zhang <zhangwenlong@loongson.cn> - 3.5.0-6 |
| 129 | - fix build error on loongarch64 | 136 | - fix build error on loongarch64 |
| 130 | 137 | ||