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