Fix CVE-2020-11979

This commit is contained in:
hht8 2020-12-01 10:12:15 +08:00
parent f7a9f83070
commit 82fe9eb9e3
3 changed files with 200 additions and 2 deletions

View File

@ -0,0 +1,23 @@
From f7159e8a084a3fcb76b933d393df1fc855d74d78 Mon Sep 17 00:00:00 2001
From: Stefan Bodewig <bodewig@apache.org>
Date: Tue, 28 Jul 2020 21:51:01 +0200
Subject: [PATCH] document why we are actually removing the file before writing
---
.../org/apache/tools/ant/types/resources/FileResource.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/main/org/apache/tools/ant/types/resources/FileResource.java b/src/main/org/apache/tools/ant/types/resources/FileResource.java
index d8d604c0f8..17ed7cc463 100644
--- a/src/main/org/apache/tools/ant/types/resources/FileResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/FileResource.java
@@ -255,7 +255,8 @@ public OutputStream getAppendOutputStream() throws IOException {
private OutputStream getOutputStream(boolean append) throws IOException {
File f = getNotNullFile();
if (f.exists()) {
- if (f.isFile() && !append) {
+ if (Files.isSymbolicLink(f.toPath()) && f.isFile() && !append) {
+ // https://bz.apache.org/bugzilla/show_bug.cgi?id=624
f.delete();
}
} else {

View File

@ -0,0 +1,170 @@
From 87ac51d3c22bcf7cfd0dc07cb0bd04a496e0d428 Mon Sep 17 00:00:00 2001
From: Stefan Bodewig <bodewig@apache.org>
Date: Sat, 4 Jul 2020 18:03:13 +0200
Subject: [PATCH] fallback to a separate owner-only tempdir if possible
---
src/main/org/apache/tools/ant/MagicNames.java | 10 +++
.../org/apache/tools/ant/util/FileUtils.java | 36 +++++++++--
.../apache/tools/ant/util/FileUtilsTest.java | 64 +++++++++++++++++++
3 files changed, 105 insertions(+), 5 deletions(-)
diff --git a/src/main/org/apache/tools/ant/MagicNames.java b/src/main/org/apache/tools/ant/MagicNames.java
index 5cf2fa8fa3..8ced505789 100644
--- a/src/main/org/apache/tools/ant/MagicNames.java
+++ b/src/main/org/apache/tools/ant/MagicNames.java
@@ -337,5 +337,15 @@ private MagicNames() {
* @since Ant 1.10.8
*/
public static final String TMPDIR = "ant.tmpdir";
+
+ /**
+ * Magic property that will be set to override java.io.tmpdir
+ * system property as the location for Ant's default temporary
+ * directory if a temp file is created and {@link #TMPDIR} is not
+ * set.
+ * Value: {@value}
+ * @since Ant 1.10.9
+ */
+ public static final String AUTO_TMPDIR = "ant.auto.tmpdir";
}
diff --git a/src/main/org/apache/tools/ant/util/FileUtils.java b/src/main/org/apache/tools/ant/util/FileUtils.java
index 46671848c9..d835438fe7 100644
--- a/src/main/org/apache/tools/ant/util/FileUtils.java
+++ b/src/main/org/apache/tools/ant/util/FileUtils.java
@@ -110,6 +110,11 @@
PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ,
PosixFilePermission.OWNER_WRITE))
};
+ private static final FileAttribute[] TMPDIR_ATTRIBUTES =
+ new FileAttribute[] {
+ PosixFilePermissions.asFileAttribute(EnumSet.of(PosixFilePermission.OWNER_READ,
+ PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE))
+ };
private static final FileAttribute[] NO_TMPFILE_ATTRIBUTES = new FileAttribute[0];
/**
@@ -991,14 +996,35 @@ public File createTempFile(String prefix, String suffix, File parentDir,
public File createTempFile(final Project project, String prefix, String suffix,
final File parentDir, final boolean deleteOnExit, final boolean createFile) {
File result;
- final String parent;
+ String p = null;
if (parentDir != null) {
- parent = parentDir.getPath();
+ p = parentDir.getPath();
} else if (project != null && project.getProperty(MagicNames.TMPDIR) != null) {
- parent = project.getProperty(MagicNames.TMPDIR);
- } else {
- parent = System.getProperty("java.io.tmpdir");
+ p = project.getProperty(MagicNames.TMPDIR);
+ } else if (project != null && deleteOnExit) {
+ if (project.getProperty(MagicNames.AUTO_TMPDIR) != null) {
+ p = project.getProperty(MagicNames.AUTO_TMPDIR);
+ } else {
+ final Path systemTempDirPath =
+ new File(System.getProperty("java.io.tmpdir")).toPath();
+ final PosixFileAttributeView systemTempDirPosixAttributes =
+ Files.getFileAttributeView(systemTempDirPath, PosixFileAttributeView.class);
+ if (systemTempDirPosixAttributes != null) {
+ // no reason to create an extra temp dir if we cannot set permissions
+ try {
+ final File projectTempDir = Files.createTempDirectory(systemTempDirPath,
+ "ant", TMPDIR_ATTRIBUTES)
+ .toFile();
+ projectTempDir.deleteOnExit();
+ p = projectTempDir.getAbsolutePath();
+ project.setProperty(MagicNames.AUTO_TMPDIR, p);
+ } catch (IOException ex) {
+ // silently fall back to system temp directory
+ }
+ }
+ }
}
+ final String parent = p != null ? p : System.getProperty("java.io.tmpdir");
if (prefix == null) {
prefix = NULL_PLACEHOLDER;
}
diff --git a/src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java b/src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java
index da46520038..d5448a6ac6 100644
--- a/src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java
+++ b/src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java
@@ -50,6 +50,8 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
@@ -450,6 +452,68 @@ public void testCreateTempFile() throws IOException {
tmp2.getAbsolutePath()));
}
+ @Test
+ public void createTempFileUsesAntTmpDirIfSetAndDeleteOnExitIsTrue() throws IOException {
+ final Project project = new Project();
+ final File projectTmpDir = folder.newFolder("subdir");
+ project.setProperty("ant.tmpdir", projectTmpDir.getAbsolutePath());
+ final File tmpFile = getFileUtils().createTempFile(project, null, null, null, true, true);
+ assertTrue(tmpFile + " must be child of " + projectTmpDir,
+ tmpFile.getAbsolutePath().startsWith(projectTmpDir.getAbsolutePath()));
+ }
+
+ @Test
+ public void createTempFileUsesAntTmpDirIfSetAndDeleteOnExitIsFalse() throws IOException {
+ final Project project = new Project();
+ final File projectTmpDir = folder.newFolder("subdir");
+ project.setProperty("ant.tmpdir", projectTmpDir.getAbsolutePath());
+ final File tmpFile = getFileUtils().createTempFile(project, null, null, null, false, true);
+ assertTrue(tmpFile + " must be child of " + projectTmpDir,
+ tmpFile.getAbsolutePath().startsWith(projectTmpDir.getAbsolutePath()));
+ }
+
+ @Test
+ public void createTempFileCreatesAutoTmpDirIfDeleteOnExitIsTrueOnUnix() throws IOException {
+ assumeFalse("Test doesn't run on DOS", Os.isFamily("dos"));
+ final Project project = new Project();
+ final File tmpFile = getFileUtils().createTempFile(project, null, null, null, true, true);
+ final String autoTempDir = project.getProperty("ant.auto.tmpdir");
+ assertNotNull(autoTempDir);
+ assertTrue(tmpFile + " must be child of " + autoTempDir,
+ tmpFile.getAbsolutePath().startsWith(autoTempDir));
+ }
+
+ @Test
+ public void createTempFileDoesntCreateAutoTmpDirIfDeleteOnExitIsFalse() throws IOException {
+ final Project project = new Project();
+ final File tmpFile = getFileUtils().createTempFile(project, null, null, null, false, true);
+ assertNull(project.getProperty("ant.auto.tmpdir"));
+ }
+
+ @Test
+ public void createTempFileReusesAutoTmpDirIfDeleteOnExitIsTrueOnUnix() throws IOException {
+ assumeFalse("Test doesn't run on DOS", Os.isFamily("dos"));
+ final Project project = new Project();
+ final File tmpFile = getFileUtils().createTempFile(project, null, null, null, true, true);
+ final String autoTempDir = project.getProperty("ant.auto.tmpdir");
+ assertNotNull(autoTempDir);
+ final File tmpFile2 = getFileUtils().createTempFile(project, null, null, null, true, true);
+ assertTrue(tmpFile2 + " must be child of " + autoTempDir,
+ tmpFile2.getAbsolutePath().startsWith(autoTempDir));
+ }
+
+ @Test
+ public void createTempFileDoesntReusesAutoTmpDirIfDeleteOnExitIsFalse() throws IOException {
+ assumeFalse("Test doesn't run on DOS", Os.isFamily("dos"));
+ final Project project = new Project();
+ final File tmpFile = getFileUtils().createTempFile(project, null, null, null, true, true);
+ final String autoTempDir = project.getProperty("ant.auto.tmpdir");
+ assertNotNull(autoTempDir);
+ final File tmpFile2 = getFileUtils().createTempFile(project, null, null, null, false, true);
+ assertFalse(tmpFile2 + " must not be child of " + autoTempDir,
+ tmpFile2.getAbsolutePath().startsWith(autoTempDir));
+ }
+
/**
* Test contentEquals
*/

View File

@ -4,13 +4,15 @@
Name: ant Name: ant
Summary: A Java-based build tool Summary: A Java-based build tool
Version: 1.10.8 Version: 1.10.8
Release: 2 Release: 3
Epoch: 0 Epoch: 0
License: ASL 2.0 License: ASL 2.0
URL: https://ant.apache.org/ URL: https://ant.apache.org/
Source0: https://archive.apache.org/dist/ant/source/apache-ant-%{version}-src.tar.bz2 Source0: https://archive.apache.org/dist/ant/source/apache-ant-%{version}-src.tar.bz2
Source2: apache-ant-1.8.ant.conf Source2: apache-ant-1.8.ant.conf
# Patch 0-1 are used for repair CVE-2020-11979
Patch0: Fallback-to-a-separate-owner-only-tempdir-if-possible.patch
Patch1: Document-why-we-are-actually-removing-the-file-before-writing.patch
BuildRequires: javapackages-local java-1.8.0-devel ant >= 1.10.2 BuildRequires: javapackages-local java-1.8.0-devel ant >= 1.10.2
BuildRequires: ant-junit xmlto mvn(antlr:antlr) mvn(bcel:bcel) BuildRequires: ant-junit xmlto mvn(antlr:antlr) mvn(bcel:bcel)
BuildRequires: mvn(bsf:bsf) mvn(com.jcraft:jsch) mvn(commons-logging:commons-logging-api) BuildRequires: mvn(bsf:bsf) mvn(com.jcraft:jsch) mvn(commons-logging:commons-logging-api)
@ -422,6 +424,9 @@ LC_ALL=en_US.utf8 %{ant} test
%{_javadocdir}/%{name} %{_javadocdir}/%{name}
%changelog %changelog
* Mon Nov 30 2020 huanghaitao <huanghaitao8@huawei.com> - 0:1.10.8-3
- Fix CVE-2020-11979
* Thu Oct 15 2020 lingsheng<lingsheng@huawei.com> - 0:1.10.8-2 * Thu Oct 15 2020 lingsheng<lingsheng@huawei.com> - 0:1.10.8-2
- Change buildrequire and require to java-1.8.0-devel - Change buildrequire and require to java-1.8.0-devel