[Jython-checkins] jython: Restrict accessibility of compiled files (fixes #2044 again).

jeff.allen jython-checkins at python.org
Sun Jan 26 15:59:24 EST 2020


https://hg.python.org/jython/rev/7e917a237b7a
changeset:   8321:7e917a237b7a
user:        Jeff Allen <ja.py at farowl.co.uk>
date:        Sun Jan 26 15:03:50 2020 +0000
summary:
  Restrict accessibility of compiled files (fixes #2044 again).

CVE-2013-2027 points out that Jython may be run with umask 0, and then
files cached will be world-writable affecting later sessions. #2044
claimed this fixed by other work, but this change fixes the permissions
explicitly in the compiler and package manager.

files:
  NEWS                                                           |   1 +
  src/org/python/core/imp.java                                   |   4 +-
  src/org/python/core/packagecache/CachedJarsPackageManager.java |   4 +-
  src/org/python/core/util/FileUtil.java                         |  32 ++++++++++
  4 files changed, 38 insertions(+), 3 deletions(-)


diff --git a/NEWS b/NEWS
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,7 @@
 
 Jython 2.7.2b3
   Bugs fixed
+    - [ 2044 ] CVE-2013-2027 Current umask sets privileges of class files and cache
     - [ 2834 ] Import of Java classes is not thread safe
     - [ 2820 ] Import fails with UnicodeDecodeError if sys.path contains invalid UTF-8 bytes
     - [ 2826 ] Unicode hex string decode failure
diff --git a/src/org/python/core/imp.java b/src/org/python/core/imp.java
--- a/src/org/python/core/imp.java
+++ b/src/org/python/core/imp.java
@@ -480,12 +480,12 @@
             if (man != null) {
                 man.checkWrite(compiledFilename);
             }
-            fop = new FileOutputStream(compiledFilename);
+            fop = new FileOutputStream(FileUtil.makePrivateRW(compiledFilename));
             fop.write(compiledSource);
             fop.close();
             return compiledFilename;
         } catch (IOException | SecurityException exc) {
-            // If we can't write the cache file, just logger and continue
+            // If we can't write the cache file, just log and continue
             logger.log(Level.FINE, "Unable to write to source cache file ''{0}'' due to {1}",
                     new Object[] {compiledFilename, exc});
             return null;
diff --git a/src/org/python/core/packagecache/CachedJarsPackageManager.java b/src/org/python/core/packagecache/CachedJarsPackageManager.java
--- a/src/org/python/core/packagecache/CachedJarsPackageManager.java
+++ b/src/org/python/core/packagecache/CachedJarsPackageManager.java
@@ -5,6 +5,7 @@
 
 import org.python.core.Options;
 import org.python.core.PyJavaPackage;
+import org.python.core.util.FileUtil;
 import org.python.util.Generic;
 
 import java.io.BufferedInputStream;
@@ -773,7 +774,7 @@
      * overridden.
      */
     protected DataOutputStream outOpenIndex() throws IOException {
-        File indexFile = new File(this.cachedir, "packages.idx");
+        File indexFile = FileUtil.makePrivateRW(new File(this.cachedir, "packages.idx"));
         FileOutputStream ostream = new FileOutputStream(indexFile);
         return new DataOutputStream(new BufferedOutputStream(ostream));
     }
@@ -821,6 +822,7 @@
                 // That name is in use: make up another one.
                 file = new File(this.cachedir, jarname + "$" + index + ".pkc");
             }
+            file = FileUtil.makePrivateRW(file);
             entry.cachefile = file.getCanonicalPath();
 
         } else {
diff --git a/src/org/python/core/util/FileUtil.java b/src/org/python/core/util/FileUtil.java
--- a/src/org/python/core/util/FileUtil.java
+++ b/src/org/python/core/util/FileUtil.java
@@ -2,6 +2,7 @@
 package org.python.core.util;
 
 import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -90,4 +91,35 @@
         }
         return out.toByteArray();
     }
+
+    /**
+     * Create the named file (if necessary) and give just the owner read-write access.
+     *
+     * @param filename to create/control
+     * @return {@code File} object for subsequent open
+     * @throws IOException
+     */
+    public static File makePrivateRW(String filename) throws IOException {
+        return makePrivateRW(new File(filename));
+    }
+
+    /**
+     * Create the identified file (if necessary) and give just the owner read-write access.
+     *
+     * @param file to create/control
+     * @return {@code File} object for subsequent open
+     * @throws IOException
+     */
+    public static File makePrivateRW(File file) throws IOException {
+        file.createNewFile();
+        // Remove permissions for all
+        file.setReadable(false, false);
+        file.setWritable(false, false);
+        file.setExecutable(false, false);
+        // Add permissions for owner
+        file.setReadable(true);
+        file.setWritable(true);
+        return file;
+    }
+
 }

-- 
Repository URL: https://hg.python.org/jython


More information about the Jython-checkins mailing list