!9 Fix CVE-2023-2976
From: @wk333 Reviewed-by: @caodongxia Signed-off-by: @caodongxia
This commit is contained in:
commit
a99f9b4eec
186
CVE-2023-2976-pre.patch
Normal file
186
CVE-2023-2976-pre.patch
Normal file
@ -0,0 +1,186 @@
|
||||
From 364aed58e083e305f3f9ffc5bcacf9536f2472ab Mon Sep 17 00:00:00 2001
|
||||
From: cpovirk <cpovirk@google.com>
|
||||
Date: Tue, 25 Apr 2023 10:00:41 -0700
|
||||
Subject: [PATCH] Split the tests for `Files.createTempDir` into a separate
|
||||
file.
|
||||
|
||||
This makes it easier to run them a second time under a newer Android emulator in our internal tests.
|
||||
|
||||
RELNOTES=n/a
|
||||
PiperOrigin-RevId: 526998248
|
||||
|
||||
Origin: https://github.com/google/guava/commit/364aed58e083e305f3f9ffc5bcacf9536f2472ab
|
||||
|
||||
---
|
||||
.../common/io/FilesCreateTempDirTest.java | 37 +++++++++++++++++
|
||||
.../test/com/google/common/io/FilesTest.java | 15 +++----
|
||||
.../common/annotations/J2ktIncompatible.java | 31 ++++++++++++++
|
||||
.../io/ElementTypesAreNonnullByDefault.java | 41 +++++++++++++++++++
|
||||
4 files changed, 115 insertions(+), 9 deletions(-)
|
||||
create mode 100644 guava-tests/test/com/google/common/io/FilesCreateTempDirTest.java
|
||||
create mode 100644 guava/src/com/google/common/annotations/J2ktIncompatible.java
|
||||
create mode 100644 guava/src/com/google/common/io/ElementTypesAreNonnullByDefault.java
|
||||
|
||||
diff --git a/guava-tests/test/com/google/common/io/FilesCreateTempDirTest.java b/guava-tests/test/com/google/common/io/FilesCreateTempDirTest.java
|
||||
new file mode 100644
|
||||
index 0000000..557689e
|
||||
--- /dev/null
|
||||
+++ b/guava-tests/test/com/google/common/io/FilesCreateTempDirTest.java
|
||||
@@ -0,0 +1,37 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2007 The Guava Authors
|
||||
+ *
|
||||
+ * Licensed 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 com.google.common.io;
|
||||
+
|
||||
+import static com.google.common.truth.Truth.assertThat;
|
||||
+
|
||||
+import java.io.File;
|
||||
+
|
||||
+/**
|
||||
+ * Unit test for {@link Files#createTempDir}.
|
||||
+ *
|
||||
+ * @author Chris Nokleberg
|
||||
+ */
|
||||
+
|
||||
+public class FilesCreateTempDirTest extends IoTestCase {
|
||||
+ public void testCreateTempDir() {
|
||||
+ File temp = Files.createTempDir();
|
||||
+ assertTrue(temp.exists());
|
||||
+ assertTrue(temp.isDirectory());
|
||||
+ assertThat(temp.listFiles()).isEmpty();
|
||||
+ assertTrue(temp.delete());
|
||||
+ }
|
||||
+}
|
||||
diff --git a/guava-tests/test/com/google/common/io/FilesTest.java b/guava-tests/test/com/google/common/io/FilesTest.java
|
||||
index e987f60..d552e0f 100644
|
||||
--- a/guava-tests/test/com/google/common/io/FilesTest.java
|
||||
+++ b/guava-tests/test/com/google/common/io/FilesTest.java
|
||||
@@ -43,7 +43,12 @@ import junit.framework.TestSuite;
|
||||
/**
|
||||
* Unit test for {@link Files}.
|
||||
*
|
||||
- * <p>Note: {@link Files#fileTraverser()} is tested in {@link FilesFileTraverserTest}.
|
||||
+ * <p>Some methods are tested in separate files:
|
||||
+ *
|
||||
+ * <ul>
|
||||
+ * <li>{@link Files#fileTraverser()} is tested in {@link FilesFileTraverserTest}.
|
||||
+ * <li>{@link Files#createTempDir()} is tested in {@link FilesCreateTempDirTest}.
|
||||
+ * </ul>
|
||||
*
|
||||
* @author Chris Nokleberg
|
||||
*/
|
||||
@@ -358,14 +363,6 @@ public class FilesTest extends IoTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
- public void testCreateTempDir() {
|
||||
- File temp = Files.createTempDir();
|
||||
- assertTrue(temp.exists());
|
||||
- assertTrue(temp.isDirectory());
|
||||
- assertThat(temp.listFiles()).isEmpty();
|
||||
- assertTrue(temp.delete());
|
||||
- }
|
||||
-
|
||||
public void testMove() throws IOException {
|
||||
File i18nFile = getTestFile("i18n.txt");
|
||||
File temp1 = createTempFile();
|
||||
diff --git a/guava/src/com/google/common/annotations/J2ktIncompatible.java b/guava/src/com/google/common/annotations/J2ktIncompatible.java
|
||||
new file mode 100644
|
||||
index 0000000..6e28d02
|
||||
--- /dev/null
|
||||
+++ b/guava/src/com/google/common/annotations/J2ktIncompatible.java
|
||||
@@ -0,0 +1,31 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2009 The Guava Authors
|
||||
+ *
|
||||
+ * Licensed 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 com.google.common.annotations;
|
||||
+
|
||||
+import java.lang.annotation.ElementType;
|
||||
+import java.lang.annotation.Retention;
|
||||
+import java.lang.annotation.RetentionPolicy;
|
||||
+import java.lang.annotation.Target;
|
||||
+
|
||||
+/**
|
||||
+ * The presence of this annotation on an API indicates that the method may <em>not</em> be used with
|
||||
+ * J2kt.
|
||||
+ *
|
||||
+ * @since NEXT
|
||||
+ */
|
||||
+@Retention(RetentionPolicy.CLASS)
|
||||
+@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
|
||||
+@GwtCompatible
|
||||
+public @interface J2ktIncompatible {}
|
||||
diff --git a/guava/src/com/google/common/io/ElementTypesAreNonnullByDefault.java b/guava/src/com/google/common/io/ElementTypesAreNonnullByDefault.java
|
||||
new file mode 100644
|
||||
index 0000000..48bc10f
|
||||
--- /dev/null
|
||||
+++ b/guava/src/com/google/common/io/ElementTypesAreNonnullByDefault.java
|
||||
@@ -0,0 +1,41 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2021 The Guava Authors
|
||||
+ *
|
||||
+ * Licensed 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 com.google.common.io;
|
||||
+
|
||||
+import static java.lang.annotation.ElementType.FIELD;
|
||||
+import static java.lang.annotation.ElementType.METHOD;
|
||||
+import static java.lang.annotation.ElementType.PARAMETER;
|
||||
+import static java.lang.annotation.ElementType.TYPE;
|
||||
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
+
|
||||
+import com.google.common.annotations.GwtCompatible;
|
||||
+import java.lang.annotation.Retention;
|
||||
+import java.lang.annotation.Target;
|
||||
+import javax.annotation.Nonnull;
|
||||
+import javax.annotation.meta.TypeQualifierDefault;
|
||||
+
|
||||
+/**
|
||||
+ * Marks all "top-level" types as non-null in a way that is recognized by Kotlin. Note that this
|
||||
+ * unfortunately includes type-variable usages, so we also provide {@link ParametricNullness} to
|
||||
+ * "undo" it as best we can.
|
||||
+ */
|
||||
+@GwtCompatible
|
||||
+@Retention(RUNTIME)
|
||||
+@Target(TYPE)
|
||||
+@TypeQualifierDefault({FIELD, METHOD, PARAMETER})
|
||||
+@Nonnull
|
||||
+@interface ElementTypesAreNonnullByDefault {}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
517
CVE-2023-2976.patch
Normal file
517
CVE-2023-2976.patch
Normal file
@ -0,0 +1,517 @@
|
||||
From feb83a1c8fd2e7670b244d5afd23cba5aca43284 Mon Sep 17 00:00:00 2001
|
||||
From: cpovirk <cpovirk@google.com>
|
||||
Date: Thu, 25 May 2023 13:18:00 -0700
|
||||
Subject: [PATCH] Restrict permissions when creating temporary files and
|
||||
directories, or fail if that's not possible.
|
||||
|
||||
(Also, check that the provided `fileThreshold` is non-negative.)
|
||||
|
||||
- Fixes https://github.com/google/guava/issues/2575
|
||||
- Fixes https://github.com/google/guava/issues/4011
|
||||
|
||||
RELNOTES=Reimplemented `Files.createTempDir` and `FileBackedOutputStream` to further address [CVE-2020-8908](https://github.com/google/guava/issues/4011) and [Guava issue #2575](https://github.com/google/guava/issues/2575) (CVE forthcoming).
|
||||
PiperOrigin-RevId: 535359233
|
||||
|
||||
Refer: https://github.com/google/guava/commit/feb83a1c8fd2e7670b244d5afd23cba5aca43284
|
||||
|
||||
---
|
||||
.../common/io/FileBackedOutputStreamTest.java | 27 +++
|
||||
.../common/io/FilesCreateTempDirTest.java | 41 +++-
|
||||
.../common/io/FileBackedOutputStream.java | 16 +-
|
||||
guava/src/com/google/common/io/Files.java | 48 ++---
|
||||
.../common/io/IgnoreJRERequirement.java | 30 +++
|
||||
.../com/google/common/io/TempFileCreator.java | 176 ++++++++++++++++++
|
||||
6 files changed, 302 insertions(+), 36 deletions(-)
|
||||
create mode 100644 guava/src/com/google/common/io/IgnoreJRERequirement.java
|
||||
create mode 100644 guava/src/com/google/common/io/TempFileCreator.java
|
||||
|
||||
diff --git a/guava-tests/test/com/google/common/io/FileBackedOutputStreamTest.java b/guava-tests/test/com/google/common/io/FileBackedOutputStreamTest.java
|
||||
index 66558e9..db74f32 100644
|
||||
--- a/guava-tests/test/com/google/common/io/FileBackedOutputStreamTest.java
|
||||
+++ b/guava-tests/test/com/google/common/io/FileBackedOutputStreamTest.java
|
||||
@@ -16,10 +16,18 @@
|
||||
|
||||
package com.google.common.io;
|
||||
|
||||
+import static com.google.common.base.StandardSystemProperty.JAVA_IO_TMPDIR;
|
||||
+import static com.google.common.truth.Truth.assertThat;
|
||||
+import static java.nio.file.attribute.PosixFilePermission.OWNER_READ;
|
||||
+import static java.nio.file.attribute.PosixFilePermission.OWNER_WRITE;
|
||||
+import static org.junit.Assert.assertThrows;
|
||||
+
|
||||
import com.google.common.testing.GcFinalization;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
+import java.nio.file.attribute.PosixFileAttributeView;
|
||||
+import java.nio.file.attribute.PosixFileAttributes;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
@@ -59,10 +67,21 @@ public class FileBackedOutputStreamTest extends IoTestCase {
|
||||
|
||||
// Write data to go over the threshold
|
||||
if (chunk2 > 0) {
|
||||
+ if (JAVA_IO_TMPDIR.value().equals("/sdcard")) {
|
||||
+ assertThrows(IOException.class, () -> write(out, data, chunk1, chunk2, singleByte));
|
||||
+ return;
|
||||
+ }
|
||||
write(out, data, chunk1, chunk2, singleByte);
|
||||
file = out.getFile();
|
||||
assertEquals(dataSize, file.length());
|
||||
assertTrue(file.exists());
|
||||
+ assertThat(file.getName()).contains("FileBackedOutputStream");
|
||||
+ if (!isAndroid()) {
|
||||
+ PosixFileAttributes attributes =
|
||||
+ java.nio.file.Files.getFileAttributeView(file.toPath(), PosixFileAttributeView.class)
|
||||
+ .readAttributes();
|
||||
+ assertThat(attributes.permissions()).containsExactly(OWNER_READ, OWNER_WRITE);
|
||||
+ }
|
||||
}
|
||||
out.close();
|
||||
|
||||
@@ -129,6 +148,10 @@ public class FileBackedOutputStreamTest extends IoTestCase {
|
||||
FileBackedOutputStream out = new FileBackedOutputStream(50);
|
||||
ByteSource source = out.asByteSource();
|
||||
|
||||
+ if (JAVA_IO_TMPDIR.value().equals("/sdcard")) {
|
||||
+ assertThrows(IOException.class, () -> out.write(data));
|
||||
+ return;
|
||||
+ }
|
||||
out.write(data);
|
||||
assertTrue(Arrays.equals(data, source.read()));
|
||||
|
||||
@@ -160,4 +183,8 @@ public class FileBackedOutputStreamTest extends IoTestCase {
|
||||
|
||||
out.close();
|
||||
}
|
||||
+
|
||||
+ private static boolean isAndroid() {
|
||||
+ return System.getProperty("java.runtime.name", "").contains("Android");
|
||||
+ }
|
||||
}
|
||||
diff --git a/guava-tests/test/com/google/common/io/FilesCreateTempDirTest.java b/guava-tests/test/com/google/common/io/FilesCreateTempDirTest.java
|
||||
index 557689e..62098ef 100644
|
||||
--- a/guava-tests/test/com/google/common/io/FilesCreateTempDirTest.java
|
||||
+++ b/guava-tests/test/com/google/common/io/FilesCreateTempDirTest.java
|
||||
@@ -16,9 +16,18 @@
|
||||
|
||||
package com.google.common.io;
|
||||
|
||||
+import static com.google.common.base.StandardSystemProperty.JAVA_IO_TMPDIR;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
+import static java.nio.file.attribute.PosixFilePermission.OWNER_EXECUTE;
|
||||
+import static java.nio.file.attribute.PosixFilePermission.OWNER_READ;
|
||||
+import static java.nio.file.attribute.PosixFilePermission.OWNER_WRITE;
|
||||
+import static org.junit.Assert.assertThrows;
|
||||
|
||||
import java.io.File;
|
||||
+import java.io.IOException;
|
||||
+import java.nio.file.attribute.PosixFileAttributeView;
|
||||
+import java.nio.file.attribute.PosixFileAttributes;
|
||||
+import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Unit test for {@link Files#createTempDir}.
|
||||
@@ -26,12 +35,32 @@ import java.io.File;
|
||||
* @author Chris Nokleberg
|
||||
*/
|
||||
|
||||
-public class FilesCreateTempDirTest extends IoTestCase {
|
||||
- public void testCreateTempDir() {
|
||||
+@SuppressWarnings("deprecation") // tests of a deprecated method
|
||||
+public class FilesCreateTempDirTest extends TestCase {
|
||||
+ public void testCreateTempDir() throws IOException {
|
||||
+ if (JAVA_IO_TMPDIR.value().equals("/sdcard")) {
|
||||
+ assertThrows(IllegalStateException.class, Files::createTempDir);
|
||||
+ return;
|
||||
+ }
|
||||
File temp = Files.createTempDir();
|
||||
- assertTrue(temp.exists());
|
||||
- assertTrue(temp.isDirectory());
|
||||
- assertThat(temp.listFiles()).isEmpty();
|
||||
- assertTrue(temp.delete());
|
||||
+ try {
|
||||
+ assertTrue(temp.exists());
|
||||
+ assertTrue(temp.isDirectory());
|
||||
+ assertThat(temp.listFiles()).isEmpty();
|
||||
+
|
||||
+ if (isAndroid()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ PosixFileAttributes attributes =
|
||||
+ java.nio.file.Files.getFileAttributeView(temp.toPath(), PosixFileAttributeView.class)
|
||||
+ .readAttributes();
|
||||
+ assertThat(attributes.permissions()).containsExactly(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE);
|
||||
+ } finally {
|
||||
+ assertTrue(temp.delete());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static boolean isAndroid() {
|
||||
+ return System.getProperty("java.runtime.name", "").contains("Android");
|
||||
}
|
||||
}
|
||||
diff --git a/guava/src/com/google/common/io/FileBackedOutputStream.java b/guava/src/com/google/common/io/FileBackedOutputStream.java
|
||||
index b002561..23d427c 100644
|
||||
--- a/guava/src/com/google/common/io/FileBackedOutputStream.java
|
||||
+++ b/guava/src/com/google/common/io/FileBackedOutputStream.java
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
package com.google.common.io;
|
||||
|
||||
+import static com.google.common.base.Preconditions.checkArgument;
|
||||
+
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtIncompatible;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
@@ -31,6 +33,14 @@ import java.io.OutputStream;
|
||||
* An {@link OutputStream} that starts buffering to a byte array, but switches to file buffering
|
||||
* once the data reaches a configurable size.
|
||||
*
|
||||
+ * <p>When this stream creates a temporary file, it restricts the file's permissions to the current
|
||||
+ * user or, in the case of Android, the current app. If that is not possible (as is the case under
|
||||
+ * the very old Android Ice Cream Sandwich release), then this stream throws an exception instead of
|
||||
+ * creating a file that would be more accessible. (This behavior is new in Guava 32.0.0. Previous
|
||||
+ * versions would create a file that is more accessible, as discussed in <a
|
||||
+ * href="https://github.com/google/guava/issues/2575">Guava issue 2575</a>. TODO: b/283778848 - Fill
|
||||
+ * in CVE number once it's available.)
|
||||
+ *
|
||||
* <p>This class is thread-safe.
|
||||
*
|
||||
* @author Chris Nokleberg
|
||||
@@ -70,6 +80,7 @@ public final class FileBackedOutputStream extends OutputStream {
|
||||
* {@link ByteSource} returned by {@link #asByteSource} is finalized.
|
||||
*
|
||||
* @param fileThreshold the number of bytes before the stream should switch to buffering to a file
|
||||
+ * @throws IllegalArgumentException if {@code fileThreshold} is negative
|
||||
*/
|
||||
public FileBackedOutputStream(int fileThreshold) {
|
||||
this(fileThreshold, false);
|
||||
@@ -82,8 +93,11 @@ public final class FileBackedOutputStream extends OutputStream {
|
||||
* @param fileThreshold the number of bytes before the stream should switch to buffering to a file
|
||||
* @param resetOnFinalize if true, the {@link #reset} method will be called when the {@link
|
||||
* ByteSource} returned by {@link #asByteSource} is finalized
|
||||
+ * @throws IllegalArgumentException if {@code fileThreshold} is negative
|
||||
*/
|
||||
public FileBackedOutputStream(int fileThreshold, boolean resetOnFinalize) {
|
||||
+ checkArgument(
|
||||
+ fileThreshold >= 0, "fileThreshold must be non-negative, but was %s", fileThreshold);
|
||||
this.fileThreshold = fileThreshold;
|
||||
this.resetOnFinalize = resetOnFinalize;
|
||||
memory = new MemoryOutput();
|
||||
@@ -193,7 +207,7 @@ public final class FileBackedOutputStream extends OutputStream {
|
||||
*/
|
||||
private void update(int len) throws IOException {
|
||||
if (file == null && (memory.getCount() + len > fileThreshold)) {
|
||||
- File temp = File.createTempFile("FileBackedOutputStream", null);
|
||||
+ File temp = TempFileCreator.INSTANCE.createTempFile("FileBackedOutputStream");
|
||||
if (resetOnFinalize) {
|
||||
// Finalizers are not guaranteed to be called on system shutdown;
|
||||
// this is insurance.
|
||||
diff --git a/guava/src/com/google/common/io/Files.java b/guava/src/com/google/common/io/Files.java
|
||||
index b0c4390..a2ef1d0 100644
|
||||
--- a/guava/src/com/google/common/io/Files.java
|
||||
+++ b/guava/src/com/google/common/io/Files.java
|
||||
@@ -67,9 +67,6 @@ import java.util.List;
|
||||
@GwtIncompatible
|
||||
public final class Files {
|
||||
|
||||
- /** Maximum loop count when creating temp directories. */
|
||||
- private static final int TEMP_DIR_ATTEMPTS = 10000;
|
||||
-
|
||||
private Files() {}
|
||||
|
||||
/**
|
||||
@@ -380,17 +377,19 @@ public final class Files {
|
||||
* Atomically creates a new directory somewhere beneath the system's temporary directory (as
|
||||
* defined by the {@code java.io.tmpdir} system property), and returns its name.
|
||||
*
|
||||
+ * <p>The temporary directory is created with permissions restricted to the current user or, in
|
||||
+ * the case of Android, the current app. If that is not possible (as is the case under the very
|
||||
+ * old Android Ice Cream Sandwich release), then this method throws an exception instead of
|
||||
+ * creating a directory that would be more accessible. (This behavior is new in Guava 32.0.0.
|
||||
+ * Previous versions would create a directory that is more accessible, as discussed in <a
|
||||
+ * href="https://github.com/google/guava/issues/4011">CVE-2020-8908</a>.)
|
||||
+ *
|
||||
* <p>Use this method instead of {@link File#createTempFile(String, String)} when you wish to
|
||||
* create a directory, not a regular file. A common pitfall is to call {@code createTempFile},
|
||||
* delete the file and create a directory in its place, but this leads a race condition which can
|
||||
* be exploited to create security vulnerabilities, especially when executable files are to be
|
||||
* written into the directory.
|
||||
*
|
||||
- * <p>Depending on the environmment that this code is run in, the system temporary directory (and
|
||||
- * thus the directory this method creates) may be more visible that a program would like - files
|
||||
- * written to this directory may be read or overwritten by hostile programs running on the same
|
||||
- * machine.
|
||||
- *
|
||||
* <p>This method assumes that the temporary volume is writable, has free inodes and free blocks,
|
||||
* and that it will not be called thousands of times per second.
|
||||
*
|
||||
@@ -399,33 +398,24 @@ public final class Files {
|
||||
*
|
||||
* @return the newly-created directory
|
||||
* @throws IllegalStateException if the directory could not be created
|
||||
+ * @throws UnsupportedOperationException if the system does not support creating temporary
|
||||
+ * directories securely
|
||||
* @deprecated For Android users, see the <a
|
||||
* href="https://developer.android.com/training/data-storage" target="_blank">Data and File
|
||||
* Storage overview</a> to select an appropriate temporary directory (perhaps {@code
|
||||
- * context.getCacheDir()}). For developers on Java 7 or later, use {@link
|
||||
- * java.nio.file.Files#createTempDirectory}, transforming it to a {@link File} using {@link
|
||||
- * java.nio.file.Path#toFile() toFile()} if needed.
|
||||
+ * context.getCacheDir()}), and create your own directory under that. (For example, you might
|
||||
+ * use {@code new File(context.getCacheDir(), "directoryname").mkdir()}, or, if you need an
|
||||
+ * arbitrary number of temporary directories, you might have to generate multiple directory
|
||||
+ * names in a loop until {@code mkdir()} returns {@code true}.) For developers on Java 7 or
|
||||
+ * later, use {@link java.nio.file.Files#createTempDirectory}, transforming it to a {@link
|
||||
+ * File} using {@link java.nio.file.Path#toFile() toFile()} if needed. To restrict permissions
|
||||
+ * as this method does, pass {@code
|
||||
+ * PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------"))} to your
|
||||
+ * call to {@code createTempDirectory}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static File createTempDir() {
|
||||
- File baseDir = new File(System.getProperty("java.io.tmpdir"));
|
||||
- String baseName = System.currentTimeMillis() + "-";
|
||||
-
|
||||
- for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) {
|
||||
- File tempDir = new File(baseDir, baseName + counter);
|
||||
- if (tempDir.mkdir()) {
|
||||
- return tempDir;
|
||||
- }
|
||||
- }
|
||||
- throw new IllegalStateException(
|
||||
- "Failed to create directory within "
|
||||
- + TEMP_DIR_ATTEMPTS
|
||||
- + " attempts (tried "
|
||||
- + baseName
|
||||
- + "0 to "
|
||||
- + baseName
|
||||
- + (TEMP_DIR_ATTEMPTS - 1)
|
||||
- + ')');
|
||||
+ return TempFileCreator.INSTANCE.createTempDir();
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/guava/src/com/google/common/io/IgnoreJRERequirement.java b/guava/src/com/google/common/io/IgnoreJRERequirement.java
|
||||
new file mode 100644
|
||||
index 0000000..b1b8e10
|
||||
--- /dev/null
|
||||
+++ b/guava/src/com/google/common/io/IgnoreJRERequirement.java
|
||||
@@ -0,0 +1,30 @@
|
||||
+/*
|
||||
+ * Copyright 2019 The Guava Authors
|
||||
+ *
|
||||
+ * Licensed 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 com.google.common.io;
|
||||
+
|
||||
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
|
||||
+import static java.lang.annotation.ElementType.METHOD;
|
||||
+import static java.lang.annotation.ElementType.TYPE;
|
||||
+
|
||||
+import java.lang.annotation.Target;
|
||||
+
|
||||
+/**
|
||||
+ * Disables Animal Sniffer's checking of compatibility with older versions of Java/Android.
|
||||
+ *
|
||||
+ * <p>Each package's copy of this annotation needs to be listed in our {@code pom.xml}.
|
||||
+ */
|
||||
+@Target({METHOD, CONSTRUCTOR, TYPE})
|
||||
+@ElementTypesAreNonnullByDefault
|
||||
+@interface IgnoreJRERequirement {}
|
||||
diff --git a/guava/src/com/google/common/io/TempFileCreator.java b/guava/src/com/google/common/io/TempFileCreator.java
|
||||
new file mode 100644
|
||||
index 0000000..103427a
|
||||
--- /dev/null
|
||||
+++ b/guava/src/com/google/common/io/TempFileCreator.java
|
||||
@@ -0,0 +1,176 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2007 The Guava Authors
|
||||
+ *
|
||||
+ * Licensed 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 com.google.common.io;
|
||||
+
|
||||
+import static com.google.common.base.StandardSystemProperty.JAVA_IO_TMPDIR;
|
||||
+
|
||||
+import com.google.common.annotations.GwtIncompatible;
|
||||
+import com.google.common.annotations.J2ktIncompatible;
|
||||
+import com.google.j2objc.annotations.J2ObjCIncompatible;
|
||||
+import java.io.File;
|
||||
+import java.io.IOException;
|
||||
+import java.nio.file.Paths;
|
||||
+import java.nio.file.attribute.FileAttribute;
|
||||
+import java.nio.file.attribute.PosixFilePermission;
|
||||
+import java.nio.file.attribute.PosixFilePermissions;
|
||||
+import java.util.Set;
|
||||
+
|
||||
+/**
|
||||
+ * Creates temporary files and directories whose permissions are restricted to the current user or,
|
||||
+ * in the case of Android, the current app. If that is not possible (as is the case under the very
|
||||
+ * old Android Ice Cream Sandwich release), then this class throws an exception instead of creating
|
||||
+ * a file or directory that would be more accessible.
|
||||
+ */
|
||||
+@J2ktIncompatible
|
||||
+@GwtIncompatible
|
||||
+@J2ObjCIncompatible
|
||||
+@ElementTypesAreNonnullByDefault
|
||||
+abstract class TempFileCreator {
|
||||
+ static final TempFileCreator INSTANCE = pickSecureCreator();
|
||||
+
|
||||
+ /**
|
||||
+ * @throws IllegalStateException if the directory could not be created (to implement the contract
|
||||
+ * of {@link Files#createTempDir()}
|
||||
+ * @throws UnsupportedOperationException if the system does not support creating temporary
|
||||
+ * directories securely
|
||||
+ */
|
||||
+ abstract File createTempDir();
|
||||
+
|
||||
+ abstract File createTempFile(String prefix) throws IOException;
|
||||
+
|
||||
+ private static TempFileCreator pickSecureCreator() {
|
||||
+ try {
|
||||
+ Class.forName("java.nio.file.Path");
|
||||
+ return new JavaNioCreator();
|
||||
+ } catch (ClassNotFoundException runningUnderAndroid) {
|
||||
+ // Try another way.
|
||||
+ }
|
||||
+
|
||||
+ try {
|
||||
+ int version = ((Integer) Class.forName("android.os.Build$VERSION").getField("SDK_INT").get(null)).intValue();
|
||||
+ int jellyBean =
|
||||
+ ((Integer) Class.forName("android.os.Build$VERSION_CODES").getField("JELLY_BEAN").get(null)).intValue();
|
||||
+ /*
|
||||
+ * I assume that this check can't fail because JELLY_BEAN will be present only if we're
|
||||
+ * running under Jelly Bean or higher. But it seems safest to check.
|
||||
+ */
|
||||
+ if (version < jellyBean) {
|
||||
+ return new ThrowingCreator();
|
||||
+ }
|
||||
+
|
||||
+ // Don't merge these catch() blocks, let alone use ReflectiveOperationException directly:
|
||||
+ // b/65343391
|
||||
+ } catch (NoSuchFieldException e) {
|
||||
+ // The JELLY_BEAN field doesn't exist because we're running on a version before Jelly Bean :)
|
||||
+ return new ThrowingCreator();
|
||||
+ } catch (ClassNotFoundException e) {
|
||||
+ // Should be impossible, but we want to return *something* so that class init succeeds.
|
||||
+ return new ThrowingCreator();
|
||||
+ } catch (IllegalAccessException e) {
|
||||
+ // ditto
|
||||
+ return new ThrowingCreator();
|
||||
+ }
|
||||
+
|
||||
+ // Android isolates apps' temporary directories since Jelly Bean:
|
||||
+ // https://github.com/google/guava/issues/4011#issuecomment-770020802
|
||||
+ // So we can create files there with any permissions and still get security from the isolation.
|
||||
+ return new JavaIoCreator();
|
||||
+ }
|
||||
+
|
||||
+ @IgnoreJRERequirement // used only when Path is available
|
||||
+ private static final class JavaNioCreator extends TempFileCreator {
|
||||
+ private static final FileAttribute<Set<PosixFilePermission>> RWX_USER_ONLY =
|
||||
+ PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------"));
|
||||
+ private static final FileAttribute<Set<PosixFilePermission>> RW_USER_ONLY =
|
||||
+ PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rw-------"));
|
||||
+
|
||||
+ @Override
|
||||
+ File createTempDir() {
|
||||
+ try {
|
||||
+ return java.nio.file.Files.createTempDirectory(
|
||||
+ Paths.get(JAVA_IO_TMPDIR.value()), /* prefix= */ null, RWX_USER_ONLY)
|
||||
+ .toFile();
|
||||
+ } catch (IOException e) {
|
||||
+ throw new IllegalStateException("Failed to create directory", e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ File createTempFile(String prefix) throws IOException {
|
||||
+ return java.nio.file.Files.createTempFile(
|
||||
+ Paths.get(JAVA_IO_TMPDIR.value()),
|
||||
+ /* prefix= */ prefix,
|
||||
+ /* suffix= */ null,
|
||||
+ RW_USER_ONLY)
|
||||
+ .toFile();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static final class JavaIoCreator extends TempFileCreator {
|
||||
+ @Override
|
||||
+ File createTempDir() {
|
||||
+ File baseDir = new File(JAVA_IO_TMPDIR.value());
|
||||
+ @SuppressWarnings("GoodTime") // reading system time without TimeSource
|
||||
+ String baseName = System.currentTimeMillis() + "-";
|
||||
+
|
||||
+ for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) {
|
||||
+ File tempDir = new File(baseDir, baseName + counter);
|
||||
+ if (tempDir.mkdir()) {
|
||||
+ return tempDir;
|
||||
+ }
|
||||
+ }
|
||||
+ throw new IllegalStateException(
|
||||
+ "Failed to create directory within "
|
||||
+ + TEMP_DIR_ATTEMPTS
|
||||
+ + " attempts (tried "
|
||||
+ + baseName
|
||||
+ + "0 to "
|
||||
+ + baseName
|
||||
+ + (TEMP_DIR_ATTEMPTS - 1)
|
||||
+ + ')');
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ File createTempFile(String prefix) throws IOException {
|
||||
+ return File.createTempFile(
|
||||
+ /* prefix= */ prefix,
|
||||
+ /* suffix= */ null,
|
||||
+ /* directory= */ null /* defaults to java.io.tmpdir */);
|
||||
+ }
|
||||
+
|
||||
+ /** Maximum loop count when creating temp directories. */
|
||||
+ private static final int TEMP_DIR_ATTEMPTS = 10000;
|
||||
+ }
|
||||
+
|
||||
+ private static final class ThrowingCreator extends TempFileCreator {
|
||||
+ private static final String MESSAGE =
|
||||
+ "Guava cannot securely create temporary files or directories under SDK versions before"
|
||||
+ + " Jelly Bean. You can create one yourself, either in the insecure default directory"
|
||||
+ + " or in a more secure directory, such as context.getCacheDir(). For more information,"
|
||||
+ + " see the Javadoc for Files.createTempDir().";
|
||||
+
|
||||
+ @Override
|
||||
+ File createTempDir() {
|
||||
+ throw new IllegalStateException(MESSAGE);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ File createTempFile(String prefix) throws IOException {
|
||||
+ throw new IOException(MESSAGE);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private TempFileCreator() {}
|
||||
+}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
Name: guava
|
||||
Version: 25.0
|
||||
Release: 5
|
||||
Release: 6
|
||||
Summary: Google Core Libraries for Java
|
||||
License: ASL 2.0 and CC0
|
||||
URL: https://github.com/google/guava
|
||||
@ -8,6 +8,8 @@ BuildArch: noarch
|
||||
|
||||
Source0: https://github.com/google/guava/archive/v%{version}.tar.gz
|
||||
Patch0000: CVE-2020-8908.patch
|
||||
Patch0001: CVE-2023-2976-pre.patch
|
||||
Patch0002: CVE-2023-2976.patch
|
||||
|
||||
BuildRequires: maven-local mvn(com.google.code.findbugs:jsr305) mvn(junit:junit)
|
||||
BuildRequires: mvn(org.apache.felix:maven-bundle-plugin) mvn(org.sonatype.oss:oss-parent:pom:)
|
||||
@ -87,6 +89,9 @@ find -name '*.java' | xargs sed -ri \
|
||||
%files testlib -f .mfiles-guava-testlib
|
||||
|
||||
%changelog
|
||||
* Tue Jul 04 2023 wangkai <13474090681@163.com> - 25.0-6
|
||||
- Fix CVE-2023-2976
|
||||
|
||||
* Fri Feb 19 2021 wangxiao <wangxiao65@huawei.com> - 25.0-5
|
||||
- Fix CVE-2020-8908
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user