vold: Add an optional wipe paramter to the volume format command

The new wipe option to the vold format command will invoke BLKDISCARD
on the partition before invoking newfs_msdos.  This will be used whenever
a full wipe of the device is wanted, as this is more secure than just
doing newfs_msdos.

Bug: 9392982
Change-Id: Ie106f1b9cc70abc61206006d1821641c27c7ccae
This commit is contained in:
Ken Sumrall 2013-06-11 19:10:20 -07:00
parent dfbf110dfa
commit 9caab76c6b
11 changed files with 90 additions and 23 deletions

View file

@ -15,6 +15,7 @@ common_src_files := \
Devmapper.cpp \
ResponseCode.cpp \
Xwarp.cpp \
VoldUtil.c \
fstrim.c \
cryptfs.c

View file

@ -162,11 +162,16 @@ int CommandListener::VolumeCmd::runCommand(SocketClient *cli,
}
rc = vm->unmountVolume(argv[2], force, revert);
} else if (!strcmp(argv[1], "format")) {
if (argc != 3) {
cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume format <path>", false);
if (argc < 3 || argc > 4 ||
(argc == 4 && strcmp(argv[3], "wipe"))) {
cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume format <path> [wipe]", false);
return 0;
}
rc = vm->formatVolume(argv[2]);
bool wipe = false;
if (argc >= 4 && !strcmp(argv[3], "wipe")) {
wipe = true;
}
rc = vm->formatVolume(argv[2], wipe);
} else if (!strcmp(argv[1], "share")) {
if (argc != 4) {
cli->sendMsg(ResponseCode::CommandSyntaxError,

35
Fat.cpp
View file

@ -30,6 +30,8 @@
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <linux/kdev_t.h>
@ -167,12 +169,16 @@ int Fat::doMount(const char *fsPath, const char *mountPoint,
return rc;
}
int Fat::format(const char *fsPath, unsigned int numSectors) {
int Fat::format(const char *fsPath, unsigned int numSectors, bool wipe) {
int fd;
const char *args[10];
int rc;
int status;
if (wipe) {
Fat::wipe(fsPath, numSectors);
}
args[0] = MKDOSFS_PATH;
args[1] = "-F";
args[2] = "32";
@ -220,3 +226,30 @@ int Fat::format(const char *fsPath, unsigned int numSectors) {
}
return 0;
}
void Fat::wipe(const char *fsPath, unsigned int numSectors) {
int fd;
unsigned long long range[2];
fd = open(fsPath, O_RDWR);
if (fd >= 0) {
if (numSectors == 0) {
numSectors = get_blkdev_size(fd);
}
if (numSectors == 0) {
SLOGE("Fat wipe failed to determine size of %s", fsPath);
close(fd);
return;
}
range[0] = 0;
range[1] = (unsigned long long)numSectors * 512;
if (ioctl(fd, BLKDISCARD, &range) < 0) {
SLOGE("Fat wipe failed to discard blocks on %s", fsPath);
} else {
SLOGI("Fat wipe %d sectors on %s succeeded", numSectors, fsPath);
}
close(fd);
} else {
SLOGE("Fat wipe failed to open device %s", fsPath);
}
}

5
Fat.h
View file

@ -26,7 +26,10 @@ public:
bool ro, bool remount, bool executable,
int ownerUid, int ownerGid, int permMask,
bool createLost);
static int format(const char *fsPath, unsigned int numSectors);
static int format(const char *fsPath, unsigned int numSectors, bool wipe);
private:
static void wipe(const char *fsPath, unsigned int numSectors);
};
#endif

29
VoldUtil.c Normal file
View file

@ -0,0 +1,29 @@
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sys/ioctl.h>
#include <linux/fs.h>
unsigned int get_blkdev_size(int fd)
{
unsigned int nr_sec;
if ( (ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) {
nr_sec = 0;
}
return nr_sec;
}

View file

@ -17,6 +17,12 @@
#ifndef _VOLDUTIL_H
#define _VOLDUTIL_H
#include <sys/cdefs.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
__BEGIN_DECLS
unsigned int get_blkdev_size(int fd);
__END_DECLS
#endif

View file

@ -206,7 +206,7 @@ int Volume::createDeviceNode(const char *path, int major, int minor) {
return 0;
}
int Volume::formatVol() {
int Volume::formatVol(bool wipe) {
if (getState() == Volume::State_NoMedia) {
errno = ENODEV;
@ -250,7 +250,7 @@ int Volume::formatVol() {
SLOGI("Formatting volume %s (%s)", getLabel(), devicePath);
}
if (Fat::format(devicePath, 0)) {
if (Fat::format(devicePath, 0, wipe)) {
SLOGE("Failed to format (%s)", strerror(errno));
goto err;
}

View file

@ -67,7 +67,7 @@ public:
int mountVol();
int unmountVol(bool force, bool revert);
int formatVol();
int formatVol(bool wipe);
const char *getLabel() { return mLabel; }
const char *getMountpoint() { return mMountpoint; }

View file

@ -167,7 +167,7 @@ int VolumeManager::listVolumes(SocketClient *cli) {
return 0;
}
int VolumeManager::formatVolume(const char *label) {
int VolumeManager::formatVolume(const char *label, bool wipe) {
Volume *v = lookupVolume(label);
if (!v) {
@ -180,7 +180,7 @@ int VolumeManager::formatVolume(const char *label) {
return -1;
}
return v->formatVol();
return v->formatVol(wipe);
}
int VolumeManager::getObbMountPath(const char *sourceFile, char *mountPath, int mountPathLen) {
@ -414,7 +414,7 @@ int VolumeManager::createAsec(const char *id, unsigned int numSectors, const cha
if (usingExt4) {
formatStatus = Ext4::format(dmDevice, mountPoint);
} else {
formatStatus = Fat::format(dmDevice, numImgSectors);
formatStatus = Fat::format(dmDevice, numImgSectors, 0);
}
if (formatStatus < 0) {

View file

@ -83,7 +83,7 @@ public:
int shareVolume(const char *label, const char *method);
int unshareVolume(const char *label, const char *method);
int shareEnabled(const char *path, const char *method, bool *enabled);
int formatVolume(const char *label);
int formatVolume(const char *label, bool wipe);
void disableVolumeManager(void) { mVolManagerDisabled = 1; }
/* ASEC */

View file

@ -46,6 +46,7 @@
#include "cutils/properties.h"
#include "hardware_legacy/power.h"
#include "VolumeManager.h"
#include "VoldUtil.h"
#define DM_CRYPT_BUF_SIZE 4096
#define DATA_MNT_POINT "/data"
@ -115,17 +116,6 @@ static unsigned int get_fs_size(char *dev)
return (unsigned int) (len / 512);
}
static unsigned int get_blkdev_size(int fd)
{
unsigned int nr_sec;
if ( (ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) {
nr_sec = 0;
}
return nr_sec;
}
static int get_crypt_ftr_info(char **metadata_fname, off64_t *off)
{
static int cached_data = 0;