Merge "Set SELinux contexts on device nodes created by vold."
diff --git a/Loop.cpp b/Loop.cpp
index 3f0ee1e..9ee7434 100644
--- a/Loop.cpp
+++ b/Loop.cpp
@@ -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 @@
     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 @@
          */
         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));
diff --git a/Volume.cpp b/Volume.cpp
index 0baf008..bfad29d 100644
--- a/Volume.cpp
+++ b/Volume.cpp
@@ -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 @@
 }
 
 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;
 }
 
diff --git a/main.cpp b/main.cpp
index d4b7d28..c07f48d 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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 @@
 #define FSTAB_PREFIX "/fstab."
 struct fstab *fstab;
 
+struct selabel_handle *sehandle;
+
 int main() {
 
     VolumeManager *vm;
@@ -51,6 +54,10 @@
 
     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 */
diff --git a/sehandle.h b/sehandle.h
new file mode 100644
index 0000000..f59d7eb
--- /dev/null
+++ b/sehandle.h
@@ -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