Merge "clang-format many files."

gugelfrei
Paul Crowley 6 years ago committed by Gerrit Code Review
commit a676df01e2

@ -28,8 +28,8 @@
#include <thread> #include <thread>
#include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h> #include <unistd.h>
using android::base::ReadFileToString; using android::base::ReadFileToString;
@ -50,12 +50,12 @@ constexpr auto kTimeout = 20s;
// RAII class for boosting device performance during benchmarks. // RAII class for boosting device performance during benchmarks.
class PerformanceBoost { class PerformanceBoost {
private: private:
int orig_prio; int orig_prio;
int orig_ioprio; int orig_ioprio;
IoSchedClass orig_clazz; IoSchedClass orig_clazz;
public: public:
PerformanceBoost() { PerformanceBoost() {
errno = 0; errno = 0;
orig_prio = getpriority(PRIO_PROCESS, 0); orig_prio = getpriority(PRIO_PROCESS, 0);
@ -87,8 +87,8 @@ public:
}; };
static status_t benchmarkInternal(const std::string& rootPath, static status_t benchmarkInternal(const std::string& rootPath,
const android::sp<android::os::IVoldTaskListener>& listener, const android::sp<android::os::IVoldTaskListener>& listener,
android::os::PersistableBundle* extras) { android::os::PersistableBundle* extras) {
status_t res = 0; status_t res = 0;
auto path = rootPath; auto path = rootPath;
@ -179,7 +179,7 @@ static status_t benchmarkInternal(const std::string& rootPath,
} }
void Benchmark(const std::string& path, void Benchmark(const std::string& path,
const android::sp<android::os::IVoldTaskListener>& listener) { const android::sp<android::os::IVoldTaskListener>& listener) {
std::lock_guard<std::mutex> lock(kBenchmarkLock); std::lock_guard<std::mutex> lock(kBenchmarkLock);
acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLock); acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLock);

@ -24,8 +24,10 @@
namespace android { namespace android {
namespace vold { namespace vold {
// clang-format off
void Benchmark(const std::string& path, void Benchmark(const std::string& path,
const android::sp<android::os::IVoldTaskListener>& listener); const android::sp<android::os::IVoldTaskListener>& listener);
// clang-format on
} // namespace vold } // namespace vold
} // namespace android } // namespace android

@ -16,23 +16,22 @@
#define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER #define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
#include <errno.h>
#include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h>
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
#include <android-base/logging.h> #include <android-base/logging.h>
#include <android-base/strings.h>
#include <android-base/stringprintf.h> #include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <utils/Trace.h> #include <utils/Trace.h>
#include "Devmapper.h" #include "Devmapper.h"
@ -43,8 +42,7 @@ using android::base::StringPrintf;
static const char* kVoldPrefix = "vold:"; static const char* kVoldPrefix = "vold:";
void Devmapper::ioctlInit(struct dm_ioctl *io, size_t dataSize, void Devmapper::ioctlInit(struct dm_ioctl* io, size_t dataSize, const char* name, unsigned flags) {
const char *name, unsigned flags) {
memset(io, 0, dataSize); memset(io, 0, dataSize);
io->data_size = dataSize; io->data_size = dataSize;
io->data_start = sizeof(struct dm_ioctl); io->data_start = sizeof(struct dm_ioctl);
@ -54,17 +52,16 @@ void Devmapper::ioctlInit(struct dm_ioctl *io, size_t dataSize,
io->flags = flags; io->flags = flags;
if (name) { if (name) {
size_t ret = strlcpy(io->name, name, sizeof(io->name)); size_t ret = strlcpy(io->name, name, sizeof(io->name));
if (ret >= sizeof(io->name)) if (ret >= sizeof(io->name)) abort();
abort();
} }
} }
int Devmapper::create(const char *name_raw, const char *loopFile, const char *key, int Devmapper::create(const char* name_raw, const char* loopFile, const char* key,
unsigned long numSectors, char *ubuffer, size_t len) { unsigned long numSectors, char* ubuffer, size_t len) {
auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw); auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw);
const char* name = name_string.c_str(); const char* name = name_string.c_str();
char *buffer = (char *) malloc(DEVMAPPER_BUFFER_SIZE); char* buffer = (char*)malloc(DEVMAPPER_BUFFER_SIZE);
if (!buffer) { if (!buffer) {
PLOG(ERROR) << "Failed malloc"; PLOG(ERROR) << "Failed malloc";
return -1; return -1;
@ -77,8 +74,8 @@ int Devmapper::create(const char *name_raw, const char *loopFile, const char *ke
return -1; return -1;
} }
struct dm_ioctl *io = (struct dm_ioctl *) buffer; struct dm_ioctl* io = (struct dm_ioctl*)buffer;
// Create the DM device // Create the DM device
ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0); ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
@ -92,11 +89,11 @@ int Devmapper::create(const char *name_raw, const char *loopFile, const char *ke
// Set the legacy geometry // Set the legacy geometry
ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0); ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
char *geoParams = buffer + sizeof(struct dm_ioctl); char* geoParams = buffer + sizeof(struct dm_ioctl);
// bps=512 spc=8 res=32 nft=2 sec=8190 mid=0xf0 spt=63 hds=64 hid=0 bspf=8 rdcl=2 infs=1 bkbs=2 // bps=512 spc=8 res=32 nft=2 sec=8190 mid=0xf0 spt=63 hds=64 hid=0 bspf=8 rdcl=2 infs=1 bkbs=2
strlcpy(geoParams, "0 64 63 0", DEVMAPPER_BUFFER_SIZE - sizeof(struct dm_ioctl)); strlcpy(geoParams, "0 64 63 0", DEVMAPPER_BUFFER_SIZE - sizeof(struct dm_ioctl));
geoParams += strlen(geoParams) + 1; geoParams += strlen(geoParams) + 1;
geoParams = (char *) _align(geoParams, 8); geoParams = (char*)_align(geoParams, 8);
if (ioctl(fd, DM_DEV_SET_GEOMETRY, io)) { if (ioctl(fd, DM_DEV_SET_GEOMETRY, io)) {
PLOG(ERROR) << "Failed DM_DEV_SET_GEOMETRY"; PLOG(ERROR) << "Failed DM_DEV_SET_GEOMETRY";
free(buffer); free(buffer);
@ -117,8 +114,8 @@ int Devmapper::create(const char *name_raw, const char *loopFile, const char *ke
snprintf(ubuffer, len, "/dev/block/dm-%u", minor); snprintf(ubuffer, len, "/dev/block/dm-%u", minor);
// Load the table // Load the table
struct dm_target_spec *tgt; struct dm_target_spec* tgt;
tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)]; tgt = (struct dm_target_spec*)&buffer[sizeof(struct dm_ioctl)];
ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, DM_STATUS_TABLE_FLAG); ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, DM_STATUS_TABLE_FLAG);
io->target_count = 1; io->target_count = 1;
@ -129,12 +126,12 @@ int Devmapper::create(const char *name_raw, const char *loopFile, const char *ke
strlcpy(tgt->target_type, "crypt", sizeof(tgt->target_type)); strlcpy(tgt->target_type, "crypt", sizeof(tgt->target_type));
char *cryptParams = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec); char* cryptParams = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
snprintf(cryptParams, snprintf(cryptParams,
DEVMAPPER_BUFFER_SIZE - (sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec)), DEVMAPPER_BUFFER_SIZE - (sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec)),
"twofish %s 0 %s 0", key, loopFile); "twofish %s 0 %s 0", key, loopFile);
cryptParams += strlen(cryptParams) + 1; cryptParams += strlen(cryptParams) + 1;
cryptParams = (char *) _align(cryptParams, 8); cryptParams = (char*)_align(cryptParams, 8);
tgt->next = cryptParams - buffer; tgt->next = cryptParams - buffer;
if (ioctl(fd, DM_TABLE_LOAD, io)) { if (ioctl(fd, DM_TABLE_LOAD, io)) {
@ -160,11 +157,11 @@ int Devmapper::create(const char *name_raw, const char *loopFile, const char *ke
return 0; return 0;
} }
int Devmapper::destroy(const char *name_raw) { int Devmapper::destroy(const char* name_raw) {
auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw); auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw);
const char* name = name_string.c_str(); const char* name = name_string.c_str();
char *buffer = (char *) malloc(DEVMAPPER_BUFFER_SIZE); char* buffer = (char*)malloc(DEVMAPPER_BUFFER_SIZE);
if (!buffer) { if (!buffer) {
PLOG(ERROR) << "Failed malloc"; PLOG(ERROR) << "Failed malloc";
return -1; return -1;
@ -177,8 +174,8 @@ int Devmapper::destroy(const char *name_raw) {
return -1; return -1;
} }
struct dm_ioctl *io = (struct dm_ioctl *) buffer; struct dm_ioctl* io = (struct dm_ioctl*)buffer;
// Create the DM device // Create the DM device
ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0); ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
@ -198,14 +195,14 @@ int Devmapper::destroy(const char *name_raw) {
int Devmapper::destroyAll() { int Devmapper::destroyAll() {
ATRACE_NAME("Devmapper::destroyAll"); ATRACE_NAME("Devmapper::destroyAll");
char *buffer = (char *) malloc(1024 * 64); char* buffer = (char*)malloc(1024 * 64);
if (!buffer) { if (!buffer) {
PLOG(ERROR) << "Failed malloc"; PLOG(ERROR) << "Failed malloc";
return -1; return -1;
} }
memset(buffer, 0, (1024 * 64)); memset(buffer, 0, (1024 * 64));
char *buffer2 = (char *) malloc(DEVMAPPER_BUFFER_SIZE); char* buffer2 = (char*)malloc(DEVMAPPER_BUFFER_SIZE);
if (!buffer2) { if (!buffer2) {
PLOG(ERROR) << "Failed malloc"; PLOG(ERROR) << "Failed malloc";
free(buffer); free(buffer);
@ -220,7 +217,7 @@ int Devmapper::destroyAll() {
return -1; return -1;
} }
struct dm_ioctl *io = (struct dm_ioctl *) buffer; struct dm_ioctl* io = (struct dm_ioctl*)buffer;
ioctlInit(io, (1024 * 64), NULL, 0); ioctlInit(io, (1024 * 64), NULL, 0);
if (ioctl(fd, DM_LIST_DEVICES, io)) { if (ioctl(fd, DM_LIST_DEVICES, io)) {
@ -231,7 +228,7 @@ int Devmapper::destroyAll() {
return -1; return -1;
} }
struct dm_name_list *n = (struct dm_name_list *) (((char *) buffer) + io->data_start); struct dm_name_list* n = (struct dm_name_list*)(((char*)buffer) + io->data_start);
if (!n->dev) { if (!n->dev) {
free(buffer); free(buffer);
free(buffer2); free(buffer2);
@ -241,13 +238,13 @@ int Devmapper::destroyAll() {
unsigned nxt = 0; unsigned nxt = 0;
do { do {
n = (struct dm_name_list *) (((char *) n) + nxt); n = (struct dm_name_list*)(((char*)n) + nxt);
auto name = std::string(n->name); auto name = std::string(n->name);
if (android::base::StartsWith(name, kVoldPrefix)) { if (android::base::StartsWith(name, kVoldPrefix)) {
LOG(DEBUG) << "Tearing down stale dm device named " << name; LOG(DEBUG) << "Tearing down stale dm device named " << name;
memset(buffer2, 0, DEVMAPPER_BUFFER_SIZE); memset(buffer2, 0, DEVMAPPER_BUFFER_SIZE);
struct dm_ioctl *io2 = (struct dm_ioctl *) buffer2; struct dm_ioctl* io2 = (struct dm_ioctl*)buffer2;
ioctlInit(io2, DEVMAPPER_BUFFER_SIZE, n->name, 0); ioctlInit(io2, DEVMAPPER_BUFFER_SIZE, n->name, 0);
if (ioctl(fd, DM_DEV_REMOVE, io2)) { if (ioctl(fd, DM_DEV_REMOVE, io2)) {
if (errno != ENXIO) { if (errno != ENXIO) {
@ -266,9 +263,8 @@ int Devmapper::destroyAll() {
return 0; return 0;
} }
void *Devmapper::_align(void *ptr, unsigned int a) void* Devmapper::_align(void* ptr, unsigned int a) {
{ unsigned long agn = --a;
unsigned long agn = --a;
return (void *) (((unsigned long) ptr + agn) & ~agn); return (void*)(((unsigned long)ptr + agn) & ~agn);
} }

@ -17,20 +17,19 @@
#ifndef _DEVMAPPER_H #ifndef _DEVMAPPER_H
#define _DEVMAPPER_H #define _DEVMAPPER_H
#include <unistd.h>
#include <linux/dm-ioctl.h> #include <linux/dm-ioctl.h>
#include <unistd.h>
class Devmapper { class Devmapper {
public: public:
static int create(const char *name, const char *loopFile, const char *key, static int create(const char* name, const char* loopFile, const char* key,
unsigned long numSectors, char *buffer, size_t len); unsigned long numSectors, char* buffer, size_t len);
static int destroy(const char *name); static int destroy(const char* name);
static int destroyAll(); static int destroyAll();
private: private:
static void *_align(void *ptr, unsigned int a); static void* _align(void* ptr, unsigned int a);
static void ioctlInit(struct dm_ioctl *io, size_t data_size, static void ioctlInit(struct dm_ioctl* io, size_t data_size, const char* name, unsigned flags);
const char *name, unsigned flags);
}; };
#endif #endif

@ -16,16 +16,16 @@
#include "EncryptInplace.h" #include "EncryptInplace.h"
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ext4_utils/ext4.h> #include <ext4_utils/ext4.h>
#include <ext4_utils/ext4_utils.h> #include <ext4_utils/ext4_utils.h>
#include <f2fs_sparseblock.h> #include <f2fs_sparseblock.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <algorithm> #include <algorithm>
@ -36,13 +36,11 @@
#include "cryptfs.h" #include "cryptfs.h"
// FIXME horrible cut-and-paste code // FIXME horrible cut-and-paste code
static inline int unix_read(int fd, void* buff, int len) static inline int unix_read(int fd, void* buff, int len) {
{
return TEMP_FAILURE_RETRY(read(fd, buff, len)); return TEMP_FAILURE_RETRY(read(fd, buff, len));
} }
static inline int unix_write(int fd, const void* buff, int len) static inline int unix_write(int fd, const void* buff, int len) {
{
return TEMP_FAILURE_RETRY(write(fd, buff, len)); return TEMP_FAILURE_RETRY(write(fd, buff, len));
} }
@ -57,15 +55,14 @@ static inline int unix_write(int fd, const void* buff, int len)
#define BLOCKS_AT_A_TIME 1024 #define BLOCKS_AT_A_TIME 1024
#endif #endif
struct encryptGroupsData struct encryptGroupsData {
{
int realfd; int realfd;
int cryptofd; int cryptofd;
off64_t numblocks; off64_t numblocks;
off64_t one_pct, cur_pct, new_pct; off64_t one_pct, cur_pct, new_pct;
off64_t blocks_already_done, tot_numblocks; off64_t blocks_already_done, tot_numblocks;
off64_t used_blocks_already_done, tot_used_blocks; off64_t used_blocks_already_done, tot_used_blocks;
char* real_blkdev, * crypto_blkdev; char *real_blkdev, *crypto_blkdev;
int count; int count;
off64_t offset; off64_t offset;
char* buffer; char* buffer;
@ -76,8 +73,7 @@ struct encryptGroupsData
bool set_progress_properties; bool set_progress_properties;
}; };
static void update_progress(struct encryptGroupsData* data, int is_used) static void update_progress(struct encryptGroupsData* data, int is_used) {
{
data->blocks_already_done++; data->blocks_already_done++;
if (is_used) { if (is_used) {
@ -104,16 +100,14 @@ static void update_progress(struct encryptGroupsData* data, int is_used)
LOG(WARNING) << "Error getting time"; LOG(WARNING) << "Error getting time";
} else { } else {
double elapsed_time = difftime(time_now.tv_sec, data->time_started); double elapsed_time = difftime(time_now.tv_sec, data->time_started);
off64_t remaining_blocks = data->tot_used_blocks off64_t remaining_blocks = data->tot_used_blocks - data->used_blocks_already_done;
- data->used_blocks_already_done; int remaining_time =
int remaining_time = (int)(elapsed_time * remaining_blocks (int)(elapsed_time * remaining_blocks / data->used_blocks_already_done);
/ data->used_blocks_already_done);
// Change time only if not yet set, lower, or a lot higher for // Change time only if not yet set, lower, or a lot higher for
// best user experience // best user experience
if (data->remaining_time == -1 if (data->remaining_time == -1 || remaining_time < data->remaining_time ||
|| remaining_time < data->remaining_time remaining_time > data->remaining_time + 60) {
|| remaining_time > data->remaining_time + 60) {
char buf[8]; char buf[8];
snprintf(buf, sizeof(buf), "%d", remaining_time); snprintf(buf, sizeof(buf), "%d", remaining_time);
android::base::SetProperty("vold.encrypt_time_remaining", buf); android::base::SetProperty("vold.encrypt_time_remaining", buf);
@ -123,8 +117,7 @@ static void update_progress(struct encryptGroupsData* data, int is_used)
} }
} }
static void log_progress(struct encryptGroupsData const* data, bool completed) static void log_progress(struct encryptGroupsData const* data, bool completed) {
{
// Precondition - if completed data = 0 else data != 0 // Precondition - if completed data = 0 else data != 0
// Track progress so we can skip logging blocks // Track progress so we can skip logging blocks
@ -147,8 +140,7 @@ static void log_progress(struct encryptGroupsData const* data, bool completed)
} }
} }
static int flush_outstanding_data(struct encryptGroupsData* data) static int flush_outstanding_data(struct encryptGroupsData* data) {
{
if (data->count == 0) { if (data->count == 0) {
return 0; return 0;
} }
@ -165,30 +157,29 @@ static int flush_outstanding_data(struct encryptGroupsData* data)
<< " for inplace encrypt"; << " for inplace encrypt";
return -1; return -1;
} else { } else {
log_progress(data, false); log_progress(data, false);
} }
data->count = 0; data->count = 0;
data->last_written_sector = (data->offset + data->count) data->last_written_sector =
/ info.block_size * CRYPT_SECTOR_SIZE - 1; (data->offset + data->count) / info.block_size * CRYPT_SECTOR_SIZE - 1;
return 0; return 0;
} }
static int encrypt_groups(struct encryptGroupsData* data) static int encrypt_groups(struct encryptGroupsData* data) {
{
unsigned int i; unsigned int i;
u8 *block_bitmap = 0; u8* block_bitmap = 0;
unsigned int block; unsigned int block;
off64_t ret; off64_t ret;
int rc = -1; int rc = -1;
data->buffer = (char*) malloc(info.block_size * BLOCKS_AT_A_TIME); data->buffer = (char*)malloc(info.block_size * BLOCKS_AT_A_TIME);
if (!data->buffer) { if (!data->buffer) {
LOG(ERROR) << "Failed to allocate crypto buffer"; LOG(ERROR) << "Failed to allocate crypto buffer";
goto errout; goto errout;
} }
block_bitmap = (u8*) malloc(info.block_size); block_bitmap = (u8*)malloc(info.block_size);
if (!block_bitmap) { if (!block_bitmap) {
LOG(ERROR) << "failed to allocate block bitmap"; LOG(ERROR) << "failed to allocate block bitmap";
goto errout; goto errout;
@ -198,11 +189,9 @@ static int encrypt_groups(struct encryptGroupsData* data)
LOG(INFO) << "Encrypting group " << i; LOG(INFO) << "Encrypting group " << i;
u32 first_block = aux_info.first_data_block + i * info.blocks_per_group; u32 first_block = aux_info.first_data_block + i * info.blocks_per_group;
u32 block_count = std::min(info.blocks_per_group, u32 block_count = std::min(info.blocks_per_group, (u32)(aux_info.len_blocks - first_block));
(u32)(aux_info.len_blocks - first_block));
off64_t offset = (u64)info.block_size off64_t offset = (u64)info.block_size * aux_info.bg_desc[i].bg_block_bitmap;
* aux_info.bg_desc[i].bg_block_bitmap;
ret = pread64(data->realfd, block_bitmap, info.block_size, offset); ret = pread64(data->realfd, block_bitmap, info.block_size, offset);
if (ret != (int)info.block_size) { if (ret != (int)info.block_size) {
@ -215,8 +204,9 @@ static int encrypt_groups(struct encryptGroupsData* data)
data->count = 0; data->count = 0;
for (block = 0; block < block_count; block++) { for (block = 0; block < block_count; block++) {
int used = (aux_info.bg_desc[i].bg_flags & EXT4_BG_BLOCK_UNINIT) ? int used = (aux_info.bg_desc[i].bg_flags & EXT4_BG_BLOCK_UNINIT)
0 : bitmap_get_bit(block_bitmap, block); ? 0
: bitmap_get_bit(block_bitmap, block);
update_progress(data, used); update_progress(data, used);
if (used) { if (used) {
if (data->count == 0) { if (data->count == 0) {
@ -232,8 +222,8 @@ static int encrypt_groups(struct encryptGroupsData* data)
offset += info.block_size; offset += info.block_size;
/* Write data if we are aligned or buffer size reached */ /* Write data if we are aligned or buffer size reached */
if (offset % (info.block_size * BLOCKS_AT_A_TIME) == 0 if (offset % (info.block_size * BLOCKS_AT_A_TIME) == 0 ||
|| data->count == BLOCKS_AT_A_TIME) { data->count == BLOCKS_AT_A_TIME) {
if (flush_outstanding_data(data)) { if (flush_outstanding_data(data)) {
goto errout; goto errout;
} }
@ -260,7 +250,7 @@ static int cryptfs_enable_inplace_ext4(char* crypto_blkdev, char* real_blkdev, o
bool set_progress_properties) { bool set_progress_properties) {
u32 i; u32 i;
struct encryptGroupsData data; struct encryptGroupsData data;
int rc; // Can't initialize without causing warning -Wclobbered int rc; // Can't initialize without causing warning -Wclobbered
int retries = RETRY_MOUNT_ATTEMPTS; int retries = RETRY_MOUNT_ATTEMPTS;
struct timespec time_started = {0}; struct timespec time_started = {0};
@ -275,7 +265,7 @@ static int cryptfs_enable_inplace_ext4(char* crypto_blkdev, char* real_blkdev, o
data.set_progress_properties = set_progress_properties; data.set_progress_properties = set_progress_properties;
LOG(DEBUG) << "Opening" << real_blkdev; LOG(DEBUG) << "Opening" << real_blkdev;
if ( (data.realfd = open(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) { if ((data.realfd = open(real_blkdev, O_RDWR | O_CLOEXEC)) < 0) {
PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt"; PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
rc = -1; rc = -1;
goto errout; goto errout;
@ -283,7 +273,7 @@ static int cryptfs_enable_inplace_ext4(char* crypto_blkdev, char* real_blkdev, o
LOG(DEBUG) << "Opening" << crypto_blkdev; LOG(DEBUG) << "Opening" << crypto_blkdev;
// Wait until the block device appears. Re-use the mount retry values since it is reasonable. // Wait until the block device appears. Re-use the mount retry values since it is reasonable.
while ((data.cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) { while ((data.cryptofd = open(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) {
if (--retries) { if (--retries) {
PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev
<< " for ext4 inplace encrypt, retrying"; << " for ext4 inplace encrypt, retrying";
@ -296,7 +286,7 @@ static int cryptfs_enable_inplace_ext4(char* crypto_blkdev, char* real_blkdev, o
} }
} }
if (setjmp(setjmp_env)) { // NOLINT if (setjmp(setjmp_env)) { // NOLINT
LOG(ERROR) << "Reading ext4 extent caused an exception"; LOG(ERROR) << "Reading ext4 extent caused an exception";
rc = -1; rc = -1;
goto errout; goto errout;
@ -316,7 +306,7 @@ static int cryptfs_enable_inplace_ext4(char* crypto_blkdev, char* real_blkdev, o
data.tot_used_blocks = data.numblocks; data.tot_used_blocks = data.numblocks;
for (i = 0; i < aux_info.groups; ++i) { for (i = 0; i < aux_info.groups; ++i) {
data.tot_used_blocks -= aux_info.bg_desc[i].bg_free_blocks_count; data.tot_used_blocks -= aux_info.bg_desc[i].bg_free_blocks_count;
} }
data.one_pct = data.tot_used_blocks / 100; data.one_pct = data.tot_used_blocks / 100;
@ -345,8 +335,7 @@ errout:
return rc; return rc;
} }
static void log_progress_f2fs(u64 block, bool completed) static void log_progress_f2fs(u64 block, bool completed) {
{
// Precondition - if completed data = 0 else data != 0 // Precondition - if completed data = 0 else data != 0
// Track progress so we can skip logging blocks // Track progress so we can skip logging blocks
@ -369,9 +358,8 @@ static void log_progress_f2fs(u64 block, bool completed)
} }
} }
static int encrypt_one_block_f2fs(u64 pos, void *data) static int encrypt_one_block_f2fs(u64 pos, void* data) {
{ struct encryptGroupsData* priv_dat = (struct encryptGroupsData*)data;
struct encryptGroupsData *priv_dat = (struct encryptGroupsData *)data;
priv_dat->blocks_already_done = pos - 1; priv_dat->blocks_already_done = pos - 1;
update_progress(priv_dat, 1); update_progress(priv_dat, 1);
@ -400,7 +388,7 @@ static int cryptfs_enable_inplace_f2fs(char* crypto_blkdev, char* real_blkdev, o
off64_t previously_encrypted_upto, off64_t previously_encrypted_upto,
bool set_progress_properties) { bool set_progress_properties) {
struct encryptGroupsData data; struct encryptGroupsData data;
struct f2fs_info *f2fs_info = NULL; struct f2fs_info* f2fs_info = NULL;
int rc = ENABLE_INPLACE_ERR_OTHER; int rc = ENABLE_INPLACE_ERR_OTHER;
if (previously_encrypted_upto > *size_already_done) { if (previously_encrypted_upto > *size_already_done) {
LOG(DEBUG) << "Not fast encrypting since resuming part way through"; LOG(DEBUG) << "Not fast encrypting since resuming part way through";
@ -412,11 +400,11 @@ static int cryptfs_enable_inplace_f2fs(char* crypto_blkdev, char* real_blkdev, o
data.set_progress_properties = set_progress_properties; data.set_progress_properties = set_progress_properties;
data.realfd = -1; data.realfd = -1;
data.cryptofd = -1; data.cryptofd = -1;
if ( (data.realfd = open64(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) { if ((data.realfd = open64(real_blkdev, O_RDWR | O_CLOEXEC)) < 0) {
PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for f2fs inplace encrypt"; PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for f2fs inplace encrypt";
goto errout; goto errout;
} }
if ( (data.cryptofd = open64(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) { if ((data.cryptofd = open64(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) {
PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev
<< " for f2fs inplace encrypt"; << " for f2fs inplace encrypt";
rc = ENABLE_INPLACE_ERR_DEV; rc = ENABLE_INPLACE_ERR_DEV;
@ -424,8 +412,7 @@ static int cryptfs_enable_inplace_f2fs(char* crypto_blkdev, char* real_blkdev, o
} }
f2fs_info = generate_f2fs_info(data.realfd); f2fs_info = generate_f2fs_info(data.realfd);
if (!f2fs_info) if (!f2fs_info) goto errout;
goto errout;
data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE; data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE; data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
@ -438,7 +425,7 @@ static int cryptfs_enable_inplace_f2fs(char* crypto_blkdev, char* real_blkdev, o
data.time_started = time(NULL); data.time_started = time(NULL);
data.remaining_time = -1; data.remaining_time = -1;
data.buffer = (char*) malloc(f2fs_info->block_size); data.buffer = (char*)malloc(f2fs_info->block_size);
if (!data.buffer) { if (!data.buffer) {
LOG(ERROR) << "Failed to allocate crypto buffer"; LOG(ERROR) << "Failed to allocate crypto buffer";
goto errout; goto errout;
@ -475,18 +462,18 @@ static int cryptfs_enable_inplace_full(char* crypto_blkdev, char* real_blkdev, o
off64_t previously_encrypted_upto, off64_t previously_encrypted_upto,
bool set_progress_properties) { bool set_progress_properties) {
int realfd, cryptofd; int realfd, cryptofd;
char *buf[CRYPT_INPLACE_BUFSIZE]; char* buf[CRYPT_INPLACE_BUFSIZE];
int rc = ENABLE_INPLACE_ERR_OTHER; int rc = ENABLE_INPLACE_ERR_OTHER;
off64_t numblocks, i, remainder; off64_t numblocks, i, remainder;
off64_t one_pct, cur_pct, new_pct; off64_t one_pct, cur_pct, new_pct;
off64_t blocks_already_done, tot_numblocks; off64_t blocks_already_done, tot_numblocks;
if ( (realfd = open(real_blkdev, O_RDONLY|O_CLOEXEC)) < 0) { if ((realfd = open(real_blkdev, O_RDONLY | O_CLOEXEC)) < 0) {
PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt"; PLOG(ERROR) << "Error opening real_blkdev " << real_blkdev << " for inplace encrypt";
return ENABLE_INPLACE_ERR_OTHER; return ENABLE_INPLACE_ERR_OTHER;
} }
if ( (cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) { if ((cryptofd = open(crypto_blkdev, O_WRONLY | O_CLOEXEC)) < 0) {
PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev << " for inplace encrypt"; PLOG(ERROR) << "Error opening crypto_blkdev " << crypto_blkdev << " for inplace encrypt";
close(realfd); close(realfd);
return ENABLE_INPLACE_ERR_DEV; return ENABLE_INPLACE_ERR_DEV;
@ -516,7 +503,7 @@ static int cryptfs_enable_inplace_full(char* crypto_blkdev, char* real_blkdev, o
goto errout; goto errout;
} }
for (;i < size && i % CRYPT_SECTORS_PER_BUFSIZE != 0; ++i) { for (; i < size && i % CRYPT_SECTORS_PER_BUFSIZE != 0; ++i) {
if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) { if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) {
PLOG(ERROR) << "Error reading initial sectors from real_blkdev " << real_blkdev PLOG(ERROR) << "Error reading initial sectors from real_blkdev " << real_blkdev
<< " for inplace encrypt"; << " for inplace encrypt";
@ -534,7 +521,7 @@ static int cryptfs_enable_inplace_full(char* crypto_blkdev, char* real_blkdev, o
one_pct = tot_numblocks / 100; one_pct = tot_numblocks / 100;
cur_pct = 0; cur_pct = 0;
/* process the majority of the filesystem in blocks */ /* process the majority of the filesystem in blocks */
for (i/=CRYPT_SECTORS_PER_BUFSIZE; i<numblocks; i++) { for (i /= CRYPT_SECTORS_PER_BUFSIZE; i < numblocks; i++) {
new_pct = (i + blocks_already_done) / one_pct; new_pct = (i + blocks_already_done) / one_pct;
if (set_progress_properties && new_pct > cur_pct) { if (set_progress_properties && new_pct > cur_pct) {
char buf[8]; char buf[8];
@ -557,7 +544,7 @@ static int cryptfs_enable_inplace_full(char* crypto_blkdev, char* real_blkdev, o
} }
/* Do any remaining sectors */ /* Do any remaining sectors */
for (i=0; i<remainder; i++) { for (i = 0; i < remainder; i++) {
if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) { if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) {
LOG(ERROR) << "Error reading final sectors from real_blkdev " << real_blkdev LOG(ERROR) << "Error reading final sectors from real_blkdev " << real_blkdev
<< " for inplace encrypt"; << " for inplace encrypt";
@ -626,9 +613,8 @@ int cryptfs_enable_inplace(char* crypto_blkdev, char* real_blkdev, off64_t size,
LOG(DEBUG) << "cryptfs_enable_inplace_full()=" << rc_full; LOG(DEBUG) << "cryptfs_enable_inplace_full()=" << rc_full;
/* Hack for b/17898962, the following is the symptom... */ /* Hack for b/17898962, the following is the symptom... */
if (rc_ext4 == ENABLE_INPLACE_ERR_DEV if (rc_ext4 == ENABLE_INPLACE_ERR_DEV && rc_f2fs == ENABLE_INPLACE_ERR_DEV &&
&& rc_f2fs == ENABLE_INPLACE_ERR_DEV rc_full == ENABLE_INPLACE_ERR_DEV) {
&& rc_full == ENABLE_INPLACE_ERR_DEV) {
LOG(DEBUG) << "ENABLE_INPLACE_ERR_DEV"; LOG(DEBUG) << "ENABLE_INPLACE_ERR_DEV";
return ENABLE_INPLACE_ERR_DEV; return ENABLE_INPLACE_ERR_DEV;
} }

@ -31,12 +31,12 @@
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h>
#include <limits.h> #include <limits.h>
#include <selinux/android.h> #include <selinux/android.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h>
#include <private/android_filesystem_config.h> #include <private/android_filesystem_config.h>
@ -93,7 +93,7 @@ std::map<userid_t, std::string> s_ce_key_raw_refs;
// TODO abolish this map, per b/26948053 // TODO abolish this map, per b/26948053
std::map<userid_t, KeyBuffer> s_ce_keys; std::map<userid_t, KeyBuffer> s_ce_keys;
} } // namespace
static bool e4crypt_is_emulated() { static bool e4crypt_is_emulated() {
return property_get_bool("persist.sys.emulate_fbe", false); return property_get_bool("persist.sys.emulate_fbe", false);
@ -145,8 +145,7 @@ static std::string get_ce_key_current_path(const std::string& directory_path) {
} }
static bool get_ce_key_new_path(const std::string& directory_path, static bool get_ce_key_new_path(const std::string& directory_path,
const std::vector<std::string>& paths, const std::vector<std::string>& paths, std::string* ce_key_path) {
std::string *ce_key_path) {
if (paths.empty()) { if (paths.empty()) {
*ce_key_path = get_ce_key_current_path(directory_path); *ce_key_path = get_ce_key_current_path(directory_path);
return true; return true;
@ -163,9 +162,9 @@ static bool get_ce_key_new_path(const std::string& directory_path,
// Discard all keys but the named one; rename it to canonical name. // Discard all keys but the named one; rename it to canonical name.
// No point in acting on errors in this; ignore them. // No point in acting on errors in this; ignore them.
static void fixate_user_ce_key(const std::string& directory_path, const std::string &to_fix, static void fixate_user_ce_key(const std::string& directory_path, const std::string& to_fix,
const std::vector<std::string>& paths) { const std::vector<std::string>& paths) {
for (auto const other_path: paths) { for (auto const other_path : paths) {
if (other_path != to_fix) { if (other_path != to_fix) {
android::vold::destroyKey(other_path); android::vold::destroyKey(other_path);
} }
@ -181,10 +180,10 @@ static void fixate_user_ce_key(const std::string& directory_path, const std::str
static bool read_and_fixate_user_ce_key(userid_t user_id, static bool read_and_fixate_user_ce_key(userid_t user_id,
const android::vold::KeyAuthentication& auth, const android::vold::KeyAuthentication& auth,
KeyBuffer *ce_key) { KeyBuffer* ce_key) {
auto const directory_path = get_ce_key_directory_path(user_id); auto const directory_path = get_ce_key_directory_path(user_id);
auto const paths = get_ce_key_paths(directory_path); auto const paths = get_ce_key_paths(directory_path);
for (auto const ce_key_path: paths) { for (auto const ce_key_path : paths) {
LOG(DEBUG) << "Trying user CE key " << ce_key_path; LOG(DEBUG) << "Trying user CE key " << ce_key_path;
if (android::vold::retrieveKey(ce_key_path, auth, ce_key)) { if (android::vold::retrieveKey(ce_key_path, auth, ce_key)) {
LOG(DEBUG) << "Successfully retrieved key"; LOG(DEBUG) << "Successfully retrieved key";
@ -242,12 +241,14 @@ static bool create_and_install_user_keys(userid_t user_id, bool create_ephemeral
auto const paths = get_ce_key_paths(directory_path); auto const paths = get_ce_key_paths(directory_path);
std::string ce_key_path; std::string ce_key_path;
if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false; if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, kEmptyAuthentication,
kEmptyAuthentication, ce_key)) return false; ce_key))
return false;
fixate_user_ce_key(directory_path, ce_key_path, paths); fixate_user_ce_key(directory_path, ce_key_path, paths);
// Write DE key second; once this is written, all is good. // Write DE key second; once this is written, all is good.
if (!android::vold::storeKeyAtomically(get_de_key_path(user_id), user_key_temp, if (!android::vold::storeKeyAtomically(get_de_key_path(user_id), user_key_temp,
kEmptyAuthentication, de_key)) return false; kEmptyAuthentication, de_key))
return false;
} }
std::string de_raw_ref; std::string de_raw_ref;
if (!android::vold::installKey(de_key, &de_raw_ref)) return false; if (!android::vold::installKey(de_key, &de_raw_ref)) return false;
@ -440,14 +441,14 @@ bool e4crypt_destroy_user_key(userid_t user_id) {
bool success = true; bool success = true;
std::string raw_ref; std::string raw_ref;
success &= evict_ce_key(user_id); success &= evict_ce_key(user_id);
success &= lookup_key_ref(s_de_key_raw_refs, user_id, &raw_ref) success &=
&& android::vold::evictKey(raw_ref); lookup_key_ref(s_de_key_raw_refs, user_id, &raw_ref) && android::vold::evictKey(raw_ref);
s_de_key_raw_refs.erase(user_id); s_de_key_raw_refs.erase(user_id);
auto it = s_ephemeral_users.find(user_id); auto it = s_ephemeral_users.find(user_id);
if (it != s_ephemeral_users.end()) { if (it != s_ephemeral_users.end()) {
s_ephemeral_users.erase(it); s_ephemeral_users.erase(it);
} else { } else {
for (auto const path: get_ce_key_paths(get_ce_key_directory_path(user_id))) { for (auto const path : get_ce_key_paths(get_ce_key_directory_path(user_id))) {
success &= android::vold::destroyKey(path); success &= android::vold::destroyKey(path);
} }
auto de_key_path = get_de_key_path(user_id); auto de_key_path = get_de_key_path(user_id);
@ -556,14 +557,14 @@ bool e4crypt_add_user_key_auth(userid_t user_id, int serial, const std::string&
std::string token, secret; std::string token, secret;
if (!parse_hex(token_hex, &token)) return false; if (!parse_hex(token_hex, &token)) return false;
if (!parse_hex(secret_hex, &secret)) return false; if (!parse_hex(secret_hex, &secret)) return false;
auto auth = secret.empty() ? kEmptyAuthentication auto auth =
: android::vold::KeyAuthentication(token, secret); secret.empty() ? kEmptyAuthentication : android::vold::KeyAuthentication(token, secret);
auto it = s_ce_keys.find(user_id); auto it = s_ce_keys.find(user_id);
if (it == s_ce_keys.end()) { if (it == s_ce_keys.end()) {
LOG(ERROR) << "Key not loaded into memory, can't change for user " << user_id; LOG(ERROR) << "Key not loaded into memory, can't change for user " << user_id;
return false; return false;
} }
const auto &ce_key = it->second; const auto& ce_key = it->second;
auto const directory_path = get_ce_key_directory_path(user_id); auto const directory_path = get_ce_key_directory_path(user_id);
auto const paths = get_ce_key_paths(directory_path); auto const paths = get_ce_key_paths(directory_path);
std::string ce_key_path; std::string ce_key_path;
@ -670,7 +671,8 @@ bool e4crypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_
if (!prepare_dir(system_legacy_path, 0700, AID_SYSTEM, AID_SYSTEM)) return false; if (!prepare_dir(system_legacy_path, 0700, AID_SYSTEM, AID_SYSTEM)) return false;
#if MANAGE_MISC_DIRS #if MANAGE_MISC_DIRS
if (!prepare_dir(misc_legacy_path, 0750, multiuser_get_uid(user_id, AID_SYSTEM), if (!prepare_dir(misc_legacy_path, 0750, multiuser_get_uid(user_id, AID_SYSTEM),
multiuser_get_uid(user_id, AID_EVERYBODY))) return false; multiuser_get_uid(user_id, AID_EVERYBODY)))
return false;
#endif #endif
if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false; if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;

@ -16,15 +16,15 @@
#include "FileDeviceUtils.h" #include "FileDeviceUtils.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <linux/fs.h>
#include <linux/fiemap.h> #include <linux/fiemap.h>
#include <linux/fs.h>
#include <mntent.h> #include <mntent.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <android-base/file.h> #include <android-base/file.h>
#include <android-base/logging.h> #include <android-base/logging.h>
@ -40,38 +40,33 @@ namespace android {
namespace vold { namespace vold {
// Given a file path, look for the corresponding block device in /proc/mount // Given a file path, look for the corresponding block device in /proc/mount
std::string BlockDeviceForPath(const std::string &path) std::string BlockDeviceForPath(const std::string& path) {
{ std::unique_ptr<FILE, int (*)(FILE*)> mnts(setmntent("/proc/mounts", "re"), endmntent);
std::unique_ptr<FILE, int(*)(FILE*)> mnts(setmntent("/proc/mounts", "re"), endmntent);
if (!mnts) { if (!mnts) {
PLOG(ERROR) << "Unable to open /proc/mounts"; PLOG(ERROR) << "Unable to open /proc/mounts";
return ""; return "";
} }
std::string result; std::string result;
size_t best_length = 0; size_t best_length = 0;
struct mntent *mnt; // getmntent returns a thread local, so it's safe. struct mntent* mnt; // getmntent returns a thread local, so it's safe.
while ((mnt = getmntent(mnts.get())) != nullptr) { while ((mnt = getmntent(mnts.get())) != nullptr) {
auto l = strlen(mnt->mnt_dir); auto l = strlen(mnt->mnt_dir);
if (l > best_length && if (l > best_length && path.size() > l && path[l] == '/' &&
path.size() > l &&
path[l] == '/' &&
path.compare(0, l, mnt->mnt_dir) == 0) { path.compare(0, l, mnt->mnt_dir) == 0) {
result = mnt->mnt_fsname; result = mnt->mnt_fsname;
best_length = l; best_length = l;
} }
} }
if (result.empty()) { if (result.empty()) {
LOG(ERROR) <<"Didn't find a mountpoint to match path " << path; LOG(ERROR) << "Didn't find a mountpoint to match path " << path;
return ""; return "";
} }
LOG(DEBUG) << "For path " << path << " block device is " << result; LOG(DEBUG) << "For path " << path << " block device is " << result;
return result; return result;
} }
std::unique_ptr<struct fiemap> PathFiemap(const std::string &path, uint32_t extent_count) std::unique_ptr<struct fiemap> PathFiemap(const std::string& path, uint32_t extent_count) {
{ android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC, 0)));
android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(
path.c_str(), O_RDONLY | O_CLOEXEC, 0)));
if (fd == -1) { if (fd == -1) {
if (errno == ENOENT) { if (errno == ENOENT) {
PLOG(DEBUG) << "Unable to open " << path; PLOG(DEBUG) << "Unable to open " << path;
@ -88,7 +83,7 @@ std::unique_ptr<struct fiemap> PathFiemap(const std::string &path, uint32_t exte
auto mapped = fiemap->fm_mapped_extents; auto mapped = fiemap->fm_mapped_extents;
if (mapped < 1 || mapped > extent_count) { if (mapped < 1 || mapped > extent_count) {
LOG(ERROR) << "Extent count not in bounds 1 <= " << mapped << " <= " << extent_count LOG(ERROR) << "Extent count not in bounds 1 <= " << mapped << " <= " << extent_count
<< " in " << path; << " in " << path;
return nullptr; return nullptr;
} }
return fiemap; return fiemap;
@ -99,10 +94,9 @@ std::unique_ptr<struct fiemap> PathFiemap(const std::string &path, uint32_t exte
namespace { namespace {
std::unique_ptr<struct fiemap> alloc_fiemap(uint32_t extent_count) std::unique_ptr<struct fiemap> alloc_fiemap(uint32_t extent_count) {
{
size_t allocsize = offsetof(struct fiemap, fm_extents[extent_count]); size_t allocsize = offsetof(struct fiemap, fm_extents[extent_count]);
std::unique_ptr<struct fiemap> res(new (::operator new (allocsize)) struct fiemap); std::unique_ptr<struct fiemap> res(new (::operator new(allocsize)) struct fiemap);
memset(res.get(), 0, allocsize); memset(res.get(), 0, allocsize);
res->fm_start = 0; res->fm_start = 0;
res->fm_length = UINT64_MAX; res->fm_length = UINT64_MAX;
@ -112,4 +106,4 @@ std::unique_ptr<struct fiemap> alloc_fiemap(uint32_t extent_count)
return res; return res;
} }
} } // namespace

@ -17,17 +17,17 @@
#ifndef ANDROID_VOLD_FILEDEVICEUTILS_H #ifndef ANDROID_VOLD_FILEDEVICEUTILS_H
#define ANDROID_VOLD_FILEDEVICEUTILS_H #define ANDROID_VOLD_FILEDEVICEUTILS_H
#include <string>
#include <linux/fiemap.h> #include <linux/fiemap.h>
#include <string>
namespace android { namespace android {
namespace vold { namespace vold {
// Given a file path, look for the corresponding block device in /proc/mount // Given a file path, look for the corresponding block device in /proc/mount
std::string BlockDeviceForPath(const std::string &path); std::string BlockDeviceForPath(const std::string& path);
// Read the file's FIEMAP // Read the file's FIEMAP
std::unique_ptr<struct fiemap> PathFiemap(const std::string &path, uint32_t extent_count); std::unique_ptr<struct fiemap> PathFiemap(const std::string& path, uint32_t extent_count);
} // namespace vold } // namespace vold
} // namespace android } // namespace android

@ -33,11 +33,11 @@
#include <private/android_filesystem_config.h> #include <private/android_filesystem_config.h>
#include <dirent.h> #include <dirent.h>
#include <fcntl.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <fcntl.h>
using android::base::Basename; using android::base::Basename;
using android::base::ReadFileToString; using android::base::ReadFileToString;
@ -80,8 +80,7 @@ static IdleMaintStats idle_maint_stat(IdleMaintStats::kStopped);
static std::condition_variable cv_abort, cv_stop; static std::condition_variable cv_abort, cv_stop;
static std::mutex cv_m; static std::mutex cv_m;
static void addFromVolumeManager(std::list<std::string>* paths, static void addFromVolumeManager(std::list<std::string>* paths, PathTypes path_type) {
PathTypes path_type) {
VolumeManager* vm = VolumeManager::Instance(); VolumeManager* vm = VolumeManager::Instance();
std::list<std::string> privateIds; std::list<std::string> privateIds;
vm->listVolumes(VolumeBase::Type::kPrivate, privateIds); vm->listVolumes(VolumeBase::Type::kPrivate, privateIds);
@ -95,11 +94,9 @@ static void addFromVolumeManager(std::list<std::string>* paths,
const std::string& fs_type = vol->getFsType(); const std::string& fs_type = vol->getFsType();
if (fs_type == "f2fs" && (Realpath(vol->getRawDmDevPath(), &gc_path) || if (fs_type == "f2fs" && (Realpath(vol->getRawDmDevPath(), &gc_path) ||
Realpath(vol->getRawDevPath(), &gc_path))) { Realpath(vol->getRawDevPath(), &gc_path))) {
paths->push_back(std::string("/sys/fs/") + fs_type + paths->push_back(std::string("/sys/fs/") + fs_type + "/" + Basename(gc_path));
"/" + Basename(gc_path));
} }
} }
} }
} }
} }
@ -107,7 +104,7 @@ static void addFromVolumeManager(std::list<std::string>* paths,
static void addFromFstab(std::list<std::string>* paths, PathTypes path_type) { static void addFromFstab(std::list<std::string>* paths, PathTypes path_type) {
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(), std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
fs_mgr_free_fstab); fs_mgr_free_fstab);
struct fstab_rec *prev_rec = NULL; struct fstab_rec* prev_rec = NULL;
for (int i = 0; i < fstab->num_entries; i++) { for (int i = 0; i < fstab->num_entries; i++) {
auto fs_type = std::string(fstab->recs[i].fs_type); auto fs_type = std::string(fstab->recs[i].fs_type);
@ -138,10 +135,11 @@ static void addFromFstab(std::list<std::string>* paths, PathTypes path_type) {
} else if (path_type == PathTypes::kBlkDevice) { } else if (path_type == PathTypes::kBlkDevice) {
std::string gc_path; std::string gc_path;
if (std::string(fstab->recs[i].fs_type) == "f2fs" && if (std::string(fstab->recs[i].fs_type) == "f2fs" &&
Realpath(android::vold::BlockDeviceForPath( Realpath(
std::string(fstab->recs[i].mount_point) + "/"), &gc_path)) { android::vold::BlockDeviceForPath(std::string(fstab->recs[i].mount_point) + "/"),
paths->push_back(std::string("/sys/fs/") + fstab->recs[i].fs_type + &gc_path)) {
"/" + Basename(gc_path)); paths->push_back(std::string("/sys/fs/") + fstab->recs[i].fs_type + "/" +
Basename(gc_path));
} }
} }
@ -184,8 +182,8 @@ void Trim(const android::sp<android::os::IVoldTaskListener>& listener) {
} }
} else { } else {
nsecs_t time = systemTime(SYSTEM_TIME_BOOTTIME) - start; nsecs_t time = systemTime(SYSTEM_TIME_BOOTTIME) - start;
LOG(INFO) << "Trimmed " << range.len << " bytes on " << path LOG(INFO) << "Trimmed " << range.len << " bytes on " << path << " in "
<< " in " << nanoseconds_to_milliseconds(time) << "ms"; << nanoseconds_to_milliseconds(time) << "ms";
extras.putLong(String16("bytes"), range.len); extras.putLong(String16("bytes"), range.len);
extras.putLong(String16("time"), time); extras.putLong(String16("time"), time);
if (listener) { if (listener) {
@ -230,8 +228,8 @@ static bool waitForGc(const std::list<std::string>& paths) {
} }
lk.lock(); lk.lock();
aborted = cv_abort.wait_for(lk, 10s, []{ aborted =
return idle_maint_stat == IdleMaintStats::kAbort;}); cv_abort.wait_for(lk, 10s, [] { return idle_maint_stat == IdleMaintStats::kAbort; });
lk.unlock(); lk.unlock();
} }
@ -267,7 +265,7 @@ static int stopGc(const std::list<std::string>& paths) {
static void runDevGcFstab(void) { static void runDevGcFstab(void) {
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(), std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
fs_mgr_free_fstab); fs_mgr_free_fstab);
struct fstab_rec *rec = NULL; struct fstab_rec* rec = NULL;
for (int i = 0; i < fstab->num_entries; i++) { for (int i = 0; i < fstab->num_entries; i++) {
if (fs_mgr_has_sysfs_path(&fstab->recs[i])) { if (fs_mgr_has_sysfs_path(&fstab->recs[i])) {
@ -427,8 +425,7 @@ int AbortIdleMaint(const android::sp<android::os::IVoldTaskListener>& listener)
cv_abort.notify_one(); cv_abort.notify_one();
lk.lock(); lk.lock();
LOG(DEBUG) << "aborting idle maintenance"; LOG(DEBUG) << "aborting idle maintenance";
cv_stop.wait(lk, []{ cv_stop.wait(lk, [] { return idle_maint_stat == IdleMaintStats::kStopped; });
return idle_maint_stat == IdleMaintStats::kStopped;});
} }
lk.unlock(); lk.unlock();

@ -34,4 +34,3 @@ KeyBuffer operator+(KeyBuffer&& lhs, const char* rhs) {
} // namespace vold } // namespace vold
} // namespace android } // namespace android

@ -33,17 +33,15 @@ namespace vold {
#define OPTNONE __attribute__((optimize("O0"))) #define OPTNONE __attribute__((optimize("O0")))
#endif // not __clang__ #endif // not __clang__
inline OPTNONE void* memset_s(void* s, int c, size_t n) { inline OPTNONE void* memset_s(void* s, int c, size_t n) {
if (!s) if (!s) return s;
return s;
return memset(s, c, n); return memset(s, c, n);
} }
#undef OPTNONE #undef OPTNONE
// Allocator that delegates useful work to standard one but zeroes data before deallocating. // Allocator that delegates useful work to standard one but zeroes data before deallocating.
class ZeroingAllocator : public std::allocator<char> { class ZeroingAllocator : public std::allocator<char> {
public: public:
void deallocate(pointer p, size_type n) void deallocate(pointer p, size_type n) {
{
memset_s(p, 0, n); memset_s(p, 0, n);
std::allocator<char>::deallocate(p, n); std::allocator<char>::deallocate(p, n);
} }
@ -60,4 +58,3 @@ KeyBuffer operator+(KeyBuffer&& lhs, const char* rhs);
} // namespace android } // namespace android
#endif #endif

@ -568,7 +568,10 @@ bool destroyKey(const std::string& dir) {
success &= deleteKey(dir); success &= deleteKey(dir);
} }
auto secdiscard_cmd = std::vector<std::string>{ auto secdiscard_cmd = std::vector<std::string>{
kSecdiscardPath, "--", dir + "/" + kFn_encrypted_key, dir + "/" + kFn_secdiscardable, kSecdiscardPath,
"--",
dir + "/" + kFn_encrypted_key,
dir + "/" + kFn_secdiscardable,
}; };
if (uses_km) { if (uses_km) {
secdiscard_cmd.emplace_back(dir + "/" + kFn_keymaster_key_blob); secdiscard_cmd.emplace_back(dir + "/" + kFn_keymaster_key_blob);

@ -88,12 +88,7 @@ static bool fillKey(const KeyBuffer& key, ext4_encryption_key* ext4_key) {
return true; return true;
} }
static char const* const NAME_PREFIXES[] = { static char const* const NAME_PREFIXES[] = {"ext4", "f2fs", "fscrypt", nullptr};
"ext4",
"f2fs",
"fscrypt",
nullptr
};
static std::string keyname(const std::string& prefix, const std::string& raw_ref) { static std::string keyname(const std::string& prefix, const std::string& raw_ref) {
std::ostringstream o; std::ostringstream o;
@ -119,7 +114,7 @@ static bool e4cryptKeyring(key_serial_t* device_keyring) {
bool installKey(const KeyBuffer& key, std::string* raw_ref) { bool installKey(const KeyBuffer& key, std::string* raw_ref) {
// Place ext4_encryption_key into automatically zeroing buffer. // Place ext4_encryption_key into automatically zeroing buffer.
KeyBuffer ext4KeyBuffer(sizeof(ext4_encryption_key)); KeyBuffer ext4KeyBuffer(sizeof(ext4_encryption_key));
ext4_encryption_key &ext4_key = *reinterpret_cast<ext4_encryption_key*>(ext4KeyBuffer.data()); ext4_encryption_key& ext4_key = *reinterpret_cast<ext4_encryption_key*>(ext4KeyBuffer.data());
if (!fillKey(key, &ext4_key)) return false; if (!fillKey(key, &ext4_key)) return false;
*raw_ref = generateKeyRef(ext4_key.raw, ext4_key.size); *raw_ref = generateKeyRef(ext4_key.raw, ext4_key.size);
@ -170,8 +165,8 @@ bool retrieveAndInstallKey(bool create_if_absent, const KeyAuthentication& key_a
if (!retrieveKey(key_path, key_authentication, &key)) return false; if (!retrieveKey(key_path, key_authentication, &key)) return false;
} else { } else {
if (!create_if_absent) { if (!create_if_absent) {
LOG(ERROR) << "No key found in " << key_path; LOG(ERROR) << "No key found in " << key_path;
return false; return false;
} }
LOG(INFO) << "Creating new key in " << key_path; LOG(INFO) << "Creating new key in " << key_path;
if (!randomKey(&key)) return false; if (!randomKey(&key)) return false;
@ -185,20 +180,19 @@ bool retrieveAndInstallKey(bool create_if_absent, const KeyAuthentication& key_a
return true; return true;
} }
bool retrieveKey(bool create_if_absent, const std::string& key_path, bool retrieveKey(bool create_if_absent, const std::string& key_path, const std::string& tmp_path,
const std::string& tmp_path, KeyBuffer* key) { KeyBuffer* key) {
if (pathExists(key_path)) { if (pathExists(key_path)) {
LOG(DEBUG) << "Key exists, using: " << key_path; LOG(DEBUG) << "Key exists, using: " << key_path;
if (!retrieveKey(key_path, kEmptyAuthentication, key)) return false; if (!retrieveKey(key_path, kEmptyAuthentication, key)) return false;
} else { } else {
if (!create_if_absent) { if (!create_if_absent) {
LOG(ERROR) << "No key found in " << key_path; LOG(ERROR) << "No key found in " << key_path;
return false; return false;
} }
LOG(INFO) << "Creating new key in " << key_path; LOG(INFO) << "Creating new key in " << key_path;
if (!randomKey(key)) return false; if (!randomKey(key)) return false;
if (!storeKeyAtomically(key_path, tmp_path, if (!storeKeyAtomically(key_path, tmp_path, kEmptyAuthentication, *key)) return false;
kEmptyAuthentication, *key)) return false;
} }
return true; return true;
} }

@ -20,8 +20,8 @@
#include "KeyBuffer.h" #include "KeyBuffer.h"
#include "KeyStorage.h" #include "KeyStorage.h"
#include <string>
#include <memory> #include <memory>
#include <string>
namespace android { namespace android {
namespace vold { namespace vold {
@ -32,8 +32,8 @@ bool evictKey(const std::string& raw_ref);
bool retrieveAndInstallKey(bool create_if_absent, const KeyAuthentication& key_authentication, bool retrieveAndInstallKey(bool create_if_absent, const KeyAuthentication& key_authentication,
const std::string& key_path, const std::string& tmp_path, const std::string& key_path, const std::string& tmp_path,
std::string* key_ref); std::string* key_ref);
bool retrieveKey(bool create_if_absent, const std::string& key_path, bool retrieveKey(bool create_if_absent, const std::string& key_path, const std::string& tmp_path,
const std::string& tmp_path, KeyBuffer* key); KeyBuffer* key);
} // namespace vold } // namespace vold
} // namespace android } // namespace android

@ -16,24 +16,24 @@
#define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER #define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h> #include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h> #include <sys/types.h>
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
#include <android-base/logging.h> #include <android-base/logging.h>
#include <android-base/strings.h>
#include <android-base/stringprintf.h> #include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h> #include <android-base/unique_fd.h>
#include <utils/Trace.h> #include <utils/Trace.h>
@ -79,7 +79,7 @@ int Loop::create(const std::string& target, std::string& out_device) {
struct loop_info64 li; struct loop_info64 li;
memset(&li, 0, sizeof(li)); memset(&li, 0, sizeof(li));
strlcpy((char*) li.lo_crypt_name, kVoldPrefix, LO_NAME_SIZE); strlcpy((char*)li.lo_crypt_name, kVoldPrefix, LO_NAME_SIZE);
if (ioctl(device_fd.get(), LOOP_SET_STATUS64, &li) == -1) { if (ioctl(device_fd.get(), LOOP_SET_STATUS64, &li) == -1) {
PLOG(ERROR) << "Failed to LOOP_SET_STATUS64"; PLOG(ERROR) << "Failed to LOOP_SET_STATUS64";
return -errno; return -errno;
@ -88,7 +88,7 @@ int Loop::create(const std::string& target, std::string& out_device) {
return 0; return 0;
} }
int Loop::destroyByDevice(const char *loopDevice) { int Loop::destroyByDevice(const char* loopDevice) {
int device_fd; int device_fd;
device_fd = open(loopDevice, O_RDONLY | O_CLOEXEC); device_fd = open(loopDevice, O_RDONLY | O_CLOEXEC);
@ -138,7 +138,7 @@ int Loop::destroyAll() {
continue; continue;
} }
auto id = std::string((char*) li.lo_crypt_name); auto id = std::string((char*)li.lo_crypt_name);
if (android::base::StartsWith(id, kVoldPrefix)) { if (android::base::StartsWith(id, kVoldPrefix)) {
LOG(DEBUG) << "Tearing down stale loop device at " << path << " named " << id; LOG(DEBUG) << "Tearing down stale loop device at " << path << " named " << id;
@ -153,7 +153,7 @@ int Loop::destroyAll() {
return 0; return 0;
} }
int Loop::createImageFile(const char *file, unsigned long numSectors) { int Loop::createImageFile(const char* file, unsigned long numSectors) {
unique_fd fd(open(file, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0600)); unique_fd fd(open(file, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0600));
if (fd.get() == -1) { if (fd.get() == -1) {
PLOG(ERROR) << "Failed to create image " << file; PLOG(ERROR) << "Failed to create image " << file;
@ -169,7 +169,7 @@ int Loop::createImageFile(const char *file, unsigned long numSectors) {
return 0; return 0;
} }
int Loop::resizeImageFile(const char *file, unsigned long numSectors) { int Loop::resizeImageFile(const char* file, unsigned long numSectors) {
int fd; int fd;
if ((fd = open(file, O_RDWR | O_CLOEXEC)) < 0) { if ((fd = open(file, O_RDWR | O_CLOEXEC)) < 0) {

@ -17,19 +17,20 @@
#ifndef _LOOP_H #ifndef _LOOP_H
#define _LOOP_H #define _LOOP_H
#include <string>
#include <unistd.h>
#include <linux/loop.h> #include <linux/loop.h>
#include <unistd.h>
#include <string>
class Loop { class Loop {
public: public:
static const int LOOP_MAX = 4096; static const int LOOP_MAX = 4096;
public:
public:
static int create(const std::string& file, std::string& out_device); static int create(const std::string& file, std::string& out_device);
static int destroyByDevice(const char *loopDevice); static int destroyByDevice(const char* loopDevice);
static int destroyAll(); static int destroyAll();
static int createImageFile(const char *file, unsigned long numSectors); static int createImageFile(const char* file, unsigned long numSectors);
static int resizeImageFile(const char *file, unsigned long numSectors); static int resizeImageFile(const char* file, unsigned long numSectors);
}; };
#endif #endif

@ -14,13 +14,13 @@
* limitations under the License. * limitations under the License.
*/ */
#include "KeyBuffer.h"
#include "MetadataCrypt.h" #include "MetadataCrypt.h"
#include "KeyBuffer.h"
#include <algorithm>
#include <string> #include <string>
#include <thread> #include <thread>
#include <vector> #include <vector>
#include <algorithm>
#include <fcntl.h> #include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -39,9 +39,9 @@
#include "EncryptInplace.h" #include "EncryptInplace.h"
#include "KeyStorage.h" #include "KeyStorage.h"
#include "KeyUtil.h" #include "KeyUtil.h"
#include "secontext.h"
#include "Utils.h" #include "Utils.h"
#include "VoldUtil.h" #include "VoldUtil.h"
#include "secontext.h"
#define DM_CRYPT_BUF_SIZE 4096 #define DM_CRYPT_BUF_SIZE 4096
#define TABLE_LOAD_RETRIES 10 #define TABLE_LOAD_RETRIES 10
@ -99,9 +99,9 @@ static KeyBuffer default_key_params(const std::string& real_blkdev, const KeyBuf
return res; return res;
} }
static bool get_number_of_sectors(const std::string& real_blkdev, uint64_t *nr_sec) { static bool get_number_of_sectors(const std::string& real_blkdev, uint64_t* nr_sec) {
android::base::unique_fd dev_fd(TEMP_FAILURE_RETRY(open( android::base::unique_fd dev_fd(
real_blkdev.c_str(), O_RDONLY | O_CLOEXEC, 0))); TEMP_FAILURE_RETRY(open(real_blkdev.c_str(), O_RDONLY | O_CLOEXEC, 0)));
if (dev_fd == -1) { if (dev_fd == -1) {
PLOG(ERROR) << "Unable to open " << real_blkdev << " to measure size"; PLOG(ERROR) << "Unable to open " << real_blkdev << " to measure size";
return false; return false;
@ -117,15 +117,14 @@ static bool get_number_of_sectors(const std::string& real_blkdev, uint64_t *nr_s
return true; return true;
} }
static struct dm_ioctl* dm_ioctl_init(char *buffer, size_t buffer_size, static struct dm_ioctl* dm_ioctl_init(char* buffer, size_t buffer_size, const std::string& dm_name) {
const std::string& dm_name) {
if (buffer_size < sizeof(dm_ioctl)) { if (buffer_size < sizeof(dm_ioctl)) {
LOG(ERROR) << "dm_ioctl buffer too small"; LOG(ERROR) << "dm_ioctl buffer too small";
return nullptr; return nullptr;
} }
memset(buffer, 0, buffer_size); memset(buffer, 0, buffer_size);
struct dm_ioctl* io = (struct dm_ioctl*) buffer; struct dm_ioctl* io = (struct dm_ioctl*)buffer;
io->data_size = buffer_size; io->data_size = buffer_size;
io->data_start = sizeof(struct dm_ioctl); io->data_start = sizeof(struct dm_ioctl);
io->version[0] = 4; io->version[0] = 4;
@ -139,8 +138,8 @@ static struct dm_ioctl* dm_ioctl_init(char *buffer, size_t buffer_size,
static bool create_crypto_blk_dev(const std::string& dm_name, uint64_t nr_sec, static bool create_crypto_blk_dev(const std::string& dm_name, uint64_t nr_sec,
const std::string& target_type, const KeyBuffer& crypt_params, const std::string& target_type, const KeyBuffer& crypt_params,
std::string* crypto_blkdev) { std::string* crypto_blkdev) {
android::base::unique_fd dm_fd(TEMP_FAILURE_RETRY(open( android::base::unique_fd dm_fd(
"/dev/device-mapper", O_RDWR | O_CLOEXEC, 0))); TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC, 0)));
if (dm_fd == -1) { if (dm_fd == -1) {
PLOG(ERROR) << "Cannot open device-mapper"; PLOG(ERROR) << "Cannot open device-mapper";
return false; return false;
@ -158,13 +157,13 @@ static bool create_crypto_blk_dev(const std::string& dm_name, uint64_t nr_sec,
PLOG(ERROR) << "Cannot retrieve dm-crypt device status " << dm_name; PLOG(ERROR) << "Cannot retrieve dm-crypt device status " << dm_name;
return false; return false;
} }
*crypto_blkdev = std::string() + "/dev/block/dm-" + std::to_string( *crypto_blkdev = std::string() + "/dev/block/dm-" +
(io->dev & 0xff) | ((io->dev >> 12) & 0xfff00)); std::to_string((io->dev & 0xff) | ((io->dev >> 12) & 0xfff00));
io = dm_ioctl_init(buffer, sizeof(buffer), dm_name); io = dm_ioctl_init(buffer, sizeof(buffer), dm_name);
size_t paramix = io->data_start + sizeof(struct dm_target_spec); size_t paramix = io->data_start + sizeof(struct dm_target_spec);
size_t nullix = paramix + crypt_params.size(); size_t nullix = paramix + crypt_params.size();
size_t endix = (nullix + 1 + 7) & 8; // Add room for \0 and align to 8 byte boundary size_t endix = (nullix + 1 + 7) & 8; // Add room for \0 and align to 8 byte boundary
if (endix > sizeof(buffer)) { if (endix > sizeof(buffer)) {
LOG(ERROR) << "crypt_params too big for DM_CRYPT_BUF_SIZE"; LOG(ERROR) << "crypt_params too big for DM_CRYPT_BUF_SIZE";
@ -172,21 +171,21 @@ static bool create_crypto_blk_dev(const std::string& dm_name, uint64_t nr_sec,
} }
io->target_count = 1; io->target_count = 1;
auto tgt = (struct dm_target_spec *) (buffer + io->data_start); auto tgt = (struct dm_target_spec*)(buffer + io->data_start);
tgt->status = 0; tgt->status = 0;
tgt->sector_start = 0; tgt->sector_start = 0;
tgt->length = nr_sec; tgt->length = nr_sec;
target_type.copy(tgt->target_type, sizeof(tgt->target_type)); target_type.copy(tgt->target_type, sizeof(tgt->target_type));
memcpy(buffer + paramix, crypt_params.data(), memcpy(buffer + paramix, crypt_params.data(),
std::min(crypt_params.size(), sizeof(buffer) - paramix)); std::min(crypt_params.size(), sizeof(buffer) - paramix));
buffer[nullix] = '\0'; buffer[nullix] = '\0';
tgt->next = endix; tgt->next = endix;
for (int i = 0; ; i++) { for (int i = 0;; i++) {
if (ioctl(dm_fd.get(), DM_TABLE_LOAD, io) == 0) { if (ioctl(dm_fd.get(), DM_TABLE_LOAD, io) == 0) {
break; break;
} }
if (i+1 >= TABLE_LOAD_RETRIES) { if (i + 1 >= TABLE_LOAD_RETRIES) {
PLOG(ERROR) << "DM_TABLE_LOAD ioctl failed"; PLOG(ERROR) << "DM_TABLE_LOAD ioctl failed";
return false; return false;
} }

@ -29,7 +29,8 @@
#include <dirent.h> #include <dirent.h>
#include <sys/wait.h> #include <sys/wait.h>
#define CONSTRAIN(amount, low, high) ((amount) < (low) ? (low) : ((amount) > (high) ? (high) : (amount))) #define CONSTRAIN(amount, low, high) \
((amount) < (low) ? (low) : ((amount) > (high) ? (high) : (amount)))
static const char* kPropBlockingExec = "persist.sys.blocking_exec"; static const char* kPropBlockingExec = "persist.sys.blocking_exec";
@ -48,7 +49,7 @@ static const char* kRmPath = "/system/bin/rm";
static const char* kWakeLock = "MoveTask"; static const char* kWakeLock = "MoveTask";
static void notifyProgress(int progress, static void notifyProgress(int progress,
const android::sp<android::os::IVoldTaskListener>& listener) { const android::sp<android::os::IVoldTaskListener>& listener) {
if (listener) { if (listener) {
android::os::PersistableBundle extras; android::os::PersistableBundle extras;
listener->onStatus(progress, extras); listener->onStatus(progress, extras);
@ -56,7 +57,7 @@ static void notifyProgress(int progress,
} }
static status_t pushBackContents(const std::string& path, std::vector<std::string>& cmd, static status_t pushBackContents(const std::string& path, std::vector<std::string>& cmd,
bool addWildcard) { bool addWildcard) {
DIR* dir = opendir(path.c_str()); DIR* dir = opendir(path.c_str());
if (dir == NULL) { if (dir == NULL) {
return -1; return -1;
@ -79,7 +80,7 @@ static status_t pushBackContents(const std::string& path, std::vector<std::strin
} }
static status_t execRm(const std::string& path, int startProgress, int stepProgress, static status_t execRm(const std::string& path, int startProgress, int stepProgress,
const android::sp<android::os::IVoldTaskListener>& listener) { const android::sp<android::os::IVoldTaskListener>& listener) {
notifyProgress(startProgress, listener); notifyProgress(startProgress, listener);
uint64_t expectedBytes = GetTreeBytes(path); uint64_t expectedBytes = GetTreeBytes(path);
@ -114,14 +115,17 @@ static status_t execRm(const std::string& path, int startProgress, int stepProgr
sleep(1); sleep(1);
uint64_t deltaFreeBytes = GetFreeBytes(path) - startFreeBytes; uint64_t deltaFreeBytes = GetFreeBytes(path) - startFreeBytes;
notifyProgress(startProgress + CONSTRAIN((int) notifyProgress(
((deltaFreeBytes * stepProgress) / expectedBytes), 0, stepProgress), listener); startProgress +
CONSTRAIN((int)((deltaFreeBytes * stepProgress) / expectedBytes), 0, stepProgress),
listener);
} }
return -1; return -1;
} }
static status_t execCp(const std::string& fromPath, const std::string& toPath, int startProgress, static status_t execCp(const std::string& fromPath, const std::string& toPath, int startProgress,
int stepProgress, const android::sp<android::os::IVoldTaskListener>& listener) { int stepProgress,
const android::sp<android::os::IVoldTaskListener>& listener) {
notifyProgress(startProgress, listener); notifyProgress(startProgress, listener);
uint64_t expectedBytes = GetTreeBytes(fromPath); uint64_t expectedBytes = GetTreeBytes(fromPath);
@ -129,7 +133,7 @@ static status_t execCp(const std::string& fromPath, const std::string& toPath, i
if (expectedBytes > startFreeBytes) { if (expectedBytes > startFreeBytes) {
LOG(ERROR) << "Data size " << expectedBytes << " is too large to fit in free space " LOG(ERROR) << "Data size " << expectedBytes << " is too large to fit in free space "
<< startFreeBytes; << startFreeBytes;
return -1; return -1;
} }
@ -165,8 +169,10 @@ static status_t execCp(const std::string& fromPath, const std::string& toPath, i
sleep(1); sleep(1);
uint64_t deltaFreeBytes = startFreeBytes - GetFreeBytes(toPath); uint64_t deltaFreeBytes = startFreeBytes - GetFreeBytes(toPath);
notifyProgress(startProgress + CONSTRAIN((int) notifyProgress(
((deltaFreeBytes * stepProgress) / expectedBytes), 0, stepProgress), listener); startProgress +
CONSTRAIN((int)((deltaFreeBytes * stepProgress) / expectedBytes), 0, stepProgress),
listener);
} }
return -1; return -1;
} }
@ -186,8 +192,8 @@ static void bringOnline(const std::shared_ptr<VolumeBase>& vol) {
} }
static status_t moveStorageInternal(const std::shared_ptr<VolumeBase>& from, static status_t moveStorageInternal(const std::shared_ptr<VolumeBase>& from,
const std::shared_ptr<VolumeBase>& to, const std::shared_ptr<VolumeBase>& to,
const android::sp<android::os::IVoldTaskListener>& listener) { const android::sp<android::os::IVoldTaskListener>& listener) {
std::string fromPath; std::string fromPath;
std::string toPath; std::string toPath;
@ -239,17 +245,19 @@ copy_fail:
// useful anyway. // useful anyway.
execRm(toPath, 80, 1, listener); execRm(toPath, 80, 1, listener);
fail: fail:
// clang-format off
{ {
std::lock_guard<std::mutex> lock(VolumeManager::Instance()->getLock()); std::lock_guard<std::mutex> lock(VolumeManager::Instance()->getLock());
bringOnline(from); bringOnline(from);
bringOnline(to); bringOnline(to);
} }
// clang-format on
notifyProgress(kMoveFailedInternalError, listener); notifyProgress(kMoveFailedInternalError, listener);
return -1; return -1;
} }
void MoveStorage(const std::shared_ptr<VolumeBase>& from, const std::shared_ptr<VolumeBase>& to, void MoveStorage(const std::shared_ptr<VolumeBase>& from, const std::shared_ptr<VolumeBase>& to,
const android::sp<android::os::IVoldTaskListener>& listener) { const android::sp<android::os::IVoldTaskListener>& listener) {
acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLock); acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLock);
android::os::PersistableBundle extras; android::os::PersistableBundle extras;

@ -24,7 +24,7 @@ namespace android {
namespace vold { namespace vold {
void MoveStorage(const std::shared_ptr<VolumeBase>& from, const std::shared_ptr<VolumeBase>& to, void MoveStorage(const std::shared_ptr<VolumeBase>& from, const std::shared_ptr<VolumeBase>& to,
const android::sp<android::os::IVoldTaskListener>& listener); const android::sp<android::os::IVoldTaskListener>& listener);
} // namespace vold } // namespace vold
} // namespace android } // namespace android

@ -14,9 +14,9 @@
* limitations under the License. * limitations under the License.
*/ */
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h>
#include <string.h> #include <string.h>
#include <android-base/logging.h> #include <android-base/logging.h>
@ -25,12 +25,9 @@
#include "NetlinkHandler.h" #include "NetlinkHandler.h"
#include "VolumeManager.h" #include "VolumeManager.h"
NetlinkHandler::NetlinkHandler(int listenerSocket) : NetlinkHandler::NetlinkHandler(int listenerSocket) : NetlinkListener(listenerSocket) {}
NetlinkListener(listenerSocket) {
}
NetlinkHandler::~NetlinkHandler() { NetlinkHandler::~NetlinkHandler() {}
}
int NetlinkHandler::start() { int NetlinkHandler::start() {
return this->startListener(); return this->startListener();
@ -40,9 +37,9 @@ int NetlinkHandler::stop() {
return this->stopListener(); return this->stopListener();
} }
void NetlinkHandler::onEvent(NetlinkEvent *evt) { void NetlinkHandler::onEvent(NetlinkEvent* evt) {
VolumeManager *vm = VolumeManager::Instance(); VolumeManager* vm = VolumeManager::Instance();
const char *subsys = evt->getSubsystem(); const char* subsys = evt->getSubsystem();
if (!subsys) { if (!subsys) {
LOG(WARNING) << "No subsystem found in netlink event"; LOG(WARNING) << "No subsystem found in netlink event";

@ -19,16 +19,15 @@
#include <sysutils/NetlinkListener.h> #include <sysutils/NetlinkListener.h>
class NetlinkHandler: public NetlinkListener { class NetlinkHandler : public NetlinkListener {
public:
public:
explicit NetlinkHandler(int listenerSocket); explicit NetlinkHandler(int listenerSocket);
virtual ~NetlinkHandler(); virtual ~NetlinkHandler();
int start(void); int start(void);
int stop(void); int stop(void);
protected: protected:
virtual void onEvent(NetlinkEvent *evt); virtual void onEvent(NetlinkEvent* evt);
}; };
#endif #endif

@ -14,12 +14,12 @@
* limitations under the License. * limitations under the License.
*/ */
#include <stdio.h>
#include <errno.h> #include <errno.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/socket.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/socket.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/un.h> #include <sys/un.h>
@ -28,14 +28,13 @@
#include <android-base/logging.h> #include <android-base/logging.h>
#include "NetlinkManager.h"
#include "NetlinkHandler.h" #include "NetlinkHandler.h"
#include "NetlinkManager.h"
NetlinkManager *NetlinkManager::sInstance = NULL; NetlinkManager* NetlinkManager::sInstance = NULL;
NetlinkManager *NetlinkManager::Instance() { NetlinkManager* NetlinkManager::Instance() {
if (!sInstance) if (!sInstance) sInstance = new NetlinkManager();
sInstance = new NetlinkManager();
return sInstance; return sInstance;
} }
@ -43,8 +42,7 @@ NetlinkManager::NetlinkManager() {
mBroadcaster = NULL; mBroadcaster = NULL;
} }
NetlinkManager::~NetlinkManager() { NetlinkManager::~NetlinkManager() {}
}
int NetlinkManager::start() { int NetlinkManager::start() {
struct sockaddr_nl nladdr; struct sockaddr_nl nladdr;
@ -56,8 +54,7 @@ int NetlinkManager::start() {
nladdr.nl_pid = getpid(); nladdr.nl_pid = getpid();
nladdr.nl_groups = 0xffffffff; nladdr.nl_groups = 0xffffffff;
if ((mSock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, if ((mSock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT)) < 0) {
NETLINK_KOBJECT_UEVENT)) < 0) {
PLOG(ERROR) << "Unable to create uevent socket"; PLOG(ERROR) << "Unable to create uevent socket";
return -1; return -1;
} }
@ -76,7 +73,7 @@ int NetlinkManager::start() {
goto out; goto out;
} }
if (bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) { if (bind(mSock, (struct sockaddr*)&nladdr, sizeof(nladdr)) < 0) {
PLOG(ERROR) << "Unable to bind uevent socket"; PLOG(ERROR) << "Unable to bind uevent socket";
goto out; goto out;
} }

@ -17,32 +17,32 @@
#ifndef _NETLINKMANAGER_H #ifndef _NETLINKMANAGER_H
#define _NETLINKMANAGER_H #define _NETLINKMANAGER_H
#include <sysutils/SocketListener.h>
#include <sysutils/NetlinkListener.h> #include <sysutils/NetlinkListener.h>
#include <sysutils/SocketListener.h>
class NetlinkHandler; class NetlinkHandler;
class NetlinkManager { class NetlinkManager {
private: private:
static NetlinkManager *sInstance; static NetlinkManager* sInstance;
private: private:
SocketListener *mBroadcaster; SocketListener* mBroadcaster;
NetlinkHandler *mHandler; NetlinkHandler* mHandler;
int mSock; int mSock;
public: public:
virtual ~NetlinkManager(); virtual ~NetlinkManager();
int start(); int start();
int stop(); int stop();
void setBroadcaster(SocketListener *sl) { mBroadcaster = sl; } void setBroadcaster(SocketListener* sl) { mBroadcaster = sl; }
SocketListener *getBroadcaster() { return mBroadcaster; } SocketListener* getBroadcaster() { return mBroadcaster; }
static NetlinkManager *Instance(); static NetlinkManager* Instance();
private: private:
NetlinkManager(); NetlinkManager();
}; };
#endif #endif

@ -14,28 +14,28 @@
* limitations under the License. * limitations under the License.
*/ */
#include <stdio.h> #include <ctype.h>
#include <unistd.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <string.h>
#include <fcntl.h> #include <fcntl.h>
#include <fts.h> #include <fts.h>
#include <dirent.h> #include <poll.h>
#include <ctype.h>
#include <pwd.h> #include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <poll.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <signal.h> #include <unistd.h>
#include <fstream> #include <fstream>
#include <unordered_set> #include <unordered_set>
#include <android-base/file.h> #include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h> #include <android-base/parseint.h>
#include <android-base/strings.h>
#include <android-base/stringprintf.h> #include <android-base/stringprintf.h>
#include <android-base/logging.h> #include <android-base/strings.h>
#include "Process.h" #include "Process.h"

@ -19,20 +19,19 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
bool parse_scrypt_parameters(const char* paramstr, int *Nf, int *rf, int *pf) { bool parse_scrypt_parameters(const char* paramstr, int* Nf, int* rf, int* pf) {
int params[3] = {}; int params[3] = {};
char *token; char* token;
char *saveptr; char* saveptr;
int i; int i;
/* /*
* The token we're looking for should be three integers separated by * The token we're looking for should be three integers separated by
* colons (e.g., "12:8:1"). Scan the property to make sure it matches. * colons (e.g., "12:8:1"). Scan the property to make sure it matches.
*/ */
for (i = 0, token = strtok_r(const_cast<char *>(paramstr), ":", &saveptr); for (i = 0, token = strtok_r(const_cast<char*>(paramstr), ":", &saveptr);
token != nullptr && i < 3; token != nullptr && i < 3; i++, token = strtok_r(nullptr, ":", &saveptr)) {
i++, token = strtok_r(nullptr, ":", &saveptr)) { char* endptr;
char *endptr;
params[i] = strtol(token, &endptr, 10); params[i] = strtol(token, &endptr, 10);
/* /*
@ -45,6 +44,8 @@ bool parse_scrypt_parameters(const char* paramstr, int *Nf, int *rf, int *pf) {
if (token != nullptr) { if (token != nullptr) {
return false; return false;
} }
*Nf = params[0]; *rf = params[1]; *pf = params[2]; *Nf = params[0];
*rf = params[1];
*pf = params[2];
return true; return true;
} }

@ -23,6 +23,6 @@
#define SCRYPT_PROP "ro.crypto.scrypt_params" #define SCRYPT_PROP "ro.crypto.scrypt_params"
#define SCRYPT_DEFAULTS "15:3:1" #define SCRYPT_DEFAULTS "15:3:1"
bool parse_scrypt_parameters(const char* paramstr, int *Nf, int *rf, int *pf); bool parse_scrypt_parameters(const char* paramstr, int* Nf, int* rf, int* pf);
#endif #endif

@ -22,26 +22,26 @@
#include <android-base/file.h> #include <android-base/file.h>
#include <android-base/logging.h> #include <android-base/logging.h>
#include <android-base/properties.h> #include <android-base/properties.h>
#include <android-base/strings.h>
#include <android-base/stringprintf.h> #include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <cutils/fs.h> #include <cutils/fs.h>
#include <logwrap/logwrap.h> #include <logwrap/logwrap.h>
#include <private/android_filesystem_config.h> #include <private/android_filesystem_config.h>
#include <mutex>
#include <dirent.h> #include <dirent.h>
#include <fcntl.h> #include <fcntl.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/statvfs.h> #include <mutex>
#ifndef UMOUNT_NOFOLLOW #ifndef UMOUNT_NOFOLLOW
#define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */ #define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */
#endif #endif
using android::base::ReadFileToString; using android::base::ReadFileToString;
@ -81,8 +81,8 @@ status_t CreateDeviceNode(const std::string& path, dev_t dev) {
mode_t mode = 0660 | S_IFBLK; mode_t mode = 0660 | S_IFBLK;
if (mknod(cpath, mode, dev) < 0) { if (mknod(cpath, mode, dev) < 0) {
if (errno != EEXIST) { if (errno != EEXIST) {
PLOG(ERROR) << "Failed to create device node for " << major(dev) PLOG(ERROR) << "Failed to create device node for " << major(dev) << ":" << minor(dev)
<< ":" << minor(dev) << " at " << path; << " at " << path;
res = -errno; res = -errno;
} }
} }
@ -209,8 +209,8 @@ bool FindValue(const std::string& raw, const std::string& key, std::string* valu
return true; return true;
} }
static status_t readMetadata(const std::string& path, std::string* fsType, static status_t readMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
std::string* fsUuid, std::string* fsLabel, bool untrusted) { std::string* fsLabel, bool untrusted) {
fsType->clear(); fsType->clear();
fsUuid->clear(); fsUuid->clear();
fsLabel->clear(); fsLabel->clear();
@ -244,13 +244,13 @@ static status_t readMetadata(const std::string& path, std::string* fsType,
return OK; return OK;
} }
status_t ReadMetadata(const std::string& path, std::string* fsType, status_t ReadMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
std::string* fsUuid, std::string* fsLabel) { std::string* fsLabel) {
return readMetadata(path, fsType, fsUuid, fsLabel, false); return readMetadata(path, fsType, fsUuid, fsLabel, false);
} }
status_t ReadMetadataUntrusted(const std::string& path, std::string* fsType, status_t ReadMetadataUntrusted(const std::string& path, std::string* fsType, std::string* fsUuid,
std::string* fsUuid, std::string* fsLabel) { std::string* fsLabel) {
return readMetadata(path, fsType, fsUuid, fsLabel, true); return readMetadata(path, fsType, fsUuid, fsLabel, true);
} }
@ -261,9 +261,9 @@ status_t ForkExecvp(const std::vector<std::string>& args) {
status_t ForkExecvp(const std::vector<std::string>& args, security_context_t context) { status_t ForkExecvp(const std::vector<std::string>& args, security_context_t context) {
std::lock_guard<std::mutex> lock(kSecurityLock); std::lock_guard<std::mutex> lock(kSecurityLock);
size_t argc = args.size(); size_t argc = args.size();
char** argv = (char**) calloc(argc, sizeof(char*)); char** argv = (char**)calloc(argc, sizeof(char*));
for (size_t i = 0; i < argc; i++) { for (size_t i = 0; i < argc; i++) {
argv[i] = (char*) args[i].c_str(); argv[i] = (char*)args[i].c_str();
if (i == 0) { if (i == 0) {
LOG(VERBOSE) << args[i]; LOG(VERBOSE) << args[i];
} else { } else {
@ -289,13 +289,12 @@ status_t ForkExecvp(const std::vector<std::string>& args, security_context_t con
return res; return res;
} }
status_t ForkExecvp(const std::vector<std::string>& args, status_t ForkExecvp(const std::vector<std::string>& args, std::vector<std::string>& output) {
std::vector<std::string>& output) {
return ForkExecvp(args, output, nullptr); return ForkExecvp(args, output, nullptr);
} }
status_t ForkExecvp(const std::vector<std::string>& args, status_t ForkExecvp(const std::vector<std::string>& args, std::vector<std::string>& output,
std::vector<std::string>& output, security_context_t context) { security_context_t context) {
std::lock_guard<std::mutex> lock(kSecurityLock); std::lock_guard<std::mutex> lock(kSecurityLock);
std::string cmd; std::string cmd;
for (size_t i = 0; i < args.size(); i++) { for (size_t i = 0; i < args.size(); i++) {
@ -314,7 +313,7 @@ status_t ForkExecvp(const std::vector<std::string>& args,
abort(); abort();
} }
} }
FILE* fp = popen(cmd.c_str(), "r"); // NOLINT FILE* fp = popen(cmd.c_str(), "r"); // NOLINT
if (context) { if (context) {
if (setexeccon(nullptr)) { if (setexeccon(nullptr)) {
LOG(ERROR) << "Failed to setexeccon"; LOG(ERROR) << "Failed to setexeccon";
@ -341,9 +340,9 @@ status_t ForkExecvp(const std::vector<std::string>& args,
pid_t ForkExecvpAsync(const std::vector<std::string>& args) { pid_t ForkExecvpAsync(const std::vector<std::string>& args) {
size_t argc = args.size(); size_t argc = args.size();
char** argv = (char**) calloc(argc + 1, sizeof(char*)); char** argv = (char**)calloc(argc + 1, sizeof(char*));
for (size_t i = 0; i < argc; i++) { for (size_t i = 0; i < argc; i++) {
argv[i] = (char*) args[i].c_str(); argv[i] = (char*)args[i].c_str();
if (i == 0) { if (i == 0) {
LOG(VERBOSE) << args[i]; LOG(VERBOSE) << args[i];
} else { } else {
@ -400,10 +399,10 @@ status_t ReadRandomBytes(size_t bytes, char* buf) {
status_t GenerateRandomUuid(std::string& out) { status_t GenerateRandomUuid(std::string& out) {
status_t res = ReadRandomBytes(16, out); status_t res = ReadRandomBytes(16, out);
if (res == OK) { if (res == OK) {
out[6] &= 0x0f; /* clear version */ out[6] &= 0x0f; /* clear version */
out[6] |= 0x40; /* set to version 4 */ out[6] |= 0x40; /* set to version 4 */
out[8] &= 0x3f; /* clear variant */ out[8] &= 0x3f; /* clear variant */
out[8] |= 0x80; /* set to IETF variant */ out[8] |= 0x80; /* set to IETF variant */
} }
return res; return res;
} }
@ -415,24 +414,26 @@ status_t HexToStr(const std::string& hex, std::string& str) {
for (size_t i = 0; i < hex.size(); i++) { for (size_t i = 0; i < hex.size(); i++) {
int val = 0; int val = 0;
switch (hex[i]) { switch (hex[i]) {
case ' ': case '-': case ':': continue; // clang-format off
case 'f': case 'F': val = 15; break; case ' ': case '-': case ':': continue;
case 'e': case 'E': val = 14; break; case 'f': case 'F': val = 15; break;
case 'd': case 'D': val = 13; break; case 'e': case 'E': val = 14; break;
case 'c': case 'C': val = 12; break; case 'd': case 'D': val = 13; break;
case 'b': case 'B': val = 11; break; case 'c': case 'C': val = 12; break;
case 'a': case 'A': val = 10; break; case 'b': case 'B': val = 11; break;
case '9': val = 9; break; case 'a': case 'A': val = 10; break;
case '8': val = 8; break; case '9': val = 9; break;
case '7': val = 7; break; case '8': val = 8; break;
case '6': val = 6; break; case '7': val = 7; break;
case '5': val = 5; break; case '6': val = 6; break;
case '4': val = 4; break; case '5': val = 5; break;
case '3': val = 3; break; case '4': val = 4; break;
case '2': val = 2; break; case '3': val = 3; break;
case '1': val = 1; break; case '2': val = 2; break;
case '0': val = 0; break; case '1': val = 1; break;
default: return -EINVAL; case '0': val = 0; break;
default: return -EINVAL;
// clang-format on
} }
if (even) { if (even) {
@ -478,7 +479,7 @@ status_t NormalizeHex(const std::string& in, std::string& out) {
uint64_t GetFreeBytes(const std::string& path) { uint64_t GetFreeBytes(const std::string& path) {
struct statvfs sb; struct statvfs sb;
if (statvfs(path.c_str(), &sb) == 0) { if (statvfs(path.c_str(), &sb) == 0) {
return (uint64_t) sb.f_bavail * sb.f_frsize; return (uint64_t)sb.f_bavail * sb.f_frsize;
} else { } else {
return -1; return -1;
} }
@ -486,7 +487,7 @@ uint64_t GetFreeBytes(const std::string& path) {
// TODO: borrowed from frameworks/native/libs/diskusage/ which should // TODO: borrowed from frameworks/native/libs/diskusage/ which should
// eventually be migrated into system/ // eventually be migrated into system/
static int64_t stat_size(struct stat *s) { static int64_t stat_size(struct stat* s) {
int64_t blksize = s->st_blksize; int64_t blksize = s->st_blksize;
// count actual blocks used instead of nominal file size // count actual blocks used instead of nominal file size
int64_t size = s->st_blocks * 512; int64_t size = s->st_blocks * 512;
@ -504,8 +505,8 @@ static int64_t stat_size(struct stat *s) {
int64_t calculate_dir_size(int dfd) { int64_t calculate_dir_size(int dfd) {
int64_t size = 0; int64_t size = 0;
struct stat s; struct stat s;
DIR *d; DIR* d;
struct dirent *de; struct dirent* de;
d = fdopendir(dfd); d = fdopendir(dfd);
if (d == NULL) { if (d == NULL) {
@ -514,7 +515,7 @@ int64_t calculate_dir_size(int dfd) {
} }
while ((de = readdir(d))) { while ((de = readdir(d))) {
const char *name = de->d_name; const char* name = de->d_name;
if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) {
size += stat_size(&s); size += stat_size(&s);
} }
@ -523,10 +524,8 @@ int64_t calculate_dir_size(int dfd) {
/* always skip "." and ".." */ /* always skip "." and ".." */
if (name[0] == '.') { if (name[0] == '.') {
if (name[1] == 0) if (name[1] == 0) continue;
continue; if ((name[1] == '.') && (name[2] == 0)) continue;
if ((name[1] == '.') && (name[2] == 0))
continue;
} }
subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_CLOEXEC); subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
@ -576,7 +575,7 @@ status_t WipeBlockDevice(const std::string& path) {
} }
range[0] = 0; range[0] = 0;
range[1] = (unsigned long long) nr_sec * 512; range[1] = (unsigned long long)nr_sec * 512;
LOG(INFO) << "About to discard " << range[1] << " on " << path; LOG(INFO) << "About to discard " << range[1] << " on " << path;
if (ioctl(fd, BLKDISCARD, &range) == 0) { if (ioctl(fd, BLKDISCARD, &range) == 0) {
@ -592,8 +591,7 @@ done:
} }
static bool isValidFilename(const std::string& name) { static bool isValidFilename(const std::string& name) {
if (name.empty() || (name == ".") || (name == "..") if (name.empty() || (name == ".") || (name == "..") || (name.find('/') != std::string::npos)) {
|| (name.find('/') != std::string::npos)) {
return false; return false;
} else { } else {
return true; return true;
@ -713,8 +711,7 @@ bool Readlinkat(int dirfd, const std::string& path, std::string* result) {
while (true) { while (true) {
ssize_t size = readlinkat(dirfd, path.c_str(), &buf[0], buf.size()); ssize_t size = readlinkat(dirfd, path.c_str(), &buf[0], buf.size());
// Unrecoverable error? // Unrecoverable error?
if (size == -1) if (size == -1) return false;
return false;
// It fit! (If size == buf.size(), it may have been truncated.) // It fit! (If size == buf.size(), it may have been truncated.)
if (static_cast<size_t>(size) < buf.size()) { if (static_cast<size_t>(size) < buf.size()) {
result->assign(&buf[0], size); result->assign(&buf[0], size);

@ -20,12 +20,12 @@
#include "KeyBuffer.h" #include "KeyBuffer.h"
#include <android-base/macros.h> #include <android-base/macros.h>
#include <utils/Errors.h>
#include <cutils/multiuser.h> #include <cutils/multiuser.h>
#include <selinux/selinux.h> #include <selinux/selinux.h>
#include <utils/Errors.h>
#include <vector>
#include <string> #include <string>
#include <vector>
struct DIR; struct DIR;
@ -59,21 +59,20 @@ status_t BindMount(const std::string& source, const std::string& target);
bool FindValue(const std::string& raw, const std::string& key, std::string* value); bool FindValue(const std::string& raw, const std::string& key, std::string* value);
/* Reads filesystem metadata from device at path */ /* Reads filesystem metadata from device at path */
status_t ReadMetadata(const std::string& path, std::string* fsType, status_t ReadMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
std::string* fsUuid, std::string* fsLabel); std::string* fsLabel);
/* Reads filesystem metadata from untrusted device at path */ /* Reads filesystem metadata from untrusted device at path */
status_t ReadMetadataUntrusted(const std::string& path, std::string* fsType, status_t ReadMetadataUntrusted(const std::string& path, std::string* fsType, std::string* fsUuid,
std::string* fsUuid, std::string* fsLabel); std::string* fsLabel);
/* Returns either WEXITSTATUS() status, or a negative errno */ /* Returns either WEXITSTATUS() status, or a negative errno */
status_t ForkExecvp(const std::vector<std::string>& args); status_t ForkExecvp(const std::vector<std::string>& args);
status_t ForkExecvp(const std::vector<std::string>& args, security_context_t context); status_t ForkExecvp(const std::vector<std::string>& args, security_context_t context);
status_t ForkExecvp(const std::vector<std::string>& args, status_t ForkExecvp(const std::vector<std::string>& args, std::vector<std::string>& output);
std::vector<std::string>& output); status_t ForkExecvp(const std::vector<std::string>& args, std::vector<std::string>& output,
status_t ForkExecvp(const std::vector<std::string>& args, security_context_t context);
std::vector<std::string>& output, security_context_t context);
pid_t ForkExecvpAsync(const std::vector<std::string>& args); pid_t ForkExecvpAsync(const std::vector<std::string>& args);

@ -14,13 +14,13 @@
* limitations under the License. * limitations under the License.
*/ */
#include <sys/ioctl.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <sys/ioctl.h>
struct fstab *fstab_default; struct fstab* fstab_default;
void get_blkdev_size(int fd, unsigned long* nr_sec) { void get_blkdev_size(int fd, unsigned long* nr_sec) {
if ((ioctl(fd, BLKGETSIZE, nr_sec)) == -1) { if ((ioctl(fd, BLKGETSIZE, nr_sec)) == -1) {
*nr_sec = 0; *nr_sec = 0;
} }
} }

@ -20,7 +20,7 @@
#include <fstab/fstab.h> #include <fstab/fstab.h>
#include <sys/cdefs.h> #include <sys/cdefs.h>
extern struct fstab *fstab_default; extern struct fstab* fstab_default;
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))

File diff suppressed because it is too large Load Diff

@ -51,32 +51,39 @@
/* definitions of flags in the structure below */ /* definitions of flags in the structure below */
#define CRYPT_MNT_KEY_UNENCRYPTED 0x1 /* The key for the partition is not encrypted. */ #define CRYPT_MNT_KEY_UNENCRYPTED 0x1 /* The key for the partition is not encrypted. */
#define CRYPT_ENCRYPTION_IN_PROGRESS 0x2 /* Encryption partially completed, #define CRYPT_ENCRYPTION_IN_PROGRESS \
encrypted_upto valid*/ 0x2 /* Encryption partially completed, \
#define CRYPT_INCONSISTENT_STATE 0x4 /* Set when starting encryption, clear when encrypted_upto valid*/
exit cleanly, either through success or #define CRYPT_INCONSISTENT_STATE \
correctly marked partial encryption */ 0x4 /* Set when starting encryption, clear when \
#define CRYPT_DATA_CORRUPT 0x8 /* Set when encryption is fine, but the exit cleanly, either through success or \
underlying volume is corrupt */ correctly marked partial encryption */
#define CRYPT_FORCE_ENCRYPTION 0x10 /* Set when it is time to encrypt this #define CRYPT_DATA_CORRUPT \
volume on boot. Everything in this 0x8 /* Set when encryption is fine, but the \
structure is set up correctly as underlying volume is corrupt */
though device is encrypted except #define CRYPT_FORCE_ENCRYPTION \
that the master key is encrypted with the 0x10 /* Set when it is time to encrypt this \
default password. */ volume on boot. Everything in this \
#define CRYPT_FORCE_COMPLETE 0x20 /* Set when the above encryption cycle is structure is set up correctly as \
complete. On next cryptkeeper entry, match though device is encrypted except \
the password. If it matches fix the master that the master key is encrypted with the \
key and remove this flag. */ default password. */
#define CRYPT_FORCE_COMPLETE \
0x20 /* Set when the above encryption cycle is \
complete. On next cryptkeeper entry, match \
the password. If it matches fix the master \
key and remove this flag. */
/* Allowed values for type in the structure below */ /* Allowed values for type in the structure below */
#define CRYPT_TYPE_PASSWORD 0 /* master_key is encrypted with a password #define CRYPT_TYPE_PASSWORD \
* Must be zero to be compatible with pre-L 0 /* master_key is encrypted with a password \
* devices where type is always password.*/ * Must be zero to be compatible with pre-L \
#define CRYPT_TYPE_DEFAULT 1 /* master_key is encrypted with default * devices where type is always password.*/
* password */ #define CRYPT_TYPE_DEFAULT \
#define CRYPT_TYPE_PATTERN 2 /* master_key is encrypted with a pattern */ 1 /* master_key is encrypted with default \
#define CRYPT_TYPE_PIN 3 /* master_key is encrypted with a pin */ * password */
#define CRYPT_TYPE_PATTERN 2 /* master_key is encrypted with a pattern */
#define CRYPT_TYPE_PIN 3 /* master_key is encrypted with a pin */
#define CRYPT_TYPE_MAX_TYPE 3 /* type cannot be larger than this value */ #define CRYPT_TYPE_MAX_TYPE 3 /* type cannot be larger than this value */
#define CRYPT_MNT_MAGIC 0xD0B5B1C4 #define CRYPT_MNT_MAGIC 0xD0B5B1C4
@ -92,78 +99,78 @@
#define KEYMASTER_BLOB_SIZE 2048 #define KEYMASTER_BLOB_SIZE 2048
/* __le32 and __le16 defined in system/extras/ext4_utils/ext4_utils.h */ /* __le32 and __le16 defined in system/extras/ext4_utils/ext4_utils.h */
#define __le8 unsigned char #define __le8 unsigned char
#if !defined(SHA256_DIGEST_LENGTH) #if !defined(SHA256_DIGEST_LENGTH)
#define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_LENGTH 32
#endif #endif
struct crypt_mnt_ftr { struct crypt_mnt_ftr {
__le32 magic; /* See above */ __le32 magic; /* See above */
__le16 major_version; __le16 major_version;
__le16 minor_version; __le16 minor_version;
__le32 ftr_size; /* in bytes, not including key following */ __le32 ftr_size; /* in bytes, not including key following */
__le32 flags; /* See above */ __le32 flags; /* See above */
__le32 keysize; /* in bytes */ __le32 keysize; /* in bytes */
__le32 crypt_type; /* how master_key is encrypted. Must be a __le32 crypt_type; /* how master_key is encrypted. Must be a
* CRYPT_TYPE_XXX value */ * CRYPT_TYPE_XXX value */
__le64 fs_size; /* Size of the encrypted fs, in 512 byte sectors */ __le64 fs_size; /* Size of the encrypted fs, in 512 byte sectors */
__le32 failed_decrypt_count; /* count of # of failed attempts to decrypt and __le32 failed_decrypt_count; /* count of # of failed attempts to decrypt and
mount, set to 0 on successful mount */ mount, set to 0 on successful mount */
unsigned char crypto_type_name[MAX_CRYPTO_TYPE_NAME_LEN]; /* The type of encryption unsigned char crypto_type_name[MAX_CRYPTO_TYPE_NAME_LEN]; /* The type of encryption
needed to decrypt this needed to decrypt this
partition, null terminated */ partition, null terminated */
__le32 spare2; /* ignored */ __le32 spare2; /* ignored */
unsigned char master_key[MAX_KEY_LEN]; /* The encrypted key for decrypting the filesystem */ unsigned char master_key[MAX_KEY_LEN]; /* The encrypted key for decrypting the filesystem */
unsigned char salt[SALT_LEN]; /* The salt used for this encryption */ unsigned char salt[SALT_LEN]; /* The salt used for this encryption */
__le64 persist_data_offset[2]; /* Absolute offset to both copies of crypt_persist_data __le64 persist_data_offset[2]; /* Absolute offset to both copies of crypt_persist_data
* on device with that info, either the footer of the * on device with that info, either the footer of the
* real_blkdevice or the metadata partition. */ * real_blkdevice or the metadata partition. */
__le32 persist_data_size; /* The number of bytes allocated to each copy of the __le32 persist_data_size; /* The number of bytes allocated to each copy of the
* persistent data table*/ * persistent data table*/
__le8 kdf_type; /* The key derivation function used. */ __le8 kdf_type; /* The key derivation function used. */
/* scrypt parameters. See www.tarsnap.com/scrypt/scrypt.pdf */ /* scrypt parameters. See www.tarsnap.com/scrypt/scrypt.pdf */
__le8 N_factor; /* (1 << N) */ __le8 N_factor; /* (1 << N) */
__le8 r_factor; /* (1 << r) */ __le8 r_factor; /* (1 << r) */
__le8 p_factor; /* (1 << p) */ __le8 p_factor; /* (1 << p) */
__le64 encrypted_upto; /* If we are in state CRYPT_ENCRYPTION_IN_PROGRESS and __le64 encrypted_upto; /* If we are in state CRYPT_ENCRYPTION_IN_PROGRESS and
we have to stop (e.g. power low) this is the last we have to stop (e.g. power low) this is the last
encrypted 512 byte sector.*/ encrypted 512 byte sector.*/
__le8 hash_first_block[SHA256_DIGEST_LENGTH]; /* When CRYPT_ENCRYPTION_IN_PROGRESS __le8 hash_first_block[SHA256_DIGEST_LENGTH]; /* When CRYPT_ENCRYPTION_IN_PROGRESS
set, hash of first block, used set, hash of first block, used
to validate before continuing*/ to validate before continuing*/
/* key_master key, used to sign the derived key which is then used to generate /* key_master key, used to sign the derived key which is then used to generate
* the intermediate key * the intermediate key
* This key should be used for no other purposes! We use this key to sign unpadded * This key should be used for no other purposes! We use this key to sign unpadded
* data, which is acceptable but only if the key is not reused elsewhere. */ * data, which is acceptable but only if the key is not reused elsewhere. */
__le8 keymaster_blob[KEYMASTER_BLOB_SIZE]; __le8 keymaster_blob[KEYMASTER_BLOB_SIZE];
__le32 keymaster_blob_size; __le32 keymaster_blob_size;
/* Store scrypt of salted intermediate key. When decryption fails, we can /* Store scrypt of salted intermediate key. When decryption fails, we can
check if this matches, and if it does, we know that the problem is with the check if this matches, and if it does, we know that the problem is with the
drive, and there is no point in asking the user for more passwords. drive, and there is no point in asking the user for more passwords.
Note that if any part of this structure is corrupt, this will not match and Note that if any part of this structure is corrupt, this will not match and
we will continue to believe the user entered the wrong password. In that we will continue to believe the user entered the wrong password. In that
case the only solution is for the user to enter a password enough times to case the only solution is for the user to enter a password enough times to
force a wipe. force a wipe.
Note also that there is no need to worry about migration. If this data is Note also that there is no need to worry about migration. If this data is
wrong, we simply won't recognise a right password, and will continue to wrong, we simply won't recognise a right password, and will continue to
prompt. On the first password change, this value will be populated and prompt. On the first password change, this value will be populated and
then we will be OK. then we will be OK.
*/ */
unsigned char scrypted_intermediate_key[SCRYPT_LEN]; unsigned char scrypted_intermediate_key[SCRYPT_LEN];
/* sha of this structure with this element set to zero /* sha of this structure with this element set to zero
Used when encrypting on reboot to validate structure before doing something Used when encrypting on reboot to validate structure before doing something
fatal fatal
*/ */
unsigned char sha256[SHA256_DIGEST_LENGTH]; unsigned char sha256[SHA256_DIGEST_LENGTH];
}; };
/* Persistant data that should be available before decryption. /* Persistant data that should be available before decryption.
@ -180,49 +187,49 @@ struct crypt_mnt_ftr {
* and higher crypt_mnt_ftr structures. * and higher crypt_mnt_ftr structures.
*/ */
struct crypt_persist_entry { struct crypt_persist_entry {
char key[PROPERTY_KEY_MAX]; char key[PROPERTY_KEY_MAX];
char val[PROPERTY_VALUE_MAX]; char val[PROPERTY_VALUE_MAX];
}; };
/* Should be exactly 4K in size */ /* Should be exactly 4K in size */
struct crypt_persist_data { struct crypt_persist_data {
__le32 persist_magic; __le32 persist_magic;
__le32 persist_valid_entries; __le32 persist_valid_entries;
__le32 persist_spare[30]; __le32 persist_spare[30];
struct crypt_persist_entry persist_entry[0]; struct crypt_persist_entry persist_entry[0];
}; };
#define DATA_MNT_POINT "/data" #define DATA_MNT_POINT "/data"
/* Return values for cryptfs_crypto_complete */ /* Return values for cryptfs_crypto_complete */
#define CRYPTO_COMPLETE_NOT_ENCRYPTED 1 #define CRYPTO_COMPLETE_NOT_ENCRYPTED 1
#define CRYPTO_COMPLETE_ENCRYPTED 0 #define CRYPTO_COMPLETE_ENCRYPTED 0
#define CRYPTO_COMPLETE_BAD_METADATA (-1) #define CRYPTO_COMPLETE_BAD_METADATA (-1)
#define CRYPTO_COMPLETE_PARTIAL (-2) #define CRYPTO_COMPLETE_PARTIAL (-2)
#define CRYPTO_COMPLETE_INCONSISTENT (-3) #define CRYPTO_COMPLETE_INCONSISTENT (-3)
#define CRYPTO_COMPLETE_CORRUPT (-4) #define CRYPTO_COMPLETE_CORRUPT (-4)
/* Return values for cryptfs_enable_inplace*() */ /* Return values for cryptfs_enable_inplace*() */
#define ENABLE_INPLACE_OK 0 #define ENABLE_INPLACE_OK 0
#define ENABLE_INPLACE_ERR_OTHER (-1) #define ENABLE_INPLACE_ERR_OTHER (-1)
#define ENABLE_INPLACE_ERR_DEV (-2) /* crypto_blkdev issue */ #define ENABLE_INPLACE_ERR_DEV (-2) /* crypto_blkdev issue */
/* Return values for cryptfs_getfield */ /* Return values for cryptfs_getfield */
#define CRYPTO_GETFIELD_OK 0 #define CRYPTO_GETFIELD_OK 0
#define CRYPTO_GETFIELD_ERROR_NO_FIELD (-1) #define CRYPTO_GETFIELD_ERROR_NO_FIELD (-1)
#define CRYPTO_GETFIELD_ERROR_OTHER (-2) #define CRYPTO_GETFIELD_ERROR_OTHER (-2)
#define CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL (-3) #define CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL (-3)
/* Return values for cryptfs_setfield */ /* Return values for cryptfs_setfield */
#define CRYPTO_SETFIELD_OK 0 #define CRYPTO_SETFIELD_OK 0
#define CRYPTO_SETFIELD_ERROR_OTHER (-1) #define CRYPTO_SETFIELD_ERROR_OTHER (-1)
#define CRYPTO_SETFIELD_ERROR_FIELD_TOO_LONG (-2) #define CRYPTO_SETFIELD_ERROR_FIELD_TOO_LONG (-2)
#define CRYPTO_SETFIELD_ERROR_VALUE_TOO_LONG (-3) #define CRYPTO_SETFIELD_ERROR_VALUE_TOO_LONG (-3)
/* Return values for persist_del_key */ /* Return values for persist_del_key */
#define PERSIST_DEL_KEY_OK 0 #define PERSIST_DEL_KEY_OK 0
#define PERSIST_DEL_KEY_ERROR_OTHER (-1) #define PERSIST_DEL_KEY_ERROR_OTHER (-1)
#define PERSIST_DEL_KEY_ERROR_NO_FIELD (-2) #define PERSIST_DEL_KEY_ERROR_NO_FIELD (-2)
int match_multi_entry(const char* key, const char* field, unsigned index); int match_multi_entry(const char* key, const char* field, unsigned index);
int wait_and_unmount(const char* mountpoint, bool kill); int wait_and_unmount(const char* mountpoint, bool kill);

@ -14,23 +14,20 @@
* limitations under the License. * limitations under the License.
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <vector> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <string> #include <string>
#include <vector>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
@ -59,9 +56,8 @@ static const char* kMkfsPath = "/system/bin/mke2fs";
static const char* kFsckPath = "/system/bin/e2fsck"; static const char* kFsckPath = "/system/bin/e2fsck";
bool IsSupported() { bool IsSupported() {
return access(kMkfsPath, X_OK) == 0 return access(kMkfsPath, X_OK) == 0 && access(kFsckPath, X_OK) == 0 &&
&& access(kFsckPath, X_OK) == 0 IsFilesystemSupported("ext4");
&& IsFilesystemSupported("ext4");
} }
status_t Check(const std::string& source, const std::string& target) { status_t Check(const std::string& source, const std::string& target) {
@ -74,7 +70,7 @@ status_t Check(const std::string& source, const std::string& target) {
int status; int status;
int ret; int ret;
long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID; long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
char *tmpmnt_opts = (char*) "nomblk_io_submit,errors=remount-ro"; char* tmpmnt_opts = (char*)"nomblk_io_submit,errors=remount-ro";
/* /*
* First try to mount and unmount the filesystem. We do this because * First try to mount and unmount the filesystem. We do this because
@ -127,8 +123,8 @@ status_t Check(const std::string& source, const std::string& target) {
return 0; return 0;
} }
status_t Mount(const std::string& source, const std::string& target, bool ro, status_t Mount(const std::string& source, const std::string& target, bool ro, bool remount,
bool remount, bool executable) { bool executable) {
int rc; int rc;
unsigned long flags; unsigned long flags;
@ -162,8 +158,7 @@ status_t Resize(const std::string& source, unsigned long numSectors) {
return ForkExecvp(cmd); return ForkExecvp(cmd);
} }
status_t Format(const std::string& source, unsigned long numSectors, status_t Format(const std::string& source, unsigned long numSectors, const std::string& target) {
const std::string& target) {
std::vector<std::string> cmd; std::vector<std::string> cmd;
cmd.push_back(kMkfsPath); cmd.push_back(kMkfsPath);

@ -28,10 +28,9 @@ namespace ext4 {
bool IsSupported(); bool IsSupported();
status_t Check(const std::string& source, const std::string& target); status_t Check(const std::string& source, const std::string& target);
status_t Mount(const std::string& source, const std::string& target, bool ro, status_t Mount(const std::string& source, const std::string& target, bool ro, bool remount,
bool remount, bool executable); bool executable);
status_t Format(const std::string& source, unsigned long numSectors, status_t Format(const std::string& source, unsigned long numSectors, const std::string& target);
const std::string& target);
status_t Resize(const std::string& source, unsigned long numSectors); status_t Resize(const std::string& source, unsigned long numSectors);
} // namespace ext4 } // namespace ext4

@ -22,8 +22,8 @@
#include <android-base/stringprintf.h> #include <android-base/stringprintf.h>
#include <ext4_utils/ext4_crypt.h> #include <ext4_utils/ext4_crypt.h>
#include <vector>
#include <string> #include <string>
#include <vector>
#include <sys/mount.h> #include <sys/mount.h>
@ -37,9 +37,8 @@ static const char* kMkfsPath = "/system/bin/make_f2fs";
static const char* kFsckPath = "/system/bin/fsck.f2fs"; static const char* kFsckPath = "/system/bin/fsck.f2fs";
bool IsSupported() { bool IsSupported() {
return access(kMkfsPath, X_OK) == 0 return access(kMkfsPath, X_OK) == 0 && access(kFsckPath, X_OK) == 0 &&
&& access(kFsckPath, X_OK) == 0 IsFilesystemSupported("f2fs");
&& IsFilesystemSupported("f2fs");
} }
status_t Check(const std::string& source) { status_t Check(const std::string& source) {

@ -14,24 +14,21 @@
* limitations under the License. * limitations under the License.
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> #include <linux/fs.h>
#include <sys/stat.h> #include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
@ -41,8 +38,8 @@
#include <logwrap/logwrap.h> #include <logwrap/logwrap.h>
#include "Vfat.h"
#include "Utils.h" #include "Utils.h"
#include "Vfat.h"
#include "VoldUtil.h" #include "VoldUtil.h"
using android::base::StringPrintf; using android::base::StringPrintf;
@ -55,9 +52,8 @@ static const char* kMkfsPath = "/system/bin/newfs_msdos";
static const char* kFsckPath = "/system/bin/fsck_msdos"; static const char* kFsckPath = "/system/bin/fsck_msdos";
bool IsSupported() { bool IsSupported() {
return access(kMkfsPath, X_OK) == 0 return access(kMkfsPath, X_OK) == 0 && access(kFsckPath, X_OK) == 0 &&
&& access(kFsckPath, X_OK) == 0 IsFilesystemSupported("vfat");
&& IsFilesystemSupported("vfat");
} }
status_t Check(const std::string& source) { status_t Check(const std::string& source) {
@ -79,43 +75,42 @@ status_t Check(const std::string& source) {
return -1; return -1;
} }
switch(rc) { switch (rc) {
case 0: case 0:
LOG(INFO) << "Filesystem check completed OK"; LOG(INFO) << "Filesystem check completed OK";
return 0; return 0;
case 2: case 2:
LOG(ERROR) << "Filesystem check failed (not a FAT filesystem)"; LOG(ERROR) << "Filesystem check failed (not a FAT filesystem)";
errno = ENODATA; errno = ENODATA;
return -1; return -1;
case 4: case 4:
if (pass++ <= 3) { if (pass++ <= 3) {
LOG(WARNING) << "Filesystem modified - rechecking (pass " << pass << ")"; LOG(WARNING) << "Filesystem modified - rechecking (pass " << pass << ")";
continue; continue;
} }
LOG(ERROR) << "Failing check after too many rechecks"; LOG(ERROR) << "Failing check after too many rechecks";
errno = EIO; errno = EIO;
return -1; return -1;
case 8: case 8:
LOG(ERROR) << "Filesystem check failed (no filesystem)"; LOG(ERROR) << "Filesystem check failed (no filesystem)";
errno = ENODATA; errno = ENODATA;
return -1; return -1;
default: default:
LOG(ERROR) << "Filesystem check failed (unknown exit code " << rc << ")"; LOG(ERROR) << "Filesystem check failed (unknown exit code " << rc << ")";
errno = EIO; errno = EIO;
return -1; return -1;
} }
} while (0); } while (0);
return 0; return 0;
} }
status_t Mount(const std::string& source, const std::string& target, bool ro, status_t Mount(const std::string& source, const std::string& target, bool ro, bool remount,
bool remount, bool executable, int ownerUid, int ownerGid, int permMask, bool executable, int ownerUid, int ownerGid, int permMask, bool createLost) {
bool createLost) {
int rc; int rc;
unsigned long flags; unsigned long flags;
@ -128,9 +123,9 @@ status_t Mount(const std::string& source, const std::string& target, bool ro,
flags |= (ro ? MS_RDONLY : 0); flags |= (ro ? MS_RDONLY : 0);
flags |= (remount ? MS_REMOUNT : 0); flags |= (remount ? MS_REMOUNT : 0);
auto mountData = android::base::StringPrintf( auto mountData =
"utf8,uid=%d,gid=%d,fmask=%o,dmask=%o,shortname=mixed", android::base::StringPrintf("utf8,uid=%d,gid=%d,fmask=%o,dmask=%o,shortname=mixed",
ownerUid, ownerGid, permMask, permMask); ownerUid, ownerGid, permMask, permMask);
rc = mount(c_source, c_target, "vfat", flags, mountData.c_str()); rc = mount(c_source, c_target, "vfat", flags, mountData.c_str());

@ -28,9 +28,8 @@ namespace vfat {
bool IsSupported(); bool IsSupported();
status_t Check(const std::string& source); status_t Check(const std::string& source);
status_t Mount(const std::string& source, const std::string& target, bool ro, status_t Mount(const std::string& source, const std::string& target, bool ro, bool remount,
bool remount, bool executable, int ownerUid, int ownerGid, int permMask, bool executable, int ownerUid, int ownerGid, int permMask, bool createLost);
bool createLost);
status_t Format(const std::string& source, unsigned long numSectors); status_t Format(const std::string& source, unsigned long numSectors);
} // namespace vfat } // namespace vfat

@ -1,18 +1,18 @@
/* /*
* Copyright (c) 1999 Kungliga Tekniska Högskolan * Copyright (c) 1999 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* *
* 3. Neither the name of KTH nor the names of its contributors may be * 3. Neither the name of KTH nor the names of its contributors may be
* used to endorse or promote products derived from this software without * used to endorse or promote products derived from this software without
@ -42,7 +42,7 @@
#include <string.h> #include <string.h>
#ifndef min #ifndef min
#define min(a,b) (((a)>(b))?(b):(a)) #define min(a, b) (((a) > (b)) ? (b) : (a))
#endif #endif
/* Vector Crays doesn't have a good 32-bit type, or more precisely, /* Vector Crays doesn't have a good 32-bit type, or more precisely,
@ -53,14 +53,12 @@
*/ */
#ifdef _CRAY #ifdef _CRAY
#define CRAYFIX(X) ((X) & 0xffffffff) #define CRAYFIX(X) ((X)&0xffffffff)
#else #else
#define CRAYFIX(X) (X) #define CRAYFIX(X) (X)
#endif #endif
static inline u_int32_t static inline u_int32_t cshift(u_int32_t x, unsigned int n) {
cshift (u_int32_t x, unsigned int n)
{
x = CRAYFIX(x); x = CRAYFIX(x);
return CRAYFIX((x << n) | (x >> (32 - n))); return CRAYFIX((x << n) | (x >> (32 - n)));
} }

@ -16,12 +16,12 @@
#define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER #define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
#include "model/Disk.h"
#include "VolumeManager.h"
#include "NetlinkManager.h" #include "NetlinkManager.h"
#include "VoldNativeService.h" #include "VoldNativeService.h"
#include "VoldUtil.h" #include "VoldUtil.h"
#include "VolumeManager.h"
#include "cryptfs.h" #include "cryptfs.h"
#include "model/Disk.h"
#include "sehandle.h" #include "sehandle.h"
#include <android-base/logging.h> #include <android-base/logging.h>
@ -31,23 +31,23 @@
#include <hidl/HidlTransportSupport.h> #include <hidl/HidlTransportSupport.h>
#include <utils/Trace.h> #include <utils/Trace.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fs_mgr.h>
#include <getopt.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <getopt.h>
#include <fcntl.h>
#include <dirent.h>
#include <fs_mgr.h>
static int process_config(VolumeManager* vm, bool* has_adoptable, bool* has_quota, static int process_config(VolumeManager* vm, bool* has_adoptable, bool* has_quota,
bool* has_reserved); bool* has_reserved);
static void coldboot(const char *path); static void coldboot(const char* path);
static void parse_args(int argc, char** argv); static void parse_args(int argc, char** argv);
struct selabel_handle *sehandle; struct selabel_handle* sehandle;
using android::base::StringPrintf; using android::base::StringPrintf;
@ -60,14 +60,13 @@ int main(int argc, char** argv) {
ATRACE_BEGIN("main"); ATRACE_BEGIN("main");
LOG(VERBOSE) << "Detected support for:" LOG(VERBOSE) << "Detected support for:"
<< (android::vold::IsFilesystemSupported("ext4") ? " ext4" : "") << (android::vold::IsFilesystemSupported("ext4") ? " ext4" : "")
<< (android::vold::IsFilesystemSupported("f2fs") ? " f2fs" : "") << (android::vold::IsFilesystemSupported("f2fs") ? " f2fs" : "")
<< (android::vold::IsFilesystemSupported("vfat") ? " vfat" : ""); << (android::vold::IsFilesystemSupported("vfat") ? " vfat" : "");
VolumeManager *vm; VolumeManager* vm;
NetlinkManager *nm; NetlinkManager* nm;
parse_args(argc, argv); parse_args(argc, argv);
@ -148,19 +147,21 @@ int main(int argc, char** argv) {
static void parse_args(int argc, char** argv) { static void parse_args(int argc, char** argv) {
static struct option opts[] = { static struct option opts[] = {
{"blkid_context", required_argument, 0, 'b' }, {"blkid_context", required_argument, 0, 'b'},
{"blkid_untrusted_context", required_argument, 0, 'B' }, {"blkid_untrusted_context", required_argument, 0, 'B'},
{"fsck_context", required_argument, 0, 'f' }, {"fsck_context", required_argument, 0, 'f'},
{"fsck_untrusted_context", required_argument, 0, 'F' }, {"fsck_untrusted_context", required_argument, 0, 'F'},
}; };
int c; int c;
while ((c = getopt_long(argc, argv, "", opts, nullptr)) != -1) { while ((c = getopt_long(argc, argv, "", opts, nullptr)) != -1) {
switch (c) { switch (c) {
// clang-format off
case 'b': android::vold::sBlkidContext = optarg; break; case 'b': android::vold::sBlkidContext = optarg; break;
case 'B': android::vold::sBlkidUntrustedContext = optarg; break; case 'B': android::vold::sBlkidUntrustedContext = optarg; break;
case 'f': android::vold::sFsckContext = optarg; break; case 'f': android::vold::sFsckContext = optarg; break;
case 'F': android::vold::sFsckUntrustedContext = optarg; break; case 'F': android::vold::sFsckUntrustedContext = optarg; break;
// clang-format on
} }
} }
@ -170,33 +171,30 @@ static void parse_args(int argc, char** argv) {
CHECK(android::vold::sFsckUntrustedContext != nullptr); CHECK(android::vold::sFsckUntrustedContext != nullptr);
} }
static void do_coldboot(DIR *d, int lvl) { static void do_coldboot(DIR* d, int lvl) {
struct dirent *de; struct dirent* de;
int dfd, fd; int dfd, fd;
dfd = dirfd(d); dfd = dirfd(d);
fd = openat(dfd, "uevent", O_WRONLY | O_CLOEXEC); fd = openat(dfd, "uevent", O_WRONLY | O_CLOEXEC);
if(fd >= 0) { if (fd >= 0) {
write(fd, "add\n", 4); write(fd, "add\n", 4);
close(fd); close(fd);
} }
while((de = readdir(d))) { while ((de = readdir(d))) {
DIR *d2; DIR* d2;
if (de->d_name[0] == '.') if (de->d_name[0] == '.') continue;
continue;
if (de->d_type != DT_DIR && lvl > 0) if (de->d_type != DT_DIR && lvl > 0) continue;
continue;
fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC); fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
if(fd < 0) if (fd < 0) continue;
continue;
d2 = fdopendir(fd); d2 = fdopendir(fd);
if(d2 == 0) if (d2 == 0)
close(fd); close(fd);
else { else {
do_coldboot(d2, lvl + 1); do_coldboot(d2, lvl + 1);
@ -205,10 +203,10 @@ static void do_coldboot(DIR *d, int lvl) {
} }
} }
static void coldboot(const char *path) { static void coldboot(const char* path) {
ATRACE_NAME("coldboot"); ATRACE_NAME("coldboot");
DIR *d = opendir(path); DIR* d = opendir(path);
if(d) { if (d) {
do_coldboot(d, 0); do_coldboot(d, 0);
closedir(d); closedir(d);
} }
@ -251,13 +249,13 @@ static int process_config(VolumeManager* vm, bool* has_adoptable, bool* has_quot
flags |= android::vold::Disk::Flags::kAdoptable; flags |= android::vold::Disk::Flags::kAdoptable;
*has_adoptable = true; *has_adoptable = true;
} }
if (fs_mgr_is_noemulatedsd(rec) if (fs_mgr_is_noemulatedsd(rec) ||
|| android::base::GetBoolProperty("vold.debug.default_primary", false)) { android::base::GetBoolProperty("vold.debug.default_primary", false)) {
flags |= android::vold::Disk::Flags::kDefaultPrimary; flags |= android::vold::Disk::Flags::kDefaultPrimary;
} }
vm->addDiskSource(std::shared_ptr<VolumeManager::DiskSource>( vm->addDiskSource(std::shared_ptr<VolumeManager::DiskSource>(
new VolumeManager::DiskSource(sysPattern, nickname, flags))); new VolumeManager::DiskSource(sysPattern, nickname, flags)));
} }
} }
return 0; return 0;

@ -15,36 +15,36 @@
*/ */
#include "Disk.h" #include "Disk.h"
#include "PublicVolume.h" #include "Ext4Crypt.h"
#include "PrivateVolume.h" #include "PrivateVolume.h"
#include "PublicVolume.h"
#include "Utils.h" #include "Utils.h"
#include "VolumeBase.h" #include "VolumeBase.h"
#include "VolumeManager.h" #include "VolumeManager.h"
#include "Ext4Crypt.h"
#include <android-base/file.h> #include <android-base/file.h>
#include <android-base/logging.h> #include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/properties.h> #include <android-base/properties.h>
#include <android-base/stringprintf.h> #include <android-base/stringprintf.h>
#include <android-base/strings.h> #include <android-base/strings.h>
#include <android-base/parseint.h>
#include <ext4_utils/ext4_crypt.h> #include <ext4_utils/ext4_crypt.h>
#include "cryptfs.h" #include "cryptfs.h"
#include <vector>
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/mount.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <sys/mount.h> #include <sys/types.h>
#include <vector>
using android::base::ReadFileToString; using android::base::ReadFileToString;
using android::base::WriteStringToFile;
using android::base::StringPrintf; using android::base::StringPrintf;
using android::base::WriteStringToFile;
namespace android { namespace android {
namespace vold { namespace vold {
@ -112,20 +112,22 @@ static bool isVirtioBlkDevice(unsigned int major) {
* "ranchu", the device's sysfs path should end with "/block/vd[d-z]", etc. * "ranchu", the device's sysfs path should end with "/block/vd[d-z]", etc.
* But just having a) and b) is enough for now. * But just having a) and b) is enough for now.
*/ */
return IsRunningInEmulator() && major >= kMajorBlockExperimentalMin return IsRunningInEmulator() && major >= kMajorBlockExperimentalMin &&
&& major <= kMajorBlockExperimentalMax; major <= kMajorBlockExperimentalMax;
} }
static bool isNvmeBlkDevice(unsigned int major, const std::string& sysPath) { static bool isNvmeBlkDevice(unsigned int major, const std::string& sysPath) {
return sysPath.find("nvme") != std::string::npos return sysPath.find("nvme") != std::string::npos && major >= kMajorBlockDynamicMin &&
&& major >= kMajorBlockDynamicMin major <= kMajorBlockDynamicMax;
&& major <= kMajorBlockDynamicMax;
} }
Disk::Disk(const std::string& eventPath, dev_t device, Disk::Disk(const std::string& eventPath, dev_t device, const std::string& nickname, int flags)
const std::string& nickname, int flags) : : mDevice(device),
mDevice(device), mSize(-1), mNickname(nickname), mFlags(flags), mCreated( mSize(-1),
false), mJustPartitioned(false) { mNickname(nickname),
mFlags(flags),
mCreated(false),
mJustPartitioned(false) {
mId = StringPrintf("disk:%u,%u", major(device), minor(device)); mId = StringPrintf("disk:%u,%u", major(device), minor(device));
mEventPath = eventPath; mEventPath = eventPath;
mSysPath = StringPrintf("/sys/%s", eventPath.c_str()); mSysPath = StringPrintf("/sys/%s", eventPath.c_str());
@ -251,73 +253,78 @@ status_t Disk::readMetadata() {
unsigned int majorId = major(mDevice); unsigned int majorId = major(mDevice);
switch (majorId) { switch (majorId) {
case kMajorBlockLoop: { case kMajorBlockLoop: {
mLabel = "Virtual";
break;
}
case kMajorBlockScsiA: case kMajorBlockScsiB: case kMajorBlockScsiC: case kMajorBlockScsiD:
case kMajorBlockScsiE: case kMajorBlockScsiF: case kMajorBlockScsiG: case kMajorBlockScsiH:
case kMajorBlockScsiI: case kMajorBlockScsiJ: case kMajorBlockScsiK: case kMajorBlockScsiL:
case kMajorBlockScsiM: case kMajorBlockScsiN: case kMajorBlockScsiO: case kMajorBlockScsiP: {
std::string path(mSysPath + "/device/vendor");
std::string tmp;
if (!ReadFileToString(path, &tmp)) {
PLOG(WARNING) << "Failed to read vendor from " << path;
return -errno;
}
tmp = android::base::Trim(tmp);
mLabel = tmp;
break;
}
case kMajorBlockMmc: {
std::string path(mSysPath + "/device/manfid");
std::string tmp;
if (!ReadFileToString(path, &tmp)) {
PLOG(WARNING) << "Failed to read manufacturer from " << path;
return -errno;
}
tmp = android::base::Trim(tmp);
int64_t manfid;
if (!android::base::ParseInt(tmp, &manfid)) {
PLOG(WARNING) << "Failed to parse manufacturer " << tmp;
return -EINVAL;
}
// Our goal here is to give the user a meaningful label, ideally
// matching whatever is silk-screened on the card. To reduce
// user confusion, this list doesn't contain white-label manfid.
switch (manfid) {
case 0x000003: mLabel = "SanDisk"; break;
case 0x00001b: mLabel = "Samsung"; break;
case 0x000028: mLabel = "Lexar"; break;
case 0x000074: mLabel = "Transcend"; break;
}
break;
}
default: {
if (isVirtioBlkDevice(majorId)) {
LOG(DEBUG) << "Recognized experimental block major ID " << majorId
<< " as virtio-blk (emulator's virtual SD card device)";
mLabel = "Virtual"; mLabel = "Virtual";
break; break;
} }
if (isNvmeBlkDevice(majorId, mSysPath)) { // clang-format off
std::string path(mSysPath + "/device/model"); case kMajorBlockScsiA: case kMajorBlockScsiB: case kMajorBlockScsiC:
case kMajorBlockScsiD: case kMajorBlockScsiE: case kMajorBlockScsiF:
case kMajorBlockScsiG: case kMajorBlockScsiH: case kMajorBlockScsiI:
case kMajorBlockScsiJ: case kMajorBlockScsiK: case kMajorBlockScsiL:
case kMajorBlockScsiM: case kMajorBlockScsiN: case kMajorBlockScsiO:
case kMajorBlockScsiP: {
// clang-format on
std::string path(mSysPath + "/device/vendor");
std::string tmp; std::string tmp;
if (!ReadFileToString(path, &tmp)) { if (!ReadFileToString(path, &tmp)) {
PLOG(WARNING) << "Failed to read vendor from " << path; PLOG(WARNING) << "Failed to read vendor from " << path;
return -errno; return -errno;
} }
tmp = android::base::Trim(tmp);
mLabel = tmp; mLabel = tmp;
break; break;
} }
LOG(WARNING) << "Unsupported block major type " << majorId; case kMajorBlockMmc: {
return -ENOTSUP; std::string path(mSysPath + "/device/manfid");
} std::string tmp;
if (!ReadFileToString(path, &tmp)) {
PLOG(WARNING) << "Failed to read manufacturer from " << path;
return -errno;
}
tmp = android::base::Trim(tmp);
int64_t manfid;
if (!android::base::ParseInt(tmp, &manfid)) {
PLOG(WARNING) << "Failed to parse manufacturer " << tmp;
return -EINVAL;
}
// Our goal here is to give the user a meaningful label, ideally
// matching whatever is silk-screened on the card. To reduce
// user confusion, this list doesn't contain white-label manfid.
switch (manfid) {
// clang-format off
case 0x000003: mLabel = "SanDisk"; break;
case 0x00001b: mLabel = "Samsung"; break;
case 0x000028: mLabel = "Lexar"; break;
case 0x000074: mLabel = "Transcend"; break;
// clang-format on
}
break;
}
default: {
if (isVirtioBlkDevice(majorId)) {
LOG(DEBUG) << "Recognized experimental block major ID " << majorId
<< " as virtio-blk (emulator's virtual SD card device)";
mLabel = "Virtual";
break;
}
if (isNvmeBlkDevice(majorId, mSysPath)) {
std::string path(mSysPath + "/device/model");
std::string tmp;
if (!ReadFileToString(path, &tmp)) {
PLOG(WARNING) << "Failed to read vendor from " << path;
return -errno;
}
mLabel = tmp;
break;
}
LOG(WARNING) << "Unsupported block major type " << majorId;
return -ENOTSUP;
}
} }
auto listener = VolumeManager::Instance()->getListener(); auto listener = VolumeManager::Instance()->getListener();
if (listener) listener->onDiskMetadataChanged(getId(), if (listener) listener->onDiskMetadataChanged(getId(), mSize, mLabel, mSysPath);
mSize, mLabel, mSysPath);
return OK; return OK;
} }
@ -563,45 +570,49 @@ int Disk::getMaxMinors() {
// Figure out maximum partition devices supported // Figure out maximum partition devices supported
unsigned int majorId = major(mDevice); unsigned int majorId = major(mDevice);
switch (majorId) { switch (majorId) {
case kMajorBlockLoop: { case kMajorBlockLoop: {
std::string tmp; std::string tmp;
if (!ReadFileToString(kSysfsLoopMaxMinors, &tmp)) { if (!ReadFileToString(kSysfsLoopMaxMinors, &tmp)) {
LOG(ERROR) << "Failed to read max minors"; LOG(ERROR) << "Failed to read max minors";
return -errno; return -errno;
} }
return std::stoi(tmp); return std::stoi(tmp);
}
case kMajorBlockScsiA: case kMajorBlockScsiB: case kMajorBlockScsiC: case kMajorBlockScsiD:
case kMajorBlockScsiE: case kMajorBlockScsiF: case kMajorBlockScsiG: case kMajorBlockScsiH:
case kMajorBlockScsiI: case kMajorBlockScsiJ: case kMajorBlockScsiK: case kMajorBlockScsiL:
case kMajorBlockScsiM: case kMajorBlockScsiN: case kMajorBlockScsiO: case kMajorBlockScsiP: {
// Per Documentation/devices.txt this is static
return 15;
}
case kMajorBlockMmc: {
// Per Documentation/devices.txt this is dynamic
std::string tmp;
if (!ReadFileToString(kSysfsMmcMaxMinors, &tmp) &&
!ReadFileToString(kSysfsMmcMaxMinorsDeprecated, &tmp)) {
LOG(ERROR) << "Failed to read max minors";
return -errno;
} }
return std::stoi(tmp); // clang-format off
} case kMajorBlockScsiA: case kMajorBlockScsiB: case kMajorBlockScsiC:
default: { case kMajorBlockScsiD: case kMajorBlockScsiE: case kMajorBlockScsiF:
if (isVirtioBlkDevice(majorId)) { case kMajorBlockScsiG: case kMajorBlockScsiH: case kMajorBlockScsiI:
// drivers/block/virtio_blk.c has "#define PART_BITS 4", so max is case kMajorBlockScsiJ: case kMajorBlockScsiK: case kMajorBlockScsiL:
// 2^4 - 1 = 15 case kMajorBlockScsiM: case kMajorBlockScsiN: case kMajorBlockScsiO:
case kMajorBlockScsiP: {
// clang-format on
// Per Documentation/devices.txt this is static
return 15; return 15;
} }
if (isNvmeBlkDevice(majorId, mSysPath)) { case kMajorBlockMmc: {
// despite kernel nvme driver supports up to 1M minors, // Per Documentation/devices.txt this is dynamic
// #define NVME_MINORS (1U << MINORBITS) std::string tmp;
// sgdisk can not support more than 127 partitions, due to if (!ReadFileToString(kSysfsMmcMaxMinors, &tmp) &&
// #define MAX_MBR_PARTS 128 !ReadFileToString(kSysfsMmcMaxMinorsDeprecated, &tmp)) {
return 127; LOG(ERROR) << "Failed to read max minors";
return -errno;
}
return std::stoi(tmp);
}
default: {
if (isVirtioBlkDevice(majorId)) {
// drivers/block/virtio_blk.c has "#define PART_BITS 4", so max is
// 2^4 - 1 = 15
return 15;
}
if (isNvmeBlkDevice(majorId, mSysPath)) {
// despite kernel nvme driver supports up to 1M minors,
// #define NVME_MINORS (1U << MINORBITS)
// sgdisk can not support more than 127 partitions, due to
// #define MAX_MBR_PARTS 128
return 127;
}
} }
}
} }
LOG(ERROR) << "Unsupported block major type " << majorId; LOG(ERROR) << "Unsupported block major type " << majorId;

@ -36,7 +36,7 @@ class VolumeBase;
* how to repartition itself. * how to repartition itself.
*/ */
class Disk { class Disk {
public: public:
Disk(const std::string& eventPath, dev_t device, const std::string& nickname, int flags); Disk(const std::string& eventPath, dev_t device, const std::string& nickname, int flags);
virtual ~Disk(); virtual ~Disk();
@ -79,7 +79,7 @@ public:
status_t partitionPrivate(); status_t partitionPrivate();
status_t partitionMixed(int8_t ratio); status_t partitionMixed(int8_t ratio);
private: private:
/* ID that uniquely references this disk */ /* ID that uniquely references this disk */
std::string mId; std::string mId;
/* Original event path */ /* Original event path */

@ -36,16 +36,16 @@ namespace vold {
* store data local to their app. * store data local to their app.
*/ */
class EmulatedVolume : public VolumeBase { class EmulatedVolume : public VolumeBase {
public: public:
explicit EmulatedVolume(const std::string& rawPath); explicit EmulatedVolume(const std::string& rawPath);
EmulatedVolume(const std::string& rawPath, dev_t device, const std::string& fsUuid); EmulatedVolume(const std::string& rawPath, dev_t device, const std::string& fsUuid);
virtual ~EmulatedVolume(); virtual ~EmulatedVolume();
protected: protected:
status_t doMount() override; status_t doMount() override;
status_t doUnmount() override; status_t doUnmount() override;
private: private:
std::string mRawPath; std::string mRawPath;
std::string mLabel; std::string mLabel;

@ -14,12 +14,12 @@
* limitations under the License. * limitations under the License.
*/ */
#include "fs/Vfat.h" #include "ObbVolume.h"
#include "Devmapper.h" #include "Devmapper.h"
#include "Loop.h" #include "Loop.h"
#include "ObbVolume.h"
#include "Utils.h" #include "Utils.h"
#include "VoldUtil.h" #include "VoldUtil.h"
#include "fs/Vfat.h"
#include <android-base/logging.h> #include <android-base/logging.h>
#include <android-base/stringprintf.h> #include <android-base/stringprintf.h>
@ -31,8 +31,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h>
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
using android::base::StringPrintf; using android::base::StringPrintf;
@ -42,15 +42,15 @@ namespace android {
namespace vold { namespace vold {
ObbVolume::ObbVolume(int id, const std::string& sourcePath, const std::string& sourceKey, ObbVolume::ObbVolume(int id, const std::string& sourcePath, const std::string& sourceKey,
gid_t ownerGid) : VolumeBase(Type::kObb) { gid_t ownerGid)
: VolumeBase(Type::kObb) {
setId(StringPrintf("obb:%d", id)); setId(StringPrintf("obb:%d", id));
mSourcePath = sourcePath; mSourcePath = sourcePath;
mSourceKey = sourceKey; mSourceKey = sourceKey;
mOwnerGid = ownerGid; mOwnerGid = ownerGid;
} }
ObbVolume::~ObbVolume() { ObbVolume::~ObbVolume() {}
}
status_t ObbVolume::doCreate() { status_t ObbVolume::doCreate() {
if (Loop::create(mSourcePath, mLoopPath)) { if (Loop::create(mSourcePath, mLoopPath)) {
@ -75,8 +75,8 @@ status_t ObbVolume::doCreate() {
} }
char tmp[PATH_MAX]; char tmp[PATH_MAX];
if (Devmapper::create(getId().c_str(), mLoopPath.c_str(), mSourceKey.c_str(), nr_sec, if (Devmapper::create(getId().c_str(), mLoopPath.c_str(), mSourceKey.c_str(), nr_sec, tmp,
tmp, PATH_MAX)) { PATH_MAX)) {
PLOG(ERROR) << getId() << " failed to create dm"; PLOG(ERROR) << getId() << " failed to create dm";
return -1; return -1;
} }
@ -108,8 +108,10 @@ status_t ObbVolume::doMount() {
PLOG(ERROR) << getId() << " failed to create mount point"; PLOG(ERROR) << getId() << " failed to create mount point";
return -1; return -1;
} }
if (android::vold::vfat::Mount(mMountPath, path, // clang-format off
true, false, true, 0, mOwnerGid, 0227, false)) { if (android::vold::vfat::Mount(mMountPath, path, true, false, true,
0, mOwnerGid, 0227, false)) {
// clang-format on
PLOG(ERROR) << getId() << " failed to mount"; PLOG(ERROR) << getId() << " failed to mount";
return -1; return -1;
} }

@ -28,18 +28,17 @@ namespace vold {
* OBB container. * OBB container.
*/ */
class ObbVolume : public VolumeBase { class ObbVolume : public VolumeBase {
public: public:
ObbVolume(int id, const std::string& sourcePath, const std::string& sourceKey, ObbVolume(int id, const std::string& sourcePath, const std::string& sourceKey, gid_t ownerGid);
gid_t ownerGid);
virtual ~ObbVolume(); virtual ~ObbVolume();
protected: protected:
status_t doCreate() override; status_t doCreate() override;
status_t doDestroy() override; status_t doDestroy() override;
status_t doMount() override; status_t doMount() override;
status_t doUnmount() override; status_t doUnmount() override;
private: private:
std::string mSourcePath; std::string mSourcePath;
std::string mSourceKey; std::string mSourceKey;
gid_t mOwnerGid; gid_t mOwnerGid;

@ -14,27 +14,27 @@
* limitations under the License. * limitations under the License.
*/ */
#include "fs/Ext4.h"
#include "fs/F2fs.h"
#include "PrivateVolume.h" #include "PrivateVolume.h"
#include "EmulatedVolume.h" #include "EmulatedVolume.h"
#include "Utils.h" #include "Utils.h"
#include "VolumeManager.h" #include "VolumeManager.h"
#include "cryptfs.h" #include "cryptfs.h"
#include "fs/Ext4.h"
#include "fs/F2fs.h"
#include <android-base/stringprintf.h>
#include <android-base/logging.h> #include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <cutils/fs.h> #include <cutils/fs.h>
#include <private/android_filesystem_config.h> #include <private/android_filesystem_config.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/param.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h>
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/param.h>
using android::base::StringPrintf; using android::base::StringPrintf;
@ -43,14 +43,13 @@ namespace vold {
static const unsigned int kMajorBlockMmc = 179; static const unsigned int kMajorBlockMmc = 179;
PrivateVolume::PrivateVolume(dev_t device, const std::string& keyRaw) : PrivateVolume::PrivateVolume(dev_t device, const std::string& keyRaw)
VolumeBase(Type::kPrivate), mRawDevice(device), mKeyRaw(keyRaw) { : VolumeBase(Type::kPrivate), mRawDevice(device), mKeyRaw(keyRaw) {
setId(StringPrintf("private:%u,%u", major(device), minor(device))); setId(StringPrintf("private:%u,%u", major(device), minor(device)));
mRawDevPath = StringPrintf("/dev/block/vold/%s", getId().c_str()); mRawDevPath = StringPrintf("/dev/block/vold/%s", getId().c_str());
} }
PrivateVolume::~PrivateVolume() { PrivateVolume::~PrivateVolume() {}
}
status_t PrivateVolume::readMetadata() { status_t PrivateVolume::readMetadata() {
status_t res = ReadMetadata(mDmDevPath, &mFsType, &mFsUuid, &mFsLabel); status_t res = ReadMetadata(mDmDevPath, &mFsType, &mFsUuid, &mFsLabel);
@ -66,9 +65,9 @@ status_t PrivateVolume::doCreate() {
return -EIO; return -EIO;
} }
if (mKeyRaw.size() != cryptfs_get_keysize()) { if (mKeyRaw.size() != cryptfs_get_keysize()) {
PLOG(ERROR) << getId() << " Raw keysize " << mKeyRaw.size() << PLOG(ERROR) << getId() << " Raw keysize " << mKeyRaw.size()
" does not match crypt keysize " << cryptfs_get_keysize(); << " does not match crypt keysize " << cryptfs_get_keysize();
return -EIO; return -EIO;
} }
// Recover from stale vold by tearing down any old mappings // Recover from stale vold by tearing down any old mappings
@ -76,10 +75,9 @@ status_t PrivateVolume::doCreate() {
// TODO: figure out better SELinux labels for private volumes // TODO: figure out better SELinux labels for private volumes
unsigned char* key = (unsigned char*) mKeyRaw.data(); unsigned char* key = (unsigned char*)mKeyRaw.data();
char crypto_blkdev[MAXPATHLEN]; char crypto_blkdev[MAXPATHLEN];
int res = cryptfs_setup_ext_volume(getId().c_str(), mRawDevPath.c_str(), int res = cryptfs_setup_ext_volume(getId().c_str(), mRawDevPath.c_str(), key, crypto_blkdev);
key, crypto_blkdev);
mDmDevPath = crypto_blkdev; mDmDevPath = crypto_blkdev;
if (res != 0) { if (res != 0) {
PLOG(ERROR) << getId() << " failed to setup cryptfs"; PLOG(ERROR) << getId() << " failed to setup cryptfs";
@ -147,12 +145,12 @@ status_t PrivateVolume::doMount() {
// Verify that common directories are ready to roll // Verify that common directories are ready to roll
if (PrepareDir(mPath + "/app", 0771, AID_SYSTEM, AID_SYSTEM) || if (PrepareDir(mPath + "/app", 0771, AID_SYSTEM, AID_SYSTEM) ||
PrepareDir(mPath + "/user", 0711, AID_SYSTEM, AID_SYSTEM) || PrepareDir(mPath + "/user", 0711, AID_SYSTEM, AID_SYSTEM) ||
PrepareDir(mPath + "/user_de", 0711, AID_SYSTEM, AID_SYSTEM) || PrepareDir(mPath + "/user_de", 0711, AID_SYSTEM, AID_SYSTEM) ||
PrepareDir(mPath + "/media", 0770, AID_MEDIA_RW, AID_MEDIA_RW) || PrepareDir(mPath + "/media", 0770, AID_MEDIA_RW, AID_MEDIA_RW) ||
PrepareDir(mPath + "/media/0", 0770, AID_MEDIA_RW, AID_MEDIA_RW) || PrepareDir(mPath + "/media/0", 0770, AID_MEDIA_RW, AID_MEDIA_RW) ||
PrepareDir(mPath + "/local", 0751, AID_ROOT, AID_ROOT) || PrepareDir(mPath + "/local", 0751, AID_ROOT, AID_ROOT) ||
PrepareDir(mPath + "/local/tmp", 0771, AID_SHELL, AID_SHELL)) { PrepareDir(mPath + "/local/tmp", 0771, AID_SHELL, AID_SHELL)) {
PLOG(ERROR) << getId() << " failed to prepare"; PLOG(ERROR) << getId() << " failed to prepare";
return -EIO; return -EIO;
} }
@ -160,8 +158,7 @@ status_t PrivateVolume::doMount() {
// Create a new emulated volume stacked above us, it will automatically // Create a new emulated volume stacked above us, it will automatically
// be destroyed during unmount // be destroyed during unmount
std::string mediaPath(mPath + "/media"); std::string mediaPath(mPath + "/media");
auto vol = std::shared_ptr<VolumeBase>( auto vol = std::shared_ptr<VolumeBase>(new EmulatedVolume(mediaPath, mRawDevice, mFsUuid));
new EmulatedVolume(mediaPath, mRawDevice, mFsUuid));
addVolume(vol); addVolume(vol);
vol->create(); vol->create();

@ -36,14 +36,14 @@ namespace vold {
* keys are tightly tied to this device. * keys are tightly tied to this device.
*/ */
class PrivateVolume : public VolumeBase { class PrivateVolume : public VolumeBase {
public: public:
PrivateVolume(dev_t device, const std::string& keyRaw); PrivateVolume(dev_t device, const std::string& keyRaw);
virtual ~PrivateVolume(); virtual ~PrivateVolume();
const std::string& getFsType() { return mFsType; }; const std::string& getFsType() { return mFsType; };
const std::string& getRawDevPath() { return mRawDevPath; }; const std::string& getRawDevPath() { return mRawDevPath; };
const std::string& getRawDmDevPath() { return mDmDevPath; }; const std::string& getRawDmDevPath() { return mDmDevPath; };
protected: protected:
status_t doCreate() override; status_t doCreate() override;
status_t doDestroy() override; status_t doDestroy() override;
status_t doMount() override; status_t doMount() override;
@ -52,7 +52,7 @@ protected:
status_t readMetadata(); status_t readMetadata();
private: private:
/* Kernel device of raw, encrypted partition */ /* Kernel device of raw, encrypted partition */
dev_t mRawDevice; dev_t mRawDevice;
/* Path to raw, encrypted block device */ /* Path to raw, encrypted block device */

@ -38,11 +38,11 @@ namespace vold {
* away the Android directory for secondary users. * away the Android directory for secondary users.
*/ */
class PublicVolume : public VolumeBase { class PublicVolume : public VolumeBase {
public: public:
explicit PublicVolume(dev_t device); explicit PublicVolume(dev_t device);
virtual ~PublicVolume(); virtual ~PublicVolume();
protected: protected:
status_t doCreate() override; status_t doCreate() override;
status_t doDestroy() override; status_t doDestroy() override;
status_t doMount() override; status_t doMount() override;
@ -52,7 +52,7 @@ protected:
status_t readMetadata(); status_t readMetadata();
status_t initAsecStage(); status_t initAsecStage();
private: private:
/* Kernel device representing partition */ /* Kernel device representing partition */
dev_t mDevice; dev_t mDevice;
/* Block device path */ /* Block device path */

@ -18,15 +18,15 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <linux/fs.h>
#include <linux/fiemap.h> #include <linux/fiemap.h>
#include <linux/fs.h>
#include <mntent.h> #include <mntent.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <android-base/logging.h> #include <android-base/logging.h>
#include <android-base/unique_fd.h> #include <android-base/unique_fd.h>
@ -42,23 +42,23 @@ struct Options {
constexpr uint32_t max_extents = 32; constexpr uint32_t max_extents = 32;
bool read_command_line(int argc, const char * const argv[], Options &options); bool read_command_line(int argc, const char* const argv[], Options& options);
void usage(const char *progname); void usage(const char* progname);
bool secdiscard_path(const std::string &path); bool secdiscard_path(const std::string& path);
bool check_fiemap(const struct fiemap &fiemap, const std::string &path); bool check_fiemap(const struct fiemap& fiemap, const std::string& path);
bool overwrite_with_zeros(int fd, off64_t start, off64_t length); bool overwrite_with_zeros(int fd, off64_t start, off64_t length);
} } // namespace
int main(int argc, const char * const argv[]) { int main(int argc, const char* const argv[]) {
android::base::InitLogging(const_cast<char **>(argv)); android::base::InitLogging(const_cast<char**>(argv));
Options options; Options options;
if (!read_command_line(argc, argv, options)) { if (!read_command_line(argc, argv, options)) {
usage(argv[0]); usage(argv[0]);
return -1; return -1;
} }
for (auto const &target: options.targets) { for (auto const& target : options.targets) {
// F2FS-specific ioctl // F2FS-specific ioctl
// It requires the below kernel commit merged in v4.16-rc1. // It requires the below kernel commit merged in v4.16-rc1.
// 1ad71a27124c ("f2fs: add an ioctl to disable GC for specific file") // 1ad71a27124c ("f2fs: add an ioctl to disable GC for specific file")
@ -70,13 +70,12 @@ int main(int argc, const char * const argv[]) {
// ce767d9a55bc ("f2fs: updates on v4.16-rc1") // ce767d9a55bc ("f2fs: updates on v4.16-rc1")
#ifndef F2FS_IOC_SET_PIN_FILE #ifndef F2FS_IOC_SET_PIN_FILE
#ifndef F2FS_IOCTL_MAGIC #ifndef F2FS_IOCTL_MAGIC
#define F2FS_IOCTL_MAGIC 0xf5 #define F2FS_IOCTL_MAGIC 0xf5
#endif #endif
#define F2FS_IOC_SET_PIN_FILE _IOW(F2FS_IOCTL_MAGIC, 13, __u32) #define F2FS_IOC_SET_PIN_FILE _IOW(F2FS_IOCTL_MAGIC, 13, __u32)
#define F2FS_IOC_GET_PIN_FILE _IOR(F2FS_IOCTL_MAGIC, 14, __u32) #define F2FS_IOC_GET_PIN_FILE _IOR(F2FS_IOCTL_MAGIC, 14, __u32)
#endif #endif
android::base::unique_fd fd(TEMP_FAILURE_RETRY(open( android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(target.c_str(), O_WRONLY, 0)));
target.c_str(), O_WRONLY, 0)));
if (fd == -1) { if (fd == -1) {
LOG(ERROR) << "Secure discard open failed for: " << target; LOG(ERROR) << "Secure discard open failed for: " << target;
return 0; return 0;
@ -102,29 +101,29 @@ int main(int argc, const char * const argv[]) {
namespace { namespace {
bool read_command_line(int argc, const char * const argv[], Options &options) { bool read_command_line(int argc, const char* const argv[], Options& options) {
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
if (!strcmp("--no-unlink", argv[i])) { if (!strcmp("--no-unlink", argv[i])) {
options.unlink = false; options.unlink = false;
} else if (!strcmp("--", argv[i])) { } else if (!strcmp("--", argv[i])) {
for (int j = i+1; j < argc; j++) { for (int j = i + 1; j < argc; j++) {
if (argv[j][0] != '/') return false; // Must be absolute path if (argv[j][0] != '/') return false; // Must be absolute path
options.targets.emplace_back(argv[j]); options.targets.emplace_back(argv[j]);
} }
return options.targets.size() > 0; return options.targets.size() > 0;
} else { } else {
return false; // Unknown option return false; // Unknown option
} }
} }
return false; // "--" not found return false; // "--" not found
} }
void usage(const char *progname) { void usage(const char* progname) {
fprintf(stderr, "Usage: %s [--no-unlink] -- <absolute path> ...\n", progname); fprintf(stderr, "Usage: %s [--no-unlink] -- <absolute path> ...\n", progname);
} }
// BLKSECDISCARD all content in "path", if it's small enough. // BLKSECDISCARD all content in "path", if it's small enough.
bool secdiscard_path(const std::string &path) { bool secdiscard_path(const std::string& path) {
auto fiemap = android::vold::PathFiemap(path, max_extents); auto fiemap = android::vold::PathFiemap(path, max_extents);
if (!fiemap || !check_fiemap(*fiemap, path)) { if (!fiemap || !check_fiemap(*fiemap, path)) {
return false; return false;
@ -133,8 +132,8 @@ bool secdiscard_path(const std::string &path) {
if (block_device.empty()) { if (block_device.empty()) {
return false; return false;
} }
android::base::unique_fd fs_fd(TEMP_FAILURE_RETRY(open( android::base::unique_fd fs_fd(
block_device.c_str(), O_RDWR | O_LARGEFILE | O_CLOEXEC, 0))); TEMP_FAILURE_RETRY(open(block_device.c_str(), O_RDWR | O_LARGEFILE | O_CLOEXEC, 0)));
if (fs_fd == -1) { if (fs_fd == -1) {
PLOG(ERROR) << "Failed to open device " << block_device; PLOG(ERROR) << "Failed to open device " << block_device;
return false; return false;
@ -153,10 +152,10 @@ bool secdiscard_path(const std::string &path) {
} }
// Ensure that the FIEMAP covers the file and is OK to discard // Ensure that the FIEMAP covers the file and is OK to discard
bool check_fiemap(const struct fiemap &fiemap, const std::string &path) { bool check_fiemap(const struct fiemap& fiemap, const std::string& path) {
auto mapped = fiemap.fm_mapped_extents; auto mapped = fiemap.fm_mapped_extents;
if (!(fiemap.fm_extents[mapped - 1].fe_flags & FIEMAP_EXTENT_LAST)) { if (!(fiemap.fm_extents[mapped - 1].fe_flags & FIEMAP_EXTENT_LAST)) {
LOG(ERROR) << "Extent " << mapped -1 << " was not the last in " << path; LOG(ERROR) << "Extent " << mapped - 1 << " was not the last in " << path;
return false; return false;
} }
for (uint32_t i = 0; i < mapped; i++) { for (uint32_t i = 0; i < mapped; i++) {
@ -188,4 +187,4 @@ bool overwrite_with_zeros(int fd, off64_t start, off64_t length) {
return true; return true;
} }
} } // namespace

@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#include <Utils.h>
#include "secontext.h" #include "secontext.h"
#include <Utils.h>
security_context_t secontextFsck() security_context_t secontextFsck() {
{
return android::vold::sFsckContext; return android::vold::sFsckContext;
} }

@ -19,6 +19,6 @@
#include <selinux/android.h> #include <selinux/android.h>
extern struct selabel_handle *sehandle; extern struct selabel_handle* sehandle;
#endif #endif

@ -18,13 +18,13 @@
#define LOG_TAG "scrypt_test" #define LOG_TAG "scrypt_test"
#include <log/log.h> #include <log/log.h>
#include <gtest/gtest.h>
#include <hardware/keymaster0.h> #include <hardware/keymaster0.h>
#include <hardware/keymaster1.h> #include <hardware/keymaster1.h>
#include <cstring> #include <cstring>
#include <gtest/gtest.h>
#include "../cryptfs.h"
#include "../Keymaster.h" #include "../Keymaster.h"
#include "../cryptfs.h"
#ifdef CONFIG_HW_DISK_ENCRYPTION #ifdef CONFIG_HW_DISK_ENCRYPTION
#include "cryptfs_hw.h" #include "cryptfs_hw.h"
@ -50,9 +50,8 @@
#define RSA_EXPONENT 0x10001 #define RSA_EXPONENT 0x10001
#define KEYMASTER_CRYPTFS_RATE_LIMIT 1 // Maximum one try per second #define KEYMASTER_CRYPTFS_RATE_LIMIT 1 // Maximum one try per second
static int keymaster_init(keymaster0_device_t **keymaster0_dev, static int keymaster_init(keymaster0_device_t** keymaster0_dev,
keymaster1_device_t **keymaster1_dev) keymaster1_device_t** keymaster1_dev) {
{
int rc; int rc;
const hw_module_t* mod; const hw_module_t* mod;
@ -76,8 +75,8 @@ static int keymaster_init(keymaster0_device_t **keymaster0_dev,
} }
if (rc) { if (rc) {
ALOGE("could not open keymaster device in %s (%s)", ALOGE("could not open keymaster device in %s (%s)", KEYSTORE_HARDWARE_MODULE_ID,
KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc)); strerror(-rc));
goto err; goto err;
} }
@ -90,10 +89,9 @@ err:
} }
/* Should we use keymaster? */ /* Should we use keymaster? */
static int keymaster_check_compatibility_old() static int keymaster_check_compatibility_old() {
{ keymaster0_device_t* keymaster0_dev = 0;
keymaster0_device_t *keymaster0_dev = 0; keymaster1_device_t* keymaster1_dev = 0;
keymaster1_device_t *keymaster1_dev = 0;
int rc = 0; int rc = 0;
if (keymaster_init(&keymaster0_dev, &keymaster1_dev)) { if (keymaster_init(&keymaster0_dev, &keymaster1_dev)) {
@ -114,8 +112,7 @@ static int keymaster_check_compatibility_old()
// TODO(swillden): Check to see if there's any reason to require v0.3. I think v0.1 and v0.2 // TODO(swillden): Check to see if there's any reason to require v0.3. I think v0.1 and v0.2
// should work. // should work.
if (keymaster0_dev->common.module->module_api_version if (keymaster0_dev->common.module->module_api_version < KEYMASTER_MODULE_API_VERSION_0_3) {
< KEYMASTER_MODULE_API_VERSION_0_3) {
rc = 0; rc = 0;
goto out; goto out;
} }
@ -136,11 +133,10 @@ out:
} }
/* Create a new keymaster key and store it in this footer */ /* Create a new keymaster key and store it in this footer */
static int keymaster_create_key_old(struct crypt_mnt_ftr *ftr) static int keymaster_create_key_old(struct crypt_mnt_ftr* ftr) {
{
uint8_t* key = 0; uint8_t* key = 0;
keymaster0_device_t *keymaster0_dev = 0; keymaster0_device_t* keymaster0_dev = 0;
keymaster1_device_t *keymaster1_dev = 0; keymaster1_device_t* keymaster1_dev = 0;
if (ftr->keymaster_blob_size) { if (ftr->keymaster_blob_size) {
SLOGI("Already have key"); SLOGI("Already have key");
@ -177,11 +173,10 @@ static int keymaster_create_key_old(struct crypt_mnt_ftr *ftr)
/* Rate-limit key usage attempts, to rate-limit brute force */ /* Rate-limit key usage attempts, to rate-limit brute force */
keymaster_param_int(KM_TAG_MIN_SECONDS_BETWEEN_OPS, KEYMASTER_CRYPTFS_RATE_LIMIT), keymaster_param_int(KM_TAG_MIN_SECONDS_BETWEEN_OPS, KEYMASTER_CRYPTFS_RATE_LIMIT),
}; };
keymaster_key_param_set_t param_set = { params, sizeof(params)/sizeof(*params) }; keymaster_key_param_set_t param_set = {params, sizeof(params) / sizeof(*params)};
keymaster_key_blob_t key_blob; keymaster_key_blob_t key_blob;
keymaster_error_t error = keymaster1_dev->generate_key(keymaster1_dev, &param_set, keymaster_error_t error = keymaster1_dev->generate_key(
&key_blob, keymaster1_dev, &param_set, &key_blob, NULL /* characteristics */);
NULL /* characteristics */);
if (error != KM_ERROR_OK) { if (error != KM_ERROR_OK) {
SLOGE("Failed to generate keymaster1 key, error %d", error); SLOGE("Failed to generate keymaster1 key, error %d", error);
rc = -1; rc = -1;
@ -190,15 +185,13 @@ static int keymaster_create_key_old(struct crypt_mnt_ftr *ftr)
key = (uint8_t*)key_blob.key_material; key = (uint8_t*)key_blob.key_material;
key_size = key_blob.key_material_size; key_size = key_blob.key_material_size;
} } else if (keymaster0_dev) {
else if (keymaster0_dev) {
keymaster_rsa_keygen_params_t params; keymaster_rsa_keygen_params_t params;
memset(&params, '\0', sizeof(params)); memset(&params, '\0', sizeof(params));
params.public_exponent = RSA_EXPONENT; params.public_exponent = RSA_EXPONENT;
params.modulus_size = RSA_KEY_SIZE; params.modulus_size = RSA_KEY_SIZE;
if (keymaster0_dev->generate_keypair(keymaster0_dev, TYPE_RSA, &params, if (keymaster0_dev->generate_keypair(keymaster0_dev, TYPE_RSA, &params, &key, &key_size)) {
&key, &key_size)) {
SLOGE("Failed to generate keypair"); SLOGE("Failed to generate keypair");
rc = -1; rc = -1;
goto out; goto out;
@ -219,24 +212,19 @@ static int keymaster_create_key_old(struct crypt_mnt_ftr *ftr)
ftr->keymaster_blob_size = key_size; ftr->keymaster_blob_size = key_size;
out: out:
if (keymaster0_dev) if (keymaster0_dev) keymaster0_close(keymaster0_dev);
keymaster0_close(keymaster0_dev); if (keymaster1_dev) keymaster1_close(keymaster1_dev);
if (keymaster1_dev)
keymaster1_close(keymaster1_dev);
free(key); free(key);
return rc; return rc;
} }
/* This signs the given object using the keymaster key. */ /* This signs the given object using the keymaster key. */
static int keymaster_sign_object_old(struct crypt_mnt_ftr *ftr, static int keymaster_sign_object_old(struct crypt_mnt_ftr* ftr, const unsigned char* object,
const unsigned char *object, const size_t object_size, unsigned char** signature,
const size_t object_size, size_t* signature_size) {
unsigned char **signature,
size_t *signature_size)
{
int rc = 0; int rc = 0;
keymaster0_device_t *keymaster0_dev = 0; keymaster0_device_t* keymaster0_dev = 0;
keymaster1_device_t *keymaster1_dev = 0; keymaster1_device_t* keymaster1_dev = 0;
unsigned char to_sign[RSA_KEY_SIZE_BYTES]; unsigned char to_sign[RSA_KEY_SIZE_BYTES];
size_t to_sign_size = sizeof(to_sign); size_t to_sign_size = sizeof(to_sign);
@ -284,32 +272,25 @@ static int keymaster_sign_object_old(struct crypt_mnt_ftr *ftr,
params.digest_type = DIGEST_NONE; params.digest_type = DIGEST_NONE;
params.padding_type = PADDING_NONE; params.padding_type = PADDING_NONE;
rc = keymaster0_dev->sign_data(keymaster0_dev, rc = keymaster0_dev->sign_data(keymaster0_dev, &params, ftr->keymaster_blob,
&params, ftr->keymaster_blob_size, to_sign, to_sign_size, signature,
ftr->keymaster_blob, signature_size);
ftr->keymaster_blob_size,
to_sign,
to_sign_size,
signature,
signature_size);
goto out; goto out;
} else if (keymaster1_dev) { } else if (keymaster1_dev) {
keymaster_key_blob_t key = { ftr->keymaster_blob, ftr->keymaster_blob_size }; keymaster_key_blob_t key = {ftr->keymaster_blob, ftr->keymaster_blob_size};
keymaster_key_param_t params[] = { keymaster_key_param_t params[] = {
keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE), keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE),
keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE), keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE),
}; };
keymaster_key_param_set_t param_set = { params, sizeof(params)/sizeof(*params) }; keymaster_key_param_set_t param_set = {params, sizeof(params) / sizeof(*params)};
keymaster_operation_handle_t op_handle; keymaster_operation_handle_t op_handle;
keymaster_error_t error = keymaster1_dev->begin(keymaster1_dev, KM_PURPOSE_SIGN, &key, keymaster_error_t error = keymaster1_dev->begin(
&param_set, NULL /* out_params */, keymaster1_dev, KM_PURPOSE_SIGN, &key, &param_set, NULL /* out_params */, &op_handle);
&op_handle);
if (error == KM_ERROR_KEY_RATE_LIMIT_EXCEEDED) { if (error == KM_ERROR_KEY_RATE_LIMIT_EXCEEDED) {
// Key usage has been rate-limited. Wait a bit and try again. // Key usage has been rate-limited. Wait a bit and try again.
sleep(KEYMASTER_CRYPTFS_RATE_LIMIT); sleep(KEYMASTER_CRYPTFS_RATE_LIMIT);
error = keymaster1_dev->begin(keymaster1_dev, KM_PURPOSE_SIGN, &key, error = keymaster1_dev->begin(keymaster1_dev, KM_PURPOSE_SIGN, &key, &param_set,
&param_set, NULL /* out_params */, NULL /* out_params */, &op_handle);
&op_handle);
} }
if (error != KM_ERROR_OK) { if (error != KM_ERROR_OK) {
SLOGE("Error starting keymaster signature transaction: %d", error); SLOGE("Error starting keymaster signature transaction: %d", error);
@ -317,11 +298,10 @@ static int keymaster_sign_object_old(struct crypt_mnt_ftr *ftr,
goto out; goto out;
} }
keymaster_blob_t input = { to_sign, to_sign_size }; keymaster_blob_t input = {to_sign, to_sign_size};
size_t input_consumed; size_t input_consumed;
error = keymaster1_dev->update(keymaster1_dev, op_handle, NULL /* in_params */, error = keymaster1_dev->update(keymaster1_dev, op_handle, NULL /* in_params */, &input,
&input, &input_consumed, NULL /* out_params */, &input_consumed, NULL /* out_params */, NULL /* output */);
NULL /* output */);
if (error != KM_ERROR_OK) { if (error != KM_ERROR_OK) {
SLOGE("Error sending data to keymaster signature transaction: %d", error); SLOGE("Error sending data to keymaster signature transaction: %d", error);
rc = -1; rc = -1;
@ -337,8 +317,7 @@ static int keymaster_sign_object_old(struct crypt_mnt_ftr *ftr,
keymaster_blob_t tmp_sig; keymaster_blob_t tmp_sig;
error = keymaster1_dev->finish(keymaster1_dev, op_handle, NULL /* in_params */, error = keymaster1_dev->finish(keymaster1_dev, op_handle, NULL /* in_params */,
NULL /* verify signature */, NULL /* out_params */, NULL /* verify signature */, NULL /* out_params */, &tmp_sig);
&tmp_sig);
if (error != KM_ERROR_OK) { if (error != KM_ERROR_OK) {
SLOGE("Error finishing keymaster signature transaction: %d", error); SLOGE("Error finishing keymaster signature transaction: %d", error);
rc = -1; rc = -1;
@ -353,19 +332,15 @@ static int keymaster_sign_object_old(struct crypt_mnt_ftr *ftr,
goto out; goto out;
} }
out: out:
if (keymaster1_dev) if (keymaster1_dev) keymaster1_close(keymaster1_dev);
keymaster1_close(keymaster1_dev); if (keymaster0_dev) keymaster0_close(keymaster0_dev);
if (keymaster0_dev)
keymaster0_close(keymaster0_dev);
return rc; return rc;
} }
/* Should we use keymaster? */ /* Should we use keymaster? */
static int keymaster_check_compatibility_new() static int keymaster_check_compatibility_new() {
{
return keymaster_compatibility_cryptfs_scrypt(); return keymaster_compatibility_cryptfs_scrypt();
} }
@ -394,12 +369,9 @@ static int keymaster_create_key_new(struct crypt_mnt_ftr *ftr)
#endif #endif
/* This signs the given object using the keymaster key. */ /* This signs the given object using the keymaster key. */
static int keymaster_sign_object_new(struct crypt_mnt_ftr *ftr, static int keymaster_sign_object_new(struct crypt_mnt_ftr* ftr, const unsigned char* object,
const unsigned char *object, const size_t object_size, unsigned char** signature,
const size_t object_size, size_t* signature_size) {
unsigned char **signature,
size_t *signature_size)
{
unsigned char to_sign[RSA_KEY_SIZE_BYTES]; unsigned char to_sign[RSA_KEY_SIZE_BYTES];
size_t to_sign_size = sizeof(to_sign); size_t to_sign_size = sizeof(to_sign);
memset(to_sign, 0, RSA_KEY_SIZE_BYTES); memset(to_sign, 0, RSA_KEY_SIZE_BYTES);
@ -443,12 +415,10 @@ static int keymaster_sign_object_new(struct crypt_mnt_ftr *ftr,
namespace android { namespace android {
class CryptFsTest : public testing::Test { class CryptFsTest : public testing::Test {
protected: protected:
virtual void SetUp() { virtual void SetUp() {}
}
virtual void TearDown() { virtual void TearDown() {}
}
}; };
TEST_F(CryptFsTest, ScryptHidlizationEquivalenceTest) { TEST_F(CryptFsTest, ScryptHidlizationEquivalenceTest) {
@ -458,8 +428,8 @@ TEST_F(CryptFsTest, ScryptHidlizationEquivalenceTest) {
ASSERT_EQ(0, keymaster_create_key_old(&ftr)); ASSERT_EQ(0, keymaster_create_key_old(&ftr));
uint8_t *sig1 = nullptr; uint8_t* sig1 = nullptr;
uint8_t *sig2 = nullptr; uint8_t* sig2 = nullptr;
size_t sig_size1 = 123456789; size_t sig_size1 = 123456789;
size_t sig_size2 = 123456789; size_t sig_size2 = 123456789;
uint8_t object[] = "the object"; uint8_t object[] = "the object";
@ -477,4 +447,4 @@ TEST_F(CryptFsTest, ScryptHidlizationEquivalenceTest) {
free(sig2); free(sig2);
} }
} } // namespace android

@ -21,8 +21,7 @@
namespace android { namespace android {
namespace vold { namespace vold {
class UtilsTest : public testing::Test { class UtilsTest : public testing::Test {};
};
TEST_F(UtilsTest, FindValueTest) { TEST_F(UtilsTest, FindValueTest) {
std::string tmp; std::string tmp;
@ -40,5 +39,5 @@ TEST_F(UtilsTest, FindValueTest) {
ASSERT_EQ("BAZ", tmp); ASSERT_EQ("BAZ", tmp);
} }
} } // namespace vold
} } // namespace android

@ -21,12 +21,10 @@
namespace android { namespace android {
class CryptfsTest : public testing::Test { class CryptfsTest : public testing::Test {
protected: protected:
virtual void SetUp() { virtual void SetUp() {}
}
virtual void TearDown() { virtual void TearDown() {}
}
}; };
TEST_F(CryptfsTest, MatchMultiEntryTest) { TEST_F(CryptfsTest, MatchMultiEntryTest) {
@ -51,4 +49,4 @@ TEST_F(CryptfsTest, MatchMultiEntryTest) {
ASSERT_EQ(0, match_multi_entry("foo_2", "bar", 0)); ASSERT_EQ(0, match_multi_entry("foo_2", "bar", 0));
} }
} } // namespace android

@ -14,15 +14,14 @@
* limitations under the License. * limitations under the License.
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h>
#include <poll.h> #include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/time.h> #include <sys/time.h>
@ -38,7 +37,7 @@
#include <private/android_filesystem_config.h> #include <private/android_filesystem_config.h>
static void usage(char *progname); static void usage(char* progname);
static android::sp<android::IBinder> getServiceAggressive() { static android::sp<android::IBinder> getServiceAggressive() {
android::sp<android::IBinder> res; android::sp<android::IBinder> res;
@ -50,7 +49,7 @@ static android::sp<android::IBinder> getServiceAggressive() {
LOG(VERBOSE) << "Waited " << (i * 10) << "ms for vold"; LOG(VERBOSE) << "Waited " << (i * 10) << "ms for vold";
break; break;
} }
usleep(10000); // 10ms usleep(10000); // 10ms
} }
return res; return res;
} }
@ -112,6 +111,6 @@ int main(int argc, char** argv) {
return 0; return 0;
} }
static void usage(char *progname) { static void usage(char* progname) {
LOG(INFO) << "Usage: " << progname << " [--wait] <system> <subcommand> [args...]"; LOG(INFO) << "Usage: " << progname << " [--wait] <system> <subcommand> [args...]";
} }

Loading…
Cancel
Save