summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2015-04-08 21:07:21 -0700
committerJeff Sharkey <jsharkey@android.com>2015-04-11 08:48:13 -0700
commitce6a913aeac7db94a41362c63bab74092767bb3e (patch)
tree43d1bd0f9c02fa38370c84ce57573062f15e0671
parent389672737673f9c695ac70464a0f8656908d20fd (diff)
downloadandroid_system_vold-ce6a913aeac7db94a41362c63bab74092767bb3e.tar.gz
android_system_vold-ce6a913aeac7db94a41362c63bab74092767bb3e.tar.bz2
android_system_vold-ce6a913aeac7db94a41362c63bab74092767bb3e.zip
Exclusive exec() path, format after partition.
Sadly setexeccon() is process global, so we need to carefully ensure that all exec() are mutually exclusive to avoid transitioning into unwanted domains. Also, because we have several threads floating around, we need to guard all our FDs with O_CLOEXEC. Format all newly created volumes immediately after partitioning, but silence all events emitted from those volumes to prevent the framework from getting all excited. Unify all notify events under a single codepath to make them easy to silence. Sent SIGINT before escalating to SIGTERM when unmounting. Bug: 19993667 Change-Id: Idc6c806afc7919a004a93e2240b42884f6b52d6b
-rw-r--r--Devmapper.cpp8
-rw-r--r--Disk.cpp117
-rw-r--r--Disk.h5
-rw-r--r--Ext4.cpp106
-rw-r--r--Fat.cpp100
-rw-r--r--Loop.cpp14
-rw-r--r--PrivateVolume.cpp14
-rw-r--r--Process.cpp2
-rw-r--r--PublicVolume.cpp14
-rw-r--r--Utils.cpp130
-rw-r--r--Utils.h10
-rw-r--r--VolumeBase.cpp41
-rw-r--r--VolumeBase.h6
-rw-r--r--VolumeManager.cpp16
-rw-r--r--cryptfs.c38
15 files changed, 310 insertions, 311 deletions
diff --git a/Devmapper.cpp b/Devmapper.cpp
index 703902f..703eade 100644
--- a/Devmapper.cpp
+++ b/Devmapper.cpp
@@ -55,7 +55,7 @@ int Devmapper::dumpState(SocketClient *c) {
}
int fd;
- if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
+ if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
SLOGE("Error opening devmapper (%s)", strerror(errno));
free(buffer);
free(buffer2);
@@ -138,7 +138,7 @@ int Devmapper::lookupActive(const char *name, char *ubuffer, size_t len) {
}
int fd;
- if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
+ if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
SLOGE("Error opening devmapper (%s)", strerror(errno));
free(buffer);
return -1;
@@ -172,7 +172,7 @@ int Devmapper::create(const char *name, const char *loopFile, const char *key,
}
int fd;
- if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
+ if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
SLOGE("Error opening devmapper (%s)", strerror(errno));
free(buffer);
return -1;
@@ -269,7 +269,7 @@ int Devmapper::destroy(const char *name) {
}
int fd;
- if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
+ if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
SLOGE("Error opening devmapper (%s)", strerror(errno));
free(buffer);
return -1;
diff --git a/Disk.cpp b/Disk.cpp
index 3bf9333..794e1dd 100644
--- a/Disk.cpp
+++ b/Disk.cpp
@@ -53,7 +53,7 @@ static const unsigned int kMajorBlockMmc = 179;
static const char* kGptBasicData = "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7";
static const char* kGptAndroidMeta = "19A710A2-B3CA-11E4-B026-10604B889DCF";
-static const char* kGptAndroidExt = "193D1EA4-B3CA-11E4-B075-10604B889DCF";
+static const char* kGptAndroidExpand = "193D1EA4-B3CA-11E4-B075-10604B889DCF";
static const char* kKeyPath = "/data/misc/vold";
@@ -63,8 +63,10 @@ enum class Table {
kGpt,
};
-Disk::Disk(const std::string& eventPath, dev_t device, const std::string& nickname, int flags) :
- mDevice(device), mSize(-1), mNickname(nickname), mFlags(flags), mCreated(false) {
+Disk::Disk(const std::string& eventPath, dev_t device,
+ const std::string& nickname, int flags) :
+ mDevice(device), mSize(-1), mNickname(nickname), mFlags(flags), mCreated(
+ false), mJustPartitioned(false) {
mId = StringPrintf("disk:%u,%u", major(device), minor(device));
mEventPath = eventPath;
mSysPath = StringPrintf("/sys/%s", eventPath.c_str());
@@ -93,9 +95,7 @@ std::shared_ptr<VolumeBase> Disk::findVolume(const std::string& id) {
status_t Disk::create() {
CHECK(!mCreated);
mCreated = true;
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::DiskCreated,
- StringPrintf("%s %d", getId().c_str(), mFlags).c_str(), false);
+ notifyEvent(ResponseCode::DiskCreated, StringPrintf("%d", mFlags));
readMetadata();
readPartitions();
return OK;
@@ -105,23 +105,28 @@ status_t Disk::destroy() {
CHECK(mCreated);
destroyAllVolumes();
mCreated = false;
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::DiskDestroyed, getId().c_str(), false);
+ notifyEvent(ResponseCode::DiskDestroyed);
return OK;
}
static std::string BuildKeyPath(const std::string& partGuid) {
- return StringPrintf("%s/ext_%s.key", kKeyPath, partGuid.c_str());
+ return StringPrintf("%s/expand_%s.key", kKeyPath, partGuid.c_str());
}
void Disk::createPublicVolume(dev_t device) {
auto vol = std::shared_ptr<VolumeBase>(new PublicVolume(device));
- vol->create();
+ if (mJustPartitioned) {
+ LOG(DEBUG) << "Device just partitioned; silently formatting";
+ vol->setSilent(true);
+ vol->create();
+ vol->format();
+ vol->destroy();
+ vol->setSilent(false);
+ }
mVolumes.push_back(vol);
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::DiskVolumeCreated,
- StringPrintf("%s %s", getId().c_str(), vol->getId().c_str()).c_str(), false);
+ vol->create();
+ notifyEvent(ResponseCode::DiskVolumeCreated, vol->getId());
}
void Disk::createPrivateVolume(dev_t device, const std::string& partGuid) {
@@ -142,12 +147,18 @@ void Disk::createPrivateVolume(dev_t device, const std::string& partGuid) {
LOG(DEBUG) << "Found key for GUID " << normalizedGuid;
auto vol = std::shared_ptr<VolumeBase>(new PrivateVolume(device, keyRaw));
- vol->create();
+ if (mJustPartitioned) {
+ LOG(DEBUG) << "Device just partitioned; silently formatting";
+ vol->setSilent(true);
+ vol->create();
+ vol->format();
+ vol->destroy();
+ vol->setSilent(false);
+ }
mVolumes.push_back(vol);
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::DiskVolumeCreated,
- StringPrintf("%s %s", getId().c_str(), vol->getId().c_str()).c_str(), false);
+ vol->create();
+ notifyEvent(ResponseCode::DiskVolumeCreated, vol->getId());
}
void Disk::destroyAllVolumes() {
@@ -161,7 +172,7 @@ status_t Disk::readMetadata() {
mSize = -1;
mLabel.clear();
- int fd = open(mDevPath.c_str(), O_RDONLY);
+ int fd = open(mDevPath.c_str(), O_RDONLY | O_CLOEXEC);
if (fd != -1) {
if (ioctl(fd, BLKGETSIZE64, &mSize)) {
mSize = -1;
@@ -205,13 +216,8 @@ status_t Disk::readMetadata() {
}
}
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::DiskSizeChanged,
- StringPrintf("%s %" PRId64, getId().c_str(), mSize).c_str(), false);
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::DiskLabelChanged,
- StringPrintf("%s %s", getId().c_str(), mLabel.c_str()).c_str(), false);
-
+ notifyEvent(ResponseCode::DiskSizeChanged, StringPrintf("%" PRId64, mSize));
+ notifyEvent(ResponseCode::DiskLabelChanged, mLabel);
return OK;
}
@@ -224,22 +230,25 @@ status_t Disk::readPartitions() {
destroyAllVolumes();
// Parse partition table
- std::string path(kSgdiskPath);
- path += " --android-dump ";
- path += mDevPath;
- FILE* fp = popen(path.c_str(), "r");
- if (!fp) {
- PLOG(ERROR) << "Failed to run " << path;
- return -errno;
+
+ std::vector<std::string> cmd;
+ cmd.push_back(kSgdiskPath);
+ cmd.push_back("--android-dump");
+ cmd.push_back(mDevPath);
+
+ std::vector<std::string> output;
+ status_t res = ForkExecvp(cmd, output);
+ if (res != OK) {
+ LOG(WARNING) << "sgdisk failed to scan " << mDevPath;
+ mJustPartitioned = false;
+ return res;
}
- char line[1024];
Table table = Table::kUnknown;
bool foundParts = false;
- while (fgets(line, sizeof(line), fp) != nullptr) {
- LOG(DEBUG) << "sgdisk: " << line;
-
- char* token = strtok(line, kSgdiskToken);
+ for (auto line : output) {
+ char* cline = (char*) line.c_str();
+ char* token = strtok(cline, kSgdiskToken);
if (token == nullptr) continue;
if (!strcmp(token, "DISK")) {
@@ -276,7 +285,7 @@ status_t Disk::readPartitions() {
if (!strcasecmp(typeGuid, kGptBasicData)) {
createPublicVolume(partDevice);
- } else if (!strcasecmp(typeGuid, kGptAndroidExt)) {
+ } else if (!strcasecmp(typeGuid, kGptAndroidExpand)) {
createPrivateVolume(partDevice, partGuid);
}
}
@@ -289,7 +298,7 @@ status_t Disk::readPartitions() {
createPublicVolume(mDevice);
}
- pclose(fp);
+ mJustPartitioned = false;
return OK;
}
@@ -303,6 +312,7 @@ status_t Disk::unmountAll() {
status_t Disk::partitionPublic() {
// TODO: improve this code
destroyAllVolumes();
+ mJustPartitioned = true;
struct disk_info dinfo;
memset(&dinfo, 0, sizeof(dinfo));
@@ -346,9 +356,10 @@ status_t Disk::partitionPrivate() {
}
status_t Disk::partitionMixed(int8_t ratio) {
- int status = 0;
+ int res;
destroyAllVolumes();
+ mJustPartitioned = true;
// First nuke any existing partition table
std::vector<std::string> cmd;
@@ -356,9 +367,9 @@ status_t Disk::partitionMixed(int8_t ratio) {
cmd.push_back("--zap-all");
cmd.push_back(mDevPath);
- if (ForkExecvp(cmd, &status, false, true)) {
- LOG(ERROR) << "Failed to zap; status " << status;
- return -EIO;
+ if ((res = ForkExecvp(cmd)) != 0) {
+ LOG(ERROR) << "Failed to zap; status " << res;
+ return res;
}
// We've had some success above, so generate both the private partition
@@ -408,20 +419,30 @@ status_t Disk::partitionMixed(int8_t ratio) {
// Define a single private partition filling the rest of disk.
cmd.push_back("--new=0:0:-0");
- cmd.push_back(StringPrintf("--typecode=0:%s", kGptAndroidExt));
+ cmd.push_back(StringPrintf("--typecode=0:%s", kGptAndroidExpand));
cmd.push_back(StringPrintf("--partition-guid=0:%s", partGuid.c_str()));
- cmd.push_back("--change-name=0:android_ext");
+ cmd.push_back("--change-name=0:android_expand");
cmd.push_back(mDevPath);
- if (ForkExecvp(cmd, &status, false, true)) {
- LOG(ERROR) << "Failed to partition; status " << status;
- return -EIO;
+ if ((res = ForkExecvp(cmd)) != 0) {
+ LOG(ERROR) << "Failed to partition; status " << res;
+ return res;
}
return OK;
}
+void Disk::notifyEvent(int event) {
+ VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
+ getId().c_str(), false);
+}
+
+void Disk::notifyEvent(int event, const std::string& value) {
+ VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
+ StringPrintf("%s %s", getId().c_str(), value.c_str()).c_str(), false);
+}
+
int Disk::getMaxMinors() {
// Figure out maximum partition devices supported
switch (major(mDevice)) {
diff --git a/Disk.h b/Disk.h
index 82ef1f5..a8461fb 100644
--- a/Disk.h
+++ b/Disk.h
@@ -74,6 +74,9 @@ public:
status_t partitionPrivate();
status_t partitionMixed(int8_t ratio);
+ void notifyEvent(int msg);
+ void notifyEvent(int msg, const std::string& value);
+
private:
/* ID that uniquely references this disk */
std::string mId;
@@ -97,6 +100,8 @@ private:
int mFlags;
/* Flag indicating object is created */
bool mCreated;
+ /* Flag that we just partitioned and should format all volumes */
+ bool mJustPartitioned;
void createPublicVolume(dev_t device);
void createPrivateVolume(dev_t device, const std::string& partGuid);
diff --git a/Ext4.cpp b/Ext4.cpp
index 7316234..a208eb5 100644
--- a/Ext4.cpp
+++ b/Ext4.cpp
@@ -48,14 +48,11 @@
#include "Utils.h"
#include "VoldUtil.h"
-#define RESIZE2FS_PATH "/system/bin/resize2fs"
-
using android::base::StringPrintf;
+static const char* kResizefsPath = "/system/bin/resize2fs";
static const char* kMkfsPath = "/system/bin/make_ext4fs";
-
static const char* kFsckPath = "/system/bin/e2fsck";
-static const char* kFsckLogFile = "/dev/fscklogs/log";
int Ext4::check(const char *fsPath, const char *mountPoint) {
// The following is shamelessly borrowed from fs_mgr.c, so it should be
@@ -68,11 +65,6 @@ int Ext4::check(const char *fsPath, const char *mountPoint) {
int ret;
long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
char *tmpmnt_opts = (char*) "nomblk_io_submit,errors=remount-ro";
- char *e2fsck_argv[] = {
- (char*) kFsckPath,
- (char*) "-y",
- blk_device
- };
/*
* First try to mount and unmount the filesystem. We do this because
@@ -112,23 +104,13 @@ int Ext4::check(const char *fsPath, const char *mountPoint) {
} else {
ALOGD("Running %s on %s\n", kFsckPath, blk_device);
- // Ext4 devices are currently always trusted
- if (setexeccon(android::vold::sFsckContext)) {
- LOG(ERROR) << "Failed to setexeccon()";
- errno = EPERM;
- return -1;
- }
- ret = android_fork_execvp(ARRAY_SIZE(e2fsck_argv), e2fsck_argv,
- &status, false, true);
- if (setexeccon(NULL)) {
- abort();
- }
+ std::vector<std::string> cmd;
+ cmd.push_back(kFsckPath);
+ cmd.push_back("-y");
+ cmd.push_back(blk_device);
- if (ret < 0) {
- /* No need to check for error in fork, we can't really handle it now */
- ALOGW("Failed trying to run %s\n", kFsckPath);
- return -1;
- }
+ // Ext4 devices are currently always trusted
+ return android::vold::ForkExecvp(cmd, android::vold::sFsckContext);
}
return 0;
@@ -157,51 +139,16 @@ int Ext4::doMount(const char *fsPath, const char *mountPoint, bool ro, bool remo
}
int Ext4::resize(const char *fspath, unsigned int numSectors) {
- const char *args[4];
- char* size_str;
- int rc;
- int status;
-
- args[0] = RESIZE2FS_PATH;
- args[1] = "-f";
- args[2] = fspath;
- if (asprintf(&size_str, "%ds", numSectors) < 0)
- {
- SLOGE("Filesystem (ext4) resize failed to set size");
- return -1;
- }
- args[3] = size_str;
- rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
- true);
- free(size_str);
- if (rc != 0) {
- SLOGE("Filesystem (ext4) resize failed due to logwrap error");
- errno = EIO;
- return -1;
- }
-
- if (!WIFEXITED(status)) {
- SLOGE("Filesystem (ext4) resize did not exit properly");
- errno = EIO;
- return -1;
- }
-
- status = WEXITSTATUS(status);
+ std::vector<std::string> cmd;
+ cmd.push_back(kResizefsPath);
+ cmd.push_back("-f");
+ cmd.push_back(fspath);
+ cmd.push_back(StringPrintf("%u", numSectors));
- if (status == 0) {
- SLOGI("Filesystem (ext4) resized OK");
- return 0;
- } else {
- SLOGE("Resize (ext4) failed (unknown exit code %d)", status);
- errno = EIO;
- return -1;
- }
- return 0;
+ return android::vold::ForkExecvp(cmd);
}
int Ext4::format(const char *fsPath, unsigned int numSectors, const char *mountpoint) {
- int status;
-
std::vector<std::string> cmd;
cmd.push_back(kMkfsPath);
cmd.push_back("-J");
@@ -214,30 +161,9 @@ int Ext4::format(const char *fsPath, unsigned int numSectors, const char *mountp
cmd.push_back(StringPrintf("%u", numSectors * 512));
}
+ // Always generate a real UUID
+ cmd.push_back("-u");
cmd.push_back(fsPath);
- int rc = android::vold::ForkExecvp(cmd, &status, false, true);
- if (rc != 0) {
- SLOGE("Filesystem (ext4) format failed due to logwrap error");
- errno = EIO;
- return -1;
- }
-
- if (!WIFEXITED(status)) {
- SLOGE("Filesystem (ext4) format did not exit properly");
- errno = EIO;
- return -1;
- }
-
- status = WEXITSTATUS(status);
-
- if (status == 0) {
- SLOGI("Filesystem (ext4) formatted OK");
- return 0;
- } else {
- SLOGE("Format (ext4) failed (unknown exit code %d)", status);
- errno = EIO;
- return -1;
- }
- return 0;
+ return android::vold::ForkExecvp(cmd);
}
diff --git a/Fat.cpp b/Fat.cpp
index 29b8598..873088d 100644
--- a/Fat.cpp
+++ b/Fat.cpp
@@ -38,6 +38,7 @@
#define LOG_TAG "Vold"
#include <base/logging.h>
+#include <base/stringprintf.h>
#include <cutils/log.h>
#include <cutils/properties.h>
#include <selinux/selinux.h>
@@ -48,12 +49,13 @@
#include "Utils.h"
#include "VoldUtil.h"
-static char FSCK_MSDOS_PATH[] = "/system/bin/fsck_msdos";
-static char MKDOSFS_PATH[] = "/system/bin/newfs_msdos";
-extern "C" int mount(const char *, const char *, const char *, unsigned long, const void *);
+using android::base::StringPrintf;
+
+static const char* kMkfsPath = "/system/bin/newfs_msdos";
+static const char* kFsckPath = "/system/bin/fsck_msdos";
int Fat::check(const char *fsPath) {
- if (access(FSCK_MSDOS_PATH, X_OK)) {
+ if (access(kFsckPath, X_OK)) {
SLOGW("Skipping fs checks\n");
return 0;
}
@@ -61,40 +63,22 @@ int Fat::check(const char *fsPath) {
int pass = 1;
int rc = 0;
do {
- const char *args[4];
- int status;
- args[0] = FSCK_MSDOS_PATH;
- args[1] = "-p";
- args[2] = "-f";
- args[3] = fsPath;
+ std::vector<std::string> cmd;
+ cmd.push_back(kFsckPath);
+ cmd.push_back("-p");
+ cmd.push_back("-f");
+ cmd.push_back(fsPath);
// Fat devices are currently always untrusted
- if (setexeccon(android::vold::sFsckUntrustedContext)) {
- LOG(ERROR) << "Failed to setexeccon()";
- errno = EPERM;
- return -1;
- }
- rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status,
- false, true);
- if (setexeccon(NULL)) {
- abort();
- }
+ rc = android::vold::ForkExecvp(cmd, android::vold::sFsckUntrustedContext);
- if (rc != 0) {
+ if (rc < 0) {
SLOGE("Filesystem check failed due to logwrap error");
errno = EIO;
return -1;
}
- if (!WIFEXITED(status)) {
- SLOGE("Filesystem check did not exit properly");
- errno = EIO;
- return -1;
- }
-
- status = WEXITSTATUS(status);
-
- switch(status) {
+ switch(rc) {
case 0:
SLOGI("Filesystem check completed OK");
return 0;
@@ -115,7 +99,7 @@ int Fat::check(const char *fsPath) {
return -1;
default:
- SLOGE("Filesystem check failed (unknown exit code %d)", status);
+ SLOGE("Filesystem check failed (unknown exit code %d)", rc);
errno = EIO;
return -1;
}
@@ -182,57 +166,39 @@ int Fat::doMount(const char *fsPath, const char *mountPoint,
}
int Fat::format(const char *fsPath, unsigned int numSectors, bool wipe) {
- const char *args[11];
- int rc;
- int status;
-
if (wipe) {
Fat::wipe(fsPath, numSectors);
}
- args[0] = MKDOSFS_PATH;
- args[1] = "-F";
- args[2] = "32";
- args[3] = "-O";
- args[4] = "android";
- args[5] = "-c";
- args[6] = "64";
- args[7] = "-A";
+ std::vector<std::string> cmd;
+ cmd.push_back(kMkfsPath);
+ cmd.push_back("-F");
+ cmd.push_back("32");
+ cmd.push_back("-O");
+ cmd.push_back("android");
+ cmd.push_back("-c");
+ cmd.push_back("64");
+ cmd.push_back("-A");
if (numSectors) {
- char tmp[32];
- snprintf(tmp, sizeof(tmp), "%u", numSectors);
- const char *size = tmp;
- args[8] = "-s";
- args[9] = size;
- args[10] = fsPath;
- rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status,
- false, true);
- } else {
- args[8] = fsPath;
- rc = android_fork_execvp(9, (char **)args, &status, false,
- true);
+ cmd.push_back("-s");
+ cmd.push_back(StringPrintf("%u", numSectors));
}
- if (rc != 0) {
- SLOGE("Filesystem format failed due to logwrap error");
- errno = EIO;
- return -1;
- }
+ cmd.push_back(fsPath);
- if (!WIFEXITED(status)) {
- SLOGE("Filesystem format did not exit properly");
+ int rc = android::vold::ForkExecvp(cmd);
+ if (rc < 0) {
+ SLOGE("Filesystem format failed due to logwrap error");
errno = EIO;
return -1;
}
- status = WEXITSTATUS(status);
-
- if (status == 0) {
+ if (rc == 0) {
SLOGI("Filesystem formatted OK");
return 0;
} else {
- SLOGE("Format failed (unknown exit code %d)", status);
+ SLOGE("Format failed (unknown exit code %d)", rc);
errno = EIO;
return -1;
}
@@ -242,7 +208,7 @@ int Fat::format(const char *fsPath, unsigned int numSectors, bool wipe) {
void Fat::wipe(const char *fsPath, unsigned int numSectors) {
unsigned long long range[2];
- int fd = open(fsPath, O_RDWR);
+ int fd = open(fsPath, O_RDWR | O_CLOEXEC);
if (fd == -1) {
SLOGE("Fat wipe failed to open device %s", fsPath);
return;
diff --git a/Loop.cpp b/Loop.cpp
index b1e9f6a..8872d7a 100644
--- a/Loop.cpp
+++ b/Loop.cpp
@@ -49,7 +49,7 @@ int Loop::dumpState(SocketClient *c) {
sprintf(filename, "/dev/block/loop%d", i);
- if ((fd = open(filename, O_RDWR)) < 0) {
+ if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) {
if (errno != ENOENT) {
SLOGE("Unable to open %s (%s)", filename, strerror(errno));
} else {
@@ -93,7 +93,7 @@ int Loop::lookupActive(const char *id, char *buffer, size_t len) {
sprintf(filename, "/dev/block/loop%d", i);
- if ((fd = open(filename, O_RDWR)) < 0) {
+ if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) {
if (errno != ENOENT) {
SLOGE("Unable to open %s (%s)", filename, strerror(errno));
} else {
@@ -168,7 +168,7 @@ int Loop::create(const char *id, const char *loopFile, char *loopDeviceBuffer, s
setfscreatecon(NULL);
}
- if ((fd = open(filename, O_RDWR)) < 0) {
+ if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) {
SLOGE("Unable to open %s (%s)", filename, strerror(errno));
return -1;
}
@@ -196,7 +196,7 @@ int Loop::create(const char *id, const char *loopFile, char *loopDeviceBuffer, s
int file_fd;
- if ((file_fd = open(loopFile, O_RDWR)) < 0) {
+ if ((file_fd = open(loopFile, O_RDWR | O_CLOEXEC)) < 0) {
SLOGE("Unable to open %s (%s)", loopFile, strerror(errno));
close(fd);
return -1;
@@ -231,7 +231,7 @@ int Loop::create(const char *id, const char *loopFile, char *loopDeviceBuffer, s
int Loop::destroyByDevice(const char *loopDevice) {
int device_fd;
- device_fd = open(loopDevice, O_RDONLY);
+ device_fd = open(loopDevice, O_RDONLY | O_CLOEXEC);
if (device_fd < 0) {
SLOGE("Failed to open loop (%d)", errno);
return -1;
@@ -272,7 +272,7 @@ int Loop::createImageFile(const char *file, unsigned int numSectors) {
int Loop::resizeImageFile(const char *file, unsigned int numSectors) {
int fd;
- if ((fd = open(file, O_RDWR)) < 0) {
+ if ((fd = open(file, O_RDWR | O_CLOEXEC)) < 0) {
SLOGE("Error opening imagefile (%s)", strerror(errno));
return -1;
}
@@ -301,7 +301,7 @@ int Loop::lookupInfo(const char *loopDevice, struct asec_superblock *sb, unsigne
int fd;
struct asec_superblock buffer;
- if ((fd = open(loopDevice, O_RDONLY)) < 0) {
+ if ((fd = open(loopDevice, O_RDONLY | O_CLOEXEC)) < 0) {
SLOGE("Failed to open loopdevice (%s)", strerror(errno));
destroyByDevice(loopDevice);
return -1;
diff --git a/PrivateVolume.cpp b/PrivateVolume.cpp
index f652c6b..6ca5480 100644
--- a/PrivateVolume.cpp
+++ b/PrivateVolume.cpp
@@ -50,17 +50,9 @@ PrivateVolume::~PrivateVolume() {
status_t PrivateVolume::readMetadata() {
status_t res = ReadMetadata(mDmDevPath, mFsType, mFsUuid, mFsLabel);
-
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::VolumeFsTypeChanged,
- StringPrintf("%s %s", getId().c_str(), mFsType.c_str()).c_str(), false);
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::VolumeFsUuidChanged,
- StringPrintf("%s %s", getId().c_str(), mFsUuid.c_str()).c_str(), false);
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::VolumeFsLabelChanged,
- StringPrintf("%s %s", getId().c_str(), mFsLabel.c_str()).c_str(), false);
-
+ notifyEvent(ResponseCode::VolumeFsTypeChanged, mFsType);
+ notifyEvent(ResponseCode::VolumeFsUuidChanged, mFsUuid);
+ notifyEvent(ResponseCode::VolumeFsLabelChanged, mFsLabel);
return res;
}
diff --git a/Process.cpp b/Process.cpp
index f01fa31..a6f0cc6 100644
--- a/Process.cpp
+++ b/Process.cpp
@@ -66,7 +66,7 @@ int Process::pathMatchesMountPoint(const char* path, const char* mountPoint) {
void Process::getProcessName(int pid, char *buffer, size_t max) {
int fd;
snprintf(buffer, max, "/proc/%d/cmdline", pid);
- fd = open(buffer, O_RDONLY);
+ fd = open(buffer, O_RDONLY | O_CLOEXEC);
if (fd < 0) {
strcpy(buffer, "???");
} else {
diff --git a/PublicVolume.cpp b/PublicVolume.cpp
index 6192e7a..9a68f50 100644
--- a/PublicVolume.cpp
+++ b/PublicVolume.cpp
@@ -52,17 +52,9 @@ PublicVolume::~PublicVolume() {
status_t PublicVolume::readMetadata() {
status_t res = ReadMetadataUntrusted(mDevPath, mFsType, mFsUuid, mFsLabel);
-
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::VolumeFsTypeChanged,
- StringPrintf("%s %s", getId().c_str(), mFsType.c_str()).c_str(), false);
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::VolumeFsUuidChanged,
- StringPrintf("%s %s", getId().c_str(), mFsUuid.c_str()).c_str(), false);
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::VolumeFsLabelChanged,
- StringPrintf("%s %s", getId().c_str(), mFsLabel.c_str()).c_str(), false);
-
+ notifyEvent(ResponseCode::VolumeFsTypeChanged, mFsType);
+ notifyEvent(ResponseCode::VolumeFsUuidChanged, mFsUuid);
+ notifyEvent(ResponseCode::VolumeFsLabelChanged, mFsLabel);
return res;
}
diff --git a/Utils.cpp b/Utils.cpp
index 1937c28..d23e182 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -24,6 +24,7 @@
#include <private/android_filesystem_config.h>
#include <logwrap/logwrap.h>
+#include <mutex>
#include <fcntl.h>
#include <linux/fs.h>
#include <stdlib.h>
@@ -41,6 +42,10 @@ using android::base::StringPrintf;
namespace android {
namespace vold {
+/* Since we use setexeccon(), we need to carefully lock around any
+ * code that calls exec() to avoid crossing the streams. */
+static std::mutex sExecLock;
+
security_context_t sBlkidContext = nullptr;
security_context_t sBlkidUntrustedContext = nullptr;
security_context_t sFsckContext = nullptr;
@@ -117,6 +122,14 @@ status_t ForceUnmount(const std::string& path) {
PLOG(WARNING) << "Failed to unmount " << path;
sleep(5);
+ Process::killProcessesWithOpenFiles(cpath, SIGINT);
+
+ if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
+ return OK;
+ }
+ PLOG(WARNING) << "Failed to unmount " << path;
+
+ sleep(5);
Process::killProcessesWithOpenFiles(cpath, SIGTERM);
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
@@ -149,48 +162,40 @@ static status_t readMetadata(const std::string& path, std::string& fsType,
fsUuid.clear();
fsLabel.clear();
- std::string cmd(StringPrintf("%s -c /dev/null %s", kBlkidPath, path.c_str()));
- if (setexeccon(untrusted ? sBlkidUntrustedContext : sBlkidContext)) {
- LOG(ERROR) << "Failed to setexeccon()";
- return -EPERM;
- }
- FILE* fp = popen(cmd.c_str(), "r");
- if (setexeccon(NULL)) {
- abort();
- }
- if (!fp) {
- PLOG(ERROR) << "Failed to run " << cmd;
- return -errno;
+ std::vector<std::string> cmd;
+ cmd.push_back(kBlkidPath);
+ cmd.push_back("-c");
+ cmd.push_back("/dev/null");
+ cmd.push_back(path);
+
+ std::vector<std::string> output;
+ status_t res = ForkExecvp(cmd, output, untrusted ? sBlkidUntrustedContext : sBlkidContext);
+ if (res != OK) {
+ LOG(WARNING) << "blkid failed to identify " << path;
+ return res;
}
- status_t res = OK;
- char line[1024];
char value[128];
- if (fgets(line, sizeof(line), fp) != nullptr) {
- LOG(DEBUG) << "blkid identified " << path << " as " << line;
-
+ for (auto line : output) {
// Extract values from blkid output, if defined
- char* start = strstr(line, "TYPE=");
+ const char* cline = line.c_str();
+ char* start = strstr(cline, "TYPE=");
if (start != nullptr && sscanf(start + 5, "\"%127[^\"]\"", value) == 1) {
fsType = value;
}
- start = strstr(line, "UUID=");
+ start = strstr(cline, "UUID=");
if (start != nullptr && sscanf(start + 5, "\"%127[^\"]\"", value) == 1) {
fsUuid = value;
}
- start = strstr(line, "LABEL=");
+ start = strstr(cline, "LABEL=");
if (start != nullptr && sscanf(start + 6, "\"%127[^\"]\"", value) == 1) {
fsLabel = value;
}
- } else {
- LOG(WARNING) << "blkid failed to identify " << path;
- res = -ENODATA;
}
- pclose(fp);
- return res;
+ return OK;
}
status_t ReadMetadata(const std::string& path, std::string& fsType,
@@ -203,11 +208,14 @@ status_t ReadMetadataUntrusted(const std::string& path, std::string& fsType,
return readMetadata(path, fsType, fsUuid, fsLabel, true);
}
-status_t ForkExecvp(const std::vector<std::string>& args, int* status,
- bool ignore_int_quit, bool logwrap) {
- int argc = args.size();
+status_t ForkExecvp(const std::vector<std::string>& args) {
+ return ForkExecvp(args, nullptr);
+}
+
+status_t ForkExecvp(const std::vector<std::string>& args, security_context_t context) {
+ size_t argc = args.size();
char** argv = (char**) calloc(argc, sizeof(char*));
- for (int i = 0; i < argc; i++) {
+ for (size_t i = 0; i < argc; i++) {
argv[i] = (char*) args[i].c_str();
if (i == 0) {
LOG(VERBOSE) << args[i];
@@ -215,11 +223,73 @@ status_t ForkExecvp(const std::vector<std::string>& args, int* status,
LOG(VERBOSE) << " " << args[i];
}
}
- int res = android_fork_execvp(argc, argv, status, ignore_int_quit, logwrap);
+
+ status_t res = OK;
+ {
+ std::lock_guard<std::mutex> lock(sExecLock);
+ if (setexeccon(context)) {
+ LOG(ERROR) << "Failed to setexeccon";
+ abort();
+ }
+ res = android_fork_execvp(argc, argv, NULL, false, true);
+ if (setexeccon(nullptr)) {
+ LOG(ERROR) << "Failed to setexeccon";
+ abort();
+ }
+ }
free(argv);
return res;
}
+status_t ForkExecvp(const std::vector<std::string>& args,
+ std::vector<std::string>& output) {
+ return ForkExecvp(args, output, nullptr);
+}
+
+status_t ForkExecvp(const std::vector<std::string>& args,
+ std::vector<std::string>& output, security_context_t context) {
+ std::string cmd;
+ for (size_t i = 0; i < args.size(); i++) {
+ cmd += args[i] + " ";
+ if (i == 0) {
+ LOG(VERBOSE) << args[i];
+ } else {
+ LOG(VERBOSE) << " " << args[i];
+ }
+ }
+ output.clear();
+
+ FILE* fp = nullptr;
+ {
+ std::lock_guard<std::mutex> lock(sExecLock);
+ if (setexeccon(context)) {
+ LOG(ERROR) << "Failed to setexeccon";
+ abort();
+ }
+ fp = popen(cmd.c_str(), "r");
+ if (setexeccon(nullptr)) {
+ LOG(ERROR) << "Failed to setexeccon";
+ abort();
+ }
+ }
+
+ if (!fp) {
+ PLOG(ERROR) << "Failed to popen " << cmd;
+ return -errno;
+ }
+ char line[1024];
+ while (fgets(line, sizeof(line), fp) != nullptr) {
+ LOG(VERBOSE) << line;
+ output.push_back(std::string(line));
+ }
+ if (pclose(fp) != 0) {
+ PLOG(ERROR) << "Failed to pclose " << cmd;
+ return -errno;
+ }
+
+ return OK;
+}
+
status_t ReadRandomBytes(size_t bytes, std::string& out) {
out.clear();
diff --git a/Utils.h b/Utils.h
index a6e1747..7e083f6 100644
--- a/Utils.h
+++ b/Utils.h
@@ -60,8 +60,14 @@ status_t ReadMetadata(const std::string& path, std::string& fsType,
status_t ReadMetadataUntrusted(const std::string& path, std::string& fsType,
std::string& fsUuid, std::string& fsLabel);
-status_t ForkExecvp(const std::vector<std::string>& args, int* status,
- bool ignore_int_quit, bool logwrap);
+/* 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, security_context_t context);
+
+status_t ForkExecvp(const std::vector<std::string>& args,
+ std::vector<std::string>& output);
+status_t ForkExecvp(const std::vector<std::string>& args,
+ std::vector<std::string>& output, security_context_t context);
status_t ReadRandomBytes(size_t bytes, std::string& out);
diff --git a/VolumeBase.cpp b/VolumeBase.cpp
index 2590ecf..de5b072 100644
--- a/VolumeBase.cpp
+++ b/VolumeBase.cpp
@@ -36,7 +36,8 @@ namespace android {
namespace vold {
VolumeBase::VolumeBase(Type type) :
- mType(type), mFlags(0), mUser(-1), mCreated(false), mState(State::kUnmounted) {
+ mType(type), mFlags(0), mUser(-1), mCreated(false), mState(
+ State::kUnmounted), mSilent(false) {
}
VolumeBase::~VolumeBase() {
@@ -45,10 +46,7 @@ VolumeBase::~VolumeBase() {
void VolumeBase::setState(State state) {
mState = state;
-
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::VolumeStateChanged,
- StringPrintf("%s %d", getId().c_str(), mState).c_str(), false);
+ notifyEvent(ResponseCode::VolumeStateChanged, StringPrintf("%d", mState));
}
status_t VolumeBase::setFlags(int flags) {
@@ -71,6 +69,16 @@ status_t VolumeBase::setUser(userid_t user) {
return OK;
}
+status_t VolumeBase::setSilent(bool silent) {
+ if (mCreated) {
+ LOG(WARNING) << getId() << " silence change requires destroyed";
+ return -EBUSY;
+ }
+
+ mSilent = silent;
+ return OK;
+}
+
status_t VolumeBase::setId(const std::string& id) {
if (mCreated) {
LOG(WARNING) << getId() << " id change requires not created";
@@ -88,12 +96,22 @@ status_t VolumeBase::setPath(const std::string& path) {
}
mPath = path;
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::VolumePathChanged,
- StringPrintf("%s %s", getId().c_str(), mPath.c_str()).c_str(), false);
+ notifyEvent(ResponseCode::VolumePathChanged, mPath);
return OK;
}
+void VolumeBase::notifyEvent(int event) {
+ if (mSilent) return;
+ VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
+ getId().c_str(), false);
+}
+
+void VolumeBase::notifyEvent(int event, const std::string& value) {
+ if (mSilent) return;
+ VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
+ StringPrintf("%s %s", getId().c_str(), value.c_str()).c_str(), false);
+}
+
void VolumeBase::addVolume(const std::shared_ptr<VolumeBase>& volume) {
mVolumes.push_back(volume);
}
@@ -116,9 +134,7 @@ status_t VolumeBase::create() {
mCreated = true;
status_t res = doCreate();
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::VolumeCreated,
- StringPrintf("%s %d", getId().c_str(), mType).c_str(), false);
+ notifyEvent(ResponseCode::VolumeCreated, StringPrintf("%d", mType));
return res;
}
@@ -133,8 +149,7 @@ status_t VolumeBase::destroy() {
unmount();
}
- VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
- ResponseCode::VolumeDestroyed, getId().c_str(), false);
+ notifyEvent(ResponseCode::VolumeDestroyed);
status_t res = doDestroy();
mCreated = false;
return res;
diff --git a/VolumeBase.h b/VolumeBase.h
index 465fc61..1494c2c 100644
--- a/VolumeBase.h
+++ b/VolumeBase.h
@@ -86,6 +86,7 @@ public:
status_t setFlags(int flags);
status_t setUser(userid_t user);
+ status_t setSilent(bool silent);
void addVolume(const std::shared_ptr<VolumeBase>& volume);
void removeVolume(const std::shared_ptr<VolumeBase>& volume);
@@ -110,6 +111,9 @@ protected:
status_t setId(const std::string& id);
status_t setPath(const std::string& path);
+ void notifyEvent(int msg);
+ void notifyEvent(int msg, const std::string& value);
+
private:
/* ID that uniquely references volume while alive */
std::string mId;
@@ -125,6 +129,8 @@ private:
State mState;
/* Path to mounted volume */
std::string mPath;
+ /* Flag indicating that volume should emit no events */
+ bool mSilent;
/* Volumes stacked on top of this volume */
std::list<std::shared_ptr<VolumeBase>> mVolumes;
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index b61bafb..5b7ce22 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -95,7 +95,7 @@ static const unsigned int kMajorBlockMmc = 179;
/* writes superblock at end of file or device given by name */
static int writeSuperBlock(const char* name, struct asec_superblock *sb, unsigned int numImgSectors) {
- int sbfd = open(name, O_RDWR);
+ int sbfd = open(name, O_RDWR | O_CLOEXEC);
if (sbfd < 0) {
SLOGE("Failed to open %s for superblock write (%s)", name, strerror(errno));
return -1;
@@ -726,7 +726,7 @@ int VolumeManager::createAsec(const char *id, unsigned int numSectors, const cha
}
if (usingExt4) {
- int dirfd = open(mountPoint, O_DIRECTORY);
+ int dirfd = open(mountPoint, O_DIRECTORY | O_CLOEXEC);
if (dirfd >= 0) {
if (fchown(dirfd, ownerUid, AID_SYSTEM)
|| fchmod(dirfd, S_IRUSR | S_IWUSR | S_IXUSR | S_ISGID | S_IRGRP | S_IXGRP)) {
@@ -775,7 +775,7 @@ int VolumeManager::resizeAsec(const char *id, unsigned numSectors, const char *k
int fd;
unsigned int oldNumSec = 0;
- if ((fd = open(asecFileName, O_RDONLY)) < 0) {
+ if ((fd = open(asecFileName, O_RDONLY | O_CLOEXEC)) < 0) {
SLOGE("Failed to open ASEC file (%s)", strerror(errno));
return -1;
}
@@ -1021,7 +1021,7 @@ int VolumeManager::fixupAsecPermissions(const char *id, gid_t gid, const char* f
*/
const bool privateFile = !strcmp(ftsent->fts_name, filename);
- int fd = open(ftsent->fts_accpath, O_NOFOLLOW);
+ int fd = open(ftsent->fts_accpath, O_NOFOLLOW | O_CLOEXEC);
if (fd < 0) {
SLOGE("Couldn't open file %s: %s", ftsent->fts_accpath, strerror(errno));
result = -1;
@@ -1046,7 +1046,7 @@ int VolumeManager::fixupAsecPermissions(const char *id, gid_t gid, const char* f
fts_close(fts);
// Finally make the directory readable by everyone.
- int dirfd = open(mountPoint, O_DIRECTORY);
+ int dirfd = open(mountPoint, O_DIRECTORY | O_CLOEXEC);
if (dirfd < 0 || fchmod(dirfd, 0755)) {
SLOGE("Couldn't change owner of existing directory %s: %s", mountPoint, strerror(errno));
result |= -1;
@@ -1354,7 +1354,7 @@ bool VolumeManager::isLegalAsecId(const char *id) const {
}
bool VolumeManager::isAsecInDirectory(const char *dir, const char *asecName) const {
- int dirfd = open(dir, O_DIRECTORY);
+ int dirfd = open(dir, O_DIRECTORY | O_CLOEXEC);
if (dirfd < 0) {
SLOGE("Couldn't open internal ASEC dir (%s)", strerror(errno));
return false;
@@ -1546,7 +1546,7 @@ int VolumeManager::mountObb(const char *img, const char *key, int ownerGid) {
int fd;
unsigned long nr_sec = 0;
- if ((fd = open(loopDevice, O_RDWR)) < 0) {
+ if ((fd = open(loopDevice, O_RDWR | O_CLOEXEC)) < 0) {
SLOGE("Failed to open loopdevice (%s)", strerror(errno));
Loop::destroyByDevice(loopDevice);
return -1;
@@ -1612,7 +1612,7 @@ int VolumeManager::listMountedObbs(SocketClient* cli) {
mntent* mentry;
while ((mentry = getmntent(fp)) != NULL) {
if (!strncmp(mentry->mnt_dir, loopDir, loopDirLen)) {
- int fd = open(mentry->mnt_fsname, O_RDONLY);
+ int fd = open(mentry->mnt_fsname, O_RDONLY | O_CLOEXEC);
if (fd >= 0) {
struct loop_info64 li;
if (ioctl(fd, LOOP_GET_STATUS64, &li) >= 0) {
diff --git a/cryptfs.c b/cryptfs.c
index ebce6e8..f6bad74 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -380,7 +380,7 @@ static unsigned int get_fs_size(char *dev)
struct ext4_super_block sb;
off64_t len;
- if ((fd = open(dev, O_RDONLY)) < 0) {
+ if ((fd = open(dev, O_RDONLY|O_CLOEXEC)) < 0) {
SLOGE("Cannot open device to get filesystem size ");
return 0;
}
@@ -423,7 +423,7 @@ static int get_crypt_ftr_info(char **metadata_fname, off64_t *off)
fs_mgr_get_crypt_info(fstab, key_loc, real_blkdev, sizeof(key_loc));
if (!strcmp(key_loc, KEY_IN_FOOTER)) {
- if ( (fd = open(real_blkdev, O_RDWR)) < 0) {
+ if ( (fd = open(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) {
SLOGE("Cannot open real block device %s\n", real_blkdev);
return -1;
}
@@ -485,7 +485,7 @@ static int put_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr)
SLOGE("Unexpected value for crypto key location\n");
return -1;
}
- if ( (fd = open(fname, O_RDWR | O_CREAT, 0600)) < 0) {
+ if ( (fd = open(fname, O_RDWR | O_CREAT|O_CLOEXEC, 0600)) < 0) {
SLOGE("Cannot open footer file %s for put\n", fname);
return -1;
}
@@ -623,7 +623,7 @@ static int get_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr)
SLOGE("Unexpected value for crypto key location\n");
return -1;
}
- if ( (fd = open(fname, O_RDWR)) < 0) {
+ if ( (fd = open(fname, O_RDWR|O_CLOEXEC)) < 0) {
SLOGE("Cannot open footer file %s for get\n", fname);
return -1;
}
@@ -748,7 +748,7 @@ static int load_persistent_data(void)
return -1;
}
- fd = open(fname, O_RDONLY);
+ fd = open(fname, O_RDONLY|O_CLOEXEC);
if (fd < 0) {
SLOGE("Cannot open %s metadata file", fname);
return -1;
@@ -829,7 +829,7 @@ static int save_persistent_data(void)
return -1;
}
- fd = open(fname, O_RDWR);
+ fd = open(fname, O_RDWR|O_CLOEXEC);
if (fd < 0) {
SLOGE("Cannot open %s metadata file", fname);
return -1;
@@ -1067,7 +1067,7 @@ static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr,
char *extra_params;
int load_count;
- if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) {
+ if ((fd = open("/dev/device-mapper", O_RDWR|O_CLOEXEC)) < 0 ) {
SLOGE("Cannot open device-mapper\n");
goto errout;
}
@@ -1132,7 +1132,7 @@ static int delete_crypto_blk_dev(char *name)
struct dm_ioctl *io;
int retval = -1;
- if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) {
+ if ((fd = open("/dev/device-mapper", O_RDWR|O_CLOEXEC)) < 0 ) {
SLOGE("Cannot open device-mapper\n");
goto errout;
}
@@ -1416,7 +1416,7 @@ static int create_encrypted_random_key(char *passwd, unsigned char *master_key,
unsigned char key_buf[KEY_LEN_BYTES];
/* Get some random bits for a key */
- fd = open("/dev/urandom", O_RDONLY);
+ fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC);
read(fd, key_buf, sizeof(key_buf));
read(fd, salt, SALT_LEN);
close(fd);
@@ -1892,7 +1892,7 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr,
*/
int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev,
const unsigned char* key, int keysize, char* out_crypto_blkdev) {
- int fd = open(real_blkdev, O_RDONLY);
+ int fd = open(real_blkdev, O_RDONLY|O_CLOEXEC);
if (fd == -1) {
SLOGE("Failed to open %s: %s", real_blkdev, strerror(errno));
return -1;
@@ -2453,14 +2453,14 @@ static int cryptfs_enable_inplace_ext4(char *crypto_blkdev,
data.real_blkdev = real_blkdev;
data.crypto_blkdev = crypto_blkdev;
- if ( (data.realfd = open(real_blkdev, O_RDWR)) < 0) {
+ if ( (data.realfd = open(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) {
SLOGE("Error opening real_blkdev %s for inplace encrypt. err=%d(%s)\n",
real_blkdev, errno, strerror(errno));
rc = -1;
goto errout;
}
- if ( (data.cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) {
+ if ( (data.cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) {
SLOGE("Error opening crypto_blkdev %s for ext4 inplace encrypt. err=%d(%s)\n",
crypto_blkdev, errno, strerror(errno));
rc = ENABLE_INPLACE_ERR_DEV;
@@ -2584,12 +2584,12 @@ static int cryptfs_enable_inplace_f2fs(char *crypto_blkdev,
data.crypto_blkdev = crypto_blkdev;
data.realfd = -1;
data.cryptofd = -1;
- if ( (data.realfd = open64(real_blkdev, O_RDWR)) < 0) {
+ if ( (data.realfd = open64(real_blkdev, O_RDWR|O_CLOEXEC)) < 0) {
SLOGE("Error opening real_blkdev %s for f2fs inplace encrypt\n",
real_blkdev);
goto errout;
}
- if ( (data.cryptofd = open64(crypto_blkdev, O_WRONLY)) < 0) {
+ if ( (data.cryptofd = open64(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) {
SLOGE("Error opening crypto_blkdev %s for f2fs inplace encrypt. err=%d(%s)\n",
crypto_blkdev, errno, strerror(errno));
rc = ENABLE_INPLACE_ERR_DEV;
@@ -2656,12 +2656,12 @@ static int cryptfs_enable_inplace_full(char *crypto_blkdev, char *real_blkdev,
off64_t one_pct, cur_pct, new_pct;
off64_t blocks_already_done, tot_numblocks;
- if ( (realfd = open(real_blkdev, O_RDONLY)) < 0) {
+ if ( (realfd = open(real_blkdev, O_RDONLY|O_CLOEXEC)) < 0) {
SLOGE("Error opening real_blkdev %s for inplace encrypt\n", real_blkdev);
return ENABLE_INPLACE_ERR_OTHER;
}
- if ( (cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) {
+ if ( (cryptofd = open(crypto_blkdev, O_WRONLY|O_CLOEXEC)) < 0) {
SLOGE("Error opening crypto_blkdev %s for inplace encrypt. err=%d(%s)\n",
crypto_blkdev, errno, strerror(errno));
close(realfd);
@@ -2819,7 +2819,7 @@ static int cryptfs_enable_inplace(char *crypto_blkdev, char *real_blkdev,
static int cryptfs_SHA256_fileblock(const char* filename, __le8* buf)
{
- int fd = open(filename, O_RDONLY);
+ int fd = open(filename, O_RDONLY|O_CLOEXEC);
if (fd == -1) {
SLOGE("Error opening file %s", filename);
return -1;
@@ -2959,7 +2959,7 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev));
/* Get the size of the real block device */
- int fd = open(real_blkdev, O_RDONLY);
+ int fd = open(real_blkdev, O_RDONLY|O_CLOEXEC);
if (fd == -1) {
SLOGE("Cannot open block device %s\n", real_blkdev);
goto error_unencrypted;
@@ -3190,7 +3190,7 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
/* wipe data if encryption failed */
SLOGE("encryption failed - rebooting into recovery to wipe data\n");
mkdir("/cache/recovery", 0700);
- int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC, 0600);
+ int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, 0600);
if (fd >= 0) {
write(fd, "--wipe_data\n", strlen("--wipe_data\n") + 1);
write(fd, "--reason=cryptfs_enable_internal\n", strlen("--reason=cryptfs_enable_internal\n") + 1);