Skip to content

Commit

Permalink
Issue #543 - avoid attempts to write .dll files when on z/OS for canW…
Browse files Browse the repository at this point in the history
…rite

On z/OS we can depend on the behavior of Files.isWritable and don't
need the extra check to see if `.dll` files can be written to the
directory.
  • Loading branch information
tjwatson committed Mar 4, 2024
1 parent 3fc1767 commit 742429a
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,47 @@
*******************************************************************************/
package org.eclipse.equinox.launcher;

import java.io.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.URLStreamHandlerFactory;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.*;
import java.util.*;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Policy;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.StringJoiner;
import java.util.StringTokenizer;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.eclipse.equinox.internal.launcher.Constants;

/**
Expand Down Expand Up @@ -715,7 +745,7 @@ private boolean checkConfigurationLocation(URL locationUrl) {
return false;
}
}
if (!canWrite(configDir)) {
if (!canWrite(configDir, getOS())) {
System.setProperty(PROP_EXITCODE, "15"); //$NON-NLS-1$
System.setProperty(PROP_EXITDATA, "<title>Invalid Configuration Location</title>The configuration area at '" + configDir + //$NON-NLS-1$
"' is not writable. Please choose a writable location using the '-configuration' command line option."); //$NON-NLS-1$
Expand Down Expand Up @@ -1273,19 +1303,24 @@ private String computeDefaultConfigurationLocation() {
// TODO a little dangerous here. Basically we have to assume that it is a file URL.
if (install.getProtocol().equals("file")) { //$NON-NLS-1$
File installDir = new File(install.getFile());
if (canWrite(installDir))
if (canWrite(installDir, getOS()))
return installDir.getAbsolutePath() + File.separator + CONFIG_DIR;
}
// We can't write in the eclipse install dir so try for some place in the user's home dir
return computeDefaultUserAreaLocation(CONFIG_DIR);
}

private static boolean canWrite(File installDir) {
private static boolean canWrite(File installDir, String os) {
if (!installDir.isDirectory())
return false;

if (Files.isWritable(installDir.toPath()))
if (Files.isWritable(installDir.toPath())) {
return true;
} else if (Constants.OS_ZOS.equals(os)) {
// For z/OS avoid doing the windows specific .dll check below.
// This causes additional alarms on z/OS for unauthorized attempts to write.
return false;
}

File fileTest = null;
try {
Expand Down Expand Up @@ -1320,7 +1355,7 @@ private String computeDefaultUserAreaLocation(String pathAppendage) {
File installDir = new File(installURL.getFile());
String installDirHash = getInstallDirHash();

if (protectBase && Constants.OS_MACOSX.equals(os)) {
if (protectBase && Constants.OS_MACOSX.equals(getOS())) {
initializeBridgeEarly();
String macConfiguration = computeConfigurationLocationForMacOS();
if (macConfiguration != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration.ConfigValues;
Expand Down Expand Up @@ -205,7 +206,8 @@ private BasicLocation buildLocation(String property, URL defaultLocation, String
// put the instance area inside the workspace meta area.
if (location == null)
return new BasicLocation(property, defaultLocation,
userReadOnlySetting != null || !computeReadOnly ? readOnly : !canWrite(defaultLocation),
userReadOnlySetting != null || !computeReadOnly ? readOnly
: !canWrite(defaultLocation, getOS()),
dataAreaPrefix, equinoxConfig, container, debugLocations);
String trimmedLocation = location.trim();
if (trimmedLocation.equalsIgnoreCase(NONE))
Expand All @@ -232,7 +234,9 @@ private BasicLocation buildLocation(String property, URL defaultLocation, String
BasicLocation result = null;
if (url != null) {
result = new BasicLocation(property, null,
userReadOnlySetting != null || !computeReadOnly ? readOnly : !canWrite(url), dataAreaPrefix,
userReadOnlySetting != null || !computeReadOnly ? readOnly
: !canWrite(url, getOS()),
dataAreaPrefix,
equinoxConfig, container, debugLocations);
result.setURL(url, false);
}
Expand Down Expand Up @@ -289,20 +293,24 @@ private String computeDefaultConfigurationLocation() {
File defaultConfigDir = new File(installDir, CONFIG_DIR);
if (!defaultConfigDir.exists())
defaultConfigDir.mkdirs();
if (defaultConfigDir.exists() && StorageUtil.canWrite(defaultConfigDir))
if (defaultConfigDir.exists() && StorageUtil.canWrite(defaultConfigDir, getOS()))
return defaultConfigDir.getAbsolutePath();
}
// We can't write in the eclipse install dir so try for some place in the user's
// home dir
return computeDefaultUserAreaLocation(CONFIG_DIR);
}

private static boolean canWrite(URL location) {
private String getOS() {
return equinoxConfig.getConfiguration(EquinoxConfiguration.PROP_OSGI_OS);
}

private static boolean canWrite(URL location, String os) {
if (location != null && "file".equals(location.getProtocol())) { //$NON-NLS-1$
File locationDir = new File(location.getPath());
if (!locationDir.exists())
locationDir.mkdirs();
if (locationDir.exists() && StorageUtil.canWrite(locationDir))
if (locationDir.exists() && StorageUtil.canWrite(locationDir, os))
return true;
}
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

package org.eclipse.osgi.storage;

import static org.eclipse.osgi.service.environment.Constants.OS_ZOS;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
Expand All @@ -32,6 +34,7 @@
import java.util.Hashtable;
import java.util.Set;
import java.util.stream.Stream;

import org.eclipse.osgi.framework.internal.reliablefile.ReliableFile;
import org.eclipse.osgi.internal.debug.Debug;
import org.osgi.framework.BundleContext;
Expand Down Expand Up @@ -139,12 +142,18 @@ public static ServiceRegistration<?> register(String name, Object service, Bundl
return context.registerService(name, service, properties);
}

public static boolean canWrite(File installDir) {
if (!installDir.isDirectory())
public static boolean canWrite(File installDir, String os) {
if (!installDir.isDirectory()) {
return false;
}

if (Files.isWritable(installDir.toPath()))
if (Files.isWritable(installDir.toPath())) {
return true;
} else if (OS_ZOS.equals(os)) {
// For z/OS avoid doing the windows specific .dll check below.
// This causes additional alarms on z/OS for unauthorized attempts to write.
return false;
}

File fileTest = null;
try {
Expand All @@ -153,8 +162,8 @@ public static boolean canWrite(File installDir) {
// like "Program Files"
fileTest = ReliableFile.createTempFile("writableArea", ".dll", installDir); //$NON-NLS-1$ //$NON-NLS-2$
} catch (IOException e) {
// If an exception occured while trying to create the file, it means that it is
// not writtable
// If an exception occurred while trying to create the file, it means that it is
// not writable
return false;
} finally {
if (fileTest != null)
Expand Down

0 comments on commit 742429a

Please sign in to comment.