jdk/test/java/io/Serializable/6559775/SerialRace.java
changeset 7034 a31042b569d0
parent 7031 d77ff2048ad5
child 7035 7c0095d515e3
equal deleted inserted replaced
7031:d77ff2048ad5 7034:a31042b569d0
     1 /*
       
     2  * @test %W% %E%
       
     3  * @bug 6559775
       
     4  * @summary  Race allows defaultReadObject to be invoked instead of readFields during deserialization
       
     5  * @run shell Test6559775.sh
       
     6 */
       
     7 
       
     8 import java.io.*;
       
     9 
       
    10 public class SerialRace {
       
    11     public static void main(String[] args) throws Exception {
       
    12         System.err.println(
       
    13             "Available processors: "+
       
    14             Runtime.getRuntime().availableProcessors()
       
    15         );
       
    16 
       
    17         final int perStream = 10000;
       
    18 
       
    19         // Construct attack data.
       
    20         ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
       
    21         {
       
    22             ObjectOutputStream out = new ObjectOutputStream(byteOut);
       
    23             char[] value = new char[] { '?' };
       
    24             out.writeObject(value);
       
    25             for (int i=0; i<perStream; ++i) {
       
    26                 SerialVictim orig = new SerialVictim(value);
       
    27                 out.writeObject(orig);
       
    28             }
       
    29             out.flush();
       
    30         }
       
    31         byte[] data = byteOut.toByteArray();
       
    32 
       
    33         ByteArrayInputStream byteIn = new ByteArrayInputStream(data);
       
    34         final ObjectInputStream in = new ObjectInputStream(byteIn);
       
    35         final char[] value = (char[])in.readObject();
       
    36         Thread thread = new Thread(new Runnable() { public void run() {
       
    37                     for (;;) {
       
    38                         try {
       
    39                             // Attempt to interlope on other thread.
       
    40                             in.defaultReadObject();
       
    41                             // Got it.
       
    42 
       
    43                             // Let other thread reach known state.
       
    44                             Thread.sleep(1000);
       
    45                             // This is the reference usually
       
    46                             //   read in extended data.
       
    47                             SerialVictim victim = (SerialVictim)
       
    48                                 in.readObject();
       
    49                             System.err.println("Victim: "+victim);
       
    50                             value[0] = '$';
       
    51                             System.err.println("Victim: "+victim);
       
    52                             return;
       
    53                         } catch (java.io.NotActiveException exc) {
       
    54                             // Not ready yet...
       
    55                         } catch (java.lang.InterruptedException exc) {
       
    56                             throw new Error(exc);
       
    57                         } catch (IOException exc) {
       
    58                             throw new Error(exc);
       
    59                         } catch (ClassNotFoundException exc) {
       
    60                             throw new Error(exc);
       
    61                         }
       
    62                     }
       
    63         }});
       
    64         thread.start();
       
    65         Thread.yield();
       
    66         // Normal reading from object stream.
       
    67         // We hope the other thread catches us out between
       
    68         //   setting up the call to SerialVictim.readObject and
       
    69         //   the AtomicBoolean acquisition in readFields.
       
    70         for (int i=0; i<perStream; ++i) {
       
    71             try {
       
    72                 SerialVictim victim = (SerialVictim)in.readObject();
       
    73             } catch (Exception exc) {
       
    74                 synchronized (System.err) {
       
    75                     System.err.println("Iteration "+i);
       
    76                     exc.printStackTrace();
       
    77                 }
       
    78                 // Allow atack thread to do it's business before close.
       
    79                 Thread.sleep(2000);
       
    80                 break;
       
    81             }
       
    82         }
       
    83         // Stop the other thread.
       
    84         in.close();
       
    85     }
       
    86 }