changeset 1692:2c854193cc9d

Add latest security patches 2009-11-03 Martin Matejovic <mmatejov@redhat.com> * patches/security/icedtea-6862968.patch * patches/security/icedtea-6863503.patch * patches/security/icedtea-6864911.patch * patches/security/icedtea-6872357.patch * patches/security/icedtea-6874643.patch * Makefile.am: apply the above
author Martin Matejovic <mmatejov@redhat.com>
date Tue, 03 Nov 2009 17:50:20 +0100
parents 7c131a5e1ccf
children 15ba41d0ff2e
files ChangeLog Makefile.am patches/security/icedtea-6862968.patch patches/security/icedtea-6863503.patch patches/security/icedtea-6864911.patch patches/security/icedtea-6872357.patch patches/security/icedtea-6874643.patch
diffstat 7 files changed, 561 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Sep 14 17:40:46 2009 +0100
+++ b/ChangeLog	Tue Nov 03 17:50:20 2009 +0100
@@ -1,3 +1,11 @@
+2009-11-03 Martin Matejovic <mmatejov@redhat.com>
+	* patches/security/icedtea-6862968.patch
+	* patches/security/icedtea-6863503.patch
+	* patches/security/icedtea-6864911.patch
+	* patches/security/icedtea-6872357.patch
+	* patches/security/icedtea-6874643.patch
+	* Makefile.am: apply the above
+
 2009-09-14  Andrew Haley  <aph@redhat.com>
 
 	* NEWS: Update.
--- a/Makefile.am	Mon Sep 14 17:40:46 2009 +0100
+++ b/Makefile.am	Tue Nov 03 17:50:20 2009 +0100
@@ -626,6 +626,11 @@
 	patches/security/icedtea-6830335.patch \
 	patches/security/icedtea-6845701.patch \
 	patches/security/icedtea-6813167.patch \
+	patches/security/icedtea-6862968.patch \
+	patches/security/icedtea-6863503.patch \
+	patches/security/icedtea-6864911.patch \
+	patches/security/icedtea-6872357.patch \
+	patches/security/icedtea-6874643.patch \
 	patches/icedtea-jar-misc.patch
 
 if WITH_ALT_HSBUILD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/icedtea-6862968.patch	Tue Nov 03 17:50:20 2009 +0100
