changeset 10597:3dfe6ebbfc51

8060474: Resolve more parsing ambiguity Reviewed-by: mullan, ahgross
author weijun
date Thu, 16 Oct 2014 11:09:56 +0800
parents ca4865cc7bea
children e7caa9e7149d
files src/share/classes/sun/security/jgss/GSSHeader.java src/share/classes/sun/security/jgss/GSSNameImpl.java src/share/classes/sun/security/jgss/wrapper/GSSNameElement.java src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java src/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java src/share/classes/sun/security/krb5/internal/ktab/KeyTabInputStream.java src/share/classes/sun/security/krb5/internal/util/KrbDataInputStream.java
diffstat 7 files changed, 78 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/security/jgss/GSSHeader.java	Mon Oct 20 23:06:21 2014 -0700
+++ b/src/share/classes/sun/security/jgss/GSSHeader.java	Thu Oct 16 11:09:56 2014 +0800
@@ -270,6 +270,9 @@
                 value <<= 8;
                 value += 0x0ff & in.read();
             }
+            if (value < 0) {
+                throw new IOException("Invalid length bytes");
+            }
         }
         return value;
     }
--- a/src/share/classes/sun/security/jgss/GSSNameImpl.java	Mon Oct 20 23:06:21 2014 -0700
+++ b/src/share/classes/sun/security/jgss/GSSNameImpl.java	Thu Oct 16 11:09:56 2014 +0800
@@ -257,6 +257,10 @@
                               ((0xFF & bytes[pos++]) << 16) |
                               ((0xFF & bytes[pos++]) << 8) |
                               (0xFF & bytes[pos++]));
+        if (mechPortionLen < 0 || pos > bytes.length - mechPortionLen) {
+             throw new GSSExceptionImpl(GSSException.BAD_NAME,
+                     "Exported name mech name is corrupted!");
+         }
         byte[] mechPortion = new byte[mechPortionLen];
         System.arraycopy(bytes, pos, mechPortion, 0, mechPortionLen);
 
--- a/src/share/classes/sun/security/jgss/wrapper/GSSNameElement.java	Mon Oct 20 23:06:21 2014 -0700
+++ b/src/share/classes/sun/security/jgss/wrapper/GSSNameElement.java	Thu Oct 16 11:09:56 2014 +0800
@@ -233,6 +233,9 @@
                               ((0xFF & nameVal[pos++]) << 16) |
                               ((0xFF & nameVal[pos++]) << 8) |
                               (0xFF & nameVal[pos++]));
+        if (mechPortionLen < 0) {
+            throw new GSSException(GSSException.BAD_NAME);
+        }
         byte[] mechPortion = new byte[mechPortionLen];
         System.arraycopy(nameVal, pos, mechPortion, 0, mechPortionLen);
         return mechPortion;
--- a/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java	Mon Oct 20 23:06:21 2014 -0700
+++ b/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java	Thu Oct 16 11:09:56 2014 +0800
@@ -122,7 +122,7 @@
         } else {
             type = read(4);
         }
-        length = read(4);
+        length = readLength4();
         String[] result = new String[length + 1];
         /*
          * DCE includes the principal's realm in the count; the new format
@@ -131,7 +131,7 @@
         if (version == KRB5_FCC_FVNO_1)
             length--;
         for (int i = 0; i <= length; i++) {
-            namelength = read(4);
+            namelength = readLength4();
             if (namelength > MAXNAMELENGTH) {
                 throw new IOException("Invalid name length in principal name.");
             }
@@ -183,7 +183,7 @@
         keyType = read(2);
         if (version == KRB5_FCC_FVNO_3)
             read(2); /* keytype recorded twice in fvno 3 */
