merge in jb-mr2-release history after reset to master
diff --git a/include/cutils/properties.h b/include/cutils/properties.h
index 25fd67a..f1461f2 100644
--- a/include/cutils/properties.h
+++ b/include/cutils/properties.h
@@ -17,6 +17,8 @@
 #ifndef __CUTILS_PROPERTIES_H
 #define __CUTILS_PROPERTIES_H
 
+#include <stddef.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -62,6 +64,26 @@
 };
 #endif /*HAVE_SYSTEM_PROPERTY_SERVER*/
 
+#if defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 && !defined(__MINGW32__) && !defined(__clang__)
+
+extern int __property_get_real(const char *, char *, const char *)
+    __asm__(__USER_LABEL_PREFIX__ "property_get");
+extern void __property_get_too_small_error()
+    __attribute__((__error__("property_get() called with too small of a buffer")));
+
+extern inline
+__attribute__ ((always_inline))
+__attribute__ ((gnu_inline))
+__attribute__ ((artificial))
+int property_get(const char *key, char *value, const char *default_value) {
+    size_t bos = __builtin_object_size(value, 0);
+    if (bos < PROPERTY_VALUE_MAX) {
+        __property_get_too_small_error();
+    }
+    return __property_get_real(key, value, default_value);
+}
+
+#endif /* defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 && !defined(__MINGW32__) && !defined(__clang__) */
 
 #ifdef __cplusplus
 }
diff --git a/init/init.c b/init/init.c
index 2fbe002..bfaf983 100755
--- a/init/init.c
+++ b/init/init.c
@@ -197,28 +197,36 @@
     }
 
     if (is_selinux_enabled() > 0) {
-        char *mycon = NULL, *fcon = NULL;
+        if (svc->seclabel) {
+            scon = strdup(svc->seclabel);
+            if (!scon) {
+                ERROR("Out of memory while starting '%s'\n", svc->name);
+                return;
+            }
+        } else {
+            char *mycon = NULL, *fcon = NULL;
 
-        INFO("computing context for service '%s'\n", svc->args[0]);
-        rc = getcon(&mycon);
-        if (rc < 0) {
-            ERROR("could not get context while starting '%s'\n", svc->name);
-            return;
-        }
+            INFO("computing context for service '%s'\n", svc->args[0]);
+            rc = getcon(&mycon);
+            if (rc < 0) {
+                ERROR("could not get context while starting '%s'\n", svc->name);
+                return;
+            }
 
-        rc = getfilecon(svc->args[0], &fcon);
-        if (rc < 0) {
-            ERROR("could not get context while starting '%s'\n", svc->name);
+            rc = getfilecon(svc->args[0], &fcon);
+            if (rc < 0) {
+                ERROR("could not get context while starting '%s'\n", svc->name);
+                freecon(mycon);
+                return;
+            }
+
+            rc = security_compute_create(mycon, fcon, string_to_security_class("process"), &scon);
             freecon(mycon);
-            return;
-        }
-
-        rc = security_compute_create(mycon, fcon, string_to_security_class("process"), &scon);
-        freecon(mycon);
-        freecon(fcon);
-        if (rc < 0) {
-            ERROR("could not get context while starting '%s'\n", svc->name);
-            return;
+            freecon(fcon);
+            if (rc < 0) {
+                ERROR("could not get context while starting '%s'\n", svc->name);
+                return;
+            }
         }
     }