D
DaLoverhino
Hello I am reading Java Programming Language 3rd Edition as a self
study and I'm stuck with the following on Chap 3, exercise 11:
Find at least one security hole in SortDouble that would let a sorting
algorithm cheat on its metrics without getting caught. Fix the
security hole. Assume that the sorting algorithm author doesn't get to
write main.
My answer: Well, the only thing I can think of is that the extended
class of SortDouble could probe() for all the values[] in SortDouble,
and then it could swap and compare without having to use SortDouble's
routines, and thus not get audited. After that, it could do a few
calls to SortDouble's swap and compare methods to make the numbers look
alright.
Anyways, I don't think that is the answer that JPL is looking for. I'm
thinking they are looking for something more language specific.
My next guess would be that values is not made final, and some how you
can trick SortDouble, but I can't think of anything.
My next guess is that somehow you can clone SortDouble, and have the
clone do all the work, but SortDouble doesn't implement Cloneable. So,
I don't see how that could be a security risk.
My next guess is that somehow you can do a trick in the extended
classes constructor. Perhaps, the extended classes constructor has
only one constructor that requires you to pass the double[] array.
And, then you can do all your work in that... don't really know....
Could someone help me out? Thanks.
Here's the sample code in the book:
/*** SortDouble.java */
abstract class SortDouble {
private double[] values;
private final SortMetrics curMetrics = new SortMetrics();
/** Invoked to do the full sort */
public final SortMetrics sort( double[] data) {
values = data;
curMetrics.init();
doSort();
return getMetrics();
}
public final SortMetrics getMetrics() {
return (SortMetrics) curMetrics.clone();
}
/** For extended classes to know the number of elements */
protected final int getDataLength() {
return values.length;
}
/** For extended classes to probe elements */
protected final double probe( int i) {
curMetrics.probeCnt++;
return values;
}
/** For extended classes to compare elements */
protected final int compare( int i, int j) {
curMetrics.compareCnt++;
double d1 = values;
double d2 = values[j];
if( d1 == d2)
return 0;
else
return ( d1 < d2 ? -1 : 1);
}
/** For extended classes to swap elements */
protected final void swap( int i, int j) {
curMetrics.swapCnt++;
double tmp = values;
values = values[j];
values[j] = tmp;
}
/** Extended classes implement this -- used by sort */
protected abstract void doSort();
}
/*** SimpleSortDouble.java */
class SimpleSortDouble extends SortDouble {
protected void doSort() {
for( int i = 0; i < getDataLength(); ++i) {
for( int j = i + 1; j < getDataLength(); ++j) {
if( compare(i,j) > 0)
swap(i,j);
}
}
}
}
/*** SortMetrics.java */
final class SortMetrics implements Cloneable {
public long probeCnt, // simple data probes
compareCnt, // comparing two elements
swapCnt; // swapping two elements
public void init() {
probeCnt = swapCnt = compareCnt = 0;
}
public String toString() {
return probeCnt + " probes " +
compareCnt + " compares " +
swapCnt + " swaps";
}
/** This class supports clone */
public Object clone() {
try {
return super.clone(); // default mechanism works
}
catch( CloneNotSupportedException e) {
// can't happen: this and Object both clone
throw new InternalError( e.toString());
}
}
}
/*** TestSort.java */
public class TestSort {
static double[] testData = {
0.3, 1.3e-2, 7.9, 3.17 };
public static void main( String[] args) {
SortDouble bsort = new SimpleSortDouble();
SortMetrics metrics = bsort.sort(testData);
System.out.println( "Metrics: " + metrics);
for( int i = 0; i < testData.length; ++i)
System.out.println( "\t" + testData);
}
}
study and I'm stuck with the following on Chap 3, exercise 11:
Find at least one security hole in SortDouble that would let a sorting
algorithm cheat on its metrics without getting caught. Fix the
security hole. Assume that the sorting algorithm author doesn't get to
write main.
My answer: Well, the only thing I can think of is that the extended
class of SortDouble could probe() for all the values[] in SortDouble,
and then it could swap and compare without having to use SortDouble's
routines, and thus not get audited. After that, it could do a few
calls to SortDouble's swap and compare methods to make the numbers look
alright.
Anyways, I don't think that is the answer that JPL is looking for. I'm
thinking they are looking for something more language specific.
My next guess would be that values is not made final, and some how you
can trick SortDouble, but I can't think of anything.
My next guess is that somehow you can clone SortDouble, and have the
clone do all the work, but SortDouble doesn't implement Cloneable. So,
I don't see how that could be a security risk.
My next guess is that somehow you can do a trick in the extended
classes constructor. Perhaps, the extended classes constructor has
only one constructor that requires you to pass the double[] array.
And, then you can do all your work in that... don't really know....
Could someone help me out? Thanks.
Here's the sample code in the book:
/*** SortDouble.java */
abstract class SortDouble {
private double[] values;
private final SortMetrics curMetrics = new SortMetrics();
/** Invoked to do the full sort */
public final SortMetrics sort( double[] data) {
values = data;
curMetrics.init();
doSort();
return getMetrics();
}
public final SortMetrics getMetrics() {
return (SortMetrics) curMetrics.clone();
}
/** For extended classes to know the number of elements */
protected final int getDataLength() {
return values.length;
}
/** For extended classes to probe elements */
protected final double probe( int i) {
curMetrics.probeCnt++;
return values;
}
/** For extended classes to compare elements */
protected final int compare( int i, int j) {
curMetrics.compareCnt++;
double d1 = values;
double d2 = values[j];
if( d1 == d2)
return 0;
else
return ( d1 < d2 ? -1 : 1);
}
/** For extended classes to swap elements */
protected final void swap( int i, int j) {
curMetrics.swapCnt++;
double tmp = values;
values = values[j];
values[j] = tmp;
}
/** Extended classes implement this -- used by sort */
protected abstract void doSort();
}
/*** SimpleSortDouble.java */
class SimpleSortDouble extends SortDouble {
protected void doSort() {
for( int i = 0; i < getDataLength(); ++i) {
for( int j = i + 1; j < getDataLength(); ++j) {
if( compare(i,j) > 0)
swap(i,j);
}
}
}
}
/*** SortMetrics.java */
final class SortMetrics implements Cloneable {
public long probeCnt, // simple data probes
compareCnt, // comparing two elements
swapCnt; // swapping two elements
public void init() {
probeCnt = swapCnt = compareCnt = 0;
}
public String toString() {
return probeCnt + " probes " +
compareCnt + " compares " +
swapCnt + " swaps";
}
/** This class supports clone */
public Object clone() {
try {
return super.clone(); // default mechanism works
}
catch( CloneNotSupportedException e) {
// can't happen: this and Object both clone
throw new InternalError( e.toString());
}
}
}
/*** TestSort.java */
public class TestSort {
static double[] testData = {
0.3, 1.3e-2, 7.9, 3.17 };
public static void main( String[] args) {
SortDouble bsort = new SimpleSortDouble();
SortMetrics metrics = bsort.sort(testData);
System.out.println( "Metrics: " + metrics);
for( int i = 0; i < testData.length; ++i)
System.out.println( "\t" + testData);
}
}