JDK-4271614 : Standard IO streams susceptible to D.o.S. by ANY code (intentional or not)
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 1.2.1
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic
  • CPU: generic
  • Submitted: 1999-09-14
  • Updated: 1999-09-22
  • Resolved: 1999-09-22
Related Reports
Relates :  
Description

Name: krT82822			Date: 09/14/99


9/14/99 eval1127@eng -- see also 4193548, 4143651, 4218002, etc.  FIling FYI bug.

package com.Inishgold;

import java.io.*;

/** Standard IO killer demonstration.<BR>
 * Standard IO streams are suspectable to DoS by ANY code (intentional or not).
 * This is a quite effective way to lose important information, esp. debugging
 * information, that could allow major bugs to go undetected.
 * This is a contrived example to demonstrate the problem with closing any of
 * Standard IO streams (stdin, stdout, stderr), as there is no easy way to
 * reopen them.  In my opinion, these streams should intercept the .close()
 * method and reassign it to something along the lines of .flush().
 * This problem is compounded by the fact that these streams are global, and
 * so can be closed anywhere, at anytime, with no prior warning, and no ability
 * to recover once done.  It could construe quite an effect Denial of Service
 * attack, if slotted into an often used library, or even if done inadvertently
 * by closing a stream that is not currently being used, expecting to be able
 * to reopen it when needed later (which is how I found out about the problem).
 * There might be a way to reopen the streams by replicating code found in the
 * java.lang.System and java.io.FileDescriptor classes, but I have yet to get
 * that approach to work.<BR>
 * <PRE>
 * Systems tested on:
 *
 * P120 32meg, Win95, JDK 1.2.1 & JBuilder2 (JDK 1.1.6_Borland)
 *
 * P166 64meg, Win95, JRE 1.2.1 & JBuilder3 (JDK 1.2)
 * java -version
 *  java version "1.2.1"
 *  HotSpot VM (1.0fcs, mixed mode, build E)
 * java -fullversion
 *  JAVA.EXE full version "JDK-1.2.1-A"
 *
 * </PRE>
 * <DL>
 * <DT><B>Date: </B><DD>13 September 1999</DD>
 * </DL>
 * @author    Daniel Hean
 * @version   1
 * @see       java.lang.System
 */
public class KillStdIO
 {
 public static void main(String[] args)
     {
     System.out.println("Testing stdout");
     System.err.println("Testing stderr");

     System.out.println("Start your engines...");
     System.out.println("Three...Two...One...");

     // This could be anywhere
     System.err.close();
     // Oh dear stderr was closed, we can't even open it again!
     // These two lines disappear into the ether
     System.err.println("Your engine blew up, you are out of the race.");
     System.err.println("Move it out of the car before the whole thing blows!!");

     System.out.println("As the remaining cars finish the race...");
     System.out.println("And the winner is...");

     System.out.println("Oh dear we seem to have had a fatality, someone never got the message that their car was in trouble :-(");

     // Try to get the standard IO streams back, this does not seem to work
//     KillStdIO.resetStdIO();
     System.out.println("Final test for stdout");
     // This line throws a java.io.IOException if the resetStdIO() is called
     // This line also disappears into the ether, either way
     System.err.println("Final test for stderr");

     System.out.flush();
     System.err.flush();
     }


 // It is a pity that this did not seem to work.
 public static void resetStdIO()
     {   // From private static method java.lang.System.initializeSystemClass() JDK1.2.? Source
     FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
     FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
     FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
     System.setIn(new BufferedInputStream(fdIn));
     System.setOut(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
     System.setErr(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
     }
 }

/* A quick note on a question below under Symptoms:
 * d) Does this bug cause your program to crash? Unknown
 *
 * If you or any class that you use, logs errors to System.err
 * and any code closes the System.err stream, anything sent to it
 * disappears, therefore you will never know whether there were
 * any logs, exceptions, or errors that use System.err, unless
 * it either produces bad output (which you may not catch),
 * or it crashes the JVM, and even then, without all of the
 * tracing information, what to do?
 */
(Review ID: 95174) 
======================================================================

Comments
EVALUATION If this happens in an application it is a bug in the application. If it happens in applets then the streams closed are streams created for that applet only. michael.mccloskey@eng 1999-09-22
22-09-1999