From a8290069ded30a66d43ad4f2cffbf37d9bc8d435 Mon Sep 17 00:00:00 2001
From: Zhao Hang
Date: Mon, 15 Jan 2024 15:06:46 +0800
Subject: [PATCH] Fix CVE-2023-24998 CVE-2023-28708 CVE-2023-28709
Signed-off-by: Zhao Hang
---
JmxRemoteLifecycleListener.patch | 40 ----
download | 2 +-
tomcat-9.0-JDTCompiler.patch | 24 +++
tomcat-9.0-memory-leak.patch | 345 +++++++++++++++++++++++++++++++
tomcat.spec | 70 +++++--
5 files changed, 427 insertions(+), 54 deletions(-)
delete mode 100644 JmxRemoteLifecycleListener.patch
create mode 100644 tomcat-9.0-JDTCompiler.patch
create mode 100644 tomcat-9.0-memory-leak.patch
diff --git a/JmxRemoteLifecycleListener.patch b/JmxRemoteLifecycleListener.patch
deleted file mode 100644
index 3145a54..0000000
--- a/JmxRemoteLifecycleListener.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-diff --git a/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java b/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java
-index f62f8d1..db19960 100644
---- a/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java
-+++ b/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java
-@@ -611,34 +611,28 @@ public class JmxRemoteLifecycleListener extends SSLHostConfig implements Lifecyc
- * Better to use the internal API than re-invent the wheel.
- */
- @SuppressWarnings("restriction")
-- private static class JmxRegistry extends sun.rmi.registry.RegistryImpl {
-+ private static class JmxRegistry {
- private static final long serialVersionUID = -3772054804656428217L;
- private final String jmxName;
- private final Remote jmxServer;
- public JmxRegistry(int port, RMIClientSocketFactory csf,
- RMIServerSocketFactory ssf, String jmxName, Remote jmxServer) throws RemoteException {
-- super(port, csf, ssf);
- this.jmxName = jmxName;
- this.jmxServer = jmxServer;
- }
-- @Override
- public Remote lookup(String name)
- throws RemoteException, NotBoundException {
- return (jmxName.equals(name)) ? jmxServer : null;
- }
-- @Override
- public void bind(String name, Remote obj)
- throws RemoteException, AlreadyBoundException, AccessException {
- }
-- @Override
- public void unbind(String name)
- throws RemoteException, NotBoundException, AccessException {
- }
-- @Override
- public void rebind(String name, Remote obj)
- throws RemoteException, AccessException {
- }
-- @Override
- public String[] list() throws RemoteException {
- return new String[] { jmxName };
- }
diff --git a/download b/download
index 8a56b53..dbcaa5b 100644
--- a/download
+++ b/download
@@ -1 +1 @@
-8f4934156ee00049f6dda95192b87763 tomcat-9.0.62.redhat-00014-src.zip
+ee30ffe19a1fa585c06c56a608208af0 apache-tomcat-9.0.62-src.tar.gz
diff --git a/tomcat-9.0-JDTCompiler.patch b/tomcat-9.0-JDTCompiler.patch
new file mode 100644
index 0000000..edf156a
--- /dev/null
+++ b/tomcat-9.0-JDTCompiler.patch
@@ -0,0 +1,24 @@
+diff -up ./java/org/apache/jasper/compiler/JDTCompiler.java ./java/org/apache/jasper/compiler/JDTCompiler.java
+index 2e361f2..277d8f4 100644
+--- java/org/apache/jasper/compiler/JDTCompiler.java
++++ java/org/apache/jasper/compiler/JDTCompiler.java
+@@ -310,7 +310,7 @@ public class JDTCompiler extends org.apache.jasper.compiler.Compiler {
+ } else if(opt.equals("15")) {
+ settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
+ } else if(opt.equals("16")) {
+- settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_16);
++ settings.put(CompilerOptions.OPTION_Source, "16");
+ } else if(opt.equals("17")) {
+ // Constant not available in latest ECJ version that runs on
+ // Java 8.
+@@ -377,8 +377,8 @@ public class JDTCompiler extends org.apache.jasper.compiler.Compiler {
+ settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
+ settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
+ } else if(opt.equals("16")) {
+- settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_16);
+- settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_16);
++ settings.put(CompilerOptions.OPTION_TargetPlatform, "16");
++ settings.put(CompilerOptions.OPTION_Compliance, "16");
+ } else if(opt.equals("17")) {
+ // Constant not available in latest ECJ version that runs on
+ // Java 8.
diff --git a/tomcat-9.0-memory-leak.patch b/tomcat-9.0-memory-leak.patch
new file mode 100644
index 0000000..00e6e56
--- /dev/null
+++ b/tomcat-9.0-memory-leak.patch
@@ -0,0 +1,345 @@
+diff --git a/java/org/apache/catalina/loader/WebappClassLoaderBase.java b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
+index 8746b6b..dc878c6 100644
+--- a/java/org/apache/catalina/loader/WebappClassLoaderBase.java
++++ b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
+@@ -1820,41 +1820,13 @@ public abstract class WebappClassLoaderBase extends URLClassLoader
+ // shutting down the executor
+ boolean usingExecutor = false;
+ try {
+-
+- // Runnable wrapped by Thread
+- // "target" in Sun/Oracle JDK
+- // "runnable" in IBM JDK
+- // "action" in Apache Harmony
+- Object target = null;
+- for (String fieldName : new String[] { "target", "runnable", "action" }) {
+- try {
+- Field targetField = thread.getClass().getDeclaredField(fieldName);
+- targetField.setAccessible(true);
+- target = targetField.get(thread);
+- break;
+- } catch (NoSuchFieldException nfe) {
+- continue;
+- }
+- }
+-
+- // "java.util.concurrent" code is in public domain,
+- // so all implementations are similar including our
+- // internal fork.
+- if (target != null && target.getClass().getCanonicalName() != null &&
+- (target.getClass().getCanonicalName().equals(
+- "org.apache.tomcat.util.threads.ThreadPoolExecutor.Worker") ||
+- target.getClass().getCanonicalName().equals(
+- "java.util.concurrent.ThreadPoolExecutor.Worker"))) {
+- Field executorField = target.getClass().getDeclaredField("this$0");
+- executorField.setAccessible(true);
+- Object executor = executorField.get(target);
+- if (executor instanceof ThreadPoolExecutor) {
+- ((ThreadPoolExecutor) executor).shutdownNow();
+- usingExecutor = true;
+- } else if (executor instanceof java.util.concurrent.ThreadPoolExecutor) {
+- ((java.util.concurrent.ThreadPoolExecutor) executor).shutdownNow();
+- usingExecutor = true;
+- }
++ Object executor = JreCompat.getInstance().getExecutor(thread);
++ if (executor instanceof ThreadPoolExecutor) {
++ ((ThreadPoolExecutor) executor).shutdownNow();
++ usingExecutor = true;
++ } else if (executor instanceof java.util.concurrent.ThreadPoolExecutor) {
++ ((java.util.concurrent.ThreadPoolExecutor) executor).shutdownNow();
++ usingExecutor = true;
+ }
+ } catch (NoSuchFieldException | IllegalAccessException | RuntimeException e) {
+ // InaccessibleObjectException is only available in Java 9+,
+@@ -2306,6 +2278,12 @@ public abstract class WebappClassLoaderBase extends URLClassLoader
+
+
+ private void clearReferencesObjectStreamClassCaches() {
++ if (JreCompat.isJre19Available()) {
++ // The memory leak this fixes has been fixed in Java 19 onwards,
++ // 17.0.4 onwards and 11.0.16 onwards
++ // See https://bugs.openjdk.java.net/browse/JDK-8277072
++ return;
++ }
+ try {
+ Class> clazz = Class.forName("java.io.ObjectStreamClass$Caches");
+ clearCache(clazz, "localDescs");
+@@ -2333,14 +2311,19 @@ public abstract class WebappClassLoaderBase extends URLClassLoader
+ throws ReflectiveOperationException, SecurityException, ClassCastException {
+ Field f = target.getDeclaredField(mapName);
+ f.setAccessible(true);
+- Map,?> map = (Map,?>) f.get(null);
+- Iterator> keys = map.keySet().iterator();
+- while (keys.hasNext()) {
+- Object key = keys.next();
+- if (key instanceof Reference) {
+- Object clazz = ((Reference>) key).get();
+- if (loadedByThisOrChild(clazz)) {
+- keys.remove();
++ Object map = f.get(null);
++ // Avoid trying to clear references if Tomcat is running on a JRE that
++ // includes the fix for this memory leak
++ // See https://bugs.openjdk.java.net/browse/JDK-8277072
++ if (map instanceof Map,?>) {
++ Iterator> keys = ((Map,?>) map).keySet().iterator();
++ while (keys.hasNext()) {
++ Object key = keys.next();
++ if (key instanceof Reference) {
++ Object clazz = ((Reference>) key).get();
++ if (loadedByThisOrChild(clazz)) {
++ keys.remove();
++ }
+ }
+ }
+ }
+diff --git a/java/org/apache/tomcat/util/compat/JreCompat.java b/java/org/apache/tomcat/util/compat/JreCompat.java
+index 62df145..e5df728 100644
+--- a/java/org/apache/tomcat/util/compat/JreCompat.java
++++ b/java/org/apache/tomcat/util/compat/JreCompat.java
+@@ -19,6 +19,7 @@ package org.apache.tomcat.util.compat;
+ import java.io.File;
+ import java.io.IOException;
+ import java.lang.reflect.AccessibleObject;
++import java.lang.reflect.Field;
+ import java.lang.reflect.InvocationTargetException;
+ import java.lang.reflect.Method;
+ import java.net.SocketAddress;
+@@ -45,6 +46,7 @@ public class JreCompat {
+
+ private static final JreCompat instance;
+ private static final boolean graalAvailable;
++ private static final boolean jre19Available;
+ private static final boolean jre16Available;
+ private static final boolean jre11Available;
+ private static final boolean jre9Available;
+@@ -67,18 +69,26 @@ public class JreCompat {
+
+ // This is Tomcat 9 with a minimum Java version of Java 8.
+ // Look for the highest supported JVM first
+- if (Jre16Compat.isSupported()) {
++ if (Jre19Compat.isSupported()) {
++ instance = new Jre19Compat();
++ jre9Available = true;
++ jre16Available = true;
++ jre19Available = true;
++ } else if (Jre16Compat.isSupported()) {
+ instance = new Jre16Compat();
+ jre9Available = true;
+ jre16Available = true;
++ jre19Available = false;
+ } else if (Jre9Compat.isSupported()) {
+ instance = new Jre9Compat();
+ jre9Available = true;
+ jre16Available = false;
++ jre19Available = false;
+ } else {
+ instance = new JreCompat();
+ jre9Available = false;
+ jre16Available = false;
++ jre19Available = false;
+ }
+ jre11Available = instance.jarFileRuntimeMajorVersion() >= 11;
+
+@@ -124,6 +134,9 @@ public class JreCompat {
+ return jre16Available;
+ }
+
++ public static boolean isJre19Available() {
++ return jre19Available;
++ }
+
+ // Java 8 implementation of Java 9 methods
+
+@@ -303,6 +316,8 @@ public class JreCompat {
+ }
+
+
++ // Java 8 implementations of Java 16 methods
++
+ /**
+ * Return Unix domain socket address for given path.
+ * @param path The path
+@@ -329,4 +344,63 @@ public class JreCompat {
+ public SocketChannel openUnixDomainSocketChannel() {
+ throw new UnsupportedOperationException(sm.getString("jreCompat.noUnixDomainSocket"));
+ }
++
++
++ // Java 8 implementations of Java 19 methods
++
++ /**
++ * Obtains the executor, if any, used to create the provided thread.
++ *
++ * @param thread The thread to examine
++ *
++ * @return The executor, if any, that created the provided thread
++ *
++ * @throws NoSuchFieldException
++ * If a field used via reflection to obtain the executor cannot
++ * be found
++ * @throws SecurityException
++ * If a security exception occurs while trying to identify the
++ * executor
++ * @throws IllegalArgumentException
++ * If the instance object does not match the class of the field
++ * when obtaining a field value via reflection
++ * @throws IllegalAccessException
++ * If a field is not accessible due to access restrictions
++ */
++ public Object getExecutor(Thread thread)
++ throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
++
++ Object result = null;
++
++ // Runnable wrapped by Thread
++ // "target" in Sun/Oracle JDK
++ // "runnable" in IBM JDK
++ // "action" in Apache Harmony
++ Object target = null;
++ for (String fieldName : new String[] { "target", "runnable", "action" }) {
++ try {
++ Field targetField = thread.getClass().getDeclaredField(fieldName);
++ targetField.setAccessible(true);
++ target = targetField.get(thread);
++ break;
++ } catch (NoSuchFieldException nfe) {
++ continue;
++ }
++ }
++
++ // "java.util.concurrent" code is in public domain,
++ // so all implementations are similar including our
++ // internal fork.
++ if (target != null && target.getClass().getCanonicalName() != null &&
++ (target.getClass().getCanonicalName().equals(
++ "org.apache.tomcat.util.threads.ThreadPoolExecutor.Worker") ||
++ target.getClass().getCanonicalName().equals(
++ "java.util.concurrent.ThreadPoolExecutor.Worker"))) {
++ Field executorField = target.getClass().getDeclaredField("this$0");
++ executorField.setAccessible(true);
++ result = executorField.get(target);
++ }
++
++ return result;
++ }
+ }
+diff --git a/java/org/apache/tomcat/util/compat/LocalStrings.properties b/java/org/apache/tomcat/util/compat/LocalStrings.properties
+index 79427da..c4c2f7d 100644
+--- a/java/org/apache/tomcat/util/compat/LocalStrings.properties
++++ b/java/org/apache/tomcat/util/compat/LocalStrings.properties
+@@ -16,6 +16,8 @@
+ jre16Compat.javaPre16=Class not found so assuming code is running on a pre-Java 16 JVM
+ jre16Compat.unexpected=Failed to create references to Java 16 classes and methods
+
++jre19Compat.javaPre19=Class not found so assuming code is running on a pre-Java 19 JVM
++
+ jre9Compat.invalidModuleUri=The module URI provided [{0}] could not be converted to a URL for the JarScanner to process
+ jre9Compat.javaPre9=Class not found so assuming code is running on a pre-Java 9 JVM
+ jre9Compat.unexpected=Failed to create references to Java 9 classes and methods
+diff --git a/webapps/docs/config/context.xml b/webapps/docs/config/context.xml
+index d118196..42dfe38 100644
+--- a/webapps/docs/config/context.xml
++++ b/webapps/docs/config/context.xml
+@@ -769,7 +769,11 @@
+ therefore requires that the command line option
+ -XaddExports:java.base/java.io=ALL-UNNAMED
is set
+ when running on Java 9 and above. If not specified, the default value of
+- true
will be used.
++ true
will be used.
++ The memory leak associated with ObjectStreamClass
has
++ been fixed in Java 19 onwards, Java 17.0.4 onwards and Java 11.0.16
++ onwards. The check will be disabled when running on a version
++ of Java that contains the fix.
+
+
+
+diff --git a/java/org/apache/tomcat/util/compat/Jre19Compat.java b/java/org/apache/tomcat/util/compat/Jre19Compat.java
+new file mode 100644
+index 0000000000..fb94810b40
+--- /dev/null
++++ b/java/org/apache/tomcat/util/compat/Jre19Compat.java
+@@ -0,0 +1,84 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache License, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++package org.apache.tomcat.util.compat;
++
++import java.lang.reflect.Field;
++
++import org.apache.juli.logging.Log;
++import org.apache.juli.logging.LogFactory;
++import org.apache.tomcat.util.res.StringManager;
++
++public class Jre19Compat extends Jre16Compat {
++
++ private static final Log log = LogFactory.getLog(Jre19Compat.class);
++ private static final StringManager sm = StringManager.getManager(Jre19Compat.class);
++
++ private static final boolean supported;
++
++ static {
++ // Don't need any Java 19 specific classes (yet) so just test for one of
++ // the new ones for now.
++ Class> c1 = null;
++ try {
++ c1 = Class.forName("java.lang.WrongThreadException");
++ } catch (ClassNotFoundException cnfe) {
++ // Must be pre-Java 16
++ log.debug(sm.getString("jre19Compat.javaPre19"), cnfe);
++ }
++
++ supported = (c1 != null);
++ }
++
++ static boolean isSupported() {
++ return supported;
++ }
++
++ @Override
++ public Object getExecutor(Thread thread)
++ throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
++
++ Object result = super.getExecutor(thread);
++
++ if (result == null) {
++ Object holder = null;
++ Object task = null;
++ try {
++ Field holderField = thread.getClass().getDeclaredField("holder");
++ holderField.setAccessible(true);
++ holder = holderField.get(thread);
++
++ Field taskField = holder.getClass().getDeclaredField("task");
++ taskField.setAccessible(true);
++ task = taskField.get(holder);
++ } catch (NoSuchFieldException nfe) {
++ return null;
++ }
++
++ if (task!= null && task.getClass().getCanonicalName() != null &&
++ (task.getClass().getCanonicalName().equals(
++ "org.apache.tomcat.util.threads.ThreadPoolExecutor.Worker") ||
++ task.getClass().getCanonicalName().equals(
++ "java.util.concurrent.ThreadPoolExecutor.Worker"))) {
++ Field executorField = task.getClass().getDeclaredField("this$0");
++ executorField.setAccessible(true);
++ result = executorField.get(task);
++ }
++ }
++
++ return result;
++ }
++}
diff --git a/tomcat.spec b/tomcat.spec
index 147c549..802284b 100644
--- a/tomcat.spec
+++ b/tomcat.spec
@@ -32,7 +32,7 @@
%global major_version 9
%global minor_version 0
%global micro_version 62
-%global packdname %{name}-%{major_version}.%{minor_version}.%{micro_version}.redhat-00014-src
+%global packdname apache-tomcat-%{version}-src
%global servletspec 4.0
%global elspec 3.0
%global tcuid 53
@@ -56,12 +56,12 @@
Name: tomcat
Epoch: 1
Version: %{major_version}.%{minor_version}.%{micro_version}
-Release: 5%{?dist}.2
+Release: 9%{?dist}
Summary: Apache Servlet/JSP Engine, RI for Servlet %{servletspec}/JSP %{jspspec} API
License: ASL 2.0
URL: http://tomcat.apache.org/
-Source0: %{packdname}.zip
+Source0: http://www.apache.org/dist/tomcat/tomcat-%{major_version}/v%{version}/src/%{packdname}.tar.gz
Source1: %{name}-%{major_version}.%{minor_version}.conf
Source3: %{name}-%{major_version}.%{minor_version}.sysconfig
Source4: %{name}-%{major_version}.%{minor_version}.wrapper
@@ -80,15 +80,18 @@ Patch1: %{name}-%{major_version}.%{minor_version}-tomcat-users-webapp.pat
Patch2: %{name}-build.patch
Patch3: %{name}-%{major_version}.%{minor_version}-catalina-policy.patch
Patch4: rhbz-1857043.patch
+# https://github.com/apache/tomcat/commit/ea57ae94edfd12319a4bf8f88d38bb0f469a7d07
+Patch5: tomcat-9.0-JDTCompiler.patch
# remove bnd dependency which version is too low on rhel8
Patch6: remove-bnd-annotation.patch
-Patch7: JmxRemoteLifecycleListener.patch
+# https://github.com/apache/tomcat/commit/7bd49fe5f8a2e2297e08de4b9acbea915de9f38a
+Patch7: tomcat-9.0-memory-leak.patch
Patch8: fix-malformed-dtd.patch
BuildArch: noarch
BuildRequires: ant
-BuildRequires: ecj >= 1:4.10
+BuildRequires: ecj
BuildRequires: findutils
BuildRequires: javapackages-local
BuildRequires: aqute-bnd
@@ -106,8 +109,8 @@ Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
-# We will change it to an obsoletes whenever the pki team is able to make the switch
-Conflicts: pki-servlet-engine <= 1:9.0.50
+Provides: pki-servlet-engine
+Obsoletes: pki-servlet-engine <= 1:9.0.50
# added after log4j sub-package was removed
Provides: %{name}-log4j = %{epoch}:%{version}-%{release}
@@ -122,6 +125,33 @@ Tomcat is developed in an open and participatory environment and
released under the Apache Software License version 2.0. Tomcat is intended
to be a collaboration of the best-of-breed developers from around the world.
+%package java-jdk8
+Group: Development/Java
+Summary: Tomcat on JDK 8
+Requires: java-1.8.0 >= 1:1.8
+Provides: tomcat-java = %{epoch}:%{version}-%{release}
+
+%description java-jdk8
+Tomcat on JDK 8
+
+%package java-jdk11
+Group: Development/Java
+Summary: Tomcat on JDK 11
+Requires: (java-11 or java-11-headless)
+Provides: tomcat-java = %{epoch}:%{version}-%{release}
+
+%description java-jdk11
+Tomcat on JDK 11
+
+%package java-jdk17
+Group: Development/Java
+Summary: Tomcat on JDK 17
+Requires: (java-17 or java-17-headless)
+Provides: tomcat-java = %{epoch}:%{version}-%{release}
+
+%description java-jdk17
+Tomcat on JDK 17
+
%package admin-webapps
Summary: The host-manager and manager web applications for Apache Tomcat
Requires: %{name} = %{epoch}:%{version}-%{release}
@@ -142,7 +172,8 @@ Provides: jsp = %{jspspec}
Obsoletes: %{name}-jsp-2.2-api
Requires: %{name}-servlet-%{servletspec}-api = %{epoch}:%{version}-%{release}
Requires: %{name}-el-%{elspec}-api = %{epoch}:%{version}-%{release}
-Conflicts: pki-servlet-engine <= 1:9.0.50
+Provides: pki-servlet-engine
+Obsoletes: pki-servlet-engine <= 1:9.0.50
%description jsp-%{jspspec}-api
Apache Tomcat JSP API Implementation Classes.
@@ -154,7 +185,8 @@ Requires: %{name}-servlet-%{servletspec}-api = %{epoch}:%{version}-%{release}
Requires: %{name}-el-%{elspec}-api = %{epoch}:%{version}-%{release}
Requires: ecj >= 1:4.10
Requires(preun): coreutils
-Conflicts: pki-servlet-engine <= 1:9.0.50
+Provides: pki-servlet-engine
+Obsoletes: pki-servlet-engine <= 1:9.0.50
%description lib
Libraries needed to run the Tomcat Web container.
@@ -165,7 +197,8 @@ Provides: servlet = %{servletspec}
Provides: servlet6
Provides: servlet3
Obsoletes: %{name}-servlet-3.1-api
-Conflicts: pki-servlet-4.0-api <= 1:9.0.50
+Provides: pki-servlet-4.0-api
+Obsoletes: pki-servlet-4.0-api <= 1:9.0.50
%description servlet-%{servletspec}-api
Apache Tomcat Servlet API Implementation Classes.
@@ -174,7 +207,8 @@ Apache Tomcat Servlet API Implementation Classes.
Summary: Apache Tomcat Expression Language v%{elspec} API Implementation Classes
Provides: el_api = %{elspec}
Obsoletes: %{name}-el-2.2-api
-Conflicts: pki-servlet-engine <= 1:9.0.50 and pki-servlet-container <= 1:9.0.7
+Provides: pki-servlet-engine
+Obsoletes: pki-servlet-engine <= 1:9.0.50
%description el-%{elspec}-api
Apache Tomcat EL API Implementation Classes.
@@ -187,7 +221,7 @@ Requires: %{name} = %{epoch}:%{version}-%{release}
The ROOT web application for Apache Tomcat.
%prep
-%setup -q -n apache-%{packdname}
+%setup -q -n %{packdname}
# remove pre-built binaries and windows files
find . -type f \( -name "*.bat" -o -name "*.class" -o -name Thumbs.db -o -name "*.gz" -o \
-name "*.jar" -o -name "*.war" -o -name "*.zip" \) -delete
@@ -197,6 +231,7 @@ find . -type f \( -name "*.bat" -o -name "*.class" -o -name Thumbs.db -o -name "
%patch -P2 -p0
%patch -P3 -p0
%patch -P4 -p0
+%patch -P5 -p0
%patch -P6 -p1
%patch -P7 -p1
%patch -P8 -p1
@@ -237,7 +272,7 @@ touch HACK
deploy
# remove some jars that we'll replace with symlinks later
-%{__rm} output/build/lib/ecj.jar
+%{__rm} output/build/bin/commons-daemon.jar output/build/lib/ecj.jar
# Remove the example webapps per Apache Tomcat Security Considerations
# see https://tomcat.apache.org/tomcat-9.0-doc/security-howto.html
%{__rm} -rf output/build/webapps/examples
@@ -557,8 +592,17 @@ fi
%defattr(0644,tomcat,tomcat,0755)
%{appdir}/ROOT
+%files java-jdk8
+
+%files java-jdk11
+
+%files java-jdk17
+
%changelog
+* Mon Jan 15 2024 Zhao Hang - 1:9.0.62-9
+- Fix CVE-2023-24998 CVE-2023-28708 CVE-2023-28709
+
* Fri Oct 13 2023 Hui Wang - 1:9.0.62-5.2
- Resolves: RHEL-12884 Missing Tomcat POM files in RHEL 8.8
--
Gitee