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 */