Merge commit 'aebfa6e7eee173b8e02f869c3a25cfe2a5fffb9b' into HEAD

gugelfrei
Bill Yi 9 years ago
commit abcf4c6fca

@ -147,26 +147,66 @@ int CryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,
rc = cryptfs_crypto_complete();
} else if (!strcmp(argv[1], "enablecrypto")) {
const char* syntax = "Usage: cryptfs enablecrypto <wipe|inplace> "
"default|password|pin|pattern [passwd]";
if ( (argc != 4 && argc != 5)
|| (strcmp(argv[2], "wipe") && strcmp(argv[2], "inplace")) ) {
"default|password|pin|pattern [passwd] [noui]";
// This should be replaced with a command line parser if more options
// are added
bool valid = true;
bool no_ui = false;
int type = CRYPT_TYPE_DEFAULT;
int options = 4; // Optional parameters are at this offset
if (argc < 4) {
// Minimum 4 parameters
valid = false;
} else if (strcmp(argv[2], "wipe") && strcmp(argv[2], "inplace") ) {
// Second parameter must be wipe or inplace
valid = false;
} else {
// Third parameter must be valid type
type = getType(argv[3]);
if (type == -1) {
valid = false;
} else if (type != CRYPT_TYPE_DEFAULT) {
options++;
}
}
if (valid) {
if(argc < options) {
// Too few parameters
valid = false;
} else if (argc == options) {
// No more, done
} else if (argc == options + 1) {
// One option, must be noui
if (!strcmp(argv[options], "noui")) {
no_ui = true;
} else {
valid = false;
}
} else {
// Too many options
valid = false;
}
}
if (!valid ) {
cli->sendMsg(ResponseCode::CommandSyntaxError, syntax, false);
return 0;
}
dumpArgs(argc, argv, 4);
int tries;
for (tries = 0; tries < 2; ++tries) {
int type = getType(argv[3]);
if (type == -1) {
cli->sendMsg(ResponseCode::CommandSyntaxError, syntax,
false);
return 0;
} else if (type == CRYPT_TYPE_DEFAULT) {
rc = cryptfs_enable_default(argv[2], /*allow_reboot*/false);
rc = cryptfs_enable_default(argv[2], no_ui);
} else {
rc = cryptfs_enable(argv[2], type, argv[4],
/*allow_reboot*/false);
rc = cryptfs_enable(argv[2], type, argv[4], no_ui);
}
if (rc == 0) {

@ -340,10 +340,24 @@ status_t Disk::unmountAll() {
}
status_t Disk::partitionPublic() {
int res;
// TODO: improve this code
destroyAllVolumes();
mJustPartitioned = true;
// First nuke any existing partition table
std::vector<std::string> cmd;
cmd.push_back(kSgdiskPath);
cmd.push_back("--zap-all");
cmd.push_back(mDevPath);
// Zap sometimes returns an error when it actually succeeded, so
// just log as warning and keep rolling forward.
if ((res = ForkExecvp(cmd)) != 0) {
LOG(WARNING) << "Failed to zap; status " << res;
}
struct disk_info dinfo;
memset(&dinfo, 0, sizeof(dinfo));

@ -113,6 +113,7 @@ status_t EmulatedVolume::doUnmount() {
mFusePid = 0;
}
KillProcessesUsingPath(getPath());
ForceUnmount(mFuseDefault);
ForceUnmount(mFuseRead);
ForceUnmount(mFuseWrite);

@ -177,13 +177,14 @@ extern "C" void vold_killProcessesWithOpenFiles(const char *path, int signal) {
/*
* Hunt down processes that have files open at the given mount point.
*/
void Process::killProcessesWithOpenFiles(const char *path, int signal) {
DIR* dir;
int Process::killProcessesWithOpenFiles(const char *path, int signal) {
int count = 0;
DIR* dir;
struct dirent* de;
if (!(dir = opendir("/proc"))) {
SLOGE("opendir failed (%s)", strerror(errno));
return;
return count;
}
while ((de = readdir(dir))) {
@ -213,7 +214,9 @@ void Process::killProcessesWithOpenFiles(const char *path, int signal) {
if (signal != 0) {
SLOGW("Sending %s to process %d", strsignal(signal), pid);
kill(pid, signal);
count++;
}
}
closedir(dir);
return count;
}

@ -21,7 +21,7 @@
class Process {
public:
static void killProcessesWithOpenFiles(const char *path, int signal);
static int killProcessesWithOpenFiles(const char *path, int signal);
static int getPid(const char *s);
static int checkSymLink(int pid, const char *path, const char *name);
static int checkFileMaps(int pid, const char *path);

@ -123,35 +123,57 @@ status_t ForceUnmount(const std::string& path) {
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
PLOG(WARNING) << "Failed to unmount " << path;
// Apps might still be handling eject request, so wait before
// we start sending signals
sleep(5);
Process::killProcessesWithOpenFiles(cpath, SIGINT);
Process::killProcessesWithOpenFiles(cpath, SIGINT);
sleep(5);
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
PLOG(WARNING) << "Failed to unmount " << path;
sleep(5);
Process::killProcessesWithOpenFiles(cpath, SIGTERM);
sleep(5);
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
PLOG(WARNING) << "Failed to unmount " << path;
sleep(5);
Process::killProcessesWithOpenFiles(cpath, SIGKILL);
sleep(5);
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
PLOG(ERROR) << "Failed to unmount " << path;
return -errno;
}
status_t KillProcessesUsingPath(const std::string& path) {
const char* cpath = path.c_str();
if (Process::killProcessesWithOpenFiles(cpath, SIGINT) == 0) {
return OK;
}
sleep(5);
if (Process::killProcessesWithOpenFiles(cpath, SIGTERM) == 0) {
return OK;
}
sleep(5);
if (Process::killProcessesWithOpenFiles(cpath, SIGKILL) == 0) {
return OK;
}
sleep(5);
// Send SIGKILL a second time to determine if we've
// actually killed everyone with open files
if (Process::killProcessesWithOpenFiles(cpath, SIGKILL) == 0) {
return OK;
}
PLOG(ERROR) << "Failed to kill processes using " << path;
return -EBUSY;
}
status_t BindMount(const std::string& source, const std::string& target) {
if (::mount(source.c_str(), target.c_str(), "", MS_BIND, NULL)) {
PLOG(ERROR) << "Failed to bind mount " << source << " to " << target;

@ -49,6 +49,9 @@ status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid);
/* Really unmounts the path, killing active processes along the way */
status_t ForceUnmount(const std::string& path);
/* Kills any processes using given path */
status_t KillProcessesUsingPath(const std::string& path);
/* Creates bind mount from source to target */
status_t BindMount(const std::string& source, const std::string& target);

@ -2901,7 +2901,7 @@ static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr *crypt_ftr, int how,
}
int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
int allow_reboot)
int no_ui)
{
int how = 0;
char crypto_blkdev[MAXPATHLEN], real_blkdev[MAXPATHLEN];
@ -3000,11 +3000,7 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
/* Now unmount the /data partition. */
if (wait_and_unmount(DATA_MNT_POINT, false)) {
if (allow_reboot) {
goto error_shutting_down;
} else {
goto error_unencrypted;
}
goto error_unencrypted;
}
/* Do extra work for a better UX when doing the long inplace encryption */
@ -3094,7 +3090,7 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
}
}
if (how == CRYPTO_ENABLE_INPLACE) {
if (how == CRYPTO_ENABLE_INPLACE && !no_ui) {
/* startup service classes main and late_start */
property_set("vold.decrypt", "trigger_restart_min_framework");
SLOGD("Just triggered restart_min_framework\n");
@ -3231,15 +3227,15 @@ error_shutting_down:
return -1;
}
int cryptfs_enable(char *howarg, int type, char *passwd, int allow_reboot)
int cryptfs_enable(char *howarg, int type, char *passwd, int no_ui)
{
return cryptfs_enable_internal(howarg, type, passwd, allow_reboot);
return cryptfs_enable_internal(howarg, type, passwd, no_ui);
}
int cryptfs_enable_default(char *howarg, int allow_reboot)
int cryptfs_enable_default(char *howarg, int no_ui)
{
return cryptfs_enable_internal(howarg, CRYPT_TYPE_DEFAULT,
DEFAULT_PASSWORD, allow_reboot);
DEFAULT_PASSWORD, no_ui);
}
int cryptfs_changepw(int crypt_type, const char *newpw)

@ -218,9 +218,9 @@ extern "C" {
int cryptfs_check_passwd(char *pw);
int cryptfs_verify_passwd(char *newpw);
int cryptfs_restart(void);
int cryptfs_enable(char *flag, int type, char *passwd, int allow_reboot);
int cryptfs_enable(char *flag, int type, char *passwd, int no_ui);
int cryptfs_changepw(int type, const char *newpw);
int cryptfs_enable_default(char *flag, int allow_reboot);
int cryptfs_enable_default(char *flag, int no_ui);
int cryptfs_setup_ext_volume(const char* label, const char* real_blkdev,
const unsigned char* key, int keysize, char* out_crypto_blkdev);
int cryptfs_revert_ext_volume(const char* label);

@ -6,7 +6,7 @@ service defaultcrypto /system/bin/vdc --wait cryptfs mountdefaultencrypted
# encryption) or trigger_restart_min_framework (other encryption)
# One shot invocation to encrypt unencrypted volumes
service encrypt /system/bin/vdc --wait cryptfs enablecrypto inplace default
service encrypt /system/bin/vdc --wait cryptfs enablecrypto inplace default noui
disabled
oneshot
# vold will set vold.decrypt to trigger_restart_framework (default

Loading…
Cancel
Save