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)
======================================================================