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> 20c90ca48a7c5981f1ebcb40ccab6e2ebbafe4c669Henrik Baard#include <ScopedUtfChars.h> 2168d4acd205e8c2da524e62734ca42847306cc029Andres Morales 2268d4acd205e8c2da524e62734ca42847306cc029Andres Morales#include <utils/misc.h> 2368d4acd205e8c2da524e62734ca42847306cc029Andres Morales#include <sys/ioctl.h> 2468d4acd205e8c2da524e62734ca42847306cc029Andres Morales#include <sys/mount.h> 25963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales#include <utils/Log.h> 26963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 2768d4acd205e8c2da524e62734ca42847306cc029Andres Morales 2868d4acd205e8c2da524e62734ca42847306cc029Andres Morales#include <inttypes.h> 2968d4acd205e8c2da524e62734ca42847306cc029Andres Morales#include <fcntl.h> 30963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales#include <errno.h> 31963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales#include <string.h> 3268d4acd205e8c2da524e62734ca42847306cc029Andres Morales 3368d4acd205e8c2da524e62734ca42847306cc029Andres Moralesnamespace android { 3468d4acd205e8c2da524e62734ca42847306cc029Andres Morales 3568d4acd205e8c2da524e62734ca42847306cc029Andres Morales uint64_t get_block_device_size(int fd) 3668d4acd205e8c2da524e62734ca42847306cc029Andres Morales { 3768d4acd205e8c2da524e62734ca42847306cc029Andres Morales uint64_t size = 0; 3868d4acd205e8c2da524e62734ca42847306cc029Andres Morales int ret; 3968d4acd205e8c2da524e62734ca42847306cc029Andres Morales 4068d4acd205e8c2da524e62734ca42847306cc029Andres Morales ret = ioctl(fd, BLKGETSIZE64, &size); 4168d4acd205e8c2da524e62734ca42847306cc029Andres Morales 4268d4acd205e8c2da524e62734ca42847306cc029Andres Morales if (ret) 4368d4acd205e8c2da524e62734ca42847306cc029Andres Morales return 0; 4468d4acd205e8c2da524e62734ca42847306cc029Andres Morales 4568d4acd205e8c2da524e62734ca42847306cc029Andres Morales return size; 4668d4acd205e8c2da524e62734ca42847306cc029Andres Morales } 4768d4acd205e8c2da524e62734ca42847306cc029Andres Morales 48963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales int wipe_block_device(int fd) 49963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales { 50963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales uint64_t range[2]; 51963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales int ret; 52963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales uint64_t len = get_block_device_size(fd); 53963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 54963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales range[0] = 0; 55963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales range[1] = len; 56963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 57963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales if (range[1] == 0) 58963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales return 0; 59963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 60963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales ret = ioctl(fd, BLKSECDISCARD, &range); 61963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales if (ret < 0) { 62963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales ALOGE("Something went wrong secure discarding block: %s\n", strerror(errno)); 63963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales range[0] = 0; 64963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales range[1] = len; 65963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales ret = ioctl(fd, BLKDISCARD, &range); 66963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales if (ret < 0) { 67963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales ALOGE("Discard failed: %s\n", strerror(errno)); 68963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales return -1; 69963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales } else { 70963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales ALOGE("Wipe via secure discard failed, used non-secure discard instead\n"); 71963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales return 0; 72963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales } 73963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 74963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales } 75963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 76963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales return ret; 77963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales } 78963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 79963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales static jlong com_android_server_PersistentDataBlockService_getBlockDeviceSize(JNIEnv *env, jclass, jstring jpath) 80963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales { 81c90ca48a7c5981f1ebcb40ccab6e2ebbafe4c669Henrik Baard ScopedUtfChars path(env, jpath); 82c90ca48a7c5981f1ebcb40ccab6e2ebbafe4c669Henrik Baard int fd = open(path.c_str(), O_RDONLY); 8368d4acd205e8c2da524e62734ca42847306cc029Andres Morales 8468d4acd205e8c2da524e62734ca42847306cc029Andres Morales if (fd < 0) 8568d4acd205e8c2da524e62734ca42847306cc029Andres Morales return 0; 8668d4acd205e8c2da524e62734ca42847306cc029Andres Morales 875c74bb313fbe3fb479f9dc4296e46e9586faf946Lianwei Wang const uint64_t size = get_block_device_size(fd); 885c74bb313fbe3fb479f9dc4296e46e9586faf946Lianwei Wang 895c74bb313fbe3fb479f9dc4296e46e9586faf946Lianwei Wang close(fd); 905c74bb313fbe3fb479f9dc4296e46e9586faf946Lianwei Wang 915c74bb313fbe3fb479f9dc4296e46e9586faf946Lianwei Wang return size; 9268d4acd205e8c2da524e62734ca42847306cc029Andres Morales } 9368d4acd205e8c2da524e62734ca42847306cc029Andres Morales 94963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales static int com_android_server_PersistentDataBlockService_wipe(JNIEnv *env, jclass, jstring jpath) { 95c90ca48a7c5981f1ebcb40ccab6e2ebbafe4c669Henrik Baard ScopedUtfChars path(env, jpath); 96c90ca48a7c5981f1ebcb40ccab6e2ebbafe4c669Henrik Baard int fd = open(path.c_str(), O_WRONLY); 97963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 98963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales if (fd < 0) 99963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales return 0; 100963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 1015c74bb313fbe3fb479f9dc4296e46e9586faf946Lianwei Wang const int ret = wipe_block_device(fd); 1025c74bb313fbe3fb479f9dc4296e46e9586faf946Lianwei Wang 1035c74bb313fbe3fb479f9dc4296e46e9586faf946Lianwei Wang close(fd); 1045c74bb313fbe3fb479f9dc4296e46e9586faf946Lianwei Wang 1055c74bb313fbe3fb479f9dc4296e46e9586faf946Lianwei Wang return ret; 106963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales } 107963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales 10876f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micay static const JNINativeMethod sMethods[] = { 10968d4acd205e8c2da524e62734ca42847306cc029Andres Morales /* name, signature, funcPtr */ 110963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales {"nativeGetBlockDeviceSize", "(Ljava/lang/String;)J", (void*)com_android_server_PersistentDataBlockService_getBlockDeviceSize}, 111963295ea105314e28e4ca9563aa09cb7440de4c3Andres Morales {"nativeWipe", "(Ljava/lang/String;)I", (void*)com_android_server_PersistentDataBlockService_wipe}, 11268d4acd205e8c2da524e62734ca42847306cc029Andres Morales }; 11368d4acd205e8c2da524e62734ca42847306cc029Andres Morales 11468d4acd205e8c2da524e62734ca42847306cc029Andres Morales int register_android_server_PersistentDataBlockService(JNIEnv* env) 11568d4acd205e8c2da524e62734ca42847306cc029Andres Morales { 11668d4acd205e8c2da524e62734ca42847306cc029Andres Morales return jniRegisterNativeMethods(env, "com/android/server/PersistentDataBlockService", 11768d4acd205e8c2da524e62734ca42847306cc029Andres Morales sMethods, NELEM(sMethods)); 11868d4acd205e8c2da524e62734ca42847306cc029Andres Morales } 11968d4acd205e8c2da524e62734ca42847306cc029Andres Morales 12068d4acd205e8c2da524e62734ca42847306cc029Andres Morales} /* namespace android */