Mercurial > hg > release > icedtea-1.9
view patches/security/icedtea-6632886.patch @ 1768:3a122c249dda
Port latest security fixes from IcedTea6.
2009-04-06 Andrew John Hughes <ahughes@redhat.com>
* Makefile.am:
Add new patches.
* patches/security/icedtea-6536193.patch,
* patches/security/icedtea-6610888.patch,
* patches/security/icedtea-6610896.patch,
* patches/security/icedtea-6630639.patch,
* patches/security/icedtea-6632886.patch,
* patches/security/icedtea-6636360.patch,
* patches/security/icedtea-6652463.patch,
* patches/security/icedtea-6656633.patch,
* patches/security/icedtea-6658158.patch,
* patches/security/icedtea-6691246.patch,
* patches/security/icedtea-6717680.patch,
* patches/security/icedtea-6721651.patch,
* patches/security/icedtea-6737315.patch,
* patches/security/icedtea-6792554.patch,
* patches/security/icedtea-6804996.patch,
* patches/security/icedtea-6804997.patch,
* patches/security/icedtea-6804998.patch:
Security patches ported from IcedTea6.
author | Andrew John Hughes <ahughes@redhat.com> |
---|---|
date | Tue, 07 Apr 2009 01:02:17 +0100 |
parents | |
children |
line wrap: on
line source
diff -Nru openjdk.orig/jdk/src/share/classes/java/awt/Font.java openjdk/jdk/src/share/classes/java/awt/Font.java --- openjdk.orig/jdk/src/share/classes/java/awt/Font.java 2009-04-06 17:20:02.000000000 +0100 +++ openjdk/jdk/src/share/classes/java/awt/Font.java 2009-04-06 17:24:48.000000000 +0100 @@ -37,6 +37,8 @@ import java.awt.peer.FontPeer; import java.io.*; import java.lang.ref.SoftReference; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; import java.text.AttributedCharacterIterator.Attribute; import java.text.CharacterIterator; import java.text.StringCharacterIterator; @@ -51,6 +53,7 @@ import sun.font.AttributeValues; import sun.font.EAttribute; import sun.font.CompositeFont; +import sun.font.CreatedFontTracker; import sun.font.Font2D; import sun.font.Font2DHandle; import sun.font.FontManager; @@ -575,14 +578,16 @@ } /* used to implement Font.createFont */ - private Font(File fontFile, int fontFormat, boolean isCopy) + private Font(File fontFile, int fontFormat, + boolean isCopy, CreatedFontTracker tracker) throws FontFormatException { this.createdFont = true; /* Font2D instances created by this method track their font file * so that when the Font2D is GC'd it can also remove the file. */ this.font2DHandle = - FontManager.createFont2D(fontFile, fontFormat, isCopy).handle; + FontManager.createFont2D(fontFile, fontFormat, + isCopy, tracker).handle; this.name = this.font2DHandle.font2D.getFontName(Locale.getDefault()); this.style = Font.PLAIN; this.size = 1; @@ -788,6 +793,29 @@ } /** + * Used with the byte count tracker for fonts created from streams. + * If a thread can create temp files anyway, no point in counting + * font bytes. + */ + private static boolean hasTempPermission() { + + if (System.getSecurityManager() == null) { + return true; + } + File f = null; + boolean hasPerm = false; + try { + f = File.createTempFile("+~JT", ".tmp", null); + f.delete(); + f = null; + hasPerm = true; + } catch (Throwable t) { + /* inc. any kind of SecurityException */ + } + return hasPerm; + } + + /** * Returns a new <code>Font</code> using the specified font type * and input data. The new <code>Font</code> is * created with a point size of 1 and style {@link #PLAIN PLAIN}. @@ -822,58 +850,96 @@ fontFormat != Font.TYPE1_FONT) { throw new IllegalArgumentException ("font format not recognized"); } - final InputStream fStream = fontStream; - Object ret = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - File tFile = null; - FileOutputStream outStream = null; - try { - tFile = File.createTempFile("+~JF", ".tmp", null); - /* Temp file deleted by font shutdown hook */ - BufferedInputStream inStream = - new BufferedInputStream(fStream); - outStream = new FileOutputStream(tFile); - int bytesRead = 0; - int bufSize = 8192; - byte [] buf = new byte[bufSize]; - while (bytesRead != -1) { - try { - bytesRead = inStream.read(buf, 0, bufSize); - } catch (Throwable t) { - throw new IOException(); - } - if (bytesRead != -1) { - outStream.write(buf, 0, bytesRead); - } - } - /* don't close the input stream */ - outStream.close(); - } catch (IOException e) { - if (outStream != null) { - try { - outStream.close(); - } catch (Exception e1) { - } - } - if (tFile != null) { - try { - tFile.delete(); - } catch (Exception e2) { - } - } - return e; - } - return tFile; - } - }); - - if (ret instanceof File) { - return new Font((File)ret, fontFormat, true); - } else if (ret instanceof IOException) { - throw (IOException)ret; - } else { - throw new FontFormatException("Couldn't access font stream"); + boolean copiedFontData = false; + + try { + final File tFile = AccessController.doPrivileged( + new PrivilegedExceptionAction<File>() { + public File run() throws IOException { + return File.createTempFile("+~JF", ".tmp", null); + } + } + ); + + int totalSize = 0; + CreatedFontTracker tracker = null; + try { + final OutputStream outStream = + AccessController.doPrivileged( + new PrivilegedExceptionAction<OutputStream>() { + public OutputStream run() throws IOException { + return new FileOutputStream(tFile); + } + } + ); + if (!hasTempPermission()) { + tracker = CreatedFontTracker.getTracker(); + } + try { + byte[] buf = new byte[8192]; + for (;;) { + int bytesRead = fontStream.read(buf); + if (bytesRead < 0) { + break; + } + if (tracker != null) { + if (totalSize+bytesRead > tracker.MAX_FILE_SIZE) { + throw new IOException("File too big."); + } + if (totalSize+tracker.getNumBytes() > + tracker.MAX_TOTAL_BYTES) + { + throw new IOException("Total files too big."); + } + totalSize += bytesRead; + tracker.addBytes(bytesRead); + } + outStream.write(buf, 0, bytesRead); + } + /* don't close the input stream */ + } finally { + outStream.close(); + } + /* After all references to a Font2D are dropped, the file + * will be removed. To support long-lived AppContexts, + * we need to then decrement the byte count by the size + * of the file. + * If the data isn't a valid font, the implementation will + * delete the tmp file and decrement the byte count + * in the tracker object before returning from the + * constructor, so we can set 'copiedFontData' to true here + * without waiting for the results of that constructor. + */ + copiedFontData = true; + Font font = new Font(tFile, fontFormat, true, tracker); + return font; + } finally { + if (!copiedFontData) { + if (tracker != null) { + tracker.subBytes(totalSize); + } + AccessController.doPrivileged( + new PrivilegedExceptionAction<Void>() { + public Void run() { + tFile.delete(); + return null; + } + } + ); + } + } + } catch (Throwable t) { + if (t instanceof FontFormatException) { + throw (FontFormatException)t; + } + if (t instanceof IOException) { + throw (IOException)t; + } + Throwable cause = t.getCause(); + if (cause instanceof FontFormatException) { + throw (FontFormatException)cause; + } + throw new IOException("Problem reading font data."); } } @@ -913,6 +979,9 @@ */ public static Font createFont(int fontFormat, File fontFile) throws java.awt.FontFormatException, java.io.IOException { + + fontFile = new File(fontFile.getPath()); + if (fontFormat != Font.TRUETYPE_FONT && fontFormat != Font.TYPE1_FONT) { throw new IllegalArgumentException ("font format not recognized"); @@ -926,7 +995,7 @@ if (!fontFile.canRead()) { throw new IOException("Can't read " + fontFile); } - return new Font(fontFile, fontFormat, false); + return new Font(fontFile, fontFormat, false, null); } /** diff -Nru openjdk.orig/jdk/src/share/classes/sun/font/CreatedFontTracker.java openjdk/jdk/src/share/classes/sun/font/CreatedFontTracker.java --- openjdk.orig/jdk/src/share/classes/sun/font/CreatedFontTracker.java 1970-01-01 01:00:00.000000000 +0100 +++ openjdk/jdk/src/share/classes/sun/font/CreatedFontTracker.java 2009-04-06 17:24:48.000000000 +0100 @@ -0,0 +1,54 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.font; + +public class CreatedFontTracker { + + public static final int MAX_FILE_SIZE = 32 * 1024 * 1024; + public static final int MAX_TOTAL_BYTES = 10 * MAX_FILE_SIZE; + + static int numBytes; + static CreatedFontTracker tracker; + + public static synchronized CreatedFontTracker getTracker() { + if (tracker == null) { + tracker = new CreatedFontTracker(); + } + return tracker; + } + + public synchronized int getNumBytes() { + return numBytes; + } + + public synchronized void addBytes(int sz) { + numBytes += sz; + } + + public synchronized void subBytes(int sz) { + numBytes -= sz; + } +} diff -Nru openjdk.orig/jdk/src/share/classes/sun/font/FileFont.java openjdk/jdk/src/share/classes/sun/font/FileFont.java --- openjdk.orig/jdk/src/share/classes/sun/font/FileFont.java 2009-04-06 17:19:53.000000000 +0100 +++ openjdk/jdk/src/share/classes/sun/font/FileFont.java 2009-04-06 17:24:48.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -125,9 +125,9 @@ return true; } - void setFileToRemove(File file) { + void setFileToRemove(File file, CreatedFontTracker tracker) { Disposer.addObjectRecord(this, - new CreatedFontFileDisposerRecord(file)); + new CreatedFontFileDisposerRecord(file, tracker)); } /* This is called when a font scaler is determined to @@ -246,12 +246,16 @@ return getScaler().getUnitsPerEm(); } - private static class CreatedFontFileDisposerRecord implements DisposerRecord { + private static class CreatedFontFileDisposerRecord + implements DisposerRecord { File fontFile = null; + CreatedFontTracker tracker; - private CreatedFontFileDisposerRecord(File file) { + private CreatedFontFileDisposerRecord(File file, + CreatedFontTracker tracker) { fontFile = file; + this.tracker = tracker; } public void dispose() { @@ -260,6 +264,9 @@ public Object run() { if (fontFile != null) { try { + if (tracker != null) { + tracker.subBytes((int)fontFile.length()); + } /* REMIND: is it possible that the file is * still open? It will be closed when the * font2D is disposed but could this code diff -Nru openjdk.orig/jdk/src/share/classes/sun/font/TrueTypeFont.java openjdk/jdk/src/share/classes/sun/font/TrueTypeFont.java --- openjdk.orig/jdk/src/share/classes/sun/font/TrueTypeFont.java 2009-04-06 17:19:53.000000000 +0100 +++ openjdk/jdk/src/share/classes/sun/font/TrueTypeFont.java 2009-04-06 17:24:48.000000000 +0100 @@ -175,8 +175,17 @@ super(platname, nativeNames); useJavaRasterizer = javaRasterizer; fontRank = Font2D.TTF_RANK; - verify(); - init(fIndex); + try { + verify(); + init(fIndex); + } catch (Throwable t) { + close(); + if (t instanceof FontFormatException) { + throw (FontFormatException)t; + } else { + throw new FontFormatException("Unexpected runtime exception."); + } + } Disposer.addObjectRecord(this, disposerRecord); } diff -Nru openjdk.orig/jdk/src/share/classes/sun/font/Type1Font.java openjdk/jdk/src/share/classes/sun/font/Type1Font.java --- openjdk.orig/jdk/src/share/classes/sun/font/Type1Font.java 2009-04-06 17:19:53.000000000 +0100 +++ openjdk/jdk/src/share/classes/sun/font/Type1Font.java 2009-04-06 17:24:48.000000000 +0100 @@ -39,6 +39,7 @@ import java.nio.channels.ClosedChannelException; import java.nio.channels.FileChannel; import sun.java2d.Disposer; +import sun.java2d.DisposerRecord; import java.util.HashSet; import java.util.HashMap; import java.awt.Font; @@ -76,6 +77,27 @@ */ public class Type1Font extends FileFont { + private static class T1DisposerRecord implements DisposerRecord { + String fileName = null; + + T1DisposerRecord(String name) { + fileName = name; + } + + public synchronized void dispose() { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Object run() { + + if (fileName != null) { + (new java.io.File(fileName)).delete(); + } + return null; + } + }); + } + } + WeakReference bufferRef = new WeakReference(null); private String psName = null; @@ -125,18 +147,42 @@ /** + * Constructs a Type1 Font. + * @param platname - Platform identifier of the font. Typically file name. + * @param nativeNames - Native names - typically XLFDs on Unix. + */ + public Type1Font(String platname, Object nativeNames) + throws FontFormatException { + + this(platname, nativeNames, false); + } + + /** * - does basic verification of the file * - reads the names (full, family). * - determines the style of the font. * @throws FontFormatException - if the font can't be opened * or fails verification, or there's no usable cmap */ - public Type1Font(String platname, Object nativeNames) + public Type1Font(String platname, Object nativeNames, boolean createdCopy) throws FontFormatException { super(platname, nativeNames); fontRank = Font2D.TYPE1_RANK; checkedNatives = true; - verify(); + try { + verify(); + } catch (Throwable t) { + if (createdCopy) { + T1DisposerRecord ref = new T1DisposerRecord(platname); + Disposer.addObjectRecord(bufferRef, ref); + bufferRef = null; + } + if (t instanceof FontFormatException) { + throw (FontFormatException)t; + } else { + throw new FontFormatException("Unexpected runtime exception."); + } + } } private synchronized ByteBuffer getBuffer() throws FontFormatException { --- openjdk.orig/jdk/src/share/classes/sun/font/FontManager.java 2009-04-06 21:46:26.000000000 +0100 +++ openjdk/jdk/src/share/classes/sun/font/FontManager.java 2009-04-06 21:48:08.000000000 +0100 @@ -2348,19 +2348,21 @@ static Vector<File> tmpFontFiles = null; public static Font2D createFont2D(File fontFile, int fontFormat, - boolean isCopy) + boolean isCopy, + CreatedFontTracker tracker) throws FontFormatException { String fontFilePath = fontFile.getPath(); FileFont font2D = null; final File fFile = fontFile; + final CreatedFontTracker _tracker = tracker; try { switch (fontFormat) { case Font.TRUETYPE_FONT: font2D = new TrueTypeFont(fontFilePath, null, 0, true); break; case Font.TYPE1_FONT: - font2D = new Type1Font(fontFilePath, null); + font2D = new Type1Font(fontFilePath, null, isCopy); break; default: throw new FontFormatException("Unrecognised Font Format"); @@ -2370,6 +2372,9 @@ java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { + if (_tracker != null) { + _tracker.subBytes((int)fFile.length()); + } fFile.delete(); return null; } @@ -2378,7 +2383,7 @@ throw(e); } if (isCopy) { - font2D.setFileToRemove(fontFile); + font2D.setFileToRemove(fontFile, tracker); synchronized (FontManager.class) { if (tmpFontFiles == null) {