Set SELinux contexts on device nodes created by vold.

Extend vold to look up and set SELinux contexts on the
device nodes it creates for extra loop devices and for volumes.
Prior to this change, these device nodes simply inherited the type
of their parent directory /dev/block, i.e. block_device, and vold
therefore required create_file perms to block_device:blk_file.
With this change we can scope vold down to accessing specific
block device types.

This depends on change Id3bea28f5958086716cd3db055bea309b3b5fa5a
to allow vold to use setfscreatecon().

Change-Id: Ib9e8294abb1da94d92503947603ec12e802ff08c
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
This commit is contained in:
Stephen Smalley 2014-09-30 10:29:24 -04:00
parent 6efa9351a2
commit 684e662502
4 changed files with 68 additions and 0 deletions

View file

@ -35,6 +35,7 @@
#include <sysutils/SocketClient.h>
#include "Loop.h"
#include "Asec.h"
#include "sehandle.h"
int Loop::dumpState(SocketClient *c) {
int i;
@ -132,6 +133,7 @@ int Loop::create(const char *id, const char *loopFile, char *loopDeviceBuffer, s
for (i = 0; i < LOOP_MAX; i++) {
struct loop_info64 li;
int rc;
char *secontext = NULL;
sprintf(filename, "/dev/block/loop%d", i);
@ -141,12 +143,29 @@ int Loop::create(const char *id, const char *loopFile, char *loopDeviceBuffer, s
*/
mode_t mode = 0660 | S_IFBLK;
unsigned int dev = (0xff & i) | ((i << 12) & 0xfff00000) | (7 << 8);
if (sehandle) {
rc = selabel_lookup(sehandle, &secontext, filename, S_IFBLK);
if (rc == 0)
setfscreatecon(secontext);
}
if (mknod(filename, mode, dev) < 0) {
if (errno != EEXIST) {
int sverrno = errno;
SLOGE("Error creating loop device node (%s)", strerror(errno));
if (secontext) {
freecon(secontext);
setfscreatecon(NULL);
}
errno = sverrno;
return -1;
}
}
if (secontext) {
freecon(secontext);
setfscreatecon(NULL);
}
if ((fd = open(filename, O_RDWR)) < 0) {
SLOGE("Unable to open %s (%s)", filename, strerror(errno));

View file

@ -48,6 +48,7 @@
#include "Fat.h"
#include "Process.h"
#include "cryptfs.h"
#include "sehandle.h"
extern "C" void dos_partition_dec(void const *pp, struct dos_partition *d);
extern "C" void dos_partition_enc(void *pp, struct dos_partition *d);
@ -219,13 +220,30 @@ void Volume::setState(int state) {
}
int Volume::createDeviceNode(const char *path, int major, int minor) {
char *secontext = NULL;
mode_t mode = 0660 | S_IFBLK;
dev_t dev = (major << 8) | minor;
int rc;
if (sehandle) {
rc = selabel_lookup(sehandle, &secontext, path, S_IFBLK);
if (rc == 0)
setfscreatecon(secontext);
}
if (mknod(path, mode, dev) < 0) {
if (errno != EEXIST) {
int sverrno = errno;
if (secontext) {
freecon(secontext);
setfscreatecon(NULL);
}
errno = sverrno;
return -1;
}
}
if (secontext) {
setfscreatecon(NULL);
freecon(secontext);
}
return 0;
}

View file

@ -36,6 +36,7 @@
#include "NetlinkManager.h"
#include "DirectVolume.h"
#include "cryptfs.h"
#include "sehandle.h"
static int process_config(VolumeManager *vm);
static void coldboot(const char *path);
@ -43,6 +44,8 @@ static void coldboot(const char *path);
#define FSTAB_PREFIX "/fstab."
struct fstab *fstab;
struct selabel_handle *sehandle;
int main() {
VolumeManager *vm;
@ -51,6 +54,10 @@ int main() {
SLOGI("Vold 2.1 (the revenge) firing up");
sehandle = selinux_android_file_context_handle();
if (sehandle)
selinux_android_set_sehandle(sehandle);
mkdir("/dev/block/vold", 0755);
/* For when cryptfs checks and mounts an encrypted filesystem */

24
sehandle.h Normal file
View file

@ -0,0 +1,24 @@
/*
* Copyright (C) 2014 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.
*/
#ifndef _SEHANDLE_H
#define _SEHANDLE_H
#include <selinux/android.h>
extern struct selabel_handle *sehandle;
#endif