1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <android_runtime/AndroidRuntime.h> 18 #include <JNIHelp.h> 19 #include <jni.h> 20 21 #include <utils/misc.h> 22 #include <sys/ioctl.h> 23 #include <sys/mount.h> 24 #include <utils/Log.h> 25 26 27 #include <inttypes.h> 28 #include <fcntl.h> 29 #include <errno.h> 30 #include <string.h> 31 32 namespace android { 33 get_block_device_size(int fd)34 uint64_t get_block_device_size(int fd) 35 { 36 uint64_t size = 0; 37 int ret; 38 39 ret = ioctl(fd, BLKGETSIZE64, &size); 40 41 if (ret) 42 return 0; 43 44 return size; 45 } 46 wipe_block_device(int fd)47 int wipe_block_device(int fd) 48 { 49 uint64_t range[2]; 50 int ret; 51 uint64_t len = get_block_device_size(fd); 52 53 range[0] = 0; 54 range[1] = len; 55 56 if (range[1] == 0) 57 return 0; 58 59 ret = ioctl(fd, BLKSECDISCARD, &range); 60 if (ret < 0) { 61 ALOGE("Something went wrong secure discarding block: %s\n", strerror(errno)); 62 range[0] = 0; 63 range[1] = len; 64 ret = ioctl(fd, BLKDISCARD, &range); 65 if (ret < 0) { 66 ALOGE("Discard failed: %s\n", strerror(errno)); 67 return -1; 68 } else { 69 ALOGE("Wipe via secure discard failed, used non-secure discard instead\n"); 70 return 0; 71 } 72 73 } 74 75 return ret; 76 } 77 com_android_server_PersistentDataBlockService_getBlockDeviceSize(JNIEnv * env,jclass,jstring jpath)78 static jlong com_android_server_PersistentDataBlockService_getBlockDeviceSize(JNIEnv *env, jclass, jstring jpath) 79 { 80 const char *path = env->GetStringUTFChars(jpath, 0); 81 int fd = open(path, O_RDONLY); 82 83 if (fd < 0) 84 return 0; 85 86 return get_block_device_size(fd); 87 } 88 com_android_server_PersistentDataBlockService_wipe(JNIEnv * env,jclass,jstring jpath)89 static int com_android_server_PersistentDataBlockService_wipe(JNIEnv *env, jclass, jstring jpath) { 90 const char *path = env->GetStringUTFChars(jpath, 0); 91 int fd = open(path, O_WRONLY); 92 93 if (fd < 0) 94 return 0; 95 96 return wipe_block_device(fd); 97 } 98 99 static JNINativeMethod sMethods[] = { 100 /* name, signature, funcPtr */ 101 {"nativeGetBlockDeviceSize", "(Ljava/lang/String;)J", (void*)com_android_server_PersistentDataBlockService_getBlockDeviceSize}, 102 {"nativeWipe", "(Ljava/lang/String;)I", (void*)com_android_server_PersistentDataBlockService_wipe}, 103 }; 104 register_android_server_PersistentDataBlockService(JNIEnv * env)105 int register_android_server_PersistentDataBlockService(JNIEnv* env) 106 { 107 return jniRegisterNativeMethods(env, "com/android/server/PersistentDataBlockService", 108 sMethods, NELEM(sMethods)); 109 } 110 111 } /* namespace android */