Different blkid and fsck execution domains.

vold works with two broad classes of block devices: untrusted devices
that come in from the wild, and trusted devices like PrivateVolume
which are encrypted.

When running blkid and fsck, we pick which SELinux execution domain
to use based on which class the device belongs to.

Bug: 19993667
Change-Id: I2695f028710a4863f0c3b2ed6da437f466401272
This commit is contained in:
Jeff Sharkey 2015-04-01 11:54:32 -07:00
parent 9c48498f45
commit 95c87cce35
6 changed files with 99 additions and 15 deletions

View file

@ -37,10 +37,12 @@
#define LOG_TAG "Vold"
#include <base/logging.h>
#include <base/stringprintf.h>
#include <cutils/log.h>
#include <cutils/properties.h>
#include <logwrap/logwrap.h>
#include <selinux/selinux.h>
#include "Ext4.h"
#include "Utils.h"
@ -110,8 +112,17 @@ 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();
}
if (ret < 0) {
/* No need to check for error in fork, we can't really handle it now */

13
Fat.cpp
View file

@ -37,12 +37,15 @@
#define LOG_TAG "Vold"
#include <base/logging.h>
#include <cutils/log.h>
#include <cutils/properties.h>
#include <selinux/selinux.h>
#include <logwrap/logwrap.h>
#include "Fat.h"
#include "Utils.h"
#include "VoldUtil.h"
static char FSCK_MSDOS_PATH[] = "/system/bin/fsck_msdos";
@ -65,8 +68,18 @@ int Fat::check(const char *fsPath) {
args[2] = "-f";
args[3] = 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();
}
if (rc != 0) {
SLOGE("Filesystem check failed due to logwrap error");
errno = EIO;

View file

@ -51,7 +51,7 @@ PublicVolume::~PublicVolume() {
}
status_t PublicVolume::readMetadata() {
status_t res = ReadMetadata(mDevPath, mFsType, mFsUuid, mFsLabel);
status_t res = ReadMetadataUntrusted(mDevPath, mFsType, mFsUuid, mFsLabel);
VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
ResponseCode::VolumeFsTypeChanged,

View file

@ -41,6 +41,11 @@ using android::base::StringPrintf;
namespace android {
namespace vold {
security_context_t sBlkidContext = nullptr;
security_context_t sBlkidUntrustedContext = nullptr;
security_context_t sFsckContext = nullptr;
security_context_t sFsckUntrustedContext = nullptr;
static const char* kBlkidPath = "/system/bin/blkid";
status_t CreateDeviceNode(const std::string& path, dev_t dev) {
@ -111,14 +116,21 @@ status_t BindMount(const std::string& source, const std::string& target) {
return OK;
}
status_t ReadMetadata(const std::string& path, std::string& fsType,
std::string& fsUuid, std::string& fsLabel) {
static status_t readMetadata(const std::string& path, std::string& fsType,
std::string& fsUuid, std::string& fsLabel, bool untrusted) {
fsType.clear();
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;
@ -154,6 +166,16 @@ status_t ReadMetadata(const std::string& path, std::string& fsType,
return res;
}
status_t ReadMetadata(const std::string& path, std::string& fsType,
std::string& fsUuid, std::string& fsLabel) {
return readMetadata(path, fsType, fsUuid, fsLabel, false);
}
status_t ReadMetadataUntrusted(const std::string& path, std::string& fsType,
std::string& fsUuid, std::string& fsLabel) {
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();

13
Utils.h
View file

@ -18,6 +18,7 @@
#define ANDROID_VOLD_UTILS_H
#include <utils/Errors.h>
#include <selinux/selinux.h>
#include <vector>
#include <string>
@ -33,6 +34,12 @@
namespace android {
namespace vold {
/* SELinux contexts used depending on the block device type */
extern security_context_t sBlkidContext;
extern security_context_t sBlkidUntrustedContext;
extern security_context_t sFsckContext;
extern security_context_t sFsckUntrustedContext;
status_t CreateDeviceNode(const std::string& path, dev_t dev);
status_t DestroyDeviceNode(const std::string& path);
@ -46,12 +53,18 @@ status_t BindMount(const std::string& source, const std::string& target);
status_t ReadMetadata(const std::string& path, std::string& fsType,
std::string& fsUuid, std::string& fsLabel);
/* Reads filesystem metadata from untrusted device at path */
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);
status_t ReadRandomBytes(size_t bytes, std::string& out);
/* Converts hex string to raw bytes, ignoring [ :-] */
status_t HexToStr(const std::string& hex, std::string& str);
/* Converts raw bytes to hex string */
status_t StrToHex(const std::string& str, std::string& hex);
} // namespace vold

View file

@ -20,6 +20,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <getopt.h>
#include <fcntl.h>
#include <dirent.h>
@ -43,6 +44,7 @@
static int process_config(VolumeManager *vm);
static void coldboot(const char *path);
static void parse_args(int argc, char** argv);
//#define DEBUG_FSTAB "/data/local/tmp/fstab.debug"
@ -52,7 +54,9 @@ struct selabel_handle *sehandle;
using android::base::StringPrintf;
int main(int argc, char* argv[]) {
int main(int argc, char** argv) {
SLOGI("Vold 2.1 (the revenge) firing up");
setenv("ANDROID_LOG_TAGS", "*:v", 1);
android::base::InitLogging(argv);
@ -60,11 +64,12 @@ int main(int argc, char* argv[]) {
CommandListener *cl;
NetlinkManager *nm;
SLOGI("Vold 2.1 (the revenge) firing up");
parse_args(argc, argv);
sehandle = selinux_android_file_context_handle();
if (sehandle)
if (sehandle) {
selinux_android_set_sehandle(sehandle);
}
mkdir("/dev/block/vold", 0755);
@ -75,13 +80,12 @@ int main(int argc, char* argv[]) {
if (!(vm = VolumeManager::Instance())) {
SLOGE("Unable to create VolumeManager");
exit(1);
};
}
if (!(nm = NetlinkManager::Instance())) {
SLOGE("Unable to create NetlinkManager");
exit(1);
};
}
cl = new CommandListener();
vm->setBroadcaster((SocketListener *) cl);
@ -121,8 +125,31 @@ int main(int argc, char* argv[]) {
exit(0);
}
static void do_coldboot(DIR *d, int lvl)
{
static void parse_args(int argc, char** argv) {
static struct option opts[] = {
{"blkid_context", required_argument, 0, 'b' },
{"blkid_untrusted_context", required_argument, 0, 'B' },
{"fsck_context", required_argument, 0, 'f' },
{"fsck_untrusted_context", required_argument, 0, 'F' },
};
int c;
while ((c = getopt_long(argc, argv, "", opts, nullptr)) != -1) {
switch (c) {
case 'b': android::vold::sBlkidContext = optarg; break;
case 'B': android::vold::sBlkidUntrustedContext = optarg; break;
case 'f': android::vold::sFsckContext = optarg; break;
case 'F': android::vold::sFsckUntrustedContext = optarg; break;
}
}
CHECK(android::vold::sBlkidContext != nullptr);
CHECK(android::vold::sBlkidUntrustedContext != nullptr);
CHECK(android::vold::sFsckContext != nullptr);
CHECK(android::vold::sFsckUntrustedContext != nullptr);
}
static void do_coldboot(DIR *d, int lvl) {
struct dirent *de;
int dfd, fd;
@ -157,8 +184,7 @@ static void do_coldboot(DIR *d, int lvl)
}
}
static void coldboot(const char *path)
{
static void coldboot(const char *path) {
DIR *d = opendir(path);
if(d) {
do_coldboot(d, 0);
@ -166,8 +192,7 @@ static void coldboot(const char *path)
}
}
static int process_config(VolumeManager *vm)
{
static int process_config(VolumeManager *vm) {
char hardware[PROPERTY_VALUE_MAX];
property_get("ro.hardware", hardware, "");
std::string fstab_filename(StringPrintf("/fstab.%s", hardware));