-        keyLen = read(4);
+        keyLen = readLength4();
         byte[] bytes = new byte[keyLen];
         for (int i = 0; i < keyLen; i++) {
             bytes[i] = (byte)read();
@@ -209,12 +209,12 @@
 
     HostAddress[] readAddr() throws IOException, KrbApErrException {
         int numAddrs, addrType, addrLength;
-        numAddrs = read(4);
+        numAddrs = readLength4();
         if (numAddrs > 0) {
             HostAddress[] addrs = new HostAddress[numAddrs];
             for (int i = 0; i < numAddrs; i++) {
                 addrType = read(2);
-                addrLength = read(4);
+                addrLength = readLength4();
                 if (!(addrLength == 4 || addrLength == 16)) {
                     if (DEBUG) {
                         System.out.println("Incorrect address format.");
@@ -233,13 +233,13 @@
 
     AuthorizationDataEntry[] readAuth() throws IOException {
         int num, adtype, adlength;
-        num = read(4);
+        num = readLength4();
         if (num > 0) {
             AuthorizationDataEntry[] auData = new AuthorizationDataEntry[num];
             byte[] data = null;
             for (int i = 0; i < num; i++) {
                 adtype = read(2);
-                adlength = read(4);
+                adlength = readLength4();
                 data = new byte[adlength];
                 for (int j = 0; j < adlength; j++) {
                     data[j] = (byte)read();
@@ -253,7 +253,7 @@
 
     byte[] readData() throws IOException {
         int length;
-        length = read(4);
+        length = readLength4();
         if (length == 0) {
             return null;
         } else {
--- a/src/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java	Mon Oct 20 23:06:21 2014 -0700
+++ b/src/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java	Thu Oct 16 11:09:56 2014 +0800
@@ -151,43 +151,43 @@
     synchronized void init(PrincipalName principal, String name)
         throws IOException, KrbException {
         primaryPrincipal = principal;
-        CCacheOutputStream cos =
-            new CCacheOutputStream(new FileOutputStream(name));
-        version = KRB5_FCC_FVNO_3;
-        cos.writeHeader(primaryPrincipal, version);
-        cos.close();
+        try (FileOutputStream fos = new FileOutputStream(name);
+             CCacheOutputStream cos = new CCacheOutputStream(fos)) {
+            version = KRB5_FCC_FVNO_3;
+            cos.writeHeader(primaryPrincipal, version);
+        }
         load(name);
     }
 
     synchronized void load(String name) throws IOException, KrbException {
         PrincipalName p;
-        CCacheInputStream cis =
-            new CCacheInputStream(new FileInputStream(name));
-        version = cis.readVersion();
-        if (version == KRB5_FCC_FVNO_4) {
-            tag = cis.readTag();
-        } else {
-            tag = null;
-            if (version == KRB5_FCC_FVNO_1 || version == KRB5_FCC_FVNO_2) {
-                cis.setNativeByteOrder();
+        try (FileInputStream fis = new FileInputStream(name);
+             CCacheInputStream cis = new CCacheInputStream(fis)) {
+            version = cis.readVersion();
+            if (version == KRB5_FCC_FVNO_4) {
+                tag = cis.readTag();
+            } else {
+                tag = null;
+                if (version == KRB5_FCC_FVNO_1 || version == KRB5_FCC_FVNO_2) {
+                    cis.setNativeByteOrder();
+                }
+            }
+            p = cis.readPrincipal(version);
+
+            if (primaryPrincipal != null) {
+                if (!(primaryPrincipal.match(p))) {
+                    throw new IOException("Primary principals don't match.");
+                }
+            } else
+                primaryPrincipal = p;
+            credentialsList = new Vector<Credentials>();
+            while (cis.available() > 0) {
+                Credentials cred = cis.readCred(version);
+                if (cred != null) {
+                    credentialsList.addElement(cred);
+                }
             }
         }
-        p = cis.readPrincipal(version);
-
-        if (primaryPrincipal != null) {
-            if (!(primaryPrincipal.match(p))) {
-                throw new IOException("Primary principals don't match.");
-            }
-        } else
-            primaryPrincipal = p;
-        credentialsList = new Vector<Credentials> ();
-        while (cis.available() > 0) {
-            Credentials cred = cis.readCred(version);
-            if (cred != null) {
-                credentialsList.addElement(cred);
-            }
-        }
-        cis.close();
     }
 
 
@@ -246,16 +246,16 @@
      * Saves the credentials cache file to the disk.
      */
     public synchronized void save() throws IOException, Asn1Exception {
-        CCacheOutputStream cos
-            = new CCacheOutputStream(new FileOutputStream(cacheName));
-        cos.writeHeader(primaryPrincipal, version);
-        Credentials[] tmp = null;
-        if ((tmp = getCredsList()) != null) {
-            for (int i = 0; i < tmp.length; i++) {
-                cos.addCreds(tmp[i]);
+        try (FileOutputStream fos = new FileOutputStream(cacheName);
+             CCacheOutputStream cos = new CCacheOutputStream(fos)) {
+            cos.writeHeader(primaryPrincipal, version);
+            Credentials[] tmp = null;
+            if ((tmp = getCredsList()) != null) {
+                for (int i = 0; i < tmp.length; i++) {
+                    cos.addCreds(tmp[i]);
+                }
             }
         }
-        cos.close();
     }
 
     boolean match(String[] s1, String[] s2) {
--- a/src/share/classes/sun/security/krb5/internal/ktab/KeyTabInputStream.java	Mon Oct 20 23:06:21 2014 -0700
+++ b/src/share/classes/sun/security/krb5/internal/ktab/KeyTabInputStream.java	Thu Oct 16 11:09:56 2014 +0800
@@ -58,7 +58,7 @@
      * Reads the number of bytes this entry data occupy.
      */
     int readEntryLength() throws IOException {
-        return read(4);
+        return readLength4();
     }
 
 
--- a/src/share/classes/sun/security/krb5/internal/util/KrbDataInputStream.java	Mon Oct 20 23:06:21 2014 -0700
+++ b/src/share/classes/sun/security/krb5/internal/util/KrbDataInputStream.java	Thu Oct 16 11:09:56 2014 +0800
@@ -56,15 +56,33 @@
     public KrbDataInputStream(InputStream is){
         super(is);
     }
+
+    /**
+     * Reads a length value which is represented in 4 bytes from
+     * this input stream. The value must be positive.
+     * @return the length value represented by this byte array.
+     * @throws IOException if there are not enough bytes or it represents
+     * a negative value
+     */
+    final public int readLength4() throws IOException {
+        int len = read(4);
+        if (len < 0) {
+            throw new IOException("Invalid encoding");
+        }
+        return len;
+    }
+
     /**
      * Reads up to the specific number of bytes from this input stream.
      * @param num the number of bytes to be read.
      * @return the int value of this byte array.
-     * @exception IOException.
+     * @throws IOException if there are not enough bytes
      */
-    public int read(int num) throws IOException{
+    public int read(int num) throws IOException {
         byte[] bytes = new byte[num];
-        read(bytes, 0, num);
+        if (read(bytes, 0, num) != num) {
+            throw new IOException("Premature end of stream reached");
+        };
         int result = 0;
         for (int i = 0; i < num; i++) {
             if (bigEndian) {