!9 Fix CVE-2023-2976

From: @wk333 
Reviewed-by: @caodongxia 
Signed-off-by: @caodongxia
This commit is contained in:
openeuler-ci-bot 2023-07-05 01:27:01 +00:00 committed by Gitee
commit a99f9b4eec
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
3 changed files with 709 additions and 1 deletions

186
CVE-2023-2976-pre.patch Normal file
View 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
View 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

View File

@ -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