168d4acd205e8c2da524e62734ca42847306cc029Andres Morales/* 268d4acd205e8c2da524e62734ca42847306cc029Andres Morales * Copyright (C) 2010 The Android Open Source Project 368d4acd205e8c2da524e62734ca42847306cc029Andres Morales * 468d4acd205e8c2da524e62734ca42847306cc029Andres Morales * Licensed under the Apache License, Version 2.0 (the "License"); 568d4acd205e8c2da524e62734ca42847306cc029Andres Morales * you may not use this file except in compliance with the License. 668d4acd205e8c2da524e62734ca42847306cc029Andres Morales * You may obtain a copy of the License at 768d4acd205e8c2da524e62734ca42847306cc029Andres Morales * 868d4acd205e8c2da524e62734ca42847306cc029Andres Morales * http://www.apache.org/licenses/LICENSE-2.0 968d4acd205e8c2da524e62734ca42847306cc029Andres Morales * 1068d4acd205e8c2da524e62734ca42847306cc029Andres Morales * Unless required by applicable law or agreed to in writing, software 1168d4acd205e8c2da524e62734ca42847306cc029Andres Morales * distributed under the License is distributed on an "AS IS" BASIS, 1268d4acd205e8c2da524e62734ca42847306cc029Andres Morales * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1368d4acd205e8c2da524e62734ca42847306cc029Andres Morales * See the License for the specific language governing permissions and 1468d4acd205e8c2da524e62734ca42847306cc029Andres Morales * limitations under the License. 1568d4acd205e8c2da524e62734ca42847306cc029Andres Morales */ 1668d4acd205e8c2da524e62734ca42847306cc029Andres Morales 1768d4acd205e8c2da524e62734ca42847306cc029Andres Morales#include <android_runtime/AndroidRuntime.h> 1868d4acd205e8c2da524e62734ca42847306cc029Andres Morales#include <JNIHelp.h> 1968d4acd205e8c2da524e62734ca42847306cc029Andres Morales#include <jni.h> 2068d4acd205e8c2da524e62734ca42847306cc029Andres Morales 2168d4acd205e8c2da524e62734ca42847306cc029Andres Morales#include <utils/misc.h> 2268d4acd205e8c2da524e62734ca42847306cc029Andres Morales#include <sys/ioctl.h> 2368d4acd205e8c2da524e62734ca42847306cc029Andres Morales#include <sys/mount.h> 24963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales#include <utils/Log.h> 25963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 2668d4acd205e8c2da524e62734ca42847306cc029Andres Morales 2768d4acd205e8c2da524e62734ca42847306cc029Andres Morales#include <inttypes.h> 2868d4acd205e8c2da524e62734ca42847306cc029Andres Morales#include <fcntl.h> 29963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales#include <errno.h> 30963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales#include <string.h> 3168d4acd205e8c2da524e62734ca42847306cc029Andres Morales 3268d4acd205e8c2da524e62734ca42847306cc029Andres Moralesnamespace android { 3368d4acd205e8c2da524e62734ca42847306cc029Andres Morales 3468d4acd205e8c2da524e62734ca42847306cc029Andres Morales uint64_t get_block_device_size(int fd) 3568d4acd205e8c2da524e62734ca42847306cc029Andres Morales { 3668d4acd205e8c2da524e62734ca42847306cc029Andres Morales uint64_t size = 0; 3768d4acd205e8c2da524e62734ca42847306cc029Andres Morales int ret; 3868d4acd205e8c2da524e62734ca42847306cc029Andres Morales 3968d4acd205e8c2da524e62734ca42847306cc029Andres Morales ret = ioctl(fd, BLKGETSIZE64, &size); 4068d4acd205e8c2da524e62734ca42847306cc029Andres Morales 4168d4acd205e8c2da524e62734ca42847306cc029Andres Morales if (ret) 4268d4acd205e8c2da524e62734ca42847306cc029Andres Morales return 0; 4368d4acd205e8c2da524e62734ca42847306cc029Andres Morales 4468d4acd205e8c2da524e62734ca42847306cc029Andres Morales return size; 4568d4acd205e8c2da524e62734ca42847306cc029Andres Morales } 4668d4acd205e8c2da524e62734ca42847306cc029Andres Morales 47963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales int wipe_block_device(int fd) 48963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales { 49963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales uint64_t range[2]; 50963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales int ret; 51963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales uint64_t len = get_block_device_size(fd); 52963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 53963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales range[0] = 0; 54963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales range[1] = len; 55963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 56963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales if (range[1] == 0) 57963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales return 0; 58963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 59963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales ret = ioctl(fd, BLKSECDISCARD, &range); 60963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales if (ret < 0) { 61963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales ALOGE("Something went wrong secure discarding block: %s\n", strerror(errno)); 62963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales range[0] = 0; 63963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales range[1] = len; 64963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales ret = ioctl(fd, BLKDISCARD, &range); 65963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales if (ret < 0) { 66963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales ALOGE("Discard failed: %s\n", strerror(errno)); 67963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales return -1; 68963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales } else { 69963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales ALOGE("Wipe via secure discard failed, used non-secure discard instead\n"); 70963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales return 0; 71963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales } 72963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 73963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales } 74963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 75963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales return ret; 76963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales } 77963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 78963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales static jlong com_android_server_PersistentDataBlockService_getBlockDeviceSize(JNIEnv *env, jclass, jstring jpath) 79963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales { 8068d4acd205e8c2da524e62734ca42847306cc029Andres Morales const char *path = env->GetStringUTFChars(jpath, 0); 8168d4acd205e8c2da524e62734ca42847306cc029Andres Morales int fd = open(path, O_RDONLY); 8268d4acd205e8c2da524e62734ca42847306cc029Andres Morales 8368d4acd205e8c2da524e62734ca42847306cc029Andres Morales if (fd < 0) 8468d4acd205e8c2da524e62734ca42847306cc029Andres Morales return 0; 8568d4acd205e8c2da524e62734ca42847306cc029Andres Morales 8668d4acd205e8c2da524e62734ca42847306cc029Andres Morales return get_block_device_size(fd); 8768d4acd205e8c2da524e62734ca42847306cc029Andres Morales } 8868d4acd205e8c2da524e62734ca42847306cc029Andres Morales 89963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales static int com_android_server_PersistentDataBlockService_wipe(JNIEnv *env, jclass, jstring jpath) { 90963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales const char *path = env->GetStringUTFChars(jpath, 0); 91963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales int fd = open(path, O_WRONLY); 92963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 93963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales if (fd < 0) 94963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales return 0; 95963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 96963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales return wipe_block_device(fd); 97963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales } 98963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 9968d4acd205e8c2da524e62734ca42847306cc029Andres Morales static JNINativeMethod sMethods[] = { 10068d4acd205e8c2da524e62734ca42847306cc029Andres Morales /* name, signature, funcPtr */ 101963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales {"nativeGetBlockDeviceSize", "(Ljava/lang/String;)J", (void*)com_android_server_PersistentDataBlockService_getBlockDeviceSize}, 102963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales {"nativeWipe", "(Ljava/lang/String;)I", (void*)com_android_server_PersistentDataBlockService_wipe}, 10368d4acd205e8c2da524e62734ca42847306cc029Andres Morales }; 10468d4acd205e8c2da524e62734ca42847306cc029Andres Morales 10568d4acd205e8c2da524e62734ca42847306cc029Andres Morales int register_android_server_PersistentDataBlockService(JNIEnv* env) 10668d4acd205e8c2da524e62734ca42847306cc029Andres Morales { 10768d4acd205e8c2da524e62734ca42847306cc029Andres Morales return jniRegisterNativeMethods(env, "com/android/server/PersistentDataBlockService", 10868d4acd205e8c2da524e62734ca42847306cc029Andres Morales sMethods, NELEM(sMethods)); 10968d4acd205e8c2da524e62734ca42847306cc029Andres Morales } 11068d4acd205e8c2da524e62734ca42847306cc029Andres Morales 11168d4acd205e8c2da524e62734ca42847306cc029Andres Morales} /* namespace android */