@@ -0,0 +1,60 @@
+--- old/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	2009-07-29 13:28:11.272200000 +0400
++++ openjdk/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	2009-07-29 13:28:10.710600000 +0400
+@@ -685,6 +685,10 @@
+ #ifdef DEBUG
+     printf("in setQTables, qlen = %d, write is %d\n", qlen, write);
+ #endif
++    if (qlen > NUM_QUANT_TBLS) {
++        /* Ignore extra qunterization tables. */
++        qlen = NUM_QUANT_TBLS;
++    }
+     for (i = 0; i < qlen; i++) {
+         table = (*env)->GetObjectArrayElement(env, qtables, i);
+         qdata = (*env)->GetObjectField(env, table, JPEGQTable_tableID);
+@@ -736,6 +740,11 @@
+     hlensBody = (*env)->GetShortArrayElements(env,
+                                               huffLens,
+                                               NULL);
++    if (hlensLen > 16) {
++        /* Ignore extra elements of bits array. Only 16 elements can be
++           stored. 0-th element is not used. (see jpeglib.h, line 107)  */
++        hlensLen = 16;
++    }
+     for (i = 1; i <= hlensLen; i++) {
+         huff_ptr->bits[i] = (UINT8)hlensBody[i-1];
+     }
+@@ -752,6 +761,11 @@
+                                               huffValues,
+                                               NULL);
+ 
++    if (hvalsLen > 256) {
++        /* Ignore extra elements of hufval array. Only 256 elements
++           can be stored. (see jpeglib.h, line 109)                  */
++        hlensLen = 256;
++    }
+     for (i = 0; i < hvalsLen; i++) {
+         huff_ptr->huffval[i] = (UINT8)hvalsBody[i];
+     }
+@@ -772,6 +786,11 @@
+     j_compress_ptr comp;
+     j_decompress_ptr decomp;
+     jsize hlen = (*env)->GetArrayLength(env, DCHuffmanTables);
++
++    if (hlen > NUM_HUFF_TBLS) {
++        /* Ignore extra DC huffman tables. */
++        hlen = NUM_HUFF_TBLS;
++    }
+     for (i = 0; i < hlen; i++) {
+         if (cinfo->is_decompressor) {
+             decomp = (j_decompress_ptr) cinfo;
+@@ -793,6 +812,10 @@
+         huff_ptr->sent_table = !write;
+     }
+     hlen = (*env)->GetArrayLength(env, ACHuffmanTables);
++    if (hlen > NUM_HUFF_TBLS) {
++        /* Ignore extra AC huffman tables. */
++        hlen = NUM_HUFF_TBLS;
++    }
+     for (i = 0; i < hlen; i++) {
+         if (cinfo->is_decompressor) {
+             decomp = (j_decompress_ptr) cinfo;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/icedtea-6863503.patch	Tue Nov 03 17:50:20 2009 +0100
@@ -0,0 +1,33 @@
+--- old/src/share/classes/java/security/MessageDigest.java	Thu Sep 24 22:22:15 2009
++++ openjdk/jdk/src/share/classes/java/security/MessageDigest.java	Thu Sep 24 22:22:15 2009
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 1996-2009 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
+@@ -414,16 +414,17 @@
+      *
+      * @return true if the digests are equal, false otherwise.
+      */
+-    public static boolean isEqual(byte digesta[], byte digestb[]) {
+-        if (digesta.length != digestb.length)
++    public static boolean isEqual(byte[] digesta, byte[] digestb) {
++        if (digesta.length != digestb.length) {
+             return false;
++        }
+ 
++        int result = 0;
++        // time-constant comparison
+         for (int i = 0; i < digesta.length; i++) {
+-            if (digesta[i] != digestb[i]) {
+-                return false;
+-            }
++            result |= digesta[i] ^ digestb[i];
+         }
+-        return true;
++        return result == 0;
+     }
+ 
+     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/icedtea-6864911.patch	Tue Nov 03 17:50:20 2009 +0100
@@ -0,0 +1,422 @@
+--- old/src/share/classes/com/sun/jndi/ldap/Connection.java	2009-08-18 09:35:56.595709900 +0800
++++ openjdk/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java	2009-08-18 09:35:56.087195700 +0800
+@@ -32,12 +32,8 @@
+ import java.io.OutputStream;
+ import java.io.InputStream;
+ import java.net.Socket;
+-import java.util.Vector;
+-import java.util.Hashtable;
+ 
+ import javax.naming.CommunicationException;
+-import javax.naming.AuthenticationException;
+-import javax.naming.AuthenticationNotSupportedException;
+ import javax.naming.ServiceUnavailableException;
+ import javax.naming.NamingException;
+ import javax.naming.InterruptedNamingException;
+@@ -47,6 +43,8 @@
+ import java.lang.reflect.Method;
+ import java.lang.reflect.Constructor;
+ import java.lang.reflect.InvocationTargetException;
++import java.util.Arrays;
++import sun.misc.IOUtils;
+ //import javax.net.SocketFactory;
+ 
+ /**
+@@ -799,7 +797,6 @@
+         byte inbuf[];   // Buffer for reading incoming bytes
+         int inMsgId;    // Message id of incoming response
+         int bytesread;  // Number of bytes in inbuf
+-        int bytesleft;  // Number of bytes that need to read for completing resp
+         int br;         // Temp; number of bytes read from stream
+         int offset;     // Offset of where to store bytes in inbuf
+         int seqlen;     // Length of ASN sequence
+@@ -811,7 +808,7 @@
+         try {
+             while (true) {
+                 try {
+-                    inbuf = new byte[2048];
++                    inbuf = new byte[10];
+ 
+                     offset = 0;
+                     seqlen = 0;
+@@ -871,19 +868,10 @@
+                     }
+ 
+                     // read in seqlen bytes
+-                    bytesleft = seqlen;
+-                    if ((offset + bytesleft) > inbuf.length) {
+-                        byte nbuf[] = new byte[offset + bytesleft];
+-                        System.arraycopy(inbuf, 0, nbuf, 0, offset);
+-                        inbuf = nbuf;
+-                    }
+-                    while (bytesleft > 0) {
+-                        bytesread = in.read(inbuf, offset, bytesleft);
+-                        if (bytesread < 0)
+-                            break; // EOF
+-                        offset += bytesread;
+-                        bytesleft -= bytesread;
+-                    }
++                    byte[] left = IOUtils.readFully(in, seqlen, false);
++                    inbuf = Arrays.copyOf(inbuf, offset + left.length);
++                    System.arraycopy(left, 0, inbuf, offset, left.length);
++                    offset += left.length;
+ /*
+ if (dump > 0) {
+ System.err.println("seqlen: " + seqlen);
+--- old/src/share/classes/sun/applet/AppletClassLoader.java	2009-08-18 09:36:00.901075900 +0800
++++ openjdk/jdk/src/share/classes/sun/applet/AppletClassLoader.java	2009-08-18 09:35:59.999916100 +0800
+@@ -51,6 +51,7 @@
+ import java.security.PermissionCollection;
+ import sun.awt.AppContext;
+ import sun.awt.SunToolkit;
++import sun.misc.IOUtils;
+ import sun.net.www.ParseUtil;
+ import sun.security.util.SecurityConstants;
+ 
+@@ -314,36 +315,7 @@
+ 
+         byte[] b;
+         try {
+-            if (len != -1) {
+-                // Read exactly len bytes from the input stream
+-                b = new byte[len];
+-                while (len > 0) {
+-                    int n = in.read(b, b.length - len, len);
+-                    if (n == -1) {
+-                        throw new IOException("unexpected EOF");
+-                    }
+-                    len -= n;
+-                }
+-            } else {
+-                // Read until end of stream is reached - use 8K buffer
+-                // to speed up performance [stanleyh]
+-                b = new byte[8192];
+-                int total = 0;
+-                while ((len = in.read(b, total, b.length - total)) != -1) {
+-                    total += len;
+-                    if (total >= b.length) {
+-                        byte[] tmp = new byte[total * 2];
+-                        System.arraycopy(b, 0, tmp, 0, total);
+-                        b = tmp;
+-                    }
+-                }
+-                // Trim array to correct size, if necessary
+-                if (total != b.length) {
+-                    byte[] tmp = new byte[total];
+-                    System.arraycopy(b, 0, tmp, 0, total);
+-                    b = tmp;
+-                }
+-            }
++            b = IOUtils.readFully(in, len, true);
+         } finally {
+             in.close();
+         }
+--- old/src/share/classes/sun/misc/Resource.java	2009-08-18 09:36:03.965921700 +0800
++++ openjdk/jdk/src/share/classes/sun/misc/Resource.java	2009-08-18 09:36:03.449689900 +0800
+@@ -25,14 +25,15 @@
+ 
+ package sun.misc;
+ 
++import java.io.EOFException;
+ import java.net.URL;
+ import java.io.IOException;
+ import java.io.InterruptedIOException;
+ import java.io.InputStream;
+ import java.security.CodeSigner;
+ import java.util.jar.Manifest;
+-import java.util.jar.Attributes;
+ import java.nio.ByteBuffer;
++import java.util.Arrays;
+ import sun.nio.ByteBuffered;
+ 
+ /**
+@@ -105,49 +106,37 @@
+         }
+ 
+         try {
+-            if (len != -1) {
+-                // Read exactly len bytes from the input stream
+-                b = new byte[len];
+-                while (len > 0) {
+-                    int n = 0;
+-                    try {
+-                        n = in.read(b, b.length - len, len);
+-                    } catch (InterruptedIOException iioe) {
+-                        Thread.interrupted();
+-                        isInterrupted = true;
++            b = new byte[0];
++            if (len == -1) len = Integer.MAX_VALUE;
++            int pos = 0;
++            while (pos < len) {
++                int bytesToRead;
++                if (pos >= b.length) { // Only expand when there's no room
++                    bytesToRead = Math.min(len - pos, b.length + 1024);
++                    if (b.length < pos + bytesToRead) {
++                        b = Arrays.copyOf(b, pos + bytesToRead);
+                     }
+-                    if (n == -1) {
+-                        throw new IOException("unexpected EOF");
+-                    }
+-                    len -= n;
++                } else {
++                    bytesToRead = b.length - pos;
+                 }
+-            } else {
+-                // Read until end of stream is reached
+-                b = new byte[1024];
+-                int total = 0;
+-                for (;;) {
+-                    len = 0;
+-                    try {
+-                        len = in.read(b, total, b.length - total);
+-                        if (len == -1)
+-                            break;
+-                    } catch (InterruptedIOException iioe) {
+-                        Thread.interrupted();
+-                        isInterrupted = true;
+-                    }
+-                    total += len;
+-                    if (total >= b.length) {
+-                        byte[] tmp = new byte[total * 2];
+-                        System.arraycopy(b, 0, tmp, 0, total);
+-                        b = tmp;
+-                    }
++                int cc = 0;
++                try {
++                    cc = in.read(b, pos, bytesToRead);
++                } catch (InterruptedIOException iioe) {
++                    Thread.interrupted();
++                    isInterrupted = true;
+                 }
+-                // Trim array to correct size, if necessary
+-                if (total != b.length) {
+-                    byte[] tmp = new byte[total];
+-                    System.arraycopy(b, 0, tmp, 0, total);
+-                    b = tmp;
++                if (cc < 0) {
++                    if (len != Integer.MAX_VALUE) {
++                        throw new EOFException("Detect premature EOF");
++                    } else {
++                        if (b.length != pos) {
++                            b = Arrays.copyOf(b, pos);
++                        }
++                        break;
++                    }
+                 }
++                pos += cc;
+             }
+         } finally {
+             try {
+--- old/src/share/classes/sun/reflect/misc/MethodUtil.java	2009-08-18 09:36:07.067128400 +0800
++++ openjdk/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java	2009-08-18 09:36:06.464179700 +0800
+@@ -44,6 +44,7 @@
+ import java.util.Collection;
+ import java.util.HashMap;
+ import java.util.Map;
++import sun.misc.IOUtils;
+ import sun.net.www.ParseUtil;
+ import sun.security.util.SecurityConstants;
+ 
+@@ -375,34 +376,7 @@
+ 
+         byte[] b;
+         try {
+-            if (len != -1) {
+-                // Read exactly len bytes from the input stream
+-                b = new byte[len];
+-                while (len > 0) {
+-                    int n = in.read(b, b.length - len, len);
+-                    if (n == -1) {
+-                        throw new IOException("unexpected EOF");
+-                    }
+-                    len -= n;
+-                }
+-            } else {
+-                b = new byte[8192];
+-                int total = 0;
+-                while ((len = in.read(b, total, b.length - total)) != -1) {
+-                    total += len;
+-                    if (total >= b.length) {
+-                        byte[] tmp = new byte[total * 2];
+-                        System.arraycopy(b, 0, tmp, 0, total);
+-                        b = tmp;
+-                    }
+-                }
+-                // Trim array to correct size, if necessary
+-                if (total != b.length) {
+-                    byte[] tmp = new byte[total];
+-                    System.arraycopy(b, 0, tmp, 0, total);
+-                    b = tmp;
+-                }
+-            }
++            b = IOUtils.readFully(in, len, true);
+         } finally {
+             in.close();
+         }
+--- old/src/share/classes/sun/security/provider/certpath/OCSPChecker.java	2009-08-18 09:36:10.684391400 +0800
++++ openjdk/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java	2009-08-18 09:36:10.088986300 +0800
+@@ -36,6 +36,7 @@
+ import java.net.*;
+ import javax.security.auth.x500.X500Principal;
+ 
++import sun.misc.IOUtils;
+ import sun.security.util.*;
+ import sun.security.x509.*;
+ 
+@@ -344,17 +345,7 @@
+             in = con.getInputStream();
+ 
+             int contentLength = con.getContentLength();
+-            if (contentLength == -1) {
+-                contentLength = Integer.MAX_VALUE;
+-            }
+-
+-            byte[] response = new byte[contentLength];
+-            int total = 0;
+-            int count = 0;
+-            while (count != -1 && total < contentLength) {
+-                count = in.read(response, total, response.length - total);
+-                total += count;
+-            }
++            byte[] response = IOUtils.readFully(in, contentLength, false);
+ 
+             OCSPResponse ocspResponse = new OCSPResponse(response, pkixParams,
+                 responderCert);
+--- old/src/share/classes/sun/security/timestamp/HttpTimestamper.java	2009-08-18 09:36:13.859436200 +0800
++++ openjdk/jdk/src/share/classes/sun/security/timestamp/HttpTimestamper.java	2009-08-18 09:36:13.165978900 +0800
+@@ -33,6 +33,7 @@
+ import java.util.Iterator;
+ import java.util.Set;
+ 
++import sun.misc.IOUtils;
+ import sun.security.pkcs.*;
+ 
+ /**
+@@ -138,19 +139,9 @@
+                 System.out.println();
+             }
+             int contentLength = connection.getContentLength();
+-            if (contentLength == -1) {
+-                contentLength = Integer.MAX_VALUE;
+-            }
+             verifyMimeType(connection.getContentType());
++            replyBuffer = IOUtils.readFully(input, contentLength, false);
+ 
+-            replyBuffer = new byte[contentLength];
+-            int total = 0;
+-            int count = 0;
+-            while (count != -1 && total < contentLength) {
+-                count = input.read(replyBuffer, total,
+-                                        replyBuffer.length - total);
+-                total += count;
+-            }
+             if (DEBUG) {
+                 System.out.println("received timestamp response (length=" +
+                         replyBuffer.length + ")");
+--- old/src/share/classes/sun/security/util/DerValue.java	2009-08-18 09:36:18.392602400 +0800
++++ openjdk/jdk/src/share/classes/sun/security/util/DerValue.java	2009-08-18 09:36:17.617711400 +0800
+@@ -28,6 +28,7 @@
+ import java.io.*;
+ import java.math.BigInteger;
+ import java.util.Date;
++import sun.misc.IOUtils;
+ 
+ /**
+  * Represents a single DER-encoded value.  DER encoding rules are a subset
+@@ -384,12 +385,8 @@
+         if (fullyBuffered && in.available() != length)
+             throw new IOException("extra data given to DerValue constructor");
+ 
+-        byte[] bytes = new byte[length];
++        byte[] bytes = IOUtils.readFully(in, length, true);
+ 
+-        // n.b. readFully not needed in normal fullyBuffered case
+-        DataInputStream dis = new DataInputStream(in);
+-
+-        dis.readFully(bytes);
+         buffer = new DerInputBuffer(bytes);
+         return new DerInputStream(buffer);
+     }
+--- /dev/null	2009-07-23 00:25:50.000000000 +0800
++++ openjdk/jdk/src/share/classes/sun/misc/IOUtils.java	2009-08-18 09:36:21.385422200 +0800
+@@ -0,0 +1,80 @@
++/*
++ * Copyright 2009 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.
++ */
++
++/**
++ * IOUtils: A collection of IO-related public static methods.
++ */
++
++package sun.misc;
++
++import java.io.EOFException;
++import java.io.IOException;
++import java.io.InputStream;
++import java.util.Arrays;
++
++public class IOUtils {
++
++    /**
++     * Read up to <code>length</code> of bytes from <code>in</code>
++     * until EOF is detected.
++     * @param in input stream, must not be null
++     * @param length number of bytes to read, -1 or Integer.MAX_VALUE means
++     *        read as much as possible
++     * @param readAll if true, an EOFException will be thrown if not enough
++     *        bytes are read. Ignored when length is -1 or Integer.MAX_VALUE
++     * @return bytes read
++     * @throws IOException Any IO error or a premature EOF is detected
++     */
++    public static byte[] readFully(InputStream is, int length, boolean readAll)
++            throws IOException {
++        byte[] output = {};
++        if (length == -1) length = Integer.MAX_VALUE;
++        int pos = 0;
++        while (pos < length) {
++            int bytesToRead;
++            if (pos >= output.length) { // Only expand when there's no room
++                bytesToRead = Math.min(length - pos, output.length + 1024);
++                if (output.length < pos + bytesToRead) {
++                    output = Arrays.copyOf(output, pos + bytesToRead);
++                }
++            } else {
++                bytesToRead = output.length - pos;
++            }
++            int cc = is.read(output, pos, bytesToRead);
++            if (cc < 0) {
++                if (readAll && length != Integer.MAX_VALUE) {
++                    throw new EOFException("Detect premature EOF");
++                } else {
++                    if (output.length != pos) {
++                        output = Arrays.copyOf(output, pos);
++                    }
++                    break;
++                }
++            }
++            pos += cc;
++        }
++        return output;
++    }
++}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/icedtea-6872357.patch	Tue Nov 03 17:50:20 2009 +0100
@@ -0,0 +1,17 @@
+--- old/src/share/native/sun/awt/image/awt_ImageRep.c	Mon Sep  7 14:46:10 2009
++++ openjdk/jdk/src/share/native/sun/awt/image/awt_ImageRep.c	Mon Sep  7 14:46:09 2009
+@@ -266,6 +266,14 @@
+     jnewlut = (*env)->GetObjectField(env, jicm, g_ICMrgbID);
+     mapSize = (*env)->GetIntField(env, jicm, g_ICMmapSizeID);
+ 
++    if (numLut < 0 || numLut > 256 || mapSize < 0 || mapSize > 256) {
++        /* Ether old or new ICM has a palette that exceeds capacity 
++           of byte data type, so we have to convert the image data
++           to default representation.
++        */
++        return 0;
++    }
++
+     srcLUT = (unsigned int *) (*env)->GetPrimitiveArrayCritical(env, jlut,
+                                                                 NULL);
+     if (srcLUT == NULL) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/icedtea-6874643.patch	Tue Nov 03 17:50:20 2009 +0100
@@ -0,0 +1,16 @@
+--- old/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Mon Sep  7 13:25:13 2009
++++ openjdk/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Mon Sep  7 13:25:12 2009
+@@ -1837,6 +1837,13 @@
+         return JNI_FALSE;
+     }
+ 
++    if (stepX > cinfo->image_width) {
++        stepX = cinfo->image_width;
++    }
++    if (stepY > cinfo->image_height) {
++        stepY = cinfo->image_height;
++    }
++
+     /*
+      * First get the source bands array and copy it to our local array
+      * so we don't have to worry about pinning and unpinning it again.