diff --git a/JavaLibrary.mk b/JavaLibrary.mk index 18fa87060..2e60a967f 100644 --- a/JavaLibrary.mk +++ b/JavaLibrary.mk @@ -159,6 +159,11 @@ ifeq ($(WITH_HOST_DALVIK),true) include $(BUILD_HOST_JAVA_LIBRARY) endif +# turn on taint tracking +ifeq ($(WITH_TAINT_TRACKING),true) + LOCAL_CFLAGS += -DWITH_TAINT_TRACKING +endif + # # Local droiddoc for faster libcore testing # diff --git a/NativeCode.mk b/NativeCode.mk index 2a222b1e6..810437d09 100644 --- a/NativeCode.mk +++ b/NativeCode.mk @@ -95,6 +95,11 @@ LOCAL_MODULE := libjavacore LOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/include LOCAL_SHARED_LIBRARIES += libstlport +# turn on taint tracking +ifeq ($(WITH_TAINT_TRACKING),true) + LOCAL_CFLAGS += -DWITH_TAINT_TRACKING +endif + include $(BUILD_SHARED_LIBRARY) # diff --git a/dalvik/src/main/java/dalvik/system/Taint.java b/dalvik/src/main/java/dalvik/system/Taint.java new file mode 100644 index 000000000..b14ed9b1c --- /dev/null +++ b/dalvik/src/main/java/dalvik/system/Taint.java @@ -0,0 +1,593 @@ +/* + * Copyright (c) 2010 The Pennsylvania State University + * Systems and Internet Infrastructure Security Laboratory + * + * Author: William Enck + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dalvik.system; + +import com.android.internal.util.HexDump; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.nio.ByteBuffer; + +/** + * Provides a Taint interface for the Dalvik VM. This class is used for + * implementing Taint Source and Sink functionality. + * + */ +public final class Taint { + + public static final int TAINT_CLEAR = 0x00000000; + public static final int TAINT_LOCATION = 0x00000001; + public static final int TAINT_CONTACTS = 0x00000002; + public static final int TAINT_MIC = 0x00000004; + public static final int TAINT_PHONE_NUMBER = 0x00000008; + public static final int TAINT_LOCATION_GPS = 0x00000010; + public static final int TAINT_LOCATION_NET = 0x00000020; + public static final int TAINT_LOCATION_LAST = 0x00000040; + public static final int TAINT_CAMERA = 0x00000080; + public static final int TAINT_ACCELEROMETER = 0x00000100; + public static final int TAINT_SMS = 0x00000200; + public static final int TAINT_IMEI = 0x00000400; + public static final int TAINT_IMSI = 0x00000800; + public static final int TAINT_ICCID = 0x00001000; + public static final int TAINT_DEVICE_SN = 0x00002000; + public static final int TAINT_ACCOUNT = 0x00004000; + public static final int TAINT_HISTORY = 0x00008000; + + // how many bytes of tainted network output data to print to log? + public static final int dataBytesToLog = 100; + + /** + * Updates the target String's taint tag. + * + * @param str + * the target string + * @param tag + * tag to update (bitwise or) onto the object + */ + native public static void addTaintString(String str, int tag); + + /** + * Updates the target Object array's taint tag. + * + * @param array + * the target object array + * @param tag + * tag to update (bitwise or) onto the object array + */ + native public static void addTaintObjectArray(Object[] array, int tag); + + /** + * Updates the target boolean array's taint tag. + * + * @param array + * the target boolean array + * @param tag + * tag to update (bitwise or) onto the boolean array + */ + native public static void addTaintBooleanArray(boolean[] array, int tag); + + /** + * Updates the target char array's taint tag. + * + * @param array + * the target char array + * @param tag + * tag to update (bitwise or) onto the char array + */ + native public static void addTaintCharArray(char[] array, int tag); + + /** + * Updates the target byte array's taint tag. + * + * @param array + * the target byte array + * @param tag + * tag to update (bitwise or) onto the byte array + */ + native public static void addTaintByteArray(byte[] array, int tag); + + /** + * Updates the target direct ByteBuffer's taint tag. + * + * @param dByteBuffer + * the target direct ByteBuffer + * @param tag + * tag to update (bitwise or) onto the direct ByteBuffer + */ + public static void addTaintDirectByteBuffer(ByteBuffer dByteBuffer, int tag) { + if (dByteBuffer.isDirect()) { + dByteBuffer.addDirectByteBufferTaint(tag); + } + } + + /** + * Updates the target int array's taint tag. + * + * @param array + * the target int array + * @param tag + * tag to update (bitwise or) onto the int array + */ + native public static void addTaintIntArray(int[] array, int tag); + + /** + * Updates the target short array's taint tag. + * + * @param array + * the target short array + * @param tag + * tag to update (bitwise or) onto the int array + */ + native public static void addTaintShortArray(short[] array, int tag); + + /** + * Updates the target long array's taint tag. + * + * @param array + * the target long array + * @param tag + * tag to update (bitwise or) onto the long array + */ + native public static void addTaintLongArray(long[] array, int tag); + + /** + * Updates the target float array's taint tag. + * + * @param array + * the target float array + * @param tag + * tag to update (bitwise or) onto the float array + */ + native public static void addTaintFloatArray(float[] array, int tag); + + /** + * Updates the target double array's taint tag. + * + * @param array + * the target double array + * @param tag + * tag to update (bitwise or) onto the double array + */ + native public static void addTaintDoubleArray(double[] array, int tag); + + /** + * Add taint to a primitive boolean value. Only the return value has the + * updated taint tag. + * + * @param val + * the input value + * @param tag + * tag to add (bitwise or) onto the input value + * @return val with the added taint tag + */ + native public static boolean addTaintBoolean(boolean val, int tag); + + /** + * Add taint to a primitive char value. Only the return value has the + * updated taint tag. + * + * @param val + * the input value + * @param tag + * tag to add (bitwise or) onto the input value + * @return val with the added taint tag + */ + native public static char addTaintChar(char val, int tag); + + /** + * Add taint to a primitive byte value. Only the return value has the + * updated taint tag. + * + * @param val + * the input value + * @param tag + * tag to add (bitwise or) onto the input value + * @return val with the added taint tag + */ + native public static byte addTaintByte(byte val, int tag); + + /** + * Add taint to a primitive int value. Only the return value has the + * updated taint tag. + * + * @param val + * the input value + * @param tag + * tag to add (bitwise or) onto the input value + * @return val with the added taint tag + */ + native public static int addTaintInt(int val, int tag); + + /** + * Add taint to a primitive short value. Only the return value has the + * updated taint tag. + * + * @param val + * the input value + * @param tag + * tag to add (bitwise or) onto the input value + * @return val with the added taint tag + */ + native public static short addTaintShort(short val, int tag); + + /** + * Add taint to a primitive long value. Only the return value has the + * updated taint tag. + * + * @param val + * the input value + * @param tag + * tag to add (bitwise or) onto the input value + * @return val with the added taint tag + */ + native public static long addTaintLong(long val, int tag); + + /** + * Add taint to a primitive float value. Only the return value has the + * updated taint tag. + * + * @param val + * the input value + * @param tag + * tag to add (bitwise or) onto the input value + * @return val with the added taint tag + */ + native public static float addTaintFloat(float val, int tag); + + /** + * Add taint to a primitive double value. Only the return value has the + * updated taint tag. + * + * @param val + * the input value + * @param tag + * tag to add (bitwise or) onto the input value + * @return val with the added taint tag + */ + native public static double addTaintDouble(double val, int tag); + + /** + * Get the current taint tag from a String. + * + * @param str + * the target String + * @return the taint tag + */ + native public static int getTaintString(String str); + + /** + * Get the current taint tag from an Object array. + * + * @param array + * the target Object array + * @return the taint tag + */ + native public static int getTaintObjectArray(Object[] array); + + /** + * Get the current taint tag from a boolean array. + * + * @param array + * the target boolean array + * @return the taint tag + */ + native public static int getTaintBooleanArray(boolean[] array); + + /** + * Get the current taint tag from a char array. + * + * @param array + * the target char array + * @return the taint tag + */ + native public static int getTaintCharArray(char[] array); + + /** + * Get the current taint tag from a byte array. + * + * @param array + * the target byte array + * @return the taint tag + */ + native public static int getTaintByteArray(byte[] array); + + /** + * Get the current taint tag from a direct ByteBuffer. + * + * @param dByteBuffer + * the target direct ByteBuffer + * @return the taint tag + */ + public static int getTaintDirectByteBuffer(ByteBuffer dByteBuffer) { + if (dByteBuffer.isDirect()) { + return dByteBuffer.getDirectByteBufferTaint(); + } else { + return -1; + } + } + + /** + * Get the current taint tag from an int array. + * + * @param array + * the target int array + * @return the taint tag + */ + native public static int getTaintIntArray(int[] array); + + /** + * Get the current taint tag from a short array. + * + * @param array + * the target short array + * @return the taint tag + */ + native public static int getTaintShortArray(short[] array); + + /** + * Get the current taint tag from a long array. + * + * @param array + * the target long array + * @return the taint tag + */ + native public static int getTaintLongArray(long[] array); + + /** + * Get the current taint tag from a float array. + * + * @param array + * the target float array + * @return the taint tag + */ + native public static int getTaintFloatArray(float[] array); + + /** + * Get the current taint tag from a double array. + * + * @param array + * the target double array + * @return the taint tag + */ + native public static int getTaintDoubleArray(double[] array); + + /** + * Get the current taint tag from a primitive boolean. + * + * @param val + * the target boolean + * @return the taint tag + */ + native public static int getTaintBoolean(boolean val); + + /** + * Get the current taint tag from a primitive char. + * + * @param val + * the target char + * @return the taint tag + */ + native public static int getTaintChar(char val); + + /** + * Get the current taint tag from a primitive byte. + * + * @param val + * the target byte + * @return the taint tag + */ + native public static int getTaintByte(byte val); + + /** + * Get the current taint tag from a primitive int. + * + * @param val + * the target int + * @return the taint tag + */ + native public static int getTaintInt(int val); + + /** + * Get the current taint tag from a primitive short. + * + * @param val + * the target short + * @return the taint tag + */ + native public static int getTaintShort(short val); + + /** + * Get the current taint tag from a primitive long. + * + * @param val + * the target long + * @return the taint tag + */ + native public static int getTaintLong(long val); + + /** + * Get the current taint tag from a primitive float. + * + * @param val + * the target float + * @return the taint tag + */ + native public static int getTaintFloat(float val); + + /** + * Get the current taint tag from a primitive double. + * + * @param val + * the target double + * @return the taint tag + */ + native public static int getTaintDouble(double val); + + /** + * Get the current taint tag from an Object reference. + * + * @param obj + * the target Object reference + * @return the taint tag + */ + native public static int getTaintRef(Object obj); + + /** + * Get the taint tag from a file identified by a descriptor. + * + * @param fd + * the target file descriptor + * @return the taint tag + */ + native public static int getTaintFile(int fd); + + /** + * add a taint tag to a file identified by a descriptor + * + * @param fd + * the target file descriptor + * @param tag + * the tag to add (bitwise or) to the file + */ + native public static void addTaintFile(int fd, int tag); + + /** + * Logging utility accessible from places android.util.Log + * is not. + * + * @param msg + * the message to log + */ + native public static void log(String msg); + + + /** + * Logging utility to obtain the file path for a file descriptor + * + * @param fd + * the file descriptor + */ + native public static void logPathFromFd(int fd); + + /** + * Logging utility to obtain the peer IP addr for a file descriptor + * + * @param fd + * the file descriptor + */ + native public static void logPeerFromFd(int fd); + + /** + * Logging utility to write large data into small chunks in json format + * + * @param fn + * parent function name which called this function + * @param buff + * buffer object + * @param offset + * buff offset + * @param byteCount + * bytes need to write + * @param fd + * file discriptor or ip address + * @param sTag + * Taint Tag for the buff + */ + public static void writeTaintLongBuffer(String fn, Object buffer, int offset, int byteCount, String fd, String sTag, boolean isHex) + { + for (int i=0; i< byteCount; i=i+Taint.dataBytesToLog) + { + int iDataLen = byteCount - i < Taint.dataBytesToLog ? byteCount - i : Taint.dataBytesToLog; + String dstr = new String((byte[]) buffer, offset + i, iDataLen ); + String logData = null; + try { + logData = new JSONObject() + .put( "fn", fn ) + .put( "fd", fd ) + .put( "tag", sTag ) + .put( "data", isHex? HexDump.dumpHexString(dstr.getBytes()) : dstr ) + .put("hex", isHex) + .toString(); + } catch (JSONException e) { + e.printStackTrace(); + } + Taint.log( "Cloudacl:" + logData ); + } + } + + /** + * Logging utility to write large data into small chunks in JSON format + * + * @param fn + * parent function name which called this function + * @param data + * data in string format + * @param fd + * file discriptor or ip address + * @param sTag + * Taint Tag for the buff + */ + public static void writeTaintLongData(String fn, String data, String fd, String sTag, boolean isHex) + { + + for (int i=0; i< data.length(); i=i+Taint.dataBytesToLog) + { + int iDataLen = data.length() - i < Taint.dataBytesToLog ? data.length() - i : Taint.dataBytesToLog; + String dstr = data.substring(i, i + iDataLen); + String logData = null; + try { + logData = new JSONObject() + .put( "fn", fn ) + .put( "fd", fd ) + .put( "tag", sTag ) + .put( "data", isHex? HexDump.dumpHexString(dstr.getBytes()) : dstr ) + .put("hex", isHex) + .toString(); + } catch (JSONException e) { + e.printStackTrace(); + } + + Taint.log( "Cloudacl:" + logData ); + } + } + /** + * Logging utility to write string data with a process id + * + * @param fn + * function name + * @param data + * data in string format + */ + public static void log2(String fn, String data) + { + String logData = null; + try { + logData = new JSONObject() + .put("fn", fn) + .put("data", data) + .toString(); + } catch (JSONException e) { + e.printStackTrace(); + } + Taint.log("Cloudacl:" + logData); + } +} + diff --git a/luni/src/main/java/java/io/FileDescriptor.java b/luni/src/main/java/java/io/FileDescriptor.java index f04ae2c4c..3011ddde5 100644 --- a/luni/src/main/java/java/io/FileDescriptor.java +++ b/luni/src/main/java/java/io/FileDescriptor.java @@ -104,4 +104,27 @@ public boolean valid() { @Override public String toString() { return "FileDescriptor[" + descriptor + "]"; } + +// begin WITH_TAINT_TRACKING + /** + * hack for printing out IP address + * @hide + */ + public boolean hasName = false; + + /** + * hack for printing out IP address + * @hide + */ + public String name = null; + + /** + * hack for setting file taint + * @hide + */ + public int getDescriptor() + { + return descriptor; + } +// end WITH_TAINT_TRACKING } diff --git a/luni/src/main/java/java/lang/Double.java b/luni/src/main/java/java/lang/Double.java index 456529b15..f2dfc1184 100644 --- a/luni/src/main/java/java/lang/Double.java +++ b/luni/src/main/java/java/lang/Double.java @@ -171,7 +171,14 @@ public byte byteValue() { * {@code value}. All Not-a-Number (NaN) values are converted to a single NaN * representation ({@code 0x7ff8000000000000L}) (compare to {@link #doubleToRawLongBits}). */ - public static native long doubleToLongBits(double value); +// begin WITH_TAINT_TRACKING + //public static native long doubleToLongBits(double value); + public static native long doubleToLongBits_intrinsic(double value); + + public static long doubleToLongBits(double value) { + return doubleToLongBits_intrinsic(value); + } +// end WITH_TAINT_TRACKING /** * Returns an integer corresponding to the bits of the given @@ -179,7 +186,14 @@ public byte byteValue() { * {@code value}. Not-a-Number (NaN) values are preserved (compare * to {@link #doubleToLongBits}). */ - public static native long doubleToRawLongBits(double value); +// begin WITH_TAINT_TRACKING + //public static native long doubleToRawLongBits(double value); + public static native long doubleToRawLongBits_intrinsic(double value); + + public static long doubleToRawLongBits(double value) { + return doubleToRawLongBits_intrinsic(value); + } +// end WITH_TAINT_TRACKING /** * Gets the primitive value of this double. @@ -275,7 +289,14 @@ public static boolean isNaN(double d) { * Returns the IEEE 754 * double precision float corresponding to the given {@code bits}. */ - public static native double longBitsToDouble(long bits); +// begin WITH_TAINT_TRACKING + //public static native double longBitsToDouble(long bits); + public static native double longBitsToDouble_intrinsic(long bits); + + public static double longBitsToDouble(long bits) { + return longBitsToDouble_intrinsic(bits); + } +// end WITH_TAINT_TRACKING @Override public long longValue() { diff --git a/luni/src/main/java/java/lang/Float.java b/luni/src/main/java/java/lang/Float.java index 900b2a098..c36c1d2ee 100644 --- a/luni/src/main/java/java/lang/Float.java +++ b/luni/src/main/java/java/lang/Float.java @@ -199,7 +199,14 @@ public boolean equals(Object object) { * float {@code value}. All Not-a-Number (NaN) values are converted to a single NaN * representation ({@code 0x7fc00000}) (compare to {@link #floatToRawIntBits}). */ - public static native int floatToIntBits(float value); +// begin WITH_TAINT_TRACKING + //public static native int floatToIntBits(float value); + public static native int floatToIntBits_intrinsic(float value); + + public static int floatToIntBits(float value) { + return floatToIntBits_intrinsic(value); + } +// end WITH_TAINT_TRACKING /** * Returns an integer corresponding to the bits of the given @@ -207,7 +214,14 @@ public boolean equals(Object object) { * float {@code value}. Not-a-Number (NaN) values are preserved (compare * to {@link #floatToIntBits}). */ - public static native int floatToRawIntBits(float value); +// begin WITH_TAINT_TRACKING + //public static native int floatToRawIntBits(float value); + public static native int floatToRawIntBits_intrinsic(float value); + + public static int floatToRawIntBits(float value) { + return floatToRawIntBits_intrinsic(value); + } +// end WITH_TAINT_TRACKING /** * Gets the primitive value of this float. @@ -228,7 +242,14 @@ public int hashCode() { * Returns the IEEE 754 * single precision float corresponding to the given {@code bits}. */ - public static native float intBitsToFloat(int bits); +// begin WITH_TAINT_TRACKING + public static native float intBitsToFloat_intrinsic(int bits); + //public static native float intBitsToFloat(int bits); + + public static float intBitsToFloat(int bits) { + return intBitsToFloat_intrinsic(bits); + } +// end WITH_TAINT_TRACKING @Override public int intValue() { diff --git a/luni/src/main/java/java/lang/IntegralToString.java b/luni/src/main/java/java/lang/IntegralToString.java index f6234a0c1..6aab56acb 100644 --- a/luni/src/main/java/java/lang/IntegralToString.java +++ b/luni/src/main/java/java/lang/IntegralToString.java @@ -16,6 +16,10 @@ package java.lang; +// begin WITH_TAINT_TRACKING +import dalvik.system.Taint; +// end WITH_TAINT_TRACKING + /** * Converts integral types to strings. This class is public but hidden so that it can also be * used by java.util.Formatter to speed up %d. This class is in java.lang so that it can take @@ -180,6 +184,9 @@ public static void appendInt(AbstractStringBuilder sb, int i) { private static String convertInt(AbstractStringBuilder sb, int i) { boolean negative = false; String quickResult = null; +// begin WITH_TAINT_TRACKING + int taint = Taint.getTaintInt(i); +// end WITH_TAINT_TRACKING if (i < 0) { negative = true; i = -i; @@ -206,9 +213,15 @@ private static String convertInt(AbstractStringBuilder sb, int i) { } if (quickResult != null) { if (sb != null) { +// begin WITH_TAINT_TRACKING + Taint.addTaintString(quickResult, taint); +// end WITH_TAINT_TRACKING sb.append0(quickResult); return null; } +// begin WITH_TAINT_TRACKING + Taint.addTaintString(quickResult, taint); +// end WITH_TAINT_TRACKING return quickResult; } @@ -243,7 +256,11 @@ private static String convertInt(AbstractStringBuilder sb, int i) { sb.append0(buf, cursor, bufLen - cursor); return null; } else { - return new String(cursor, bufLen - cursor, buf); +// begin WITH_TAINT_TRACKING + String ret = new String(cursor, bufLen - cursor, buf); + Taint.addTaintString(ret, taint); + return ret; +// end WITH_TAINT_TRACKING } } @@ -316,6 +333,10 @@ private static String convertLong(AbstractStringBuilder sb, long n) { if (i == n) { return convertInt(sb, i); } + +// begin WITH_TAINT_TRACKING + int taint = Taint.getTaintLong(n); +// end WITH_TAINT_TRACKING boolean negative = (n < 0); if (negative) { @@ -323,6 +344,9 @@ private static String convertLong(AbstractStringBuilder sb, long n) { if (n < 0) { // If -n is still negative, n is Long.MIN_VALUE String quickResult = "-9223372036854775808"; +// begin WITH_TAINT_TRACKING + Taint.addTaintString(quickResult, taint); +// end WITH_TAINT_TRACKING if (sb != null) { sb.append0(quickResult); return null; @@ -386,7 +410,11 @@ private static String convertLong(AbstractStringBuilder sb, long n) { sb.append0(buf, cursor, bufLen - cursor); return null; } else { - return new String(cursor, bufLen - cursor, buf); +// begin WITH_TAINT_TRACKING + String ret = new String(cursor, bufLen - cursor, buf); + Taint.addTaintString(ret, taint); + return ret; +// end WITH_TAINT_TRACKING } } diff --git a/luni/src/main/java/java/lang/Math.java b/luni/src/main/java/java/lang/Math.java index 68db4fa8d..770d6c6d7 100644 --- a/luni/src/main/java/java/lang/Math.java +++ b/luni/src/main/java/java/lang/Math.java @@ -58,7 +58,14 @@ private Math() { * the value whose absolute value has to be computed. * @return the absolute value of the argument. */ - public static native double abs(double d); +// begin WITH_TAINT_TRACKING + //public static native double abs(double d); + public static native double abs_intrinsic(double d); + + public static double abs(double d) { + return abs_intrinsic(d); + } +// end WITH_TAINT_TRACKING /** * Returns the absolute value of the argument. @@ -76,7 +83,14 @@ private Math() { * @return the argument if it is positive, otherwise the negation of the * argument. */ - public static native float abs(float f); +// begin WITH_TAINT_TRACKING + //public static native float abs(float f); + public static native float abs_intrinsic(float f); + + public static float abs(float f) { + return abs_intrinsic(f); + } +// end WITH_TAINT_TRACKING /** * Returns the absolute value of the argument. @@ -89,7 +103,14 @@ private Math() { * @return the argument if it is positive, otherwise the negation of the * argument. */ - public static native int abs(int i); +// begin WITH_TAINT_TRACKING + //public static native int abs(int i); + public static native int abs_intrinsic(int i); + + public static int abs(int i) { + return abs_intrinsic(i); + } +// end WITH_TAINT_TRACKING /** * Returns the absolute value of the argument. If the argument is {@code @@ -100,7 +121,14 @@ private Math() { * @return the argument if it is positive, otherwise the negation of the * argument. */ - public static native long abs(long l); +// begin WITH_TAINT_TRACKING + //public static native long abs(long l); + public static native long abs_intrinsic(long l); + + public static long abs(long l) { + return abs_intrinsic(l); + } +// end WITH_TAINT_TRACKING /** * Returns the closest double approximation of the arc cosine of the @@ -253,7 +281,14 @@ private Math() { * the angle whose cosine has to be computed, in radians. * @return the cosine of the argument. */ - public static native double cos(double d); +// begin WITH_TAINT_TRACKING + //public static native double cos(double d); + public static native double cos_intrinsic(double d); + + public static double cos(double d) { + return cos_intrinsic(d); + } +// end WITH_TAINT_TRACKING /** * Returns the closest double approximation of the hyperbolic cosine of the @@ -540,7 +575,14 @@ public static float max(float f1, float f2) { * the second argument. * @return the larger of {@code i1} and {@code i2}. */ - public static native int max(int i1, int i2); +// begin WITH_TAINT_TRACKING + //public static native int max(int i1, int i2); + public static native int max_intrinsic(int i1, int i2); + + public static int max(int i1, int i2) { + return max_intrinsic(i1, i2); + } +// end WITH_TAINT_TRACKING /** * Returns the most positive (closest to positive infinity) of the two @@ -640,7 +682,14 @@ public static float min(float f1, float f2) { * the second argument. * @return the smaller of {@code i1} and {@code i2}. */ - public static native int min(int i1, int i2); +// begin WITH_TAINT_TRACKING + //public static native int min(int i1, int i2); + public static native int min_intrinsic(int i1, int i2); + + public static int min(int i1, int i2) { + return min_intrinsic(i1, i2); + } +// end WITH_TAINT_TRACKING /** * Returns the most negative (closest to negative infinity) of the two @@ -850,7 +899,14 @@ public static float signum(float f) { * the angle whose sin has to be computed, in radians. * @return the sine of the argument. */ - public static native double sin(double d); +// begin WITH_TAINT_TRACKING + //public static native double sin(double d); + public static native double sin_intrinsic(double d); + + public static double sin(double d) { + return sin_intrinsic(d); + } +// end WITH_TAINT_TRACKING /** * Returns the closest double approximation of the hyperbolic sine of the @@ -889,7 +945,14 @@ public static float signum(float f) { * the value whose square root has to be computed. * @return the square root of the argument. */ - public static native double sqrt(double d); +// begin WITH_TAINT_TRACKING + //public static native double sqrt(double d); + public static native double sqrt_intrinsic(double d); + + public static double sqrt(double d) { + return sqrt_intrinsic(d); + } +// end WITH_TAINT_TRACKING /** * Returns the closest double approximation of the tangent of the argument. diff --git a/luni/src/main/java/java/lang/RealToString.java b/luni/src/main/java/java/lang/RealToString.java index 31203ebf2..fe2f33409 100644 --- a/luni/src/main/java/java/lang/RealToString.java +++ b/luni/src/main/java/java/lang/RealToString.java @@ -19,6 +19,10 @@ import libcore.math.MathUtils; +// begin WITH_TAINT_TRACKING +import dalvik.system.Taint; +// end WITH_TAINT_TRACKING + final class RealToString { private static final ThreadLocal INSTANCE = new ThreadLocal() { @Override protected RealToString initialValue() { @@ -64,6 +68,10 @@ public void appendDouble(AbstractStringBuilder sb, double d) { } private String convertDouble(AbstractStringBuilder sb, double inputNumber) { +// begin WITH_TAINT_TRACKING + int tag = Taint.getTaintDouble(inputNumber); +// end WITH_TAINT_TRACKING + long inputNumberBits = Double.doubleToRawLongBits(inputNumber); boolean positive = (inputNumberBits & Double.SIGN_MASK) == 0; int e = (int) ((inputNumberBits & Double.EXPONENT_MASK) >> Double.MANTISSA_BITS); @@ -86,6 +94,11 @@ private String convertDouble(AbstractStringBuilder sb, double inputNumber) { } } if (quickResult != null) { +// begin WITH_TAINT_TRACKING + if (tag != Taint.TAINT_CLEAR) { + Taint.addTaintString(quickResult, tag); + } +// end WITH_TAINT_TRACKING return resultOrSideEffect(sb, quickResult); } @@ -119,7 +132,16 @@ private String convertDouble(AbstractStringBuilder sb, double inputNumber) { } else { freeFormat(dst, positive); } - return (sb != null) ? null : dst.toString(); + +// begin WITH_TAINT_TRACKING + if (tag != Taint.TAINT_CLEAR) { + String ts = dst.toString(); + Taint.addTaintString(ts, tag); + return (sb != null) ? null : ts; + } else { + return (sb != null) ? null : dst.toString(); + } +// end WITH_TAINT_TRACKING } public String floatToString(float f) { @@ -131,6 +153,10 @@ public void appendFloat(AbstractStringBuilder sb, float f) { } public String convertFloat(AbstractStringBuilder sb, float inputNumber) { +// begin WITH_TAINT_TRACKING + int tag = Taint.getTaintFloat(inputNumber); +// end WITH_TAINT_TRACKING + int inputNumberBits = Float.floatToRawIntBits(inputNumber); boolean positive = (inputNumberBits & Float.SIGN_MASK) == 0; int e = (inputNumberBits & Float.EXPONENT_MASK) >> Float.MANTISSA_BITS; @@ -148,6 +174,11 @@ public String convertFloat(AbstractStringBuilder sb, float inputNumber) { quickResult = positive ? "0.0" : "-0.0"; } if (quickResult != null) { +// begin WITH_TAINT_TRACKING + if (tag != Taint.TAINT_CLEAR) { + Taint.addTaintString(quickResult, tag); + } +// end WITH_TAINT_TRACKING return resultOrSideEffect(sb, quickResult); } @@ -185,7 +216,16 @@ public String convertFloat(AbstractStringBuilder sb, float inputNumber) { } else { freeFormat(dst, positive); } - return (sb != null) ? null : dst.toString(); + +// begin WITH_TAINT_TRACKING + if (tag != Taint.TAINT_CLEAR) { + String ts = dst.toString(); + Taint.addTaintString(ts, tag); + return (sb != null) ? null : ts; + } else { + return (sb != null) ? null : dst.toString(); + } +// end WITH_TAINT_TRACKING } private void freeFormatExponential(AbstractStringBuilder sb, boolean positive) { diff --git a/luni/src/main/java/java/lang/String.java b/luni/src/main/java/java/lang/String.java index efd421008..5309e706b 100644 --- a/luni/src/main/java/java/lang/String.java +++ b/luni/src/main/java/java/lang/String.java @@ -29,6 +29,9 @@ import java.util.Locale; import java.util.regex.Pattern; import libcore.util.EmptyArray; +// begin WITH_TAINT_TRACKING +import dalvik.system.Taint; +// end WITH_TAINT_TRACKING /** * An immutable sequence of characters/code units ({@code char}s). A @@ -583,7 +586,14 @@ private String(String s1, int v1) { * @throws IndexOutOfBoundsException * if {@code index < 0} or {@code index >= length()}. */ - public native char charAt(int index); +// begin WITH_TAINT_TRACKING + //public native char charAt(int index); + public native char charAt_intrinsic(int index); + + public char charAt(int index) { + return Taint.addTaintChar(charAt_intrinsic(index), Taint.getTaintString(this)|Taint.getTaintInt(index)); + } +// end WITH_TAINT_TRACKING private StringIndexOutOfBoundsException indexAndLength(int index) { throw new StringIndexOutOfBoundsException(this, index); @@ -631,7 +641,14 @@ private char foldCase(char ch) { * @throws NullPointerException * if {@code string} is {@code null}. */ - public native int compareTo(String string); +// begin WITH_TAINT_TRACKING + //public native int compareTo(String string); + public native int compareTo_intrinsic(String string); + + public int compareTo(String string) { + return compareTo_intrinsic(string); + } +// end WITH_TAINT_TRACKING /** * Compares the specified string to this string using the Unicode values of @@ -752,7 +769,14 @@ public boolean endsWith(String suffix) { * {@code false} otherwise. * @see #hashCode */ - @Override public native boolean equals(Object object); +// begin WITH_TAINT_TRACKING + //@Override public native boolean equals(Object object); + public native boolean equals_intrinsic(Object object); + + @Override public boolean equals(Object object) { + return equals_intrinsic(object); + } +// end WITH_TAINT_TRACKING /** * Compares the specified string to this string ignoring the case of the @@ -966,7 +990,14 @@ public int indexOf(int c, int start) { return fastIndexOf(c, start); } - private native int fastIndexOf(int c, int start); +// begin WITH_TAINT_TRACKING + //private native int fastIndexOf(int c, int start); + private native int fastIndexOf_intrinsic(int c, int start); + + private int fastIndexOf(int c, int start) { + return fastIndexOf_intrinsic(c, start); + } +// end WITH_TAINT_TRACKING private int indexOfSupplementary(int c, int start) { if (!Character.isSupplementaryCodePoint(c)) { @@ -1087,7 +1118,14 @@ public int indexOf(String subString, int start) { * * @since 1.6 */ - public native boolean isEmpty(); +// begin WITH_TAINT_TRACKING + //public native boolean isEmpty(); + public native boolean isEmpty_intrinsic(); + + public boolean isEmpty() { + return isEmpty_intrinsic(); + } +// end WITH_TAINT_TRACKING /** * Returns the last index of the code point {@code c}, or -1. @@ -1211,7 +1249,14 @@ public int lastIndexOf(String subString, int start) { * * @return the number of characters in this string. */ - public native int length(); +// begin WITH_TAINT_TRACKING + //public native int length(); + public native int length_intrinsic(); + + public int length() { + return length_intrinsic(); + } +// end WITH_TAINT_TRACKING /** * Compares the specified string to this string and compares the specified @@ -1621,6 +1666,9 @@ public static String valueOf(char value) { s = new String(0, 1, new char[] { value }); } s.hashCode = value; +// begin WITH_TAINT_TRACKING + Taint.addTaintString(s,Taint.getTaintChar(value)); +// end WITH_TAINT_TRACKING return s; } @@ -1691,7 +1739,11 @@ public static String valueOf(Object value) { * @return the boolean converted to a string. */ public static String valueOf(boolean value) { - return value ? "true" : "false"; +// begin WITH_TAINT_TRACKING + String ret = value ? "true" : "false"; + Taint.addTaintString(ret, Taint.getTaintBoolean(value)); + return ret; +// end WITH_TAINT_TRACKING } /** diff --git a/luni/src/main/java/java/nio/ByteBuffer.java b/luni/src/main/java/java/nio/ByteBuffer.java index ef725c1f2..34afb2e55 100644 --- a/luni/src/main/java/java/nio/ByteBuffer.java +++ b/luni/src/main/java/java/nio/ByteBuffer.java @@ -1031,4 +1031,20 @@ public ByteBuffer put(ByteBuffer src) { * @return a sliced buffer that shares its content with this buffer. */ public abstract ByteBuffer slice(); + +// begin WITH_TAINT_TRACKING + public int getDirectByteBufferTaint() { + if (this.isDirect()) { + return this.block.getTaint(); + } else { + return 0; + } + } + + public void addDirectByteBufferTaint(int tag) { + if (this.isDirect()) { + this.block.addTaint(tag); + } + } +// end WITH_TAINT_TRACKING } diff --git a/luni/src/main/java/java/nio/MemoryBlock.java b/luni/src/main/java/java/nio/MemoryBlock.java index add69c545..0853e2f3d 100644 --- a/luni/src/main/java/java/nio/MemoryBlock.java +++ b/luni/src/main/java/java/nio/MemoryBlock.java @@ -26,6 +26,10 @@ import libcore.io.Memory; import static libcore.io.OsConstants.*; +// begin WITH_TAINT_TRACKING +import dalvik.system.Taint; +// end WITH_TAINT_TRACKING + class MemoryBlock { /** * Handles calling munmap(2) on a memory-mapped region. @@ -76,6 +80,13 @@ private NonMovableHeapBlock(byte[] array, int address, long byteCount) { array = null; address = 0; } + + // begin WITH_TAINT_TRACKING + @Override public void addTaint(int newTaint) { + super.addTaint(newTaint); + Taint.addTaintByteArray(array, newTaint); + } + // end WITH_TAINT_TRACKING } /** @@ -91,6 +102,12 @@ private UnmanagedBlock(int address, long byteCount) { // TODO: should be long on 64-bit devices; int for performance. protected int address; protected final long size; +// begin WITH_TAINT_TRACKING + protected int taint; + public void addTaint(int newTaint) { + taint = taint | newTaint; + } +// end WITH_TAINT_TRACKING public static MemoryBlock mmap(FileDescriptor fd, long offset, long size, MapMode mapMode) throws IOException { if (size == 0) { @@ -135,6 +152,9 @@ public static MemoryBlock wrapFromJni(int address, long byteCount) { private MemoryBlock(int address, long size) { this.address = address; this.size = size; +// begin WITH_TAINT_TRACKING + this.taint = Taint.TAINT_CLEAR; +// end WITH_TAINT_TRACKING } // Used to support array/arrayOffset/hasArray for direct buffers. @@ -146,91 +166,161 @@ public void free() { } public final void pokeByte(int offset, byte value) { +// begin WITH_TAINT_TRACKING + addTaint(Taint.getTaintByte(value)); +// end WITH_TAINT_TRACKING Memory.pokeByte(address + offset, value); } public final void pokeByteArray(int offset, byte[] src, int srcOffset, int byteCount) { +// begin WITH_TAINT_TRACKING + addTaint(Taint.getTaintByteArray(src)); +// end WITH_TAINT_TRACKING Memory.pokeByteArray(address + offset, src, srcOffset, byteCount); } public final void pokeCharArray(int offset, char[] src, int srcOffset, int charCount, boolean swap) { +// begin WITH_TAINT_TRACKING + addTaint(Taint.getTaintCharArray(src)); +// end WITH_TAINT_TRACKING Memory.pokeCharArray(address + offset, src, srcOffset, charCount, swap); } public final void pokeDoubleArray(int offset, double[] src, int srcOffset, int doubleCount, boolean swap) { +// begin WITH_TAINT_TRACKING + addTaint(Taint.getTaintDoubleArray(src)); +// end WITH_TAINT_TRACKING Memory.pokeDoubleArray(address + offset, src, srcOffset, doubleCount, swap); } public final void pokeFloatArray(int offset, float[] src, int srcOffset, int floatCount, boolean swap) { +// begin WITH_TAINT_TRACKING + addTaint(Taint.getTaintFloatArray(src)); +// end WITH_TAINT_TRACKING Memory.pokeFloatArray(address + offset, src, srcOffset, floatCount, swap); } public final void pokeIntArray(int offset, int[] src, int srcOffset, int intCount, boolean swap) { +// begin WITH_TAINT_TRACKING + addTaint(Taint.getTaintIntArray(src)); +// end WITH_TAINT_TRACKING Memory.pokeIntArray(address + offset, src, srcOffset, intCount, swap); } public final void pokeLongArray(int offset, long[] src, int srcOffset, int longCount, boolean swap) { +// begin WITH_TAINT_TRACKING + addTaint(Taint.getTaintLongArray(src)); +// end WITH_TAINT_TRACKING Memory.pokeLongArray(address + offset, src, srcOffset, longCount, swap); } public final void pokeShortArray(int offset, short[] src, int srcOffset, int shortCount, boolean swap) { +// begin WITH_TAINT_TRACKING + addTaint(Taint.getTaintShortArray(src)); +// end WITH_TAINT_TRACKING Memory.pokeShortArray(address + offset, src, srcOffset, shortCount, swap); } public final byte peekByte(int offset) { - return Memory.peekByte(address + offset); +// begin WITH_TAINT_TRACKING +// return Memory.peekByte(address + offset); + byte val = Memory.peekByte(address + offset); + return Taint.addTaintByte(val, taint); +// end WITH_TAINT_TRACKING } public final void peekByteArray(int offset, byte[] dst, int dstOffset, int byteCount) { Memory.peekByteArray(address + offset, dst, dstOffset, byteCount); +// begin WITH_TAINT_TRACKING + Taint.addTaintByteArray(dst, taint); +// end WITH_TAINT_TRACKING } public final void peekCharArray(int offset, char[] dst, int dstOffset, int charCount, boolean swap) { Memory.peekCharArray(address + offset, dst, dstOffset, charCount, swap); +// begin WITH_TAINT_TRACKING + Taint.addTaintCharArray(dst, taint); +// end WITH_TAINT_TRACKING } public final void peekDoubleArray(int offset, double[] dst, int dstOffset, int doubleCount, boolean swap) { Memory.peekDoubleArray(address + offset, dst, dstOffset, doubleCount, swap); +// begin WITH_TAINT_TRACKING + Taint.addTaintDoubleArray(dst, taint); +// end WITH_TAINT_TRACKING } public final void peekFloatArray(int offset, float[] dst, int dstOffset, int floatCount, boolean swap) { Memory.peekFloatArray(address + offset, dst, dstOffset, floatCount, swap); +// begin WITH_TAINT_TRACKING + Taint.addTaintFloatArray(dst, taint); +// end WITH_TAINT_TRACKING } public final void peekIntArray(int offset, int[] dst, int dstOffset, int intCount, boolean swap) { Memory.peekIntArray(address + offset, dst, dstOffset, intCount, swap); +// begin WITH_TAINT_TRACKING + Taint.addTaintIntArray(dst, taint); +// end WITH_TAINT_TRACKING } public final void peekLongArray(int offset, long[] dst, int dstOffset, int longCount, boolean swap) { Memory.peekLongArray(address + offset, dst, dstOffset, longCount, swap); +// begin WITH_TAINT_TRACKING + Taint.addTaintLongArray(dst, taint); +// end WITH_TAINT_TRACKING } public final void peekShortArray(int offset, short[] dst, int dstOffset, int shortCount, boolean swap) { Memory.peekShortArray(address + offset, dst, dstOffset, shortCount, swap); +// begin WITH_TAINT_TRACKING + Taint.addTaintShortArray(dst, taint); +// end WITH_TAINT_TRACKING } public final void pokeShort(int offset, short value, ByteOrder order) { +// begin WITH_TAINT_TRACKING + addTaint(Taint.getTaintShort(value)); +// end WITH_TAINT_TRACKING Memory.pokeShort(address + offset, value, order.needsSwap); } public final short peekShort(int offset, ByteOrder order) { - return Memory.peekShort(address + offset, order.needsSwap); +// begin WITH_TAINT_TRACKING +// return Memory.peekShort(address + offset, order.needsSwap); + short val = Memory.peekShort(address + offset, order.needsSwap); + return Taint.addTaintShort(val, taint); +// end WITH_TAINT_TRACKING } public final void pokeInt(int offset, int value, ByteOrder order) { +// begin WITH_TAINT_TRACKING + addTaint(Taint.getTaintInt(value)); +// end WITH_TAINT_TRACKING Memory.pokeInt(address + offset, value, order.needsSwap); } public final int peekInt(int offset, ByteOrder order) { - return Memory.peekInt(address + offset, order.needsSwap); +// begin WITH_TAINT_TRACKING +// return Memory.peekInt(address + offset, order.needsSwap); + int val = Memory.peekInt(address + offset, order.needsSwap); + return Taint.addTaintInt(val, taint); +// end WITH_TAINT_TRACKING } public final void pokeLong(int offset, long value, ByteOrder order) { +// begin WITH_TAINT_TRACKING + addTaint(Taint.getTaintLong(value)); +// end WITH_TAINT_TRACKING Memory.pokeLong(address + offset, value, order.needsSwap); } public final long peekLong(int offset, ByteOrder order) { - return Memory.peekLong(address + offset, order.needsSwap); +// begin WITH_TAINT_TRACKING +// return Memory.peekLong(address + offset, order.needsSwap); + long val = Memory.peekLong(address + offset, order.needsSwap); + return Taint.addTaintLong(val, taint); +// end WITH_TAINT_TRACKING } public final int toInt() { @@ -244,4 +334,10 @@ public final String toString() { public final long getSize() { return size; } + +// begin WITH_TAINT_TRACKING + public int getTaint() { + return taint; + } +// end WITH_TAINT_TRACKING } diff --git a/luni/src/main/java/libcore/io/Posix.java b/luni/src/main/java/libcore/io/Posix.java index 7bbf49f7f..8f5c2643f 100644 --- a/luni/src/main/java/libcore/io/Posix.java +++ b/luni/src/main/java/libcore/io/Posix.java @@ -16,6 +16,7 @@ package libcore.io; + import java.io.FileDescriptor; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -25,6 +26,12 @@ import libcore.util.MutableInt; import libcore.util.MutableLong; + + +// begin WITH_TAINT_TRACKING +import dalvik.system.Taint; +// end WITH_TAINT_TRACKING + public final class Posix implements Os { Posix() { } @@ -33,7 +40,18 @@ public final class Posix implements Os { public native void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException; public native void chmod(String path, int mode) throws ErrnoException; public native void close(FileDescriptor fd) throws ErrnoException; - public native void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException; +// begin WITH_TAINT_TRACKING + //public native void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException; + public native void connectImpl(FileDescriptor fd, InetAddress address, int port) throws ErrnoException; + public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException { + String addr = address.getHostAddress(); + if (addr != null) { + fd.hasName = true; + fd.name = addr; + } + connectImpl(fd, address, port); + } +// end WITH_TAINT_TRACKING public native FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException; public native FileDescriptor dup2(FileDescriptor oldFd, int newFd) throws ErrnoException; public native String[] environ(); @@ -93,9 +111,42 @@ public int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, // This indirection isn't strictly necessary, but ensures that our public interface is type safe. return preadBytes(fd, bytes, byteOffset, byteCount, offset); } - private native int preadBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException; +// begin WITH_TAINT_TRACKING + //private native int preadBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException; + private native int preadBytesImpl(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException; + private int preadBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException { + if (buffer == null) { + throw new NullPointerException(); + } + int bytesRead = preadBytesImpl(fd, buffer, bufferOffset, byteCount, offset); + int fdInt = fd.getDescriptor(); + int tag = Taint.getTaintFile(fdInt); + if (tag != Taint.TAINT_CLEAR) { + String dstr = new String((byte[])buffer, bufferOffset, ((byteCount > Taint.dataBytesToLog) ? Taint.dataBytesToLog : byteCount)); + // replace non-printable characters + dstr = dstr.replaceAll("\\p{C}", "."); + String tstr = "0x" + Integer.toHexString(tag); + // Taint.log("libcore.os.read(" + fdInt + ") reading with tag " + tstr + " data[" + dstr + "]"); + Taint.writeTaintLongBuffer("libcore.os.read", buffer, bufferOffset, byteCount, ""+fdInt, tstr, true); + Taint.addTaintByteArray((byte[])buffer, tag); + } + return bytesRead; + } +// end WITH_TAINT_TRACKING public int pwrite(FileDescriptor fd, ByteBuffer buffer, long offset) throws ErrnoException { if (buffer.isDirect()) { +// begin WITH_TAINT_TRACKING + int tag = buffer.getDirectByteBufferTaint(); + if (tag != Taint.TAINT_CLEAR) { + int fdInt = fd.getDescriptor(); + Taint.logPathFromFd(fdInt); + String tstr = "0x" + Integer.toHexString(tag); + // Taint.log("libcore.os.pwrite(" + fdInt + ") writing a direct ByteBuffer with tag " + tstr); + + Taint.writeTaintLongData("libcore.os.pwrite", "Direct ByteBufer write", "" + fdInt, tstr, false); + Taint.addTaintFile(fdInt, tag); + } +// end WITH_TAINT_TRACKING return pwriteBytes(fd, buffer, buffer.position(), buffer.remaining(), offset); } else { return pwriteBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + buffer.position(), buffer.remaining(), offset); @@ -105,8 +156,33 @@ public int pwrite(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount // This indirection isn't strictly necessary, but ensures that our public interface is type safe. return pwriteBytes(fd, bytes, byteOffset, byteCount, offset); } - private native int pwriteBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException; - public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException { +// begin WITH_TAINT_TRACKING + //private native int pwriteBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException; + private native int pwriteBytesImpl(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException; + private int pwriteBytes(FileDescriptor fd, Object buffer, int bufferOffset, int byteCount, long offset) throws ErrnoException { + if (buffer == null) { + throw new NullPointerException(); + } + + if (buffer instanceof byte[]) { + int fdInt = fd.getDescriptor(); + int tag = Taint.getTaintByteArray((byte[]) buffer); + if (tag != Taint.TAINT_CLEAR) { + String dstr = new String((byte[]) buffer, bufferOffset, ((byteCount > Taint.dataBytesToLog) ? Taint.dataBytesToLog : byteCount)); + // replace non-printable characters + dstr = dstr.replaceAll("\\p{C}", "."); + Taint.logPathFromFd(fdInt); + String tstr = "0x" + Integer.toHexString(tag); + // Taint.log("libcore.os.pwrite(" + fdInt + ") writing with tag " + tstr + " data[" + dstr + "]"); + Taint.writeTaintLongBuffer("libcore.os.pwrite", buffer, bufferOffset, byteCount, "" + fdInt, tstr, true); + Taint.addTaintFile(fdInt, tag); + } + } + int bytesWritten = pwriteBytesImpl(fd, buffer, bufferOffset, byteCount, offset); + return bytesWritten; + } +// end WITH_TAINT_TRACKING + public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException { if (buffer.isDirect()) { return readBytes(fd, buffer, buffer.position(), buffer.remaining()); } else { @@ -117,7 +193,29 @@ public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) // This indirection isn't strictly necessary, but ensures that our public interface is type safe. return readBytes(fd, bytes, byteOffset, byteCount); } - private native int readBytes(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException; + +// begin WITH_TAINT_TRACKING + //private native int readBytes(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException; + private native int readBytesImpl(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException; + private int readBytes(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException { + if (buffer == null) { + throw new NullPointerException(); + } + int bytesRead = readBytesImpl(fd, buffer, offset, byteCount); + int fdInt = fd.getDescriptor(); + int tag = Taint.getTaintFile(fdInt); + if (tag != Taint.TAINT_CLEAR) { + String dstr = new String((byte[])buffer, offset, ((byteCount > Taint.dataBytesToLog) ? Taint.dataBytesToLog : byteCount)); + // replace non-printable characters + dstr = dstr.replaceAll("\\p{C}", "."); + String tstr = "0x" + Integer.toHexString(tag); + // Taint.log("libcore.os.read(" + fdInt + ") reading with tag " + tstr + " data[" + dstr + "]"); + Taint.writeTaintLongBuffer("libcore.os.read", buffer, offset, byteCount, ""+fdInt, tstr, true); + Taint.addTaintByteArray((byte[])buffer, tag); + } + return bytesRead; + } +// end WITH_TAINT_TRACKING public native int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException; public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException { if (buffer.isDirect()) { @@ -136,6 +234,15 @@ public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCou public native long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException; public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException { if (buffer.isDirect()) { +// begin WITH_TAINT_TRACKING + int tag = buffer.getDirectByteBufferTaint(); + if (tag != Taint.TAINT_CLEAR) { + String addr = (fd.hasName) ? fd.name : "unknown"; + String tstr = "0x" + Integer.toHexString(tag); + Taint.log("libcore.os.sendto(" + addr + ") received a ByteBuffer with tag " + tstr); + Taint.writeTaintLongData("libcore.os.sendto", "received a Bytebuffer", "", tstr, false); + } +// end WITH_TAINT_TRACKING return sendtoBytes(fd, buffer, buffer.position(), buffer.remaining(), flags, inetAddress, port); } else { return sendtoBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + buffer.position(), buffer.remaining(), flags, inetAddress, port); @@ -145,7 +252,27 @@ public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount // This indirection isn't strictly necessary, but ensures that our public interface is type safe. return sendtoBytes(fd, bytes, byteOffset, byteCount, flags, inetAddress, port); } - private native int sendtoBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException; + +// begin WITH_TAINT_TRACKING + //private native int sendtoBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException; + private native int sendtoBytesImpl(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException; + private int sendtoBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException { + if (buffer instanceof byte[]) { + int tag = Taint.getTaintByteArray((byte[]) buffer); + if (tag != Taint.TAINT_CLEAR) { + String dstr = new String((byte[]) buffer, byteOffset, ((byteCount > Taint.dataBytesToLog) ? Taint.dataBytesToLog : byteCount)); + // replace non-printable characters + dstr = dstr.replaceAll("\\p{C}", "."); + String addr = (fd.hasName) ? fd.name : "unknown"; + String tstr = "0x" + Integer.toHexString(tag); + // Taint.log("libcore.os.send("+addr+") received data with tag " + tstr + " data=["+dstr+"] "); + Taint.writeTaintLongBuffer("libcore.os.send", buffer, byteOffset, byteCount, addr,tstr, true); + } + } + return sendtoBytesImpl(fd, buffer, byteOffset, byteCount, flags, inetAddress, port); + } +// end WITH_TAINT_TRACKING + public native void setegid(int egid) throws ErrnoException; public native void seteuid(int euid) throws ErrnoException; public native void setgid(int gid) throws ErrnoException; @@ -168,6 +295,16 @@ public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount public native int waitpid(int pid, MutableInt status, int options) throws ErrnoException; public int write(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException { if (buffer.isDirect()) { +// begin WITH_TAINT_TRACKING + int tag = buffer.getDirectByteBufferTaint(); + if (tag != Taint.TAINT_CLEAR) { + int fdInt = fd.getDescriptor(); + Taint.logPathFromFd(fdInt); + String tstr = "0x" + Integer.toHexString(tag); + Taint.log("libcore.os.write(" + fdInt + ") writing a direct ByteBuffer with tag " + tstr); + Taint.addTaintFile(fdInt, tag); + } +// end WITH_TAINT_TRACKING return writeBytes(fd, buffer, buffer.position(), buffer.remaining()); } else { return writeBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + buffer.position(), buffer.remaining()); @@ -177,6 +314,35 @@ public int write(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) // This indirection isn't strictly necessary, but ensures that our public interface is type safe. return writeBytes(fd, bytes, byteOffset, byteCount); } - private native int writeBytes(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException; + +//begin WITH_TAINT_TRACKING + //private native int writeBytes(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException; + private native int writeBytesImpl(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException; + private int writeBytes(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException { + if (buffer == null) { + throw new NullPointerException(); + } + + if (buffer instanceof byte[]) { + int fdInt = fd.getDescriptor(); + int tag = Taint.getTaintByteArray((byte[]) buffer); + if (tag != Taint.TAINT_CLEAR) { + //We only display at most Taint.dataBytesToLog characters of the data in logcat, to avoid the overflow + // String dstr = new String((byte[]) buffer, offset, ((byteCount > Taint.dataBytesToLog) ? Taint.dataBytesToLog : byteCount)); + + // replace non-printable characters + // dstr = dstr.replaceAll("\\p{C}", "."); + Taint.logPathFromFd(fdInt); + String tstr = "0x" + Integer.toHexString(tag); + Taint.writeTaintLongBuffer("libcore.os.write",buffer, offset, byteCount, "" + fdInt, tstr, true); + Taint.addTaintFile(fdInt, tag); + } + } + int bytesWritten = writeBytesImpl(fd, buffer, offset, byteCount); + return bytesWritten; + } + + +//end WITH_TAINT_TRACKING public native int writev(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException; } diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java index 4c92952bb..de7686d66 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java @@ -44,6 +44,9 @@ import javax.security.auth.x500.X500Principal; import libcore.io.Streams; import org.apache.harmony.security.provider.cert.X509CertImpl; +// begin WITH_TAINT_TRACKING +import dalvik.system.Taint; +// end WITH_TAINT_TRACKING /** * Implementation of the class OpenSSLSocketImpl based on OpenSSL. @@ -512,6 +515,7 @@ private void setCertificate(String alias) throws CertificateEncodingException, S NativeCrypto.SSL_check_private_key(sslNativePointer); } + @Override @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks / client_cert_cb public void clientCertificateRequested(byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals) throws CertificateEncodingException, SSLException { @@ -533,6 +537,7 @@ public void clientCertificateRequested(byte[] keyTypeBytes, byte[][] asn1DerEnco setCertificate(sslParameters.getKeyManager().chooseClientAlias(keyTypes, issuers, this)); } + @Override @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks / info_callback public void handshakeCompleted() { handshakeCompleted = true; @@ -698,6 +703,23 @@ private class SSLOutputStream extends OutputStream { */ @Override public void write(int oneByte) throws IOException { +// begin WITH_TAINT_TRACKING + int tag = Taint.getTaintInt(oneByte); + FileDescriptor fd = socket.getFileDescriptor$(); + if (tag != Taint.TAINT_CLEAR) { + String dstr = String.valueOf(oneByte); + // We only display at most Taint.dataBytesToLog characters in logcat of data + // if (dstr.length() > Taint.dataBytesToLog) { + // dstr = dstr.substring(0, Taint.dataBytesToLog); + // } + // replace non-printable characters + // dstr = dstr.replaceAll("\\p{C}", "."); + String addr = (fd.hasName) ? fd.name : "unknown"; + String tstr = "0x" + Integer.toHexString(tag); + // Taint.log("SSLOutputStream.write(" + addr + ") received data with tag " + tstr + " data=[" + dstr + "]"); + Taint.writeTaintLongData("SSLOutputStream.write", dstr, addr, tstr, true); + } +// end WITH_TAINT_TRACKING Streams.writeSingleByte(this, oneByte); } @@ -714,6 +736,26 @@ public void write(byte[] buf, int offset, int byteCount) throws IOException { if (byteCount == 0) { return; } +// begin WITH_TAINT_TRACKING + int tag = Taint.getTaintByteArray(buf); + FileDescriptor fd = socket.getFileDescriptor$(); + if (tag != Taint.TAINT_CLEAR) { + /* + * int disLen = byteCount; + * if (byteCount > Taint.dataBytesToLog) { + * disLen = Taint.dataBytesToLog; + * } + */ + // We only display at most Taint.dataBytesToLog characters in logcat + // String dstr = new String(buf, offset, disLen); + // replace non-printable characters + // dstr = dstr.replaceAll("\\p{C}", "."); + String addr = (fd.hasName) ? fd.name : "unknown"; + String tstr = "0x" + Integer.toHexString(tag); + // Taint.log("SSLOutputStream.write(" + addr + ") received data with tag " + tstr + " data=[" + dstr + "]"); + Taint.writeTaintLongBuffer("SSLOutputStream.write", buf, offset, byteCount, addr, tstr, true); + } +// end WITH_TAINT_TRACKING NativeCrypto.SSL_write(sslNativePointer, socket.getFileDescriptor$(), OpenSSLSocketImpl.this, buf, offset, byteCount); } diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp index 30ca14559..8fd7d8f14 100644 --- a/luni/src/main/native/libcore_io_Posix.cpp +++ b/luni/src/main/native/libcore_io_Posix.cpp @@ -432,7 +432,10 @@ static void Posix_close(JNIEnv* env, jobject, jobject javaFd) { throwIfMinusOne(env, "close", close(fd)); } -static void Posix_connect(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) { +// begin WITH_TAINT_TRACKING +//static void Posix_connect(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) { +static void Posix_connectImpl(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) { +// end WITH_TAINT_TRACKING sockaddr_storage ss; if (!inetAddressToSockaddr(env, javaAddress, port, &ss)) { return; @@ -827,7 +830,21 @@ static void Posix_mkdir(JNIEnv* env, jobject, jstring javaPath, jint mode) { if (path.c_str() == NULL) { return; } +#ifdef WITH_TAINT_TRACKING + // In case the SDcard is ext2, make sure it is 777 + if ((strncmp(path.c_str(), "/sdcard", sizeof("/sdcard")-1) == 0) || + (strncmp(path.c_str(), "/mnt/sdcard", sizeof("/mnt/sdcard")-1)==0) || + (strncmp(path.c_str(), "/storage/sdcard", sizeof("/storage/sdcard")-1)==0)) { + //return (mkdir(path.c_str(), S_IRWXU|S_IRWXG|S_IRWXO) == 0); + throwIfMinusOne(env, "mkdir", TEMP_FAILURE_RETRY(mkdir(path.c_str(), S_IRWXU|S_IRWXG|S_IRWXO))); + } else if (strncmp(path.c_str(), "/data/taintwall", 15) == 0) { + throwIfMinusOne(env, "mkdir", TEMP_FAILURE_RETRY(mkdir(path.c_str(), S_IRWXU|S_IRWXG|S_IRWXO))); + } else { + throwIfMinusOne(env, "mkdir", TEMP_FAILURE_RETRY(mkdir(path.c_str(), mode))); + } +#else throwIfMinusOne(env, "mkdir", TEMP_FAILURE_RETRY(mkdir(path.c_str(), mode))); +#endif } static void Posix_mlock(JNIEnv* env, jobject, jlong address, jlong byteCount) { @@ -865,6 +882,20 @@ static jobject Posix_open(JNIEnv* env, jobject, jstring javaPath, jint flags, ji if (path.c_str() == NULL) { return NULL; } +#ifdef WITH_TAINT_TRACKING + // Ensure /sdcard always acts like FAT, even if it is ext2 + if ((strncmp(path.c_str(), "/sdcard", sizeof("/sdcard")-1) == 0) || + (strncmp(path.c_str(), "/mnt/sdcard", sizeof("/mnt/sdcard")-1)==0) || + (strncmp(path.c_str(), "/storage/sdcard", sizeof("/storage/sdcard")-1)==0)) { + mode = 0777; + } + + // Tuan: change permission of every file in this folder, so everyone can read, but just the owner can write + // maybe we need to verify the app name as well, just "taintwall" can modify here + if ((strncmp(path.c_str(), "/data/taintwall/", 16) == 0)) { + mode = 0644; + } +#endif int fd = throwIfMinusOne(env, "open", TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode))); return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL; } @@ -939,7 +970,10 @@ static jint Posix_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint time return rc; } -static jint Posix_preadBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jlong offset) { +// begin WITH_TAINT_TRACKING +//static jint Posix_preadBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jlong offset) { +static jint Posix_preadBytesImpl(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jlong offset) { +// end WITH_TAINT_TRACKING ScopedBytesRW bytes(env, javaBytes); if (bytes.get() == NULL) { return -1; @@ -948,7 +982,10 @@ static jint Posix_preadBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaB return throwIfMinusOne(env, "pread", TEMP_FAILURE_RETRY(pread64(fd, bytes.get() + byteOffset, byteCount, offset))); } -static jint Posix_pwriteBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount, jlong offset) { +// begin WITH_TAINT_TRACKING +//static jint Posix_pwriteBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount, jlong offset) { +static jint Posix_pwriteBytesImpl(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount, jlong offset) { +// end WITH_TAINT_TRACKING ScopedBytesRO bytes(env, javaBytes); if (bytes.get() == NULL) { return -1; @@ -957,7 +994,10 @@ static jint Posix_pwriteBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray j return throwIfMinusOne(env, "pwrite", TEMP_FAILURE_RETRY(pwrite64(fd, bytes.get() + byteOffset, byteCount, offset))); } -static jint Posix_readBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount) { +// begin WITH_TAINT_TRACKING +//static jint Posix_readBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount) { +static jint Posix_readBytesImpl(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount) { +// end WITH_TAINT_TRACKING ScopedBytesRW bytes(env, javaBytes); if (bytes.get() == NULL) { return -1; @@ -1029,7 +1069,10 @@ static jlong Posix_sendfile(JNIEnv* env, jobject, jobject javaOutFd, jobject jav return result; } -static jint Posix_sendtoBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetAddress, jint port) { +// begin WITH_TAINT_TRACKING +//static jint Posix_sendtoBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetAddress, jint port) { +static jint Posix_sendtoBytesImpl(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetAddress, jint port) { +// end WITH_TAINT_TRACKING ScopedBytesRO bytes(env, javaBytes); if (bytes.get() == NULL) { return -1; @@ -1213,7 +1256,10 @@ static jint Posix_waitpid(JNIEnv* env, jobject, jint pid, jobject javaStatus, ji return rc; } -static jint Posix_writeBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount) { +// begin WITH_TAINT_TRACKING +//static jint Posix_writeBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount) { +static jint Posix_writeBytesImpl(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount) { +// end WITH_TAINT_TRACKING ScopedBytesRO bytes(env, javaBytes); if (bytes.get() == NULL) { return -1; @@ -1237,7 +1283,10 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Posix, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"), NATIVE_METHOD(Posix, chmod, "(Ljava/lang/String;I)V"), NATIVE_METHOD(Posix, close, "(Ljava/io/FileDescriptor;)V"), - NATIVE_METHOD(Posix, connect, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"), +// begin WITH_TAINT_TRACKING + //NATIVE_METHOD(Posix, connect, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"), + NATIVE_METHOD(Posix, connectImpl, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"), +// end WITH_TAINT_TRACKING NATIVE_METHOD(Posix, dup, "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;"), NATIVE_METHOD(Posix, dup2, "(Ljava/io/FileDescriptor;I)Ljava/io/FileDescriptor;"), NATIVE_METHOD(Posix, environ, "()[Ljava/lang/String;"), @@ -1286,15 +1335,23 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Posix, open, "(Ljava/lang/String;II)Ljava/io/FileDescriptor;"), NATIVE_METHOD(Posix, pipe, "()[Ljava/io/FileDescriptor;"), NATIVE_METHOD(Posix, poll, "([Llibcore/io/StructPollfd;I)I"), - NATIVE_METHOD(Posix, preadBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"), - NATIVE_METHOD(Posix, pwriteBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"), - NATIVE_METHOD(Posix, readBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"), +// begin WITH_TAINT_TRACKING + //NATIVE_METHOD(Posix, preadBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"), + //NATIVE_METHOD(Posix, pwriteBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"), + //NATIVE_METHOD(Posix, readBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"), + NATIVE_METHOD(Posix, preadBytesImpl, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"), + NATIVE_METHOD(Posix, pwriteBytesImpl, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"), + NATIVE_METHOD(Posix, readBytesImpl, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"), +// end WITH_TAINT_TRACKING NATIVE_METHOD(Posix, readv, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"), NATIVE_METHOD(Posix, recvfromBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetSocketAddress;)I"), NATIVE_METHOD(Posix, remove, "(Ljava/lang/String;)V"), NATIVE_METHOD(Posix, rename, "(Ljava/lang/String;Ljava/lang/String;)V"), NATIVE_METHOD(Posix, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Llibcore/util/MutableLong;J)J"), - NATIVE_METHOD(Posix, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"), +// begin WITH_TAINT_TRACKING + //NATIVE_METHOD(Posix, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"), + NATIVE_METHOD(Posix, sendtoBytesImpl, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"), +// end WITH_TAINT_TRACKING NATIVE_METHOD(Posix, setegid, "(I)V"), NATIVE_METHOD(Posix, seteuid, "(I)V"), NATIVE_METHOD(Posix, setgid, "(I)V"), @@ -1315,7 +1372,10 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Posix, sysconf, "(I)J"), NATIVE_METHOD(Posix, uname, "()Llibcore/io/StructUtsname;"), NATIVE_METHOD(Posix, waitpid, "(ILlibcore/util/MutableInt;I)I"), - NATIVE_METHOD(Posix, writeBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"), +// begin WITH_TAINT_TRACKING + //NATIVE_METHOD(Posix, writeBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"), + NATIVE_METHOD(Posix, writeBytesImpl, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"), +// end WITH_TAINT_TRACKING NATIVE_METHOD(Posix, writev, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"), }; void register_libcore_io_Posix(JNIEnv* env